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,125 @@
1
+ <template>
2
+ <div>
3
+ <v-subheader class="pl-0 query-input-label">{{ label }}</v-subheader>
4
+ <div ref="cm" class="solara-sql-code" :style="`height: ${height};`"></div>
5
+ <div>Use <kbd>Ctrl</kbd>+<kbd>Space</kbd> for auto-complete</div>
6
+ </div>
7
+ </template>
8
+ <script>
9
+ module.exports = {
10
+ async mounted() {
11
+ const cmVersion = '5.65.3';
12
+
13
+ if (!document.getElementById('codemirror-hint.css')) {
14
+ const link = document.createElement('link');
15
+ link.href = `${this.getCdn()}/codemirror@${cmVersion}/addon/hint/show-hint.css`;
16
+ link.type = "text/css";
17
+ link.rel = "stylesheet";
18
+ link.id="codemirror-hint.css";
19
+ document.head.appendChild(link);
20
+ }
21
+
22
+ await this.loadRequire();
23
+
24
+ requirejs.config({paths:{
25
+ codemirror: `${this.getCdn()}/codemirror@${cmVersion}`
26
+ }});
27
+
28
+ requirejs(["codemirror/lib/codemirror", "codemirror/mode/sql/sql", "codemirror/addon/hint/show-hint", "codemirror/addon/hint/sql-hint"],
29
+ (cm) => {
30
+ this.myCodeMirror = cm(this.$refs.cm, {
31
+ value: this.query || '',
32
+ mode: "text/x-sql",
33
+ extraKeys: {"Ctrl-Space": "autocomplete"},
34
+ hint: cm.hint.sql,
35
+ hintOptions: {
36
+ tables: this.tables
37
+ },
38
+ lineNumbers: true,
39
+ gutter: true,
40
+ });
41
+ this.myCodeMirror.on('change', (cm, changeObj) => this.query=cm.getValue())
42
+ });
43
+ },
44
+ watch: {
45
+ query(value) {
46
+ if (this.myCodeMirror.getValue() !== value) {
47
+ this.myCodeMirror.setValue(value)
48
+ }
49
+ },
50
+ tables(value) {
51
+ if (this.myCodeMirror) {
52
+ this.myCodeMirror.options.hintOptions.tables = value;
53
+ }
54
+ }
55
+ },
56
+ methods: {
57
+ import(deps) {
58
+ return this.loadRequire().then(
59
+ () => {
60
+ if(window.jupyterVue) {
61
+ // in jupyterlab, we take Vue from ipyvue/jupyterVue
62
+ define("vue", [], () => window.jupyterVue.Vue);
63
+ } else {
64
+ define("vue", ['jupyter-vue'], jupyterVue => jupyterVue.Vue);
65
+ }
66
+ return new Promise((resolve, reject) => {
67
+ requirejs(deps, (...modules) => resolve(modules));
68
+ })
69
+ }
70
+ );
71
+ },
72
+ loadRequire() {
73
+ /* Needed in lab */
74
+ if (window.requirejs) {
75
+ console.log('require found');
76
+ return Promise.resolve()
77
+ }
78
+ return new Promise((resolve, reject) => {
79
+ const script = document.createElement('script');
80
+ script.src = `${this.getCdn()}/requirejs@2.3.6/require.js`;
81
+ script.onload = resolve;
82
+ script.onerror = reject;
83
+ document.head.appendChild(script);
84
+ });
85
+ },
86
+ getJupyterBaseUrl() {
87
+ // if base url is set, we use ./ for relative paths compared to the base url
88
+ if (document.getElementsByTagName("base").length) {
89
+ return document.baseURI;
90
+ }
91
+ const labConfigData = document.getElementById('jupyter-config-data');
92
+ if(labConfigData) {
93
+ /* lab and Voila */
94
+ return JSON.parse(labConfigData.textContent).baseUrl;
95
+ }
96
+ let base = document.body.dataset.baseUrl || document.baseURI;
97
+ if(!base.endsWith('/')) {
98
+ base += '/';
99
+ }
100
+ return base
101
+ },
102
+ getCdn() {
103
+ return this.cdn || (window.solara ? window.solara.cdn : `${this.getJupyterBaseUrl()}_solara/cdn`);
104
+ },
105
+ }
106
+ }
107
+ </script>
108
+ <style id="solara-sql-code">
109
+ .solara-sql-code {
110
+ border: 1px solid gray;
111
+ }
112
+
113
+ ul.CodeMirror-hints.default {
114
+ z-index: 10000;
115
+ }
116
+
117
+ .solara-sql-code .CodeMirror.cm-s-default {
118
+ height: 100%
119
+ }
120
+
121
+ .v-subheader.query-input-label {
122
+ font-size: 12px;
123
+ height: unset;
124
+ }
125
+ </style>
@@ -0,0 +1,105 @@
1
+ import asyncio
2
+ import hashlib
3
+ import logging
4
+ from pathlib import Path
5
+ from typing import Optional, Union, cast
6
+
7
+ import ipyvuetify as v
8
+
9
+ try:
10
+ import watchfiles
11
+ except ModuleNotFoundError:
12
+ watchfiles = None # type: ignore
13
+
14
+ import solara
15
+ import solara.server.settings
16
+
17
+ logger = logging.getLogger("solara.Style")
18
+
19
+
20
+ @solara.component
21
+ def Style(value: Union[str, Path] = ""):
22
+ """Add a custom piece of CSS.
23
+
24
+ Note that this is considered an advanced feature, and should be used with caution.
25
+
26
+ ## Example
27
+
28
+ ```python
29
+ from pathlib import Path
30
+ import solara
31
+
32
+
33
+ @solara.component
34
+ def Page():
35
+ solara.Style(Path("style.css"))
36
+ solara.Button("Click me", classes=["company-style-button"])
37
+ ```
38
+
39
+ ## Arguments
40
+
41
+ - `value`: The CSS string of CSS file to insert into the page. In development mode (the default)
42
+ when a Path argument is passed, the file will be watched for changes, and the CSS will be reloaded when
43
+ the file changes. In production mode, the CSS will be inserted once, and not reloaded.
44
+ """
45
+ css_content_reloaded, set_css_content_reloaded = solara.use_state(cast(Optional[str], None))
46
+
47
+ def hot_reload():
48
+ in_production = solara.server.settings.main.mode == "production"
49
+ if not in_production and isinstance(value, Path):
50
+
51
+ async def watch():
52
+ try:
53
+ async for _ in watchfiles.awatch(value):
54
+ print(value, "changed, reloading css") # noqa
55
+ set_css_content_reloaded(cast(Path, value).read_text(encoding="utf-8"))
56
+ except RuntimeError:
57
+ pass # swallow the RuntimeError: Already borrowed errors from watchfiles
58
+ except Exception:
59
+ logger.exception("Error watching file")
60
+
61
+ if watchfiles:
62
+ future = asyncio.create_task(watch())
63
+ return future.cancel
64
+ else:
65
+ logger.warning("watchfiles not installed, cannot watch file")
66
+
67
+ solara.use_effect(hot_reload, [value])
68
+
69
+ uuid = solara.use_unique_key()
70
+ if css_content_reloaded is not None:
71
+ css_content = css_content_reloaded
72
+ else:
73
+ css_content = value.read_text(encoding="utf-8") if isinstance(value, Path) else value
74
+ # del value
75
+ hash = hashlib.sha256(css_content.encode("utf-8")).hexdigest()
76
+ # the key is unique for this component + value
77
+ # so that we create a new component if the value changes
78
+ # but we do not remove the css of a component with the same value
79
+ key = uuid + "-" + hash
80
+ # ipyvue does not remove the css itself, so we need to do it manually
81
+ script = (
82
+ """
83
+ <script>
84
+ module.exports = {
85
+ destroyed() {
86
+ document.getElementById("ipyvue-%s").remove();
87
+ },
88
+ };
89
+ </script>
90
+ """
91
+ % key
92
+ )
93
+
94
+ template = f"""
95
+ <template>
96
+ <span style="display: none">
97
+ </span>
98
+ </template>
99
+ {script}
100
+ <style id="{key}">
101
+ {css_content}
102
+ </style>
103
+ """
104
+ # using .key avoids reusing the template, which causes a flicker (due to ipyvue)
105
+ return v.VuetifyTemplate.element(template=template).key(key)
@@ -0,0 +1,71 @@
1
+ from typing import Callable, Dict, List, Optional, Union
2
+
3
+ import reacton.ipyvuetify as v
4
+
5
+ import solara
6
+
7
+
8
+ @solara.value_component(bool)
9
+ def Switch(
10
+ *,
11
+ label: str = None,
12
+ value: Union[bool, solara.Reactive[bool]] = True,
13
+ on_value: Callable[[bool], None] = None,
14
+ disabled: bool = False,
15
+ color: str = None,
16
+ children: list = [],
17
+ classes: List[str] = [],
18
+ style: Optional[Union[str, Dict[str, str]]] = None,
19
+ ):
20
+ """A switch component provides users the ability to choose between two distinct values. But aesthetically different from a checkbox.
21
+
22
+ Basic examples
23
+
24
+ ```solara
25
+ import solara
26
+
27
+ show_message = solara.reactive(True)
28
+ disable = solara.reactive(False)
29
+
30
+
31
+ @solara.component
32
+ def Page():
33
+ with solara.Column():
34
+ with solara.Row():
35
+ solara.Switch(label="Hide Message", value=show_message, disabled=disable.value)
36
+ solara.Switch(label="Disable Message Switch", value=disable)
37
+
38
+ if show_message.value:
39
+ solara.Markdown("## Use Switch to show/hide message")
40
+
41
+ ```
42
+
43
+
44
+ ## Arguments
45
+
46
+ * `label`: The label to display next to the switch.
47
+ * `value`: The current value of the switch (True or False).
48
+ * `on_value`: A callback that is called when the switch is toggled.
49
+ * `disabled`: If True, the switch is disabled and cannot be used.
50
+ * `color`: The color of the switch. Can be the name of a [theme](https://solara.dev/documentation/components/lab/theming) color variable (i.e. "success"), a color from the [Material color palette](https://v2.vuetifyjs.com/en/styles/colors/#material-colors) (i.e. "red darken-3"), or a CSS color (i.e. "#ff991f").
51
+ * `children`: A list of child elements to display on the switch.
52
+ * `classes`: Additional CSS classes to apply.
53
+ * `style`: CSS style to apply.
54
+
55
+ """
56
+ reactive_value = solara.use_reactive(value, on_value)
57
+ del value, on_value
58
+
59
+ if label:
60
+ children = [label] + children
61
+
62
+ return v.Switch(
63
+ label=label,
64
+ v_model=reactive_value.value,
65
+ on_v_model=reactive_value.set,
66
+ disabled=disabled,
67
+ color=color,
68
+ class_=solara.util._combine_classes(classes),
69
+ style_=solara.util._flatten_style(style),
70
+ children=children,
71
+ )
@@ -0,0 +1,37 @@
1
+ import solara
2
+ from solara.alias import rv, rvue
3
+
4
+
5
+ @solara.component
6
+ def LinkTab(path, label):
7
+ # both adding href to tab or adding Link makes vuetify buggy
8
+ with rv.Tab() as tab:
9
+ # with solara.Link(path):
10
+ solara.Text(label)
11
+ router = solara.use_router()
12
+
13
+ def go(*ignore):
14
+ router.push(path)
15
+
16
+ rvue.use_event(tab, "click.prevent.stop", go)
17
+ return tab
18
+
19
+
20
+ @solara.component
21
+ def TabNavigation(children=[], vertical=False, **kwargs):
22
+ children = children or []
23
+ route_current, all_routes = solara.use_route()
24
+
25
+ tab_index = all_routes.index(route_current) if route_current is not None else 0
26
+
27
+ with rv.Tabs(v_model=tab_index, vertical=vertical, **kwargs) as main:
28
+ for i, route in enumerate(all_routes):
29
+ path = solara.resolve_path(route)
30
+ LinkTab(path, route.label or "No title")
31
+ if route_current is None:
32
+ return solara.Error("Page does not exist")
33
+
34
+ with rv.TabsItems(v_model=tab_index, children=children):
35
+ pass
36
+
37
+ return main
@@ -0,0 +1,90 @@
1
+ from typing import Callable, Dict, Optional, Tuple, cast
2
+
3
+ import ipyvuetify as vy
4
+ import reacton.core
5
+ import traitlets
6
+
7
+ import solara
8
+ import solara.lab
9
+
10
+
11
+ class TitleWidget(vy.VuetifyTemplate):
12
+ template_file = (__file__, "title.vue")
13
+ title = traitlets.Unicode().tag(sync=True)
14
+ level = traitlets.Int().tag(sync=True)
15
+
16
+
17
+ Titles = Dict[str, Tuple[int, str]]
18
+
19
+
20
+ def _set_titles_default(updater: Callable[[Titles], Titles]):
21
+ pass
22
+
23
+
24
+ titles_context = solara.create_context(_set_titles_default)
25
+
26
+
27
+ def use_title_get() -> Optional[str]:
28
+ titles, set_titles = solara.use_state(cast(Titles, {}))
29
+ titles_context.provide(set_titles) # type: ignore
30
+ if titles:
31
+ title = max([(order, title) for (key, (order, title)) in titles.items()], key=lambda x: x[0])[1]
32
+ else:
33
+ title = None
34
+ return title
35
+
36
+
37
+ def use_title_set(title: str, offset: int):
38
+ key = solara.use_unique_key(prefix="title-")
39
+ set_titles = solara.use_context(titles_context)
40
+
41
+ def update():
42
+ set_titles(lambda titles: {**titles, key: (offset, title)})
43
+
44
+ solara.use_effect(update, [title])
45
+
46
+ def restore():
47
+ def cleanup():
48
+ def without(titles):
49
+ titles_restored = titles.copy()
50
+ titles_restored.pop(key, None)
51
+ return titles_restored
52
+
53
+ set_titles(without)
54
+
55
+ return cleanup
56
+
57
+ solara.use_effect(restore, [])
58
+
59
+
60
+ @solara.component
61
+ def Title(title: str):
62
+ """Set the title of a page.
63
+
64
+ ```python
65
+ import solara
66
+
67
+ @solara.component
68
+ def Page():
69
+ with solara.VBox() as main:
70
+ MyAwesomeComponent()
71
+ solara.Title("My page title")
72
+ return main
73
+ ```
74
+
75
+ If multiple Title components are used, the 'deepest' child will take precedence.
76
+
77
+ ## Arguments
78
+
79
+ * title: the title of the page
80
+ """
81
+ level = 0
82
+ rc = reacton.core.get_render_context()
83
+ context = rc.context
84
+ while context and context.parent:
85
+ level += 1
86
+ context = context.parent
87
+ offset = 2**level
88
+ use_title_set(title, offset)
89
+
90
+ return TitleWidget.element(title=title, level=level)
@@ -0,0 +1,38 @@
1
+ <template><span style="display: none">{{ title }}</span></template>
2
+
3
+ <script>
4
+ module.exports = {
5
+ mounted() {
6
+ if (window._solaraTitles === undefined) {
7
+ window._solaraTitles = [];
8
+ }
9
+ window._solaraTitles.push(this);
10
+ this.updateTitle();
11
+ },
12
+ destroyed() {
13
+ window._solaraTitles.splice(window._solaraTitles.indexOf(this), 1);
14
+ if (window._solaraTitles.length) {
15
+ window._solaraTitles[0].updateTitle();
16
+ }
17
+ },
18
+ watch: {
19
+ title() {
20
+ this.updateTitle();
21
+ },
22
+ level() {
23
+ this.updateTitle();
24
+ },
25
+ },
26
+ methods: {
27
+ updateTitle() {
28
+ let deepestTitle = window._solaraTitles[0];
29
+ for (let i = 1; i < window._solaraTitles.length; i++) {
30
+ if (window._solaraTitles[i].level > deepestTitle.level) {
31
+ deepestTitle = window._solaraTitles[i];
32
+ }
33
+ }
34
+ document.title = deepestTitle.title;
35
+ }
36
+ },
37
+ };
38
+ </script>
@@ -0,0 +1,200 @@
1
+ from typing import Callable, Dict, List, Optional, TypeVar, Union, cast, overload
2
+
3
+ import ipyvuetify as v
4
+ import reacton
5
+ from typing_extensions import Literal
6
+
7
+ import solara
8
+ from solara.alias import rv
9
+ from solara.util import _combine_classes
10
+
11
+ T = TypeVar("T")
12
+
13
+
14
+ def _get_button_value(button: reacton.core.Element):
15
+ if "value" in button.kwargs:
16
+ value = button.kwargs["value"]
17
+ else:
18
+ value = button.kwargs.get("label")
19
+ if value is None and button.args:
20
+ value = button.args[0]
21
+ return value
22
+
23
+
24
+ @overload
25
+ @solara.value_component(None)
26
+ def ToggleButtonsSingle(
27
+ value: Union[T, solara.Reactive[T]],
28
+ values: List[T] = ...,
29
+ children: List[reacton.core.Element] = ...,
30
+ on_value: Optional[Callable[[T], None]] = ...,
31
+ dense: bool = ...,
32
+ mandatory: Literal[True] = ...,
33
+ classes: List[str] = ...,
34
+ style: Union[str, Dict[str, str], None] = ...,
35
+ ) -> reacton.core.ValueElement[v.BtnToggle, T]: ...
36
+
37
+
38
+ @overload
39
+ @solara.value_component(None)
40
+ def ToggleButtonsSingle(
41
+ value: Union[Optional[T], solara.Reactive[Optional[T]]] = None,
42
+ values: List[T] = ...,
43
+ children: List[reacton.core.Element] = ...,
44
+ on_value: Optional[Callable[[Optional[T]], None]] = ...,
45
+ dense: bool = ...,
46
+ mandatory: Literal[False] = ...,
47
+ classes: List[str] = ...,
48
+ style: Union[str, Dict[str, str], None] = ...,
49
+ ) -> reacton.core.ValueElement[v.BtnToggle, T]: ...
50
+
51
+
52
+ @solara.value_component(None)
53
+ def ToggleButtonsSingle(
54
+ value: Union[None, T, Optional[T], solara.Reactive[T], solara.Reactive[Optional[T]]] = None,
55
+ values: List[T] = [],
56
+ children: List[reacton.core.Element] = [],
57
+ on_value: Optional[Callable[[T], None]] = None,
58
+ dense: bool = False,
59
+ mandatory: bool = True,
60
+ classes: List[str] = [],
61
+ style: Union[str, Dict[str, str], None] = None,
62
+ ) -> reacton.core.ValueElement[v.BtnToggle, T]:
63
+ """ToggleButtons for selecting a single value.
64
+
65
+ ```solara
66
+ import solara
67
+
68
+ foods = ["Kiwi", "Banana", "Apple"]
69
+ food = solara.reactive("Banana")
70
+
71
+
72
+ @solara.component
73
+ def Page():
74
+ with solara.Card("My favorite food"):
75
+ solara.ToggleButtonsSingle(value=food, values=foods)
76
+ solara.Markdown(f"**Selected**: {food.value}")
77
+ ```
78
+
79
+ ### Using Buttons
80
+
81
+ Instead of passing the values as a list, we can also use the buttons as children.
82
+ This allows us to customize the buttons, for example to add an icon.
83
+
84
+ ```solara
85
+ import solara
86
+
87
+ direction = solara.reactive("left")
88
+
89
+
90
+ @solara.component
91
+ def Page():
92
+ with solara.Card("Pick a direction"):
93
+ # instead of using the values argument, we can use the buttons as children
94
+ # the label of the button will be used as value, if no value is given.
95
+ with solara.ToggleButtonsSingle(value=direction):
96
+ # note that the label and the value are different
97
+ solara.Button("Up", icon_name="mdi-arrow-up-bold", value="up", text=True)
98
+ solara.Button("Down", icon_name="mdi-arrow-down-bold", value="down", text=True)
99
+ solara.Button("Left", icon_name="mdi-arrow-left-bold", value="left", text=True)
100
+ solara.Button("Right", icon_name="mdi-arrow-right-bold", value="right", text=True)
101
+ solara.Markdown(f"**Selected**: {direction.value}")
102
+ ```
103
+
104
+ ## Arguments
105
+
106
+ * `value`: The currently selected value.
107
+ * `values`: List of values to select from.
108
+ * `children`: List of buttons to use as values.
109
+ * `on_value`: Callback to call when the value changes.
110
+ * `dense`: Whether to use a dense (smaller) style.
111
+ * `mandatory`: Whether a choice is mandatory.
112
+ * `style`: CSS style to apply to the top level element.
113
+ * `classes`: List of CSS classes to be applied to the top level element.
114
+ """
115
+ class_ = _combine_classes(classes)
116
+ style_flat = solara.util._flatten_style(style)
117
+ # TODO: make type safe
118
+ # typing is ignored below due to an issue with the typing; The combination of value being T and on_value being of type Callback[[Optional[T]], None] is
119
+ # not allowed to be passed to use_reactive. We also do not allow this by using our overloads, but this information seems lost at this point by
120
+ # the typechecker
121
+ reactive_value = solara.use_reactive(value, on_value) # type: ignore
122
+ children = [solara.Button(label=str(value)) for value in values] + children
123
+ values = values + [_get_button_value(button) for button in children] # type: ignore
124
+ # When mandatory = True, index should not be None, but we are letting the front-end take care of setting index to 0 because of a bug
125
+ # (see https://github.com/widgetti/solara/issues/282)
126
+ # TODO: set index to 0 on python side (after #282 is resolved)
127
+ index, set_index = solara.use_state_or_update(values.index(reactive_value.value) if reactive_value.value in values else None, key="index")
128
+
129
+ def on_index(index):
130
+ set_index(index)
131
+ if mandatory:
132
+ value = values[index]
133
+ else:
134
+ value = values[index] if index is not None else None
135
+ reactive_value.set(value)
136
+
137
+ return cast(
138
+ reacton.core.ValueElement[v.BtnToggle, T],
139
+ rv.BtnToggle(children=children, multiple=False, mandatory=mandatory, v_model=index, on_v_model=on_index, dense=dense, class_=class_, style_=style_flat),
140
+ )
141
+
142
+
143
+ @solara.value_component(None)
144
+ def ToggleButtonsMultiple(
145
+ value: Union[List[T], solara.Reactive[List[T]]] = [],
146
+ values: List[T] = [],
147
+ children: List[reacton.core.Element] = [],
148
+ on_value: Union[Callable[[List[T]], None], None] = None,
149
+ dense: bool = False,
150
+ mandatory: bool = False,
151
+ classes: List[str] = [],
152
+ style: Union[str, Dict[str, str], None] = None,
153
+ ) -> reacton.core.ValueElement[v.BtnToggle, List[T]]:
154
+ """ToggleButtons for selecting multiple values.
155
+
156
+ ### Basic example:
157
+ ```solara
158
+ import solara
159
+
160
+ all_languages = "Python C++ Java JavaScript TypeScript BASIC".split()
161
+ languages = solara.reactive([all_languages[0]])
162
+
163
+
164
+ @solara.component
165
+ def Page():
166
+ with solara.Card("My favorite programming languages"):
167
+ solara.ToggleButtonsMultiple(languages, all_languages)
168
+ solara.Markdown(f"**Selected**: {languages.value}")
169
+ ```
170
+
171
+ ## Arguments
172
+
173
+ * `value`: The currently selected values.
174
+ * `values`: List of values to select from.
175
+ * `children`: List of buttons to use as values.
176
+ * `on_value`: Callback to call when the value changes.
177
+ * `dense`: Whether to use a dense (smaller) style.
178
+ * `mandatory`: Whether selecting at least one element is mandatory.
179
+ * `style`: CSS style to apply to the top level element.
180
+ * `classes`: List of CSS classes to be applied to the top level element.
181
+ """
182
+ class_ = _combine_classes(classes)
183
+ style_flat = solara.util._flatten_style(style)
184
+ # See comment regarding typing issue in ToggleButtonsSingle
185
+ reactive_value = solara.use_reactive(value, on_value) # type: ignore
186
+ children = [solara.Button(label=str(value)) for value in values] + children
187
+ allvalues = values + [_get_button_value(button) for button in children]
188
+ indices, set_indices = solara.use_state_or_update([allvalues.index(k) for k in reactive_value.value], key="index")
189
+
190
+ def on_indices(indices):
191
+ set_indices(indices)
192
+ value = [allvalues[k] for k in indices]
193
+ reactive_value.set(value)
194
+
195
+ return cast(
196
+ reacton.core.ValueElement[v.BtnToggle, List[T]],
197
+ rv.BtnToggle(
198
+ children=children, multiple=True, mandatory=mandatory, v_model=indices, on_v_model=on_indices, dense=dense, class_=class_, style_=style_flat
199
+ ),
200
+ )