solara-ui 1.31.0__py2.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.
- prefix/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
- prefix/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
- solara/__init__.py +124 -0
- solara/__main__.py +734 -0
- solara/alias.py +6 -0
- solara/autorouting.py +546 -0
- solara/cache.py +303 -0
- solara/checks.html +71 -0
- solara/checks.py +224 -0
- solara/comm.py +28 -0
- solara/components/__init__.py +59 -0
- solara/components/alert.py +155 -0
- solara/components/applayout.py +393 -0
- solara/components/button.py +85 -0
- solara/components/card.py +87 -0
- solara/components/checkbox.py +50 -0
- solara/components/code_highlight_css.py +11 -0
- solara/components/code_highlight_css.vue +63 -0
- solara/components/columns.py +159 -0
- solara/components/component_vue.py +110 -0
- solara/components/cross_filter.py +335 -0
- solara/components/dataframe.py +546 -0
- solara/components/datatable.py +221 -0
- solara/components/datatable.vue +175 -0
- solara/components/details.py +21 -0
- solara/components/download.vue +35 -0
- solara/components/echarts.py +75 -0
- solara/components/echarts.vue +128 -0
- solara/components/figure_altair.py +39 -0
- solara/components/file_browser.py +182 -0
- solara/components/file_download.py +199 -0
- solara/components/file_drop.py +139 -0
- solara/components/file_drop.vue +83 -0
- solara/components/file_list_widget.vue +78 -0
- solara/components/head.py +27 -0
- solara/components/head_tag.py +49 -0
- solara/components/head_tag.vue +60 -0
- solara/components/image.py +173 -0
- solara/components/input.py +436 -0
- solara/components/link.py +55 -0
- solara/components/markdown.py +378 -0
- solara/components/markdown_editor.py +25 -0
- solara/components/markdown_editor.vue +362 -0
- solara/components/matplotlib.py +74 -0
- solara/components/meta.py +47 -0
- solara/components/misc.py +333 -0
- solara/components/pivot_table.py +258 -0
- solara/components/pivot_table.vue +158 -0
- solara/components/progress.py +47 -0
- solara/components/select.py +182 -0
- solara/components/select.vue +27 -0
- solara/components/slider.py +442 -0
- solara/components/slider_date.vue +56 -0
- solara/components/spinner-solara.vue +105 -0
- solara/components/spinner.py +30 -0
- solara/components/sql_code.py +33 -0
- solara/components/sql_code.vue +128 -0
- solara/components/style.py +105 -0
- solara/components/switch.py +68 -0
- solara/components/tab_navigation.py +37 -0
- solara/components/title.py +90 -0
- solara/components/title.vue +38 -0
- solara/components/togglebuttons.py +200 -0
- solara/components/tooltip.py +61 -0
- solara/datatypes.py +143 -0
- solara/express.py +241 -0
- solara/hooks/__init__.py +4 -0
- solara/hooks/dataframe.py +99 -0
- solara/hooks/misc.py +263 -0
- solara/hooks/use_reactive.py +129 -0
- solara/hooks/use_thread.py +129 -0
- solara/kitchensink.py +8 -0
- solara/lab/__init__.py +34 -0
- solara/lab/components/__init__.py +6 -0
- solara/lab/components/chat.py +203 -0
- solara/lab/components/confirmation_dialog.py +163 -0
- solara/lab/components/cross_filter.py +7 -0
- solara/lab/components/input_date.py +298 -0
- solara/lab/components/menu.py +181 -0
- solara/lab/components/menu.vue +38 -0
- solara/lab/components/tabs.py +274 -0
- solara/lab/components/theming.py +98 -0
- solara/lab/components/theming.vue +72 -0
- solara/lab/hooks/__init__.py +0 -0
- solara/lab/hooks/dataframe.py +12 -0
- solara/lab/toestand.py +3 -0
- solara/lab/utils/__init__.py +2 -0
- solara/lab/utils/cookies.py +5 -0
- solara/lab/utils/dataframe.py +115 -0
- solara/lab/utils/headers.py +5 -0
- solara/layout.py +44 -0
- solara/lifecycle.py +46 -0
- solara/minisettings.py +133 -0
- solara/py.typed +0 -0
- solara/reactive.py +93 -0
- solara/routing.py +268 -0
- solara/scope/__init__.py +88 -0
- solara/scope/types.py +55 -0
- solara/server/__init__.py +0 -0
- solara/server/app.py +491 -0
- solara/server/assets/custom.css +1 -0
- solara/server/assets/custom.js +1 -0
- solara/server/assets/favicon.png +0 -0
- solara/server/assets/favicon.svg +5 -0
- solara/server/assets/style.css +1665 -0
- solara/server/assets/theme-dark.css +437 -0
- solara/server/assets/theme-light.css +420 -0
- solara/server/assets/theme.js +3 -0
- solara/server/cdn_helper.py +77 -0
- solara/server/esm.py +69 -0
- solara/server/fastapi.py +5 -0
- solara/server/flask.py +286 -0
- solara/server/jupyter/__init__.py +2 -0
- solara/server/jupyter/cdn_handler.py +28 -0
- solara/server/jupyter/server_extension.py +29 -0
- solara/server/jupytertools.py +46 -0
- solara/server/kernel.py +338 -0
- solara/server/kernel_context.py +357 -0
- solara/server/patch.py +552 -0
- solara/server/reload.py +242 -0
- solara/server/server.py +456 -0
- solara/server/settings.py +215 -0
- solara/server/shell.py +251 -0
- solara/server/starlette.py +601 -0
- solara/server/static/ansi.js +270 -0
- solara/server/static/highlight-dark.css +82 -0
- solara/server/static/highlight.css +43 -0
- solara/server/static/main-vuetify.js +260 -0
- solara/server/static/main.js +163 -0
- solara/server/static/solara_bootstrap.py +129 -0
- solara/server/static/sun.svg +23 -0
- solara/server/static/webworker.js +42 -0
- solara/server/telemetry.py +212 -0
- solara/server/templates/index.html.j2 +1 -0
- solara/server/templates/loader-plain.css +11 -0
- solara/server/templates/loader-plain.html +20 -0
- solara/server/templates/loader-solara.css +111 -0
- solara/server/templates/loader-solara.html +40 -0
- solara/server/templates/plain.html +82 -0
- solara/server/templates/solara.html.j2 +446 -0
- solara/server/threaded.py +75 -0
- solara/server/utils.py +30 -0
- solara/server/websocket.py +45 -0
- solara/settings.py +56 -0
- solara/tasks.py +837 -0
- solara/template/button.py +16 -0
- solara/template/markdown.py +42 -0
- solara/template/portal/.flake8 +6 -0
- solara/template/portal/.pre-commit-config.yaml +28 -0
- solara/template/portal/LICENSE +21 -0
- solara/template/portal/Procfile +7 -0
- solara/template/portal/mypy.ini +3 -0
- solara/template/portal/pyproject.toml +26 -0
- solara/template/portal/solara_portal/__init__.py +4 -0
- solara/template/portal/solara_portal/components/__init__.py +2 -0
- solara/template/portal/solara_portal/components/article.py +28 -0
- solara/template/portal/solara_portal/components/data.py +28 -0
- solara/template/portal/solara_portal/components/header.py +6 -0
- solara/template/portal/solara_portal/components/layout.py +6 -0
- solara/template/portal/solara_portal/content/articles/equis-in-vidi.md +85 -0
- solara/template/portal/solara_portal/content/articles/substiterat-vati.md +70 -0
- solara/template/portal/solara_portal/data.py +60 -0
- solara/template/portal/solara_portal/pages/__init__.py +67 -0
- solara/template/portal/solara_portal/pages/article/__init__.py +26 -0
- solara/template/portal/solara_portal/pages/tabular.py +29 -0
- solara/template/portal/solara_portal/pages/viz/__init__.py +70 -0
- solara/template/portal/solara_portal/pages/viz/overview.py +14 -0
- solara/test/__init__.py +0 -0
- solara/test/pytest_plugin.py +697 -0
- solara/toestand.py +772 -0
- solara/util.py +308 -0
- solara/website/__init__.py +0 -0
- solara/website/assets/custom.css +468 -0
- solara/website/assets/images/logo-small.png +0 -0
- solara/website/assets/images/logo.svg +17 -0
- solara/website/assets/images/logo_white.svg +50 -0
- solara/website/assets/theme.js +8 -0
- solara/website/components/__init__.py +5 -0
- solara/website/components/algolia.vue +24 -0
- solara/website/components/algolia_api.vue +187 -0
- solara/website/components/docs.py +118 -0
- solara/website/components/header.py +72 -0
- solara/website/components/hero.py +15 -0
- solara/website/components/mailchimp.py +12 -0
- solara/website/components/mailchimp.vue +47 -0
- solara/website/components/markdown.py +30 -0
- solara/website/components/notebook.py +171 -0
- solara/website/pages/__init__.py +575 -0
- solara/website/pages/apps/__init__.py +16 -0
- solara/website/pages/apps/authorization/__init__.py +119 -0
- solara/website/pages/apps/authorization/admin.py +12 -0
- solara/website/pages/apps/authorization/users.py +12 -0
- solara/website/pages/apps/jupyter-dashboard-1.py +116 -0
- solara/website/pages/apps/layout-demo.py +40 -0
- solara/website/pages/apps/multipage/__init__.py +38 -0
- solara/website/pages/apps/multipage/page1.py +26 -0
- solara/website/pages/apps/multipage/page2.py +34 -0
- solara/website/pages/apps/scatter.py +136 -0
- solara/website/pages/apps/scrolling.py +63 -0
- solara/website/pages/apps/tutorial-streamlit.py +18 -0
- solara/website/pages/changelog/__init__.py +8 -0
- solara/website/pages/changelog/changelog.md +204 -0
- solara/website/pages/contact/__init__.py +8 -0
- solara/website/pages/contact/contact.md +17 -0
- solara/website/pages/doc_use_download.py +85 -0
- solara/website/pages/documentation/__init__.py +184 -0
- solara/website/pages/documentation/advanced/__init__.py +9 -0
- solara/website/pages/documentation/advanced/content/00-overview.md +1 -0
- solara/website/pages/documentation/advanced/content/10-howto/00-overview.md +6 -0
- solara/website/pages/documentation/advanced/content/10-howto/10-multipage.md +196 -0
- solara/website/pages/documentation/advanced/content/10-howto/20-layout.md +125 -0
- solara/website/pages/documentation/advanced/content/10-howto/30-testing.md +162 -0
- solara/website/pages/documentation/advanced/content/10-howto/31-debugging.md +69 -0
- solara/website/pages/documentation/advanced/content/10-howto/40-embed.md +49 -0
- solara/website/pages/documentation/advanced/content/10-howto/50-ipywidget_libraries.md +124 -0
- solara/website/pages/documentation/advanced/content/15-reference/00-overview.md +3 -0
- solara/website/pages/documentation/advanced/content/15-reference/40-static_files.md +31 -0
- solara/website/pages/documentation/advanced/content/15-reference/41-asset-files.md +36 -0
- solara/website/pages/documentation/advanced/content/15-reference/60-static-site-generation.md +59 -0
- solara/website/pages/documentation/advanced/content/15-reference/70-search.md +34 -0
- solara/website/pages/documentation/advanced/content/15-reference/80-reloading.md +34 -0
- solara/website/pages/documentation/advanced/content/15-reference/90-notebook-support.md +7 -0
- solara/website/pages/documentation/advanced/content/15-reference/95-caching.md +148 -0
- solara/website/pages/documentation/advanced/content/20-understanding/00-introduction.md +10 -0
- solara/website/pages/documentation/advanced/content/20-understanding/05-ipywidgets.md +35 -0
- solara/website/pages/documentation/advanced/content/20-understanding/06-ipyvuetify.md +42 -0
- solara/website/pages/documentation/advanced/content/20-understanding/10-reacton.md +28 -0
- solara/website/pages/documentation/advanced/content/20-understanding/12-reacton-basics.md +108 -0
- solara/website/pages/documentation/advanced/content/20-understanding/15-anatomy.md +23 -0
- solara/website/pages/documentation/advanced/content/20-understanding/17-rules-of-hooks.md +7 -0
- solara/website/pages/documentation/advanced/content/20-understanding/18-containers.md +166 -0
- solara/website/pages/documentation/advanced/content/20-understanding/20-solara.md +18 -0
- solara/website/pages/documentation/advanced/content/20-understanding/40-routing.md +240 -0
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +97 -0
- solara/website/pages/documentation/advanced/content/20-understanding/60-voila.md +12 -0
- solara/website/pages/documentation/advanced/content/30-enterprise/00-overview.md +1 -0
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +171 -0
- solara/website/pages/documentation/advanced/content/40-development/00-overview.md +0 -0
- solara/website/pages/documentation/advanced/content/40-development/01-contribute.md +45 -0
- solara/website/pages/documentation/advanced/content/40-development/10-setup.md +76 -0
- solara/website/pages/documentation/api/__init__.py +19 -0
- solara/website/pages/documentation/api/cross_filter/__init__.py +9 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_dataframe.py +23 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +22 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +22 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +22 -0
- solara/website/pages/documentation/api/hooks/__init__.py +9 -0
- solara/website/pages/documentation/api/hooks/use_cross_filter.py +25 -0
- solara/website/pages/documentation/api/hooks/use_dark_effective.py +12 -0
- solara/website/pages/documentation/api/hooks/use_effect.md +43 -0
- solara/website/pages/documentation/api/hooks/use_effect.py +9 -0
- solara/website/pages/documentation/api/hooks/use_exception.py +33 -0
- solara/website/pages/documentation/api/hooks/use_memo.md +16 -0
- solara/website/pages/documentation/api/hooks/use_memo.py +9 -0
- solara/website/pages/documentation/api/hooks/use_previous.py +33 -0
- solara/website/pages/documentation/api/hooks/use_reactive.py +16 -0
- solara/website/pages/documentation/api/hooks/use_state.py +10 -0
- solara/website/pages/documentation/api/hooks/use_state_or_update.py +69 -0
- solara/website/pages/documentation/api/hooks/use_thread.md +58 -0
- solara/website/pages/documentation/api/hooks/use_thread.py +44 -0
- solara/website/pages/documentation/api/hooks/use_trait_observe.py +12 -0
- solara/website/pages/documentation/api/routing/__init__.py +9 -0
- solara/website/pages/documentation/api/routing/generate_routes.py +10 -0
- solara/website/pages/documentation/api/routing/generate_routes_directory.py +10 -0
- solara/website/pages/documentation/api/routing/resolve_path.py +35 -0
- solara/website/pages/documentation/api/routing/route.py +31 -0
- solara/website/pages/documentation/api/routing/use_route.py +80 -0
- solara/website/pages/documentation/api/routing/use_router.py +16 -0
- solara/website/pages/documentation/api/utilities/__init__.py +9 -0
- solara/website/pages/documentation/api/utilities/component_vue.py +10 -0
- solara/website/pages/documentation/api/utilities/computed.py +16 -0
- solara/website/pages/documentation/api/utilities/display.py +16 -0
- solara/website/pages/documentation/api/utilities/get_kernel_id.py +16 -0
- solara/website/pages/documentation/api/utilities/get_session_id.py +16 -0
- solara/website/pages/documentation/api/utilities/memoize.py +35 -0
- solara/website/pages/documentation/api/utilities/on_kernel_start.py +27 -0
- solara/website/pages/documentation/api/utilities/reactive.py +16 -0
- solara/website/pages/documentation/api/utilities/widget.py +104 -0
- solara/website/pages/documentation/components/__init__.py +12 -0
- solara/website/pages/documentation/components/advanced/__init__.py +9 -0
- solara/website/pages/documentation/components/advanced/link.py +27 -0
- solara/website/pages/documentation/components/advanced/meta.py +20 -0
- solara/website/pages/documentation/components/advanced/style.py +45 -0
- solara/website/pages/documentation/components/common.py +9 -0
- solara/website/pages/documentation/components/data/__init__.py +9 -0
- solara/website/pages/documentation/components/data/dataframe.py +44 -0
- solara/website/pages/documentation/components/data/pivot_table.py +81 -0
- solara/website/pages/documentation/components/enterprise/__init__.py +9 -0
- solara/website/pages/documentation/components/enterprise/avatar.py +24 -0
- solara/website/pages/documentation/components/enterprise/avatar_menu.py +25 -0
- solara/website/pages/documentation/components/input/__init__.py +9 -0
- solara/website/pages/documentation/components/input/button.py +23 -0
- solara/website/pages/documentation/components/input/checkbox.py +10 -0
- solara/website/pages/documentation/components/input/file_browser.py +32 -0
- solara/website/pages/documentation/components/input/file_drop.py +76 -0
- solara/website/pages/documentation/components/input/input.py +19 -0
- solara/website/pages/documentation/components/input/select.py +22 -0
- solara/website/pages/documentation/components/input/slider.py +29 -0
- solara/website/pages/documentation/components/input/switch.py +10 -0
- solara/website/pages/documentation/components/input/togglebuttons.py +21 -0
- solara/website/pages/documentation/components/lab/__init__.py +9 -0
- solara/website/pages/documentation/components/lab/chat.py +109 -0
- solara/website/pages/documentation/components/lab/confirmation_dialog.py +55 -0
- solara/website/pages/documentation/components/lab/cookies_headers.py +48 -0
- solara/website/pages/documentation/components/lab/input_date.py +20 -0
- solara/website/pages/documentation/components/lab/menu.py +22 -0
- solara/website/pages/documentation/components/lab/tab.py +25 -0
- solara/website/pages/documentation/components/lab/tabs.py +45 -0
- solara/website/pages/documentation/components/lab/task.py +11 -0
- solara/website/pages/documentation/components/lab/theming.py +72 -0
- solara/website/pages/documentation/components/lab/use_task.py +11 -0
- solara/website/pages/documentation/components/layout/__init__.py +9 -0
- solara/website/pages/documentation/components/layout/app_bar.py +16 -0
- solara/website/pages/documentation/components/layout/app_bar_title.py +16 -0
- solara/website/pages/documentation/components/layout/app_layout.py +24 -0
- solara/website/pages/documentation/components/layout/card.py +15 -0
- solara/website/pages/documentation/components/layout/card_actions.py +16 -0
- solara/website/pages/documentation/components/layout/column.py +30 -0
- solara/website/pages/documentation/components/layout/columns.py +27 -0
- solara/website/pages/documentation/components/layout/columns_responsive.py +68 -0
- solara/website/pages/documentation/components/layout/griddraggable.py +62 -0
- solara/website/pages/documentation/components/layout/gridfixed.py +21 -0
- solara/website/pages/documentation/components/layout/hbox.py +18 -0
- solara/website/pages/documentation/components/layout/row.py +30 -0
- solara/website/pages/documentation/components/layout/sidebar.py +24 -0
- solara/website/pages/documentation/components/layout/vbox.py +19 -0
- solara/website/pages/documentation/components/output/__init__.py +9 -0
- solara/website/pages/documentation/components/output/file_download.py +11 -0
- solara/website/pages/documentation/components/output/html.py +21 -0
- solara/website/pages/documentation/components/output/image.py +11 -0
- solara/website/pages/documentation/components/output/markdown.py +57 -0
- solara/website/pages/documentation/components/output/markdown_editor.py +51 -0
- solara/website/pages/documentation/components/output/sql_code.py +85 -0
- solara/website/pages/documentation/components/output/tooltip.py +11 -0
- solara/website/pages/documentation/components/page/__init__.py +9 -0
- solara/website/pages/documentation/components/page/head.py +18 -0
- solara/website/pages/documentation/components/page/title.py +27 -0
- solara/website/pages/documentation/components/status/__init__.py +9 -0
- solara/website/pages/documentation/components/status/error.py +40 -0
- solara/website/pages/documentation/components/status/info.py +40 -0
- solara/website/pages/documentation/components/status/progress.py +10 -0
- solara/website/pages/documentation/components/status/spinner.py +11 -0
- solara/website/pages/documentation/components/status/success.py +40 -0
- solara/website/pages/documentation/components/status/warning.py +47 -0
- solara/website/pages/documentation/components/viz/__init__.py +9 -0
- solara/website/pages/documentation/components/viz/altair.py +42 -0
- solara/website/pages/documentation/components/viz/echarts.py +75 -0
- solara/website/pages/documentation/components/viz/matplotlib.py +30 -0
- solara/website/pages/documentation/components/viz/plotly.py +63 -0
- solara/website/pages/documentation/components/viz/plotly_express.py +41 -0
- solara/website/pages/documentation/examples/__init__.py +52 -0
- solara/website/pages/documentation/examples/ai/__init__.py +11 -0
- solara/website/pages/documentation/examples/ai/chatbot.py +95 -0
- solara/website/pages/documentation/examples/ai/tokenizer.py +107 -0
- solara/website/pages/documentation/examples/basics/__init__.py +10 -0
- solara/website/pages/documentation/examples/basics/sine.py +28 -0
- solara/website/pages/documentation/examples/fullscreen/__init__.py +10 -0
- solara/website/pages/documentation/examples/fullscreen/authorization.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/layout_demo.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/multipage.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/scatter.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/scrolling.py +3 -0
- solara/website/pages/documentation/examples/fullscreen/tutorial_streamlit.py +3 -0
- solara/website/pages/documentation/examples/general/__init__.py +10 -0
- solara/website/pages/documentation/examples/general/custom_storage.py +70 -0
- solara/website/pages/documentation/examples/general/deploy_model.py +115 -0
- solara/website/pages/documentation/examples/general/live_update.py +38 -0
- solara/website/pages/documentation/examples/general/login_oauth.py +81 -0
- solara/website/pages/documentation/examples/general/mycard.vue +58 -0
- solara/website/pages/documentation/examples/general/pokemon_search.py +51 -0
- solara/website/pages/documentation/examples/general/vue_component.py +50 -0
- solara/website/pages/documentation/examples/ipycanvas.py +49 -0
- solara/website/pages/documentation/examples/libraries/__init__.py +10 -0
- solara/website/pages/documentation/examples/libraries/altair.py +64 -0
- solara/website/pages/documentation/examples/libraries/bqplot.py +39 -0
- solara/website/pages/documentation/examples/libraries/ipyleaflet.py +33 -0
- solara/website/pages/documentation/examples/libraries/ipyleaflet_advanced.py +66 -0
- solara/website/pages/documentation/examples/utilities/__init__.py +10 -0
- solara/website/pages/documentation/examples/utilities/calculator.py +157 -0
- solara/website/pages/documentation/examples/utilities/countdown_timer.py +64 -0
- solara/website/pages/documentation/examples/utilities/todo.py +196 -0
- solara/website/pages/documentation/examples/visualization/__init__.py +6 -0
- solara/website/pages/documentation/examples/visualization/annotator.py +69 -0
- solara/website/pages/documentation/examples/visualization/linked_views.py +84 -0
- solara/website/pages/documentation/examples/visualization/plotly.py +44 -0
- solara/website/pages/documentation/faq/__init__.py +12 -0
- solara/website/pages/documentation/faq/content/99-faq.md +76 -0
- solara/website/pages/documentation/getting_started/__init__.py +9 -0
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +89 -0
- solara/website/pages/documentation/getting_started/content/01-introduction.md +125 -0
- solara/website/pages/documentation/getting_started/content/02-installing.md +134 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/00-overview.md +14 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/10_data_science.py +13 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/20-web-app.md +89 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/30-ipywidgets.md +124 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/40-streamlit.md +146 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/50-dash.md +144 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/60-jupyter-dashboard-part1.py +64 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/SF_crime_sample.csv.gz +0 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/_data_science.ipynb +445 -0
- solara/website/pages/documentation/getting_started/content/04-tutorials/_jupyter_dashboard_1.ipynb +1000 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/00-overview.md +11 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/10-components.md +223 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +88 -0
- solara/website/pages/documentation/getting_started/content/07-deploying/00-overview.md +7 -0
- solara/website/pages/documentation/getting_started/content/07-deploying/10-self-hosted.md +273 -0
- solara/website/pages/documentation/getting_started/content/07-deploying/20-cloud-hosted.md +80 -0
- solara/website/pages/documentation/getting_started/content/80-what-is-lab.md +7 -0
- solara/website/pages/documentation/getting_started/content/90-troubleshoot.md +26 -0
- solara/website/pages/docutils.py +38 -0
- solara/website/pages/showcase/__init__.py +105 -0
- solara/website/pages/showcase/domino_code_assist.py +60 -0
- solara/website/pages/showcase/planeto_tessa.py +19 -0
- solara/website/pages/showcase/solara_dev.py +54 -0
- solara/website/pages/showcase/solarathon_2023_team_2.py +22 -0
- solara/website/pages/showcase/solarathon_2023_team_4.py +22 -0
- solara/website/pages/showcase/solarathon_2023_team_5.py +23 -0
- solara/website/pages/showcase/solarathon_2023_team_6.py +34 -0
- solara/website/pages/showcase/wanderlust.py +27 -0
- solara/website/public/beach.jpeg +0 -0
- solara/website/public/logo.svg +6 -0
- solara/website/public/social/discord.svg +1 -0
- solara/website/public/social/github.svg +1 -0
- solara/website/public/social/twitter.svg +3 -0
- solara/website/public/success.html +25 -0
- solara/website/templates/index.html.j2 +117 -0
- solara/website/utils.py +51 -0
- solara/widgets/__init__.py +1 -0
- solara/widgets/vue/gridlayout.vue +110 -0
- solara/widgets/vue/html.vue +4 -0
- solara/widgets/vue/navigator.vue +104 -0
- solara/widgets/vue/vegalite.vue +115 -0
- solara/widgets/widgets.py +66 -0
- solara_ui-1.31.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
- solara_ui-1.31.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
- solara_ui-1.31.0.dist-info/METADATA +158 -0
- solara_ui-1.31.0.dist-info/RECORD +439 -0
- solara_ui-1.31.0.dist-info/WHEEL +5 -0
- solara_ui-1.31.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
from typing import Callable, Dict, List, Optional, Union
|
|
2
|
+
|
|
3
|
+
import solara
|
|
4
|
+
from solara.components.component_vue import component_vue
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@component_vue("menu.vue")
|
|
8
|
+
def MenuWidget(
|
|
9
|
+
activator: List[solara.Element],
|
|
10
|
+
show_menu: bool,
|
|
11
|
+
on_show_menu: Optional[Callable] = None,
|
|
12
|
+
close_on_content_click: bool = True,
|
|
13
|
+
children: List[solara.Element] = [],
|
|
14
|
+
style: Optional[str] = None,
|
|
15
|
+
context: bool = False,
|
|
16
|
+
use_absolute: bool = True,
|
|
17
|
+
use_activator_width: bool = True,
|
|
18
|
+
):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@solara.component
|
|
23
|
+
def ClickMenu(
|
|
24
|
+
activator: Union[solara.Element, List[solara.Element]],
|
|
25
|
+
open_value: Union[solara.Reactive[bool], bool] = False,
|
|
26
|
+
on_open_value: Optional[Callable] = None,
|
|
27
|
+
children: List[solara.Element] = [],
|
|
28
|
+
style: Optional[Union[str, Dict[str, str]]] = None,
|
|
29
|
+
):
|
|
30
|
+
"""
|
|
31
|
+
Show a pop-up menu by clicking on the `activator` element. The menu appears at the cursor position.
|
|
32
|
+
|
|
33
|
+
```solara
|
|
34
|
+
import solara
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@solara.component
|
|
38
|
+
def Page():
|
|
39
|
+
image_url = "/static/public/beach.jpeg"
|
|
40
|
+
image = solara.Image(image=image_url)
|
|
41
|
+
|
|
42
|
+
with solara.lab.ClickMenu(activator=image):
|
|
43
|
+
with solara.Column(gap="0px"):
|
|
44
|
+
[solara.Button(f"Click me {i}!", text=True) for i in range(5)]
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Arguments
|
|
50
|
+
|
|
51
|
+
* activator: Clicking on this element will open the menu. Accepts either a `solara.Element`, or a list of elements.
|
|
52
|
+
* open_value: Controls and communicates the state of the menu. If True, the menu is open. If False, the menu is closed.
|
|
53
|
+
* on_open_value: Function to call when the menu is opened or closed.
|
|
54
|
+
* menu_contents: List of Elements to be contained in the menu.
|
|
55
|
+
* style: CSS style to apply. Applied directly onto the `v-menu` component.
|
|
56
|
+
"""
|
|
57
|
+
open_reactive = solara.use_reactive(open_value, on_open_value)
|
|
58
|
+
del open_value
|
|
59
|
+
|
|
60
|
+
style_flat = solara.util._flatten_style(style)
|
|
61
|
+
|
|
62
|
+
if not isinstance(activator, list):
|
|
63
|
+
activator = [activator]
|
|
64
|
+
|
|
65
|
+
return MenuWidget(
|
|
66
|
+
activator=activator,
|
|
67
|
+
children=children,
|
|
68
|
+
show_menu=open_reactive.value,
|
|
69
|
+
on_show_menu=open_reactive.set,
|
|
70
|
+
style=style_flat,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@solara.component
|
|
75
|
+
def ContextMenu(
|
|
76
|
+
activator: Union[solara.Element, List[solara.Element]],
|
|
77
|
+
open_value: Union[solara.Reactive[bool], bool] = False,
|
|
78
|
+
on_open_value: Optional[Callable] = None,
|
|
79
|
+
children: List[solara.Element] = [],
|
|
80
|
+
style: Optional[Union[str, Dict[str, str]]] = None,
|
|
81
|
+
):
|
|
82
|
+
"""
|
|
83
|
+
Show a context menu by triggering the contextmenu event on the `activator` element. The menu appears at the cursor position.
|
|
84
|
+
|
|
85
|
+
A contextmenu event is typically triggered by clicking the right mouse button, or by pressing the context menu key.
|
|
86
|
+
|
|
87
|
+
```solara
|
|
88
|
+
import solara
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@solara.component
|
|
92
|
+
def Page():
|
|
93
|
+
image_url = "/static/public/beach.jpeg"
|
|
94
|
+
image = solara.Image(image=image_url)
|
|
95
|
+
|
|
96
|
+
with solara.lab.ContextMenu(activator=image):
|
|
97
|
+
with solara.Column(gap="0px"):
|
|
98
|
+
[solara.Button(f"Click me {i}!", text=True) for i in range(5)]
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Arguments
|
|
103
|
+
|
|
104
|
+
* activator: Clicking on this element will open the menu. Accepts either a `solara.Element`, or a list of elements.
|
|
105
|
+
* open_value: Controls and communicates the state of the menu. If True, the menu is open. If False, the menu is closed.
|
|
106
|
+
* on_open_value: Function to call when the menu is opened or closed.
|
|
107
|
+
* children: List of Elements to be contained in the menu
|
|
108
|
+
* style: CSS style to apply. Applied directly onto the `v-menu` component.
|
|
109
|
+
"""
|
|
110
|
+
open_reactive = solara.use_reactive(open_value, on_open_value)
|
|
111
|
+
del open_value
|
|
112
|
+
style_flat = solara.util._flatten_style(style)
|
|
113
|
+
|
|
114
|
+
if not isinstance(activator, list):
|
|
115
|
+
activator = [activator]
|
|
116
|
+
|
|
117
|
+
return MenuWidget(
|
|
118
|
+
activator=activator,
|
|
119
|
+
children=children,
|
|
120
|
+
show_menu=open_reactive.value,
|
|
121
|
+
on_show_menu=open_reactive.set,
|
|
122
|
+
style=style_flat,
|
|
123
|
+
context=True,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@solara.component
|
|
128
|
+
def Menu(
|
|
129
|
+
activator: Union[solara.Element, List[solara.Element]],
|
|
130
|
+
open_value: Union[solara.Reactive[bool], bool] = False,
|
|
131
|
+
on_open_value: Optional[Callable] = None,
|
|
132
|
+
close_on_content_click: bool = True,
|
|
133
|
+
children: List[solara.Element] = [],
|
|
134
|
+
style: Optional[Union[str, Dict[str, str]]] = None,
|
|
135
|
+
use_activator_width: bool = True,
|
|
136
|
+
):
|
|
137
|
+
"""
|
|
138
|
+
Show a pop-up menu by clicking on the `activator` element. The menu appears below the `activator` element.
|
|
139
|
+
|
|
140
|
+
```solara
|
|
141
|
+
import solara
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@solara.component
|
|
145
|
+
def Page():
|
|
146
|
+
btn = solara.Button("Show suboptions")
|
|
147
|
+
|
|
148
|
+
with solara.lab.Menu(activator=btn):
|
|
149
|
+
with solara.Column(gap="0px"):
|
|
150
|
+
[solara.Button(f"Click me {str(i)}!", text=True) for i in range(5)]
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Arguments
|
|
155
|
+
|
|
156
|
+
* activator: Clicking on this element will open the menu. Accepts either a `solara.Element`, or a list of elements.
|
|
157
|
+
* open_value: Controls and communicates the state of the menu. If True, the menu is open. If False, the menu is closed.
|
|
158
|
+
* on_open_value: Function to call when the menu is opened or closed.
|
|
159
|
+
* children: List of Elements to be contained in the menu
|
|
160
|
+
* style: CSS style to apply. Applied directly onto the `v-menu` component.
|
|
161
|
+
* use_activator_width: If True, the menu will have a minimum width equal to the activator element.
|
|
162
|
+
If False, the menu width will be determined by the content.
|
|
163
|
+
"""
|
|
164
|
+
open_reactive = solara.use_reactive(open_value, on_open_value)
|
|
165
|
+
del open_value
|
|
166
|
+
|
|
167
|
+
style_flat = solara.util._flatten_style(style)
|
|
168
|
+
|
|
169
|
+
if not isinstance(activator, list):
|
|
170
|
+
activator = [activator]
|
|
171
|
+
|
|
172
|
+
return MenuWidget(
|
|
173
|
+
activator=activator,
|
|
174
|
+
children=children,
|
|
175
|
+
show_menu=open_reactive.value,
|
|
176
|
+
on_show_menu=open_reactive.set,
|
|
177
|
+
close_on_content_click=close_on_content_click,
|
|
178
|
+
style=style_flat,
|
|
179
|
+
use_absolute=False,
|
|
180
|
+
use_activator_width=use_activator_width,
|
|
181
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-menu
|
|
3
|
+
v-model="show_menu"
|
|
4
|
+
:absolute="use_absolute"
|
|
5
|
+
offset-y
|
|
6
|
+
:close-on-content-click="close_on_content_click"
|
|
7
|
+
:min-width="use_activator_width ? null : 'auto'"
|
|
8
|
+
>
|
|
9
|
+
<template v-if="context" v-slot:activator="{ on }">
|
|
10
|
+
<div v-for="(element, index) in activator"
|
|
11
|
+
:key="index"
|
|
12
|
+
@contextmenu.prevent="show($event, on)">
|
|
13
|
+
<jupyter-widget :widget="element"></jupyter-widget>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
<template v-else v-slot:activator="{ on }">
|
|
17
|
+
<jupyter-widget :widget="element" v-for="(element, index) in activator" :key="index" @click.native="on.click"></jupyter-widget>
|
|
18
|
+
</template>
|
|
19
|
+
<v-list v-for="(element, index) in children" :key="index" style="padding: 0;">
|
|
20
|
+
<jupyter-widget :widget="element" :style="style" ></jupyter-widget>
|
|
21
|
+
</v-list>
|
|
22
|
+
</v-menu>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
module.exports = {
|
|
27
|
+
methods: {
|
|
28
|
+
show(e, on) {
|
|
29
|
+
// hide menu, and trigger the event on the next tick, otherwise vue does not see
|
|
30
|
+
// `show_menu` changing and will no do any animation
|
|
31
|
+
this.show_menu = false;
|
|
32
|
+
this.$nextTick(() => {
|
|
33
|
+
on.click(e)
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
</script>
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
from typing import Callable, Dict, List, Optional, TypeVar, Union
|
|
2
|
+
|
|
3
|
+
import solara
|
|
4
|
+
from solara import v
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@solara.component
|
|
8
|
+
def Tab(
|
|
9
|
+
label: Union[None, str, solara.Element] = None,
|
|
10
|
+
icon_name: Optional[str] = None,
|
|
11
|
+
path_or_route: Union[None, str, "solara.Route"] = None,
|
|
12
|
+
disabled=False,
|
|
13
|
+
classes: List[str] = [],
|
|
14
|
+
style: Union[str, Dict[str, str], None] = None,
|
|
15
|
+
children: List[solara.Element] = [],
|
|
16
|
+
tab_children: List[Union[solara.Element, str]] = [],
|
|
17
|
+
):
|
|
18
|
+
"""An item in a Tabs component.
|
|
19
|
+
|
|
20
|
+
(*Note: [This component is experimental and its API may change in the future](/documentation/getting_started/what-is-lab).*)
|
|
21
|
+
|
|
22
|
+
Should be a direct child of a [Tabs](/documentation/components/lab/tabs).
|
|
23
|
+
|
|
24
|
+
## Arguments
|
|
25
|
+
* `label`: The label of the tab.
|
|
26
|
+
* `icon_name`: The name of the icon to display in the tab.
|
|
27
|
+
* `path_or_route`: The path or route to navigate to when the tab is clicked.
|
|
28
|
+
* `disabled`: Whether the tab is disabled.
|
|
29
|
+
* `classes`: Additional CSS classes to apply.
|
|
30
|
+
* `style`: CSS style to apply.
|
|
31
|
+
* `children`: The children of the tab. These will be displayed when the tab is active.
|
|
32
|
+
* `tab_children`: The children of the tab header. These will be displayed in the tab
|
|
33
|
+
header, if a label or icon_name is provided they are prepended to the `tab_children`.
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
if label is not None:
|
|
37
|
+
tab_children = [label] + tab_children
|
|
38
|
+
if icon_name:
|
|
39
|
+
tab_children = [v.Icon(left=bool(label), children=[icon_name])] + tab_children
|
|
40
|
+
style_flat = solara.util._flatten_style(style)
|
|
41
|
+
class_ = solara.util._combine_classes(classes)
|
|
42
|
+
# note: children is not used, it is only used in the Tabs component
|
|
43
|
+
return v.Tab(children=tab_children, disabled=disabled, class_=class_, style_=style_flat)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
T = TypeVar("T")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@solara.component
|
|
50
|
+
def Tabs(
|
|
51
|
+
value: Union[None, int, "solara.Reactive[int]"] = None,
|
|
52
|
+
on_value: Optional[Callable[[int], None]] = None,
|
|
53
|
+
color: Optional[str] = None,
|
|
54
|
+
background_color: Optional[str] = None,
|
|
55
|
+
slider_color: Optional[str] = None,
|
|
56
|
+
dark: bool = False,
|
|
57
|
+
grow: bool = False,
|
|
58
|
+
vertical=False,
|
|
59
|
+
align: str = "left",
|
|
60
|
+
lazy=False,
|
|
61
|
+
children: List[solara.Element] = [],
|
|
62
|
+
):
|
|
63
|
+
"""A tabbed container showing one tab at a time.
|
|
64
|
+
|
|
65
|
+
(*Note: [This component is experimental and its API may change in the future](/documentation/getting_started/what-is-lab).*)
|
|
66
|
+
|
|
67
|
+
Note that if Tabs are used as a child of the [AppBar](/documentation/components/layout/app_bar) component, the tabs
|
|
68
|
+
will be placed under the app bar. See our [authorization app](/apps/authorization) for an example.
|
|
69
|
+
|
|
70
|
+
If the children [Tab](/documentation/components/lab/tab) elements are passed a `path_or_route` argument, the active tab
|
|
71
|
+
will be based on the path of the current page.
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
## Examples
|
|
75
|
+
|
|
76
|
+
### Only tabs headers
|
|
77
|
+
|
|
78
|
+
```solara
|
|
79
|
+
import solara
|
|
80
|
+
import solara.lab
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@solara.component
|
|
84
|
+
def Page():
|
|
85
|
+
with solara.lab.Tabs():
|
|
86
|
+
solara.lab.Tab("Tab 1")
|
|
87
|
+
solara.lab.Tab("Tab 2")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Tabs with content
|
|
91
|
+
|
|
92
|
+
This is usually only used when the tabs are placed in the [AppBar](/documentation/components/layout/app_bar) component.
|
|
93
|
+
|
|
94
|
+
```solara
|
|
95
|
+
import solara
|
|
96
|
+
import solara.lab
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@solara.component
|
|
100
|
+
def Page():
|
|
101
|
+
with solara.lab.Tabs():
|
|
102
|
+
with solara.lab.Tab("Tab 1"):
|
|
103
|
+
solara.Markdown("Hello")
|
|
104
|
+
with solara.lab.Tab("Tab 2"):
|
|
105
|
+
solara.Markdown("World")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
### Tabs events
|
|
110
|
+
|
|
111
|
+
The `value` on the Tabs component is a reactive value that can be used to
|
|
112
|
+
listen to changes in the selected tab and make the UI respond to it.
|
|
113
|
+
|
|
114
|
+
```solara
|
|
115
|
+
import solara
|
|
116
|
+
import solara.lab
|
|
117
|
+
|
|
118
|
+
tab_index = solara.reactive(0)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@solara.component
|
|
122
|
+
def Page():
|
|
123
|
+
|
|
124
|
+
def next_tab():
|
|
125
|
+
tab_index.value = (tab_index.value + 1) % 2
|
|
126
|
+
|
|
127
|
+
solara.Title(f"Tab {tab_index.value + 1}")
|
|
128
|
+
solara.Button('Next Tab', on_click=next_tab)
|
|
129
|
+
|
|
130
|
+
with solara.lab.Tabs(value=tab_index):
|
|
131
|
+
with solara.lab.Tab("Tab 1"):
|
|
132
|
+
solara.Markdown("Hello")
|
|
133
|
+
with solara.lab.Tab("Tab 2"):
|
|
134
|
+
solara.Markdown("World")
|
|
135
|
+
with solara.lab.Tab("Disabled", disabled=True):
|
|
136
|
+
solara.Markdown("World")
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Advanced tabs
|
|
141
|
+
|
|
142
|
+
Tabs can be nested, styled and placed vertically.
|
|
143
|
+
|
|
144
|
+
```solara
|
|
145
|
+
import solara
|
|
146
|
+
import solara.lab
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@solara.component
|
|
150
|
+
def Page():
|
|
151
|
+
with solara.lab.Tabs(background_color="primary", dark=True):
|
|
152
|
+
with solara.lab.Tab("Home", icon_name="mdi-home"):
|
|
153
|
+
solara.Markdown("Hello")
|
|
154
|
+
with solara.lab.Tab("Advanced", icon_name="mdi-apps"):
|
|
155
|
+
with solara.lab.Tabs(grow=True, background_color="primary", dark=True, slider_color="green"):
|
|
156
|
+
with solara.lab.Tab("Settings", icon_name="mdi-cogs"):
|
|
157
|
+
with solara.lab.Tabs(vertical=True, slider_color="green"):
|
|
158
|
+
with solara.lab.Tab("User", icon_name="mdi-account"):
|
|
159
|
+
solara.Markdown("User settings")
|
|
160
|
+
with solara.lab.Tab("System", icon_name="mdi-access-point"):
|
|
161
|
+
solara.Markdown("System settings")
|
|
162
|
+
with solara.lab.Tab("Analytics", icon_name="mdi-chart-line"):
|
|
163
|
+
with solara.lab.Tabs(vertical=True):
|
|
164
|
+
with solara.lab.Tab("User", icon_name="mdi-account"):
|
|
165
|
+
solara.Markdown("User analytics")
|
|
166
|
+
with solara.lab.Tab("System", icon_name="mdi-access-point"):
|
|
167
|
+
solara.Markdown("System analytics")
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
### Many tabs
|
|
173
|
+
|
|
174
|
+
If many tabs are shown, paginations arrows are shown.
|
|
175
|
+
|
|
176
|
+
```solara
|
|
177
|
+
import solara
|
|
178
|
+
import solara.lab
|
|
179
|
+
|
|
180
|
+
tab_count = 30
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@solara.component
|
|
184
|
+
def Page():
|
|
185
|
+
with solara.lab.Tabs():
|
|
186
|
+
for i in range(tab_count):
|
|
187
|
+
with solara.lab.Tab(f"Tab {i+1}"):
|
|
188
|
+
solara.Markdown(f"Content for tab {i+1}")
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
## Arguments
|
|
193
|
+
|
|
194
|
+
* `value`: The index of the selected tab. If `None`, the first tab is selected or it is based in the route/path.
|
|
195
|
+
* `on_value`: A callback that is called when the selected tab changes.
|
|
196
|
+
* `color`: The color of text in the tab headers (only for dark=False).
|
|
197
|
+
* `background_color`: The background color of the tab headers.
|
|
198
|
+
* `slider_color`: The color of the slider.
|
|
199
|
+
* `dark`: Apply a dark theme.
|
|
200
|
+
* `grow`: Whether the tabs should grow to fill the available space.
|
|
201
|
+
* `vertical`: Whether the tabs are vertical.
|
|
202
|
+
* `align`: The alignment of the tabs, possible values are 'left', 'start', 'center', 'right' or 'end'.
|
|
203
|
+
* `lazy`: Whether the child components of the inactive tabs are rendered or not. If lazy=True, components of inactive tabs are not rendered.
|
|
204
|
+
* `classes`: Additional CSS classes to apply.
|
|
205
|
+
* `style`: CSS style to apply.
|
|
206
|
+
"""
|
|
207
|
+
|
|
208
|
+
paths_of_routes = [child.kwargs.get("path_or_route") for child in children]
|
|
209
|
+
paths = [solara.resolve_path(path_or_route, level=0) if path_or_route else None for path_or_route in paths_of_routes]
|
|
210
|
+
router = solara.use_router()
|
|
211
|
+
if value is None:
|
|
212
|
+
if router.path in paths:
|
|
213
|
+
value = paths.index(router.path)
|
|
214
|
+
else:
|
|
215
|
+
value = 0
|
|
216
|
+
|
|
217
|
+
def safe_on_value(index: Optional[int]):
|
|
218
|
+
if on_value and index is not None:
|
|
219
|
+
on_value(index)
|
|
220
|
+
|
|
221
|
+
reactive_value = solara.use_reactive(value, safe_on_value)
|
|
222
|
+
del value
|
|
223
|
+
|
|
224
|
+
has_content = False
|
|
225
|
+
for i, child in enumerate(children):
|
|
226
|
+
if not child.component == Tab:
|
|
227
|
+
raise ValueError(f"Tabs children must be Tab components, but child {i} is {child.component}")
|
|
228
|
+
if child.kwargs.get("children"):
|
|
229
|
+
has_content = True
|
|
230
|
+
|
|
231
|
+
def on_v_model(index: Optional[int]):
|
|
232
|
+
if index is not None:
|
|
233
|
+
path = paths[index]
|
|
234
|
+
if path:
|
|
235
|
+
router.push(path)
|
|
236
|
+
reactive_value.value = index
|
|
237
|
+
|
|
238
|
+
if align not in ["left", "start", "center", "right", "end"]:
|
|
239
|
+
raise ValueError(f"Tabs align must be one of 'left', 'start', 'center', 'right', 'end', but is {align}")
|
|
240
|
+
|
|
241
|
+
with v.Tabs(
|
|
242
|
+
v_model=reactive_value.value,
|
|
243
|
+
on_v_model=on_v_model,
|
|
244
|
+
centered=align == "center",
|
|
245
|
+
right=align in ["right", "end"],
|
|
246
|
+
children=children,
|
|
247
|
+
vertical=vertical,
|
|
248
|
+
color=color,
|
|
249
|
+
background_color=background_color,
|
|
250
|
+
show_arrows=True,
|
|
251
|
+
grow=grow,
|
|
252
|
+
dark=dark,
|
|
253
|
+
) as tabs:
|
|
254
|
+
v.TabsSlider(color=slider_color)
|
|
255
|
+
if has_content:
|
|
256
|
+
with v.TabsItems(v_model=reactive_value.value, on_v_model=on_v_model):
|
|
257
|
+
for i, child in enumerate(children):
|
|
258
|
+
if not lazy or reactive_value.value == i:
|
|
259
|
+
v.TabItem(children=child.kwargs.get("children", []), value=i)
|
|
260
|
+
else:
|
|
261
|
+
v.TabItem(
|
|
262
|
+
value=i,
|
|
263
|
+
children=[
|
|
264
|
+
# Nice idea, but by using the widget interface the tab does not change without binding using
|
|
265
|
+
# v-model. So we would need to implement this using a vuetify template.
|
|
266
|
+
# v.SkeletonLoader(
|
|
267
|
+
# class_="mx-auto",
|
|
268
|
+
# max_width="300",
|
|
269
|
+
# type="card",
|
|
270
|
+
# )
|
|
271
|
+
],
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
return tabs
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from typing import Callable, Dict, Union, cast
|
|
2
|
+
|
|
3
|
+
import ipyvuetify.Themes
|
|
4
|
+
from ipyvuetify.Themes import Theme
|
|
5
|
+
|
|
6
|
+
import solara
|
|
7
|
+
from solara.components.component_vue import component_vue
|
|
8
|
+
from solara.tasks import Proxy
|
|
9
|
+
|
|
10
|
+
theme = Proxy(Theme)
|
|
11
|
+
ipyvuetify.Themes.theme = cast(ipyvuetify.Themes.Theme, theme)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def use_dark_effective():
|
|
15
|
+
"""Return True if the frontend is using a dark theme.
|
|
16
|
+
|
|
17
|
+
Equivalent of
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
solara.use_trait_observe(solara.lab.theme, "dark_effective")
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
See [use_trait_observe](/api/use_trait_observe).
|
|
24
|
+
"""
|
|
25
|
+
return solara.use_trait_observe(theme, "dark_effective")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _set_theme(themes: Union[Dict[str, Dict[str, str]], None]):
|
|
29
|
+
if themes is None:
|
|
30
|
+
return
|
|
31
|
+
|
|
32
|
+
for theme_type in themes.keys():
|
|
33
|
+
widget = getattr(theme.themes, theme_type)
|
|
34
|
+
with widget.hold_trait_notifications():
|
|
35
|
+
for k, v in themes[theme_type].items():
|
|
36
|
+
setattr(widget, k, v)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _get_theme(theme: Theme) -> Dict[str, Dict[str, str]]:
|
|
40
|
+
theme_dict: Dict[str, Dict[str, str]] = cast(Dict[str, Dict[str, str]], {})
|
|
41
|
+
for theme_type, theme_value in theme.themes.__dict__.items():
|
|
42
|
+
theme_traits = theme_value.keys
|
|
43
|
+
theme_dict[theme_type] = {}
|
|
44
|
+
for trait in theme_traits:
|
|
45
|
+
if not trait.startswith("_"):
|
|
46
|
+
theme_dict[theme_type][trait] = getattr(theme_value, trait)
|
|
47
|
+
return theme_dict
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@component_vue("theming.vue")
|
|
51
|
+
def _ThemeToggle(
|
|
52
|
+
theme_dark: str,
|
|
53
|
+
event_sync_themes: Callable[[str], None],
|
|
54
|
+
enable_auto: bool,
|
|
55
|
+
on_icon: str,
|
|
56
|
+
off_icon: str,
|
|
57
|
+
auto_icon: str,
|
|
58
|
+
clicks: int = 1,
|
|
59
|
+
):
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@solara.component
|
|
64
|
+
def ThemeToggle(
|
|
65
|
+
on_icon: str = "mdi-weather-night",
|
|
66
|
+
off_icon: str = "mdi-weather-sunny",
|
|
67
|
+
auto_icon: str = "mdi-brightness-auto",
|
|
68
|
+
enable_auto: bool = True,
|
|
69
|
+
):
|
|
70
|
+
"""
|
|
71
|
+
Insert a toggle switch for user to switch between light and dark themes.
|
|
72
|
+
|
|
73
|
+
```solara
|
|
74
|
+
import solara.lab
|
|
75
|
+
|
|
76
|
+
@solara.component
|
|
77
|
+
def Page():
|
|
78
|
+
solara.lab.ThemeToggle()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Arguments
|
|
82
|
+
- `on_icon`: The icon to display when the dark theme is enabled.
|
|
83
|
+
- `off_icon`: The icon to display when the dark theme is disabled.
|
|
84
|
+
- `auto_icon`: The icon to display when the theme is set to auto. Only visible if `enable_auto` is `True`.
|
|
85
|
+
- `enable_auto`: Whether to enable the auto detection of dark mode.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
def sync_themes(selected_theme: str):
|
|
89
|
+
theme.dark = selected_theme
|
|
90
|
+
|
|
91
|
+
return _ThemeToggle(
|
|
92
|
+
theme_dark=theme.dark,
|
|
93
|
+
event_sync_themes=sync_themes,
|
|
94
|
+
enable_auto=enable_auto,
|
|
95
|
+
on_icon=on_icon,
|
|
96
|
+
off_icon=off_icon,
|
|
97
|
+
auto_icon=auto_icon,
|
|
98
|
+
)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-btn
|
|
3
|
+
icon
|
|
4
|
+
@click="countClicks"
|
|
5
|
+
>
|
|
6
|
+
<v-icon>
|
|
7
|
+
{{ this.clicks === 1 ? this.on_icon : this.clicks === 2 ? this.off_icon : this.auto_icon }}
|
|
8
|
+
</v-icon>
|
|
9
|
+
</v-btn>
|
|
10
|
+
</template>
|
|
11
|
+
<script>
|
|
12
|
+
module.exports = {
|
|
13
|
+
mounted() {
|
|
14
|
+
if (window.solara) {
|
|
15
|
+
if (localStorage.getItem(':solara:theme.variant')) {
|
|
16
|
+
this.theme_dark = this.initTheme();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if ( this.theme_dark === false ) {
|
|
21
|
+
this.clicks = 2;
|
|
22
|
+
} else if ( this.theme_dark === null ) {
|
|
23
|
+
this.clicks = 3;
|
|
24
|
+
}
|
|
25
|
+
this.lim = this.enable_auto ? 3 : 2;
|
|
26
|
+
},
|
|
27
|
+
methods: {
|
|
28
|
+
countClicks() {
|
|
29
|
+
if ( this.clicks < this.lim ) {
|
|
30
|
+
this.clicks++;
|
|
31
|
+
} else {
|
|
32
|
+
this.clicks = 1;
|
|
33
|
+
}
|
|
34
|
+
this.theme_dark = this.get_theme_bool( this.clicks );
|
|
35
|
+
},
|
|
36
|
+
get_theme_bool( clicks ) {
|
|
37
|
+
if ( clicks === 3 ) {
|
|
38
|
+
return null;
|
|
39
|
+
} else if ( clicks === 2 ) {
|
|
40
|
+
return false;
|
|
41
|
+
} else {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
stringifyTheme() {
|
|
46
|
+
return this.theme_dark === true ? 'dark' : this.theme_dark === false ? 'light' : 'auto';
|
|
47
|
+
},
|
|
48
|
+
initTheme() {
|
|
49
|
+
storedTheme = JSON.parse(localStorage.getItem(':solara:theme.variant'));
|
|
50
|
+
return storedTheme === 'dark' ? true : storedTheme === 'light' ? false : null;
|
|
51
|
+
},
|
|
52
|
+
setTheme() {
|
|
53
|
+
if ( window.solara && this.theme_dark === null ) {
|
|
54
|
+
this.$vuetify.theme.dark = this.prefersDarkScheme();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.$vuetify.theme.dark = this.theme_dark;
|
|
58
|
+
},
|
|
59
|
+
prefersDarkScheme() {
|
|
60
|
+
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
watch: {
|
|
64
|
+
clicks (val) {
|
|
65
|
+
if ( window.solara ) {theme.variant = this.stringifyTheme();}
|
|
66
|
+
this.setTheme();
|
|
67
|
+
if ( window.solara ) {localStorage.setItem(':solara:theme.variant', JSON.stringify(theme.variant));}
|
|
68
|
+
this.sync_themes(this.theme_dark);
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
</script>
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from ..utils.dataframe import df_type
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def use_df_column_names(df):
|
|
5
|
+
if df_type(df) == "vaex":
|
|
6
|
+
return df.get_column_names()
|
|
7
|
+
elif df_type(df) == "pandas":
|
|
8
|
+
return df.columns.tolist()
|
|
9
|
+
elif df_type(df) == "polars":
|
|
10
|
+
return df.columns
|
|
11
|
+
else:
|
|
12
|
+
raise TypeError(f"{type(df)} not supported")
|
solara/lab/toestand.py
ADDED