solara-ui 1.45.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (464) hide show
  1. prefix/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
  2. prefix/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
  3. solara/__init__.py +124 -0
  4. solara/__main__.py +765 -0
  5. solara/_stores.py +297 -0
  6. solara/alias.py +6 -0
  7. solara/autorouting.py +555 -0
  8. solara/cache.py +305 -0
  9. solara/checks.html +71 -0
  10. solara/checks.py +227 -0
  11. solara/comm.py +28 -0
  12. solara/components/__init__.py +77 -0
  13. solara/components/alert.py +155 -0
  14. solara/components/applayout.py +397 -0
  15. solara/components/button.py +85 -0
  16. solara/components/card.py +87 -0
  17. solara/components/checkbox.py +50 -0
  18. solara/components/code_highlight_css.py +11 -0
  19. solara/components/code_highlight_css.vue +63 -0
  20. solara/components/columns.py +159 -0
  21. solara/components/component_vue.py +134 -0
  22. solara/components/cross_filter.py +335 -0
  23. solara/components/dataframe.py +546 -0
  24. solara/components/datatable.py +214 -0
  25. solara/components/datatable.vue +175 -0
  26. solara/components/details.py +56 -0
  27. solara/components/download.vue +35 -0
  28. solara/components/echarts.py +86 -0
  29. solara/components/echarts.vue +139 -0
  30. solara/components/figure_altair.py +39 -0
  31. solara/components/file_browser.py +181 -0
  32. solara/components/file_download.py +199 -0
  33. solara/components/file_drop.py +159 -0
  34. solara/components/file_drop.vue +83 -0
  35. solara/components/file_list_widget.vue +78 -0
  36. solara/components/head.py +27 -0
  37. solara/components/head_tag.py +49 -0
  38. solara/components/head_tag.vue +60 -0
  39. solara/components/image.py +173 -0
  40. solara/components/input.py +456 -0
  41. solara/components/input_text_area.py +86 -0
  42. solara/components/link.py +55 -0
  43. solara/components/markdown.py +441 -0
  44. solara/components/markdown_editor.py +33 -0
  45. solara/components/markdown_editor.vue +359 -0
  46. solara/components/matplotlib.py +74 -0
  47. solara/components/meta.py +47 -0
  48. solara/components/misc.py +333 -0
  49. solara/components/pivot_table.py +258 -0
  50. solara/components/pivot_table.vue +158 -0
  51. solara/components/progress.py +47 -0
  52. solara/components/select.py +182 -0
  53. solara/components/select.vue +27 -0
  54. solara/components/slider.py +442 -0
  55. solara/components/slider_date.vue +56 -0
  56. solara/components/spinner-solara.vue +105 -0
  57. solara/components/spinner.py +45 -0
  58. solara/components/sql_code.py +41 -0
  59. solara/components/sql_code.vue +125 -0
  60. solara/components/style.py +105 -0
  61. solara/components/switch.py +71 -0
  62. solara/components/tab_navigation.py +37 -0
  63. solara/components/title.py +90 -0
  64. solara/components/title.vue +38 -0
  65. solara/components/togglebuttons.py +200 -0
  66. solara/components/tooltip.py +61 -0
  67. solara/core.py +42 -0
  68. solara/datatypes.py +143 -0
  69. solara/express.py +241 -0
  70. solara/hooks/__init__.py +4 -0
  71. solara/hooks/dataframe.py +99 -0
  72. solara/hooks/misc.py +263 -0
  73. solara/hooks/use_reactive.py +151 -0
  74. solara/hooks/use_thread.py +129 -0
  75. solara/kitchensink.py +8 -0
  76. solara/lab/__init__.py +34 -0
  77. solara/lab/components/__init__.py +7 -0
  78. solara/lab/components/chat.py +215 -0
  79. solara/lab/components/confirmation_dialog.py +163 -0
  80. solara/lab/components/cross_filter.py +7 -0
  81. solara/lab/components/input_date.py +339 -0
  82. solara/lab/components/input_time.py +133 -0
  83. solara/lab/components/menu.py +181 -0
  84. solara/lab/components/menu.vue +38 -0
  85. solara/lab/components/tabs.py +274 -0
  86. solara/lab/components/theming.py +98 -0
  87. solara/lab/components/theming.vue +72 -0
  88. solara/lab/hooks/__init__.py +0 -0
  89. solara/lab/hooks/dataframe.py +2 -0
  90. solara/lab/toestand.py +3 -0
  91. solara/lab/utils/__init__.py +2 -0
  92. solara/lab/utils/cookies.py +5 -0
  93. solara/lab/utils/dataframe.py +165 -0
  94. solara/lab/utils/headers.py +5 -0
  95. solara/layout.py +44 -0
  96. solara/lifecycle.py +46 -0
  97. solara/minisettings.py +141 -0
  98. solara/py.typed +0 -0
  99. solara/reactive.py +99 -0
  100. solara/routing.py +268 -0
  101. solara/scope/__init__.py +88 -0
  102. solara/scope/types.py +55 -0
  103. solara/server/__init__.py +0 -0
  104. solara/server/app.py +527 -0
  105. solara/server/assets/custom.css +1 -0
  106. solara/server/assets/custom.js +1 -0
  107. solara/server/assets/favicon.png +0 -0
  108. solara/server/assets/favicon.svg +5 -0
  109. solara/server/assets/style.css +1681 -0
  110. solara/server/assets/theme-dark.css +437 -0
  111. solara/server/assets/theme-light.css +420 -0
  112. solara/server/assets/theme.js +3 -0
  113. solara/server/cdn_helper.py +91 -0
  114. solara/server/esm.py +71 -0
  115. solara/server/fastapi.py +5 -0
  116. solara/server/flask.py +297 -0
  117. solara/server/jupyter/__init__.py +2 -0
  118. solara/server/jupyter/cdn_handler.py +28 -0
  119. solara/server/jupyter/server_extension.py +40 -0
  120. solara/server/jupyter/solara.py +91 -0
  121. solara/server/jupytertools.py +46 -0
  122. solara/server/kernel.py +388 -0
  123. solara/server/kernel_context.py +467 -0
  124. solara/server/patch.py +564 -0
  125. solara/server/pyinstaller/__init__.py +9 -0
  126. solara/server/pyinstaller/hook-ipyreact.py +5 -0
  127. solara/server/pyinstaller/hook-ipyvuetify.py +5 -0
  128. solara/server/pyinstaller/hook-solara.py +9 -0
  129. solara/server/qt.py +113 -0
  130. solara/server/reload.py +251 -0
  131. solara/server/server.py +484 -0
  132. solara/server/settings.py +249 -0
  133. solara/server/shell.py +269 -0
  134. solara/server/starlette.py +770 -0
  135. solara/server/static/ansi.js +270 -0
  136. solara/server/static/highlight-dark.css +82 -0
  137. solara/server/static/highlight.css +43 -0
  138. solara/server/static/main-vuetify.js +272 -0
  139. solara/server/static/main.js +163 -0
  140. solara/server/static/solara_bootstrap.py +129 -0
  141. solara/server/static/sun.svg +23 -0
  142. solara/server/static/webworker.js +42 -0
  143. solara/server/telemetry.py +212 -0
  144. solara/server/templates/index.html.j2 +1 -0
  145. solara/server/templates/loader-plain.css +11 -0
  146. solara/server/templates/loader-plain.html +20 -0
  147. solara/server/templates/loader-solara.css +111 -0
  148. solara/server/templates/loader-solara.html +40 -0
  149. solara/server/templates/plain.html +82 -0
  150. solara/server/templates/solara.html.j2 +486 -0
  151. solara/server/threaded.py +84 -0
  152. solara/server/utils.py +44 -0
  153. solara/server/websocket.py +45 -0
  154. solara/settings.py +86 -0
  155. solara/tasks.py +893 -0
  156. solara/template/button.py +16 -0
  157. solara/template/markdown.py +42 -0
  158. solara/template/portal/.flake8 +6 -0
  159. solara/template/portal/.pre-commit-config.yaml +28 -0
  160. solara/template/portal/LICENSE +21 -0
  161. solara/template/portal/Procfile +7 -0
  162. solara/template/portal/mypy.ini +3 -0
  163. solara/template/portal/pyproject.toml +26 -0
  164. solara/template/portal/solara_portal/__init__.py +4 -0
  165. solara/template/portal/solara_portal/components/__init__.py +2 -0
  166. solara/template/portal/solara_portal/components/article.py +28 -0
  167. solara/template/portal/solara_portal/components/data.py +28 -0
  168. solara/template/portal/solara_portal/components/header.py +6 -0
  169. solara/template/portal/solara_portal/components/layout.py +6 -0
  170. solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +85 -0
  171. solara/template/portal/solara_portal/content/articles/substiterat-vati.md +70 -0
  172. solara/template/portal/solara_portal/data.py +60 -0
  173. solara/template/portal/solara_portal/pages/__init__.py +67 -0
  174. solara/template/portal/solara_portal/pages/article/__init__.py +26 -0
  175. solara/template/portal/solara_portal/pages/tabular.py +29 -0
  176. solara/template/portal/solara_portal/pages/viz/__init__.py +70 -0
  177. solara/template/portal/solara_portal/pages/viz/overview.py +14 -0
  178. solara/test/__init__.py +0 -0
  179. solara/test/pytest_plugin.py +783 -0
  180. solara/toestand.py +998 -0
  181. solara/util.py +348 -0
  182. solara/validate_hooks.py +258 -0
  183. solara/website/__init__.py +0 -0
  184. solara/website/assets/custom.css +444 -0
  185. solara/website/assets/images/logo-small.png +0 -0
  186. solara/website/assets/images/logo.svg +17 -0
  187. solara/website/assets/images/logo_white.svg +50 -0
  188. solara/website/assets/theme.js +8 -0
  189. solara/website/components/__init__.py +5 -0
  190. solara/website/components/algolia.py +6 -0
  191. solara/website/components/algolia.vue +24 -0
  192. solara/website/components/algolia_api.vue +202 -0
  193. solara/website/components/breadcrumbs.py +28 -0
  194. solara/website/components/contact.py +144 -0
  195. solara/website/components/docs.py +143 -0
  196. solara/website/components/header.py +75 -0
  197. solara/website/components/mailchimp.py +12 -0
  198. solara/website/components/mailchimp.vue +47 -0
  199. solara/website/components/markdown.py +99 -0
  200. solara/website/components/markdown_nav.vue +34 -0
  201. solara/website/components/notebook.py +171 -0
  202. solara/website/components/sidebar.py +105 -0
  203. solara/website/pages/__init__.py +370 -0
  204. solara/website/pages/about/__init__.py +9 -0
  205. solara/website/pages/about/about.md +3 -0
  206. solara/website/pages/apps/__init__.py +16 -0
  207. solara/website/pages/apps/authorization/__init__.py +119 -0
  208. solara/website/pages/apps/authorization/admin.py +12 -0
  209. solara/website/pages/apps/authorization/users.py +12 -0
  210. solara/website/pages/apps/jupyter-dashboard-1.py +116 -0
  211. solara/website/pages/apps/layout-demo.py +40 -0
  212. solara/website/pages/apps/multipage/__init__.py +38 -0
  213. solara/website/pages/apps/multipage/page1.py +26 -0
  214. solara/website/pages/apps/multipage/page2.py +34 -0
  215. solara/website/pages/apps/scatter.py +136 -0
  216. solara/website/pages/apps/scrolling.py +63 -0
  217. solara/website/pages/apps/tutorial-streamlit.py +18 -0
  218. solara/website/pages/careers/__init__.py +27 -0
  219. solara/website/pages/changelog/__init__.py +10 -0
  220. solara/website/pages/changelog/changelog.md +372 -0
  221. solara/website/pages/contact/__init__.py +34 -0
  222. solara/website/pages/doc_use_download.py +85 -0
  223. solara/website/pages/documentation/__init__.py +90 -0
  224. solara/website/pages/documentation/advanced/__init__.py +9 -0
  225. solara/website/pages/documentation/advanced/content/00-overview.md +1 -0
  226. solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +6 -0
  227. solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +196 -0
  228. solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +125 -0
  229. solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +417 -0
  230. solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +69 -0
  231. solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +50 -0
  232. solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +124 -0
  233. solara/website/pages/documentation/advanced/content/15-reference/00-overview.md +3 -0
  234. solara/website/pages/documentation/advanced/content/15-reference/40-static_files.md +31 -0
  235. solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +72 -0
  236. solara/website/pages/documentation/advanced/content/15-reference/60-static-site-generation.md +59 -0
  237. solara/website/pages/documentation/advanced/content/15-reference/70-search.md +34 -0
  238. solara/website/pages/documentation/advanced/content/15-reference/80-reloading.md +34 -0
  239. solara/website/pages/documentation/advanced/content/15-reference/90-notebook-support.md +7 -0
  240. solara/website/pages/documentation/advanced/content/15-reference/95-caching.md +148 -0
  241. solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +10 -0
  242. solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +35 -0
  243. solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +42 -0
  244. solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +28 -0
  245. solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +108 -0
  246. solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +23 -0
  247. solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +192 -0
  248. solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +166 -0
  249. solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +18 -0
  250. solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +256 -0
  251. solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +108 -0
  252. solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +12 -0
  253. solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +7 -0
  254. solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +187 -0
  255. solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
  256. solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +45 -0
  257. solara/website/pages/documentation/advanced/content/40-development/10-setup.md +76 -0
  258. solara/website/pages/documentation/api/__init__.py +19 -0
  259. solara/website/pages/documentation/api/cross_filter/__init__.py +9 -0
  260. solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +22 -0
  261. solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +20 -0
  262. solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +20 -0
  263. solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +20 -0
  264. solara/website/pages/documentation/api/hooks/__init__.py +9 -0
  265. solara/website/pages/documentation/api/hooks/use_cross_filter.py +23 -0
  266. solara/website/pages/documentation/api/hooks/use_dark_effective.py +12 -0
  267. solara/website/pages/documentation/api/hooks/use_effect.md +43 -0
  268. solara/website/pages/documentation/api/hooks/use_effect.py +9 -0
  269. solara/website/pages/documentation/api/hooks/use_exception.py +31 -0
  270. solara/website/pages/documentation/api/hooks/use_memo.md +16 -0
  271. solara/website/pages/documentation/api/hooks/use_memo.py +9 -0
  272. solara/website/pages/documentation/api/hooks/use_previous.py +30 -0
  273. solara/website/pages/documentation/api/hooks/use_reactive.py +16 -0
  274. solara/website/pages/documentation/api/hooks/use_state.py +10 -0
  275. solara/website/pages/documentation/api/hooks/use_state_or_update.py +66 -0
  276. solara/website/pages/documentation/api/hooks/use_thread.md +64 -0
  277. solara/website/pages/documentation/api/hooks/use_thread.py +42 -0
  278. solara/website/pages/documentation/api/hooks/use_trait_observe.py +12 -0
  279. solara/website/pages/documentation/api/routing/__init__.py +9 -0
  280. solara/website/pages/documentation/api/routing/generate_routes.py +10 -0
  281. solara/website/pages/documentation/api/routing/generate_routes_directory.py +10 -0
  282. solara/website/pages/documentation/api/routing/resolve_path.py +35 -0
  283. solara/website/pages/documentation/api/routing/route.py +29 -0
  284. solara/website/pages/documentation/api/routing/use_route.py +76 -0
  285. solara/website/pages/documentation/api/routing/use_router.py +16 -0
  286. solara/website/pages/documentation/api/utilities/__init__.py +9 -0
  287. solara/website/pages/documentation/api/utilities/component_vue.py +10 -0
  288. solara/website/pages/documentation/api/utilities/computed.py +16 -0
  289. solara/website/pages/documentation/api/utilities/display.py +16 -0
  290. solara/website/pages/documentation/api/utilities/get_kernel_id.py +16 -0
  291. solara/website/pages/documentation/api/utilities/get_session_id.py +16 -0
  292. solara/website/pages/documentation/api/utilities/memoize.py +35 -0
  293. solara/website/pages/documentation/api/utilities/on_kernel_start.py +44 -0
  294. solara/website/pages/documentation/api/utilities/reactive.py +16 -0
  295. solara/website/pages/documentation/api/utilities/widget.py +104 -0
  296. solara/website/pages/documentation/components/__init__.py +12 -0
  297. solara/website/pages/documentation/components/advanced/__init__.py +9 -0
  298. solara/website/pages/documentation/components/advanced/link.py +25 -0
  299. solara/website/pages/documentation/components/advanced/meta.py +17 -0
  300. solara/website/pages/documentation/components/advanced/style.py +43 -0
  301. solara/website/pages/documentation/components/common.py +9 -0
  302. solara/website/pages/documentation/components/data/__init__.py +9 -0
  303. solara/website/pages/documentation/components/data/dataframe.py +44 -0
  304. solara/website/pages/documentation/components/data/pivot_table.py +81 -0
  305. solara/website/pages/documentation/components/enterprise/__init__.py +9 -0
  306. solara/website/pages/documentation/components/enterprise/avatar.py +24 -0
  307. solara/website/pages/documentation/components/enterprise/avatar_menu.py +25 -0
  308. solara/website/pages/documentation/components/input/__init__.py +9 -0
  309. solara/website/pages/documentation/components/input/button.py +23 -0
  310. solara/website/pages/documentation/components/input/checkbox.py +10 -0
  311. solara/website/pages/documentation/components/input/file_browser.py +30 -0
  312. solara/website/pages/documentation/components/input/file_drop.py +76 -0
  313. solara/website/pages/documentation/components/input/input.py +43 -0
  314. solara/website/pages/documentation/components/input/select.py +22 -0
  315. solara/website/pages/documentation/components/input/slider.py +29 -0
  316. solara/website/pages/documentation/components/input/switch.py +10 -0
  317. solara/website/pages/documentation/components/input/togglebuttons.py +21 -0
  318. solara/website/pages/documentation/components/lab/__init__.py +9 -0
  319. solara/website/pages/documentation/components/lab/chat.py +109 -0
  320. solara/website/pages/documentation/components/lab/confirmation_dialog.py +55 -0
  321. solara/website/pages/documentation/components/lab/cookies_headers.py +48 -0
  322. solara/website/pages/documentation/components/lab/input_date.py +20 -0
  323. solara/website/pages/documentation/components/lab/input_time.py +15 -0
  324. solara/website/pages/documentation/components/lab/menu.py +22 -0
  325. solara/website/pages/documentation/components/lab/tab.py +25 -0
  326. solara/website/pages/documentation/components/lab/tabs.py +45 -0
  327. solara/website/pages/documentation/components/lab/task.py +11 -0
  328. solara/website/pages/documentation/components/lab/theming.py +74 -0
  329. solara/website/pages/documentation/components/lab/use_task.py +11 -0
  330. solara/website/pages/documentation/components/layout/__init__.py +9 -0
  331. solara/website/pages/documentation/components/layout/app_bar.py +16 -0
  332. solara/website/pages/documentation/components/layout/app_bar_title.py +16 -0
  333. solara/website/pages/documentation/components/layout/app_layout.py +24 -0
  334. solara/website/pages/documentation/components/layout/card.py +15 -0
  335. solara/website/pages/documentation/components/layout/card_actions.py +16 -0
  336. solara/website/pages/documentation/components/layout/column.py +30 -0
  337. solara/website/pages/documentation/components/layout/columns.py +27 -0
  338. solara/website/pages/documentation/components/layout/columns_responsive.py +66 -0
  339. solara/website/pages/documentation/components/layout/details.py +13 -0
  340. solara/website/pages/documentation/components/layout/griddraggable.py +62 -0
  341. solara/website/pages/documentation/components/layout/gridfixed.py +19 -0
  342. solara/website/pages/documentation/components/layout/hbox.py +18 -0
  343. solara/website/pages/documentation/components/layout/row.py +30 -0
  344. solara/website/pages/documentation/components/layout/sidebar.py +24 -0
  345. solara/website/pages/documentation/components/layout/vbox.py +19 -0
  346. solara/website/pages/documentation/components/output/__init__.py +9 -0
  347. solara/website/pages/documentation/components/output/file_download.py +11 -0
  348. solara/website/pages/documentation/components/output/html.py +19 -0
  349. solara/website/pages/documentation/components/output/image.py +11 -0
  350. solara/website/pages/documentation/components/output/markdown.py +57 -0
  351. solara/website/pages/documentation/components/output/markdown_editor.py +51 -0
  352. solara/website/pages/documentation/components/output/sql_code.py +83 -0
  353. solara/website/pages/documentation/components/output/tooltip.py +11 -0
  354. solara/website/pages/documentation/components/page/__init__.py +9 -0
  355. solara/website/pages/documentation/components/page/head.py +15 -0
  356. solara/website/pages/documentation/components/page/title.py +25 -0
  357. solara/website/pages/documentation/components/status/__init__.py +9 -0
  358. solara/website/pages/documentation/components/status/error.py +39 -0
  359. solara/website/pages/documentation/components/status/info.py +39 -0
  360. solara/website/pages/documentation/components/status/progress.py +10 -0
  361. solara/website/pages/documentation/components/status/spinner.py +11 -0
  362. solara/website/pages/documentation/components/status/success.py +40 -0
  363. solara/website/pages/documentation/components/status/warning.py +47 -0
  364. solara/website/pages/documentation/components/viz/__init__.py +9 -0
  365. solara/website/pages/documentation/components/viz/altair.py +42 -0
  366. solara/website/pages/documentation/components/viz/echarts.py +77 -0
  367. solara/website/pages/documentation/components/viz/matplotlib.py +30 -0
  368. solara/website/pages/documentation/components/viz/plotly.py +63 -0
  369. solara/website/pages/documentation/components/viz/plotly_express.py +41 -0
  370. solara/website/pages/documentation/examples/__init__.py +54 -0
  371. solara/website/pages/documentation/examples/ai/__init__.py +11 -0
  372. solara/website/pages/documentation/examples/ai/chatbot.py +113 -0
  373. solara/website/pages/documentation/examples/ai/tokenizer.py +107 -0
  374. solara/website/pages/documentation/examples/basics/__init__.py +10 -0
  375. solara/website/pages/documentation/examples/basics/sine.py +28 -0
  376. solara/website/pages/documentation/examples/fullscreen/__init__.py +10 -0
  377. solara/website/pages/documentation/examples/fullscreen/authorization.py +3 -0
  378. solara/website/pages/documentation/examples/fullscreen/layout_demo.py +3 -0
  379. solara/website/pages/documentation/examples/fullscreen/multipage.py +3 -0
  380. solara/website/pages/documentation/examples/fullscreen/scatter.py +3 -0
  381. solara/website/pages/documentation/examples/fullscreen/scrolling.py +3 -0
  382. solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +3 -0
  383. solara/website/pages/documentation/examples/general/__init__.py +10 -0
  384. solara/website/pages/documentation/examples/general/custom_storage.py +70 -0
  385. solara/website/pages/documentation/examples/general/deploy_model.py +115 -0
  386. solara/website/pages/documentation/examples/general/live_update.py +32 -0
  387. solara/website/pages/documentation/examples/general/login_oauth.py +81 -0
  388. solara/website/pages/documentation/examples/general/mycard.vue +58 -0
  389. solara/website/pages/documentation/examples/general/pokemon_search.py +51 -0
  390. solara/website/pages/documentation/examples/general/vue_component.py +50 -0
  391. solara/website/pages/documentation/examples/ipycanvas.py +49 -0
  392. solara/website/pages/documentation/examples/libraries/__init__.py +10 -0
  393. solara/website/pages/documentation/examples/libraries/altair.py +65 -0
  394. solara/website/pages/documentation/examples/libraries/bqplot.py +39 -0
  395. solara/website/pages/documentation/examples/libraries/ipyleaflet.py +33 -0
  396. solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +66 -0
  397. solara/website/pages/documentation/examples/utilities/__init__.py +10 -0
  398. solara/website/pages/documentation/examples/utilities/calculator.py +157 -0
  399. solara/website/pages/documentation/examples/utilities/countdown_timer.py +62 -0
  400. solara/website/pages/documentation/examples/utilities/todo.py +196 -0
  401. solara/website/pages/documentation/examples/visualization/__init__.py +6 -0
  402. solara/website/pages/documentation/examples/visualization/annotator.py +67 -0
  403. solara/website/pages/documentation/examples/visualization/linked_views.py +81 -0
  404. solara/website/pages/documentation/examples/visualization/plotly.py +44 -0
  405. solara/website/pages/documentation/faq/__init__.py +12 -0
  406. solara/website/pages/documentation/faq/content/99-faq.md +112 -0
  407. solara/website/pages/documentation/getting_started/__init__.py +9 -0
  408. solara/website/pages/documentation/getting_started/content/00-quickstart.md +107 -0
  409. solara/website/pages/documentation/getting_started/content/01-introduction.md +125 -0
  410. solara/website/pages/documentation/getting_started/content/02-installing.md +134 -0
  411. solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +14 -0
  412. solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +13 -0
  413. solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +89 -0
  414. solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +124 -0
  415. solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +146 -0
  416. solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +144 -0
  417. solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +65 -0
  418. solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
  419. solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +445 -0
  420. solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +1021 -0
  421. solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +11 -0
  422. solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +228 -0
  423. solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +278 -0
  424. solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +7 -0
  425. solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +305 -0
  426. solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +80 -0
  427. solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +7 -0
  428. solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +26 -0
  429. solara/website/pages/docutils.py +38 -0
  430. solara/website/pages/home.vue +1199 -0
  431. solara/website/pages/our_team/__init__.py +83 -0
  432. solara/website/pages/pricing/__init__.py +31 -0
  433. solara/website/pages/roadmap/__init__.py +11 -0
  434. solara/website/pages/roadmap/roadmap.md +47 -0
  435. solara/website/pages/scale_ipywidgets.py +45 -0
  436. solara/website/pages/showcase/__init__.py +105 -0
  437. solara/website/pages/showcase/domino_code_assist.py +60 -0
  438. solara/website/pages/showcase/planeto_tessa.py +19 -0
  439. solara/website/pages/showcase/solara_dev.py +54 -0
  440. solara/website/pages/showcase/solarathon_2023_team_2.py +22 -0
  441. solara/website/pages/showcase/solarathon_2023_team_4.py +22 -0
  442. solara/website/pages/showcase/solarathon_2023_team_5.py +23 -0
  443. solara/website/pages/showcase/solarathon_2023_team_6.py +34 -0
  444. solara/website/pages/showcase/wanderlust.py +27 -0
  445. solara/website/public/beach.jpeg +0 -0
  446. solara/website/public/logo.svg +6 -0
  447. solara/website/public/social/discord.svg +1 -0
  448. solara/website/public/social/github.svg +1 -0
  449. solara/website/public/social/twitter.svg +3 -0
  450. solara/website/public/success.html +25 -0
  451. solara/website/templates/index.html.j2 +117 -0
  452. solara/website/utils.py +51 -0
  453. solara/widgets/__init__.py +1 -0
  454. solara/widgets/vue/gridlayout.vue +107 -0
  455. solara/widgets/vue/html.vue +4 -0
  456. solara/widgets/vue/navigator.vue +134 -0
  457. solara/widgets/vue/vegalite.vue +130 -0
  458. solara/widgets/widgets.py +74 -0
  459. solara_ui-1.45.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
  460. solara_ui-1.45.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
  461. solara_ui-1.45.0.dist-info/METADATA +162 -0
  462. solara_ui-1.45.0.dist-info/RECORD +464 -0
  463. solara_ui-1.45.0.dist-info/WHEEL +4 -0
  464. solara_ui-1.45.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,214 @@
1
+ import dataclasses
2
+ import math
3
+ import os
4
+ from dataclasses import replace
5
+ from typing import Any, Callable, List, Optional, cast
6
+
7
+ import ipyvuetify as v
8
+ import ipywidgets
9
+ import solara
10
+ import solara.hooks.dataframe
11
+ import solara.lab
12
+ import traitlets
13
+ from solara.lab.hooks.dataframe import use_df_column_names, df_row_names
14
+ from solara.lab.utils.dataframe import df_len, df_records, df_slice
15
+
16
+ from .. import CellAction, ColumnAction
17
+
18
+
19
+ def _ensure_dict(d):
20
+ if dataclasses.is_dataclass(d) and not isinstance(d, type): # is_dataclass also returns True for dataclass type, rather than instance
21
+ return dataclasses.asdict(d)
22
+ return d
23
+
24
+
25
+ def _drop_keys_from_list_of_mappings(drop):
26
+ def closure(list_of_dicts, widget):
27
+ return [{k: v for k, v in _ensure_dict(d).items() if k not in drop} for d in list_of_dicts]
28
+
29
+ return closure
30
+
31
+
32
+ class DataTableWidget(v.VuetifyTemplate):
33
+ template_file = os.path.realpath(os.path.join(os.path.dirname(__file__), "datatable.vue"))
34
+
35
+ total_length = traitlets.CInt().tag(sync=True)
36
+ checked = traitlets.List(cast(List[Any], [])).tag(sync=True) # indices of which rows are selected
37
+ column_actions = traitlets.List(trait=traitlets.Instance(ColumnAction), default_value=[]).tag(
38
+ sync=True, to_json=_drop_keys_from_list_of_mappings(["on_click"])
39
+ )
40
+ _column_actions_callbacks = traitlets.List(trait=traitlets.Callable(), default_value=[])
41
+ cell_actions = traitlets.List(trait=traitlets.Instance(CellAction), default_value=[]).tag(sync=True, to_json=_drop_keys_from_list_of_mappings(["on_click"]))
42
+ _cell_actions_callbacks = traitlets.List(trait=traitlets.Callable(), default_value=[])
43
+ items = traitlets.Any().tag(sync=True) # the data, a list of dict
44
+ headers = traitlets.Any().tag(sync=True)
45
+ headers_selections = traitlets.Any().tag(sync=True)
46
+ options = traitlets.Any().tag(sync=True)
47
+ items_per_page = traitlets.CInt(11).tag(sync=True)
48
+ selections = traitlets.Any([]).tag(sync=True)
49
+ selection_colors = traitlets.Any([]).tag(sync=True)
50
+ selection_enabled = traitlets.Bool(True).tag(sync=True)
51
+ highlighted = traitlets.Int(None, allow_none=True).tag(sync=True)
52
+ scrollable = traitlets.Bool(False).tag(sync=True)
53
+
54
+ # for use with scrollable, when used in the default UI
55
+ height = traitlets.Unicode(None, allow_none=True).tag(sync=True)
56
+
57
+ hidden_components = traitlets.List(cast(List[Any], [])).tag(sync=False)
58
+ column_header_hover = traitlets.Unicode(allow_none=True).tag(sync=True)
59
+ column_header_widget = traitlets.Any(allow_none=True).tag(sync=True, **ipywidgets.widget_serialization)
60
+
61
+ def vue_on_column_action(self, data):
62
+ header_value, action_index = data
63
+ on_click = self._column_actions_callbacks[action_index]
64
+ if on_click:
65
+ on_click(header_value)
66
+
67
+ def vue_on_cell_action(self, data):
68
+ row, header_value, action_index = data
69
+ on_click = self._cell_actions_callbacks[action_index]
70
+ if on_click:
71
+ on_click(header_value, row)
72
+
73
+
74
+ def format_default(df, column, row_index, value):
75
+ if isinstance(value, float) and math.isnan(value):
76
+ return "NaN"
77
+ return str(value)
78
+
79
+
80
+ @solara.component
81
+ def DataTable(
82
+ df,
83
+ page=0,
84
+ items_per_page=20,
85
+ format=None,
86
+ column_actions: List[ColumnAction] = [],
87
+ cell_actions: List[CellAction] = [],
88
+ scrollable=False,
89
+ on_column_header_hover: Optional[Callable[[Optional[str]], None]] = None,
90
+ column_header_info: Optional[solara.Element] = None,
91
+ ):
92
+ total_length = df_len(df)
93
+ options = {"descending": False, "page": page + 1, "itemsPerPage": items_per_page, "sortBy": [], "totalItems": total_length}
94
+ options, set_options = solara.use_state(options, key="options")
95
+ format = format or format_default
96
+ # frontend does 1 base, we use 0 based
97
+ page = options["page"] - 1
98
+ items_per_page = options["itemsPerPage"]
99
+ i1 = page * items_per_page
100
+ i2 = min(total_length, (page + 1) * items_per_page)
101
+
102
+ columns = use_df_column_names(df)
103
+ rows = df_row_names(df)
104
+ items = []
105
+ dfs = df_slice(df, i1, i2)
106
+ records = df_records(dfs)
107
+ for i in range(i2 - i1):
108
+ item = {"__row__": format(dfs, columns, i + 1, rows[i + i1])} # special key for the row number
109
+ for column in columns:
110
+ item[column] = format(dfs, column, i + i1, records[i][column])
111
+ items.append(item)
112
+
113
+ headers = [{"text": name, "value": name, "sortable": False} for name in columns]
114
+ column_actions_callbacks = [k.on_click for k in column_actions]
115
+ cell_actions_callbacks = [k.on_click for k in cell_actions]
116
+ column_actions = [replace(k, on_click=None) for k in column_actions]
117
+ cell_actions = [replace(k, on_click=None) for k in cell_actions]
118
+
119
+ return DataTableWidget.element(
120
+ total_length=total_length,
121
+ items=items,
122
+ headers=headers,
123
+ headers_selections=[],
124
+ options=options,
125
+ items_per_page=items_per_page,
126
+ selections=[],
127
+ selection_colors=[],
128
+ selection_enabled=False,
129
+ highlighted=None,
130
+ scrollable=scrollable,
131
+ on_options=set_options,
132
+ column_actions=column_actions,
133
+ cell_actions=cell_actions,
134
+ _column_actions_callbacks=column_actions_callbacks,
135
+ _cell_actions_callbacks=cell_actions_callbacks,
136
+ on_column_header_hover=on_column_header_hover,
137
+ column_header_widget=column_header_info,
138
+ )
139
+
140
+
141
+ @solara.component
142
+ def DataFrame(
143
+ df,
144
+ items_per_page=20,
145
+ column_actions: List[ColumnAction] = [],
146
+ cell_actions: List[CellAction] = [],
147
+ scrollable=False,
148
+ on_column_header_hover: Optional[Callable[[Optional[str]], None]] = None,
149
+ column_header_info: Optional[solara.Element] = None,
150
+ ):
151
+ """Displays a Pandas dataframe in a table.
152
+
153
+ Pass in a dataframe as first argument, and optionally how many items per page to display.
154
+
155
+ ```solara
156
+ import solara
157
+ import pandas as pd
158
+ import plotly
159
+
160
+ df = plotly.data.iris()
161
+
162
+ @solara.component
163
+ def Page():
164
+ solara.DataFrame(df, items_per_page=5)
165
+
166
+ ```
167
+
168
+ # Custom column header info
169
+
170
+ Use the `column_header_info` argument to display a custom component on the column header when
171
+ the user hover above it. In this case we display the value counts for the column.
172
+
173
+ ```solara
174
+ import solara
175
+ import pandas as pd
176
+ import plotly
177
+
178
+ df = plotly.data.iris()
179
+
180
+ @solara.component
181
+ def Page():
182
+ column_hover, set_column_hover = solara.use_state(None)
183
+
184
+ with solara.Column(margin=4) as column_header_info:
185
+ if column_hover:
186
+ solara.Text("Value counts for " + column_hover)
187
+ display(df[column_hover].value_counts())
188
+ # if no column is hovered above, we provide an empty container
189
+ # so we always see the triple dot icon on the column header
190
+
191
+ solara.DataFrame(df, column_header_info=column_header_info, on_column_header_hover=set_column_hover)
192
+ ```
193
+
194
+
195
+ ## Arguments
196
+
197
+ * `df` - `DataFrame` - a Pandas dataframe.
198
+ * `items_per_page` - `int` - number of items per page.
199
+ * `column_actions` - Triggered via clicking on the triple dot icon on the headers (visible when hovering).
200
+ * `cell_actions` - Triggered via clicking on the triple dot icon in the cell (visible when hovering).
201
+ * `on_column_header_hover` - Optional callback when the user hovers over the triple dot icon on a header.
202
+ * `column_header_info` - Element to display in the column menu popup (visible when hovering), provide an
203
+ empty container element (like [Column](/documentation/components/layout/column)) to force showing the trigle dot icon (see example).
204
+
205
+ """
206
+ return DataTable(
207
+ df,
208
+ items_per_page=items_per_page,
209
+ column_actions=column_actions,
210
+ cell_actions=cell_actions,
211
+ scrollable=scrollable,
212
+ on_column_header_hover=on_column_header_hover,
213
+ column_header_info=column_header_info,
214
+ )
@@ -0,0 +1,175 @@
1
+ <template>
2
+ <v-slide-x-transition appear>
3
+ <div class="solara-data-table__viewport">
4
+ <v-data-table dense hide-default-header :headers="[...headers]" :items="items"
5
+ :footer-props="{ 'items-per-page-options': [10, 20, 50, 100] }" :options.sync="options"
6
+ :items_per_page.sync="items_per_page" :server-items-length="total_length" :class="[
7
+ 'elevation-1',
8
+ 'solara-data-table',
9
+ scrollable && 'solara-data-table--scrollable',
10
+ ]" :style="scrollable && height != null && `height: ${height}`">
11
+ <template v-slot:header="props">
12
+ <thead>
13
+ <tr>
14
+ <th style="padding: 0 10px; width: 40px">#</th>
15
+ <th style="padding: 0 1px; width: 30px" v-if="selection_enabled">
16
+ <v-btn icon color="primary" text small @click="apply_filter">
17
+ <v-icon>filter_list</v-icon>
18
+ </v-btn>
19
+ </th>
20
+ <th style="padding: 0 1px" v-for="(header, index) in headers_selections" :key="header.text">
21
+ <v-icon style="padding: 0 1px" :key="index" :color="selection_colors[index]">brightness_1</v-icon>
22
+ </th>
23
+ <v-slide-x-transition :key="header.text" v-for="header in headers">
24
+ <th class="text-no-wrap">
25
+ {{ header.text }}
26
+ <v-menu open-on-hover bottom offset-y @input="isOpen => onHeaderHover({ isOpen, header })"
27
+ v-if="(column_actions && column_actions.length) || column_header_widget">
28
+ <template v-slot:activator="{ on, attrs }">
29
+ <v-icon v-bind="attrs" v-on="on" small class="solara-data-table-menu">mdi-dots-vertical</v-icon>
30
+ </template>
31
+ <v-sheet v-if="header.value === column_header_hover" class="solara-data-table-column-header-sheet">
32
+ <jupyter-widget v-if="column_header_widget" :widget="column_header_widget"></jupyter-widget>
33
+ </v-sheet>
34
+ <v-list v-if="column_actions && column_actions.length">
35
+ <v-subheader>Actions:</v-subheader>
36
+ <v-list-item link @click="on_column_action([header.value, index])"
37
+ v-for="(action, index) in column_actions" :key="index">
38
+ <v-list-item-icon><v-icon>{{ action.icon }}</v-icon></v-list-item-icon>
39
+ <v-list-item-title>{{ action.name }}</v-list-item-title>
40
+ </v-list-item>
41
+ </v-list>
42
+ </v-menu>
43
+ </th>
44
+ </v-slide-x-transition>
45
+ </tr>
46
+ </thead>
47
+ </template>
48
+ <template v-slot:item="props">
49
+ <!-- @click="on_row_clicked(props.item.__row__)" -->
50
+ <tr :class="{ highlightedRow: props.item.__row__ === highlighted }">
51
+ <td style="padding: 0 10px" class="text-xs-left">
52
+ <i>{{ props.item.__row__ }}</i>
53
+ </td>
54
+ <td style="padding: 0 1px" class="text-xs-left" v-if="selection_enabled">
55
+ <v-checkbox hide-details style="margin-top: 0; padding-top: 0"
56
+ :input-value="checked.indexOf(props.item.__row__) != -1" :key="props.item.__row__"
57
+ @change="(value) => select({ checked: value, row: props.item.__row__ })" />
58
+ </td>
59
+ <td style="padding: 0 1px" :key="header.text" v-for="(header, index) in headers_selections">
60
+ <v-fade-transition leave-absolute>
61
+ <v-icon v-if="props.item[header.value]" v-model="props.item[header.value]"
62
+ :color="selection_colors[index]">brightness_1</v-icon>
63
+ </v-fade-transition>
64
+ </td>
65
+ <td v-for="header in headers" class="text-truncate text-no-wrap" :key="header.text"
66
+ :title="props.item[header.value]">
67
+ <v-slide-x-transition appear>
68
+ <!-- <span @click="on_item_click([props.item.__row__, header.value])">{{ props.item[header.value] }}</span> -->
69
+ <span>
70
+ {{ props.item[header.value] }}
71
+ <v-menu open-on-hover bottom offset-y v-if="cell_actions.length">
72
+ <template v-slot:activator="{ on, attrs }">
73
+ <v-icon v-bind="attrs" v-on="on" small class="solara-data-table-menu">mdi-dots-vertical</v-icon>
74
+ </template>
75
+ <v-list v-for="(action, index) in cell_actions" :key="index">
76
+ <v-list-item link @click="on_cell_action([props.item.__row__, header.value, index])">
77
+ <v-list-item-icon><v-icon>{{ action.icon }}</v-icon></v-list-item-icon>
78
+ <v-list-item-title>{{ action.name }}</v-list-item-title>
79
+ </v-list-item>
80
+ </v-list>
81
+ </v-menu>
82
+ </span>
83
+
84
+ </v-slide-x-transition>
85
+ </td>
86
+ </tr>
87
+ </template>
88
+ </v-data-table>
89
+ </div>
90
+ </v-slide-x-transition>
91
+ </template>
92
+
93
+ <script>
94
+ module.exports = {
95
+ methods: {
96
+ onHeaderHover({ header, isOpen }) {
97
+ if (isOpen) {
98
+ // if isOpen is true, we clicked, and we set it header.value
99
+ this.column_header_hover = header.value
100
+ } else {
101
+ // if false, we only 'unset' if the current header equals the current open menu
102
+ // because sometimes the menu from another column is closed after opening the new one
103
+ if (this.column_header_hover == header.value) {
104
+ this.column_header_hover = null
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }
110
+ </script>
111
+ <style id="solara_table">
112
+ .highlightedRow {
113
+ background-color: #e3f2fd;
114
+ }
115
+
116
+ .solara-data-table table {
117
+ table-layout: fixed;
118
+ }
119
+
120
+ .solara-data-table--scrollable .v-data-table__wrapper {
121
+ overflow-y: auto;
122
+ height: calc(100% - 59px);
123
+ }
124
+
125
+ .solara-data-table--scrollable thead>tr {
126
+ position: sticky;
127
+ top: 0;
128
+ }
129
+
130
+ .solara-data-table--scrollable .v-data-table__wrapper,
131
+ .solara-data-table--scrollable .v-data-table__wrapper>table,
132
+ .solara-data-table--scrollable .v-data-table__wrapper>table thead,
133
+ .solara-data-table--scrollable .v-data-table__wrapper>table thead * {
134
+ background-color: inherit;
135
+ }
136
+
137
+ /* prevent checkboxes overlaying the table header */
138
+ .solara-data-table--scrollable .v-data-table__wrapper>table thead {
139
+ position: relative;
140
+ z-index: 1;
141
+ }
142
+
143
+ /* avoid margins to collapse, to avoid a white background */
144
+ .solara-data-table-column-header-sheet {
145
+ overflow: auto;
146
+ }
147
+
148
+ .solara-data-table.v-data-table th,
149
+ .solara-data-table.v-data-table td {
150
+ padding-left: 4px;
151
+ padding-right: 0;
152
+ }
153
+
154
+ .v-data-table .solara-data-table-menu {
155
+ opacity: 0;
156
+ transition: opacity 0.5s;
157
+ }
158
+
159
+ .v-data-table th:hover .solara-data-table-menu,
160
+ .v-data-table td:hover .solara-data-table-menu {
161
+ opacity: 1;
162
+ }
163
+
164
+ .solara-data-table__viewport {
165
+ overflow-x: auto;
166
+ width: 100%;
167
+ max-height: 100%;
168
+ }
169
+
170
+ .solara-data-table.v-data-table,
171
+ .solara-data-table.v-data-table table {
172
+ max-width: unset;
173
+ width: unset;
174
+ }
175
+ </style>
@@ -0,0 +1,56 @@
1
+ import solara
2
+ from solara.alias import rv
3
+
4
+
5
+ @solara.component
6
+ def Details(summary="Summary", children=[], expand=False):
7
+ """Creates an expandable/collapsible section with a summary and additional children content
8
+
9
+ ```solara
10
+ import solara
11
+
12
+
13
+ show_message = solara.reactive(True)
14
+ disable = solara.reactive(False)
15
+
16
+
17
+ @solara.component
18
+ def Page():
19
+ summary_text = "Click to expand for more details"
20
+ additional_content = [
21
+ "Additional detail 1",
22
+ "Additional detail 2",
23
+ "Additional detail 3"
24
+ ]
25
+
26
+ solara.Details(
27
+ summary=summary_text,
28
+ children=additional_content,
29
+ expand=False
30
+ )
31
+
32
+ ```
33
+
34
+
35
+ ## Arguments:
36
+
37
+ * summary: String showing the summary text for the expandable section: Defaults "Summary"
38
+ * children: List showing the children content of the expandable section: Defaults to an Empty list
39
+ * expand: Boolean showing if the section is expanded or collapsed: Defaults to False
40
+ """
41
+
42
+ expand, set_expand = solara.use_state_or_update(expand)
43
+
44
+ def on_v_model(v_model):
45
+ if v_model is None: # collapsed:
46
+ set_expand(False)
47
+ elif v_model == 0:
48
+ set_expand(True)
49
+ else:
50
+ raise RuntimeError(f"v_model has odd value: {v_model}")
51
+
52
+ with rv.ExpansionPanels(v_model=0 if expand else None, on_v_model=on_v_model) as main:
53
+ with rv.ExpansionPanel():
54
+ rv.ExpansionPanelHeader(children=[summary])
55
+ rv.ExpansionPanelContent(children=children)
56
+ return main
@@ -0,0 +1,35 @@
1
+ <template>
2
+ <div @click="request_download = true" class="solara-file-download-container">
3
+ <jupyter-widget v-for="child in children" :key="child" :widget="child"></jupyter-widget>
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ module.exports = {
9
+ watch: {
10
+ bytes(value) {
11
+ if (this.request_download) {
12
+ const a = document.createElement('a');
13
+ a.download = this.filename;
14
+ const blob = new Blob([this.bytes], { type: this.mime_type });
15
+ const blobUrl = window.URL.createObjectURL(blob);
16
+ a.href = blobUrl;
17
+ document.body.appendChild(a);
18
+ a.click();
19
+ document.body.removeChild(a);
20
+ setTimeout(() => {
21
+ // Make sure we clean up
22
+ window.URL.revokeObjectURL(blobUrl);
23
+ }, 1000);
24
+ this.request_download = false;
25
+ }
26
+ }
27
+ }
28
+ }
29
+ </script>
30
+
31
+ <style id="solara-file-download">
32
+ .solara-file-download-container {
33
+ cursor: pointer;
34
+ }
35
+ </style>
@@ -0,0 +1,86 @@
1
+ from typing import Any, Callable
2
+
3
+ import ipyvuetify
4
+ import traitlets
5
+
6
+ import solara
7
+
8
+
9
+ class EchartsWidget(ipyvuetify.VuetifyTemplate):
10
+ template_file = (__file__, "echarts.vue")
11
+
12
+ attributes = traitlets.Dict(default_value=None, allow_none=True).tag(sync=True)
13
+ responsive = traitlets.Bool(False).tag(sync=True)
14
+ maps = traitlets.Any({}).tag(sync=True)
15
+ option = traitlets.Any({}).tag(sync=True)
16
+ on_click = traitlets.Callable(None, allow_none=True)
17
+ on_mouseover = traitlets.Callable(None, allow_none=True)
18
+ # for performance, so we don't get events from the frontend we don't care about
19
+ on_mouseover_enabled = traitlets.Bool(False).tag(sync=True)
20
+ on_mouseout = traitlets.Callable(None, allow_none=True)
21
+ # same, for performance
22
+ on_mouseout_enabled = traitlets.Bool(False).tag(sync=True)
23
+ cdn = traitlets.Unicode(None, allow_none=True).tag(sync=True)
24
+
25
+ @traitlets.default("cdn")
26
+ def _cdn(self):
27
+ import solara.settings
28
+
29
+ if not solara.settings.assets.proxy:
30
+ return solara.settings.assets.cdn
31
+
32
+ def vue_on_click(self, data):
33
+ if self.on_click is not None:
34
+ self.on_click(data)
35
+
36
+ def vue_on_mouseover(self, data):
37
+ if self.on_mouseover is not None:
38
+ self.on_mouseover(data)
39
+
40
+ def vue_on_mouseout(self, data):
41
+ if self.on_mouseout is not None:
42
+ self.on_mouseout(data)
43
+
44
+
45
+ @solara.component
46
+ def FigureEcharts(
47
+ option: dict = {},
48
+ on_click: Callable[[Any], Any] = None,
49
+ on_mouseover: Callable[[Any], Any] = None,
50
+ on_mouseout: Callable[[Any], Any] = None,
51
+ maps: dict = {},
52
+ attributes={"style": "height: 400px;"},
53
+ responsive: bool = False,
54
+ ):
55
+ """Create a Echarts figure.
56
+
57
+ See [The Echarts website for examples](https://echarts.apache.org/)
58
+
59
+ Note that we do not support a Python API to create the figure data.
60
+
61
+ A library such as Pyecharts can help you with that, otherwise you can provide
62
+ the data simply as data similarly as on the Echarts example webpage.
63
+
64
+ # Arguments
65
+
66
+ * option: dict, the option for the figure, see the echart documentation.
67
+ * on_click: Callable, a function that will be called when the user clicks on the figure.
68
+ * on_mouseover: Callable, a function that will be called when the user moves the mouse over a certain component.
69
+ * on_mouseout: Callable, a function that will be called when the user moves the mouse out of a certain component.
70
+ * maps: dict, a dictionary of maps to be used in the figure.
71
+ * attributes: dict, a dictionary of attributes to be passed to the container (like style, class).
72
+ * responsive: bool, whether the chart should resize when the container changes size.
73
+
74
+
75
+ """
76
+ return EchartsWidget.element(
77
+ option=option,
78
+ on_click=on_click,
79
+ on_mouseover=on_mouseover,
80
+ on_mouseover_enabled=on_mouseover is not None,
81
+ maps=maps,
82
+ on_mouseout=on_mouseout,
83
+ on_mouseout_enabled=on_mouseout is not None,
84
+ attributes=attributes,
85
+ responsive=responsive,
86
+ )