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.
- 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 +765 -0
- solara/_stores.py +297 -0
- solara/alias.py +6 -0
- solara/autorouting.py +555 -0
- solara/cache.py +305 -0
- solara/checks.html +71 -0
- solara/checks.py +227 -0
- solara/comm.py +28 -0
- solara/components/__init__.py +77 -0
- solara/components/alert.py +155 -0
- solara/components/applayout.py +397 -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 +134 -0
- solara/components/cross_filter.py +335 -0
- solara/components/dataframe.py +546 -0
- solara/components/datatable.py +214 -0
- solara/components/datatable.vue +175 -0
- solara/components/details.py +56 -0
- solara/components/download.vue +35 -0
- solara/components/echarts.py +86 -0
- solara/components/echarts.vue +139 -0
- solara/components/figure_altair.py +39 -0
- solara/components/file_browser.py +181 -0
- solara/components/file_download.py +199 -0
- solara/components/file_drop.py +159 -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 +456 -0
- solara/components/input_text_area.py +86 -0
- solara/components/link.py +55 -0
- solara/components/markdown.py +441 -0
- solara/components/markdown_editor.py +33 -0
- solara/components/markdown_editor.vue +359 -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 +45 -0
- solara/components/sql_code.py +41 -0
- solara/components/sql_code.vue +125 -0
- solara/components/style.py +105 -0
- solara/components/switch.py +71 -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/core.py +42 -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 +151 -0
- solara/hooks/use_thread.py +129 -0
- solara/kitchensink.py +8 -0
- solara/lab/__init__.py +34 -0
- solara/lab/components/__init__.py +7 -0
- solara/lab/components/chat.py +215 -0
- solara/lab/components/confirmation_dialog.py +163 -0
- solara/lab/components/cross_filter.py +7 -0
- solara/lab/components/input_date.py +339 -0
- solara/lab/components/input_time.py +133 -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 +2 -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 +165 -0
- solara/lab/utils/headers.py +5 -0
- solara/layout.py +44 -0
- solara/lifecycle.py +46 -0
- solara/minisettings.py +141 -0
- solara/py.typed +0 -0
- solara/reactive.py +99 -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 +527 -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 +1681 -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 +91 -0
- solara/server/esm.py +71 -0
- solara/server/fastapi.py +5 -0
- solara/server/flask.py +297 -0
- solara/server/jupyter/__init__.py +2 -0
- solara/server/jupyter/cdn_handler.py +28 -0
- solara/server/jupyter/server_extension.py +40 -0
- solara/server/jupyter/solara.py +91 -0
- solara/server/jupytertools.py +46 -0
- solara/server/kernel.py +388 -0
- solara/server/kernel_context.py +467 -0
- solara/server/patch.py +564 -0
- solara/server/pyinstaller/__init__.py +9 -0
- solara/server/pyinstaller/hook-ipyreact.py +5 -0
- solara/server/pyinstaller/hook-ipyvuetify.py +5 -0
- solara/server/pyinstaller/hook-solara.py +9 -0
- solara/server/qt.py +113 -0
- solara/server/reload.py +251 -0
- solara/server/server.py +484 -0
- solara/server/settings.py +249 -0
- solara/server/shell.py +269 -0
- solara/server/starlette.py +770 -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 +272 -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 +486 -0
- solara/server/threaded.py +84 -0
- solara/server/utils.py +44 -0
- solara/server/websocket.py +45 -0
- solara/settings.py +86 -0
- solara/tasks.py +893 -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 +783 -0
- solara/toestand.py +998 -0
- solara/util.py +348 -0
- solara/validate_hooks.py +258 -0
- solara/website/__init__.py +0 -0
- solara/website/assets/custom.css +444 -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.py +6 -0
- solara/website/components/algolia.vue +24 -0
- solara/website/components/algolia_api.vue +202 -0
- solara/website/components/breadcrumbs.py +28 -0
- solara/website/components/contact.py +144 -0
- solara/website/components/docs.py +143 -0
- solara/website/components/header.py +75 -0
- solara/website/components/mailchimp.py +12 -0
- solara/website/components/mailchimp.vue +47 -0
- solara/website/components/markdown.py +99 -0
- solara/website/components/markdown_nav.vue +34 -0
- solara/website/components/notebook.py +171 -0
- solara/website/components/sidebar.py +105 -0
- solara/website/pages/__init__.py +370 -0
- solara/website/pages/about/__init__.py +9 -0
- solara/website/pages/about/about.md +3 -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/careers/__init__.py +27 -0
- solara/website/pages/changelog/__init__.py +10 -0
- solara/website/pages/changelog/changelog.md +372 -0
- solara/website/pages/contact/__init__.py +34 -0
- solara/website/pages/doc_use_download.py +85 -0
- solara/website/pages/documentation/__init__.py +90 -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 +417 -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 +50 -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 +72 -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 +192 -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 +256 -0
- solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md +108 -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 +7 -0
- solara/website/pages/documentation/advanced/content/30-enterprise/10-oauth.md +187 -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 +22 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_report.py +20 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_select.py +20 -0
- solara/website/pages/documentation/api/cross_filter/cross_filter_slider.py +20 -0
- solara/website/pages/documentation/api/hooks/__init__.py +9 -0
- solara/website/pages/documentation/api/hooks/use_cross_filter.py +23 -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 +31 -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 +30 -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 +66 -0
- solara/website/pages/documentation/api/hooks/use_thread.md +64 -0
- solara/website/pages/documentation/api/hooks/use_thread.py +42 -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 +29 -0
- solara/website/pages/documentation/api/routing/use_route.py +76 -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 +44 -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 +25 -0
- solara/website/pages/documentation/components/advanced/meta.py +17 -0
- solara/website/pages/documentation/components/advanced/style.py +43 -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 +30 -0
- solara/website/pages/documentation/components/input/file_drop.py +76 -0
- solara/website/pages/documentation/components/input/input.py +43 -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/input_time.py +15 -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 +74 -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 +66 -0
- solara/website/pages/documentation/components/layout/details.py +13 -0
- solara/website/pages/documentation/components/layout/griddraggable.py +62 -0
- solara/website/pages/documentation/components/layout/gridfixed.py +19 -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 +19 -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 +83 -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 +15 -0
- solara/website/pages/documentation/components/page/title.py +25 -0
- solara/website/pages/documentation/components/status/__init__.py +9 -0
- solara/website/pages/documentation/components/status/error.py +39 -0
- solara/website/pages/documentation/components/status/info.py +39 -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 +77 -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 +54 -0
- solara/website/pages/documentation/examples/ai/__init__.py +11 -0
- solara/website/pages/documentation/examples/ai/chatbot.py +113 -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 +32 -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 +65 -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 +62 -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 +67 -0
- solara/website/pages/documentation/examples/visualization/linked_views.py +81 -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 +112 -0
- solara/website/pages/documentation/getting_started/__init__.py +9 -0
- solara/website/pages/documentation/getting_started/content/00-quickstart.md +107 -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 +65 -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 +1021 -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 +228 -0
- solara/website/pages/documentation/getting_started/content/05-fundamentals/50-state-management.md +278 -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 +305 -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/home.vue +1199 -0
- solara/website/pages/our_team/__init__.py +83 -0
- solara/website/pages/pricing/__init__.py +31 -0
- solara/website/pages/roadmap/__init__.py +11 -0
- solara/website/pages/roadmap/roadmap.md +47 -0
- solara/website/pages/scale_ipywidgets.py +45 -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 +107 -0
- solara/widgets/vue/html.vue +4 -0
- solara/widgets/vue/navigator.vue +134 -0
- solara/widgets/vue/vegalite.vue +130 -0
- solara/widgets/widgets.py +74 -0
- solara_ui-1.45.0.data/data/etc/jupyter/jupyter_notebook_config.d/solara.json +7 -0
- solara_ui-1.45.0.data/data/etc/jupyter/jupyter_server_config.d/solara.json +7 -0
- solara_ui-1.45.0.dist-info/METADATA +162 -0
- solara_ui-1.45.0.dist-info/RECORD +464 -0
- solara_ui-1.45.0.dist-info/WHEEL +4 -0
- solara_ui-1.45.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from typing import Callable, Dict, List, Optional, Union
|
|
2
|
+
|
|
3
|
+
import solara
|
|
4
|
+
import solara.util
|
|
5
|
+
from reacton import ipyvue
|
|
6
|
+
from reacton import ipyvuetify as v
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@solara.component
|
|
10
|
+
def Button(
|
|
11
|
+
label: str = None,
|
|
12
|
+
on_click: Callable[[], None] = None,
|
|
13
|
+
icon_name: str = None,
|
|
14
|
+
children: list = [],
|
|
15
|
+
disabled=False,
|
|
16
|
+
text=False,
|
|
17
|
+
outlined=False,
|
|
18
|
+
color: Optional[str] = None,
|
|
19
|
+
click_event="click",
|
|
20
|
+
classes: List[str] = [],
|
|
21
|
+
style: Union[str, Dict[str, str], None] = None,
|
|
22
|
+
value=None,
|
|
23
|
+
**kwargs,
|
|
24
|
+
):
|
|
25
|
+
"""A button that can be clicked to trigger an event.
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
|
|
29
|
+
```solara
|
|
30
|
+
import solara
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@solara.component
|
|
34
|
+
def Page():
|
|
35
|
+
with solara.Row():
|
|
36
|
+
solara.Button(label="Default")
|
|
37
|
+
solara.Button(label="Default+color", color="primary")
|
|
38
|
+
solara.Button(label="Text", text=True)
|
|
39
|
+
solara.Button(label="Outlined", outlined=True)
|
|
40
|
+
solara.Button(label="Outlined+color", outlined=True, color="primary")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## Arguments
|
|
45
|
+
|
|
46
|
+
- `label`: The text to display on the button.
|
|
47
|
+
- `on_click`: A callback function that is called when the button is clicked.
|
|
48
|
+
- `icon_name`: The name of the icon to display on the button ([Overview of available icons](https://pictogrammers.github.io/@mdi/font/4.9.95/)).
|
|
49
|
+
- `children`: A list of child elements to display on the button.
|
|
50
|
+
- `disabled`: Whether the button is disabled.
|
|
51
|
+
- `text`: Whether the button should be displayed as text, it has no shadow and no background.
|
|
52
|
+
- `outlined`: Whether the button should be displayed as outlined, it has no background.
|
|
53
|
+
- `value`: (Optional) When used as a child of a ToggleButtons component, the value of the selected button, see
|
|
54
|
+
[ToggleButtons](/documentation/components/input/togglebuttons).
|
|
55
|
+
- `classes`: Additional CSS classes to apply.
|
|
56
|
+
- `style`: CSS style to apply.
|
|
57
|
+
|
|
58
|
+
### Deprecated arguments
|
|
59
|
+
- click_event: (Deprecated/export option: The event that triggers the on_click callback, which can include vue event modifiers).
|
|
60
|
+
|
|
61
|
+
"""
|
|
62
|
+
if label:
|
|
63
|
+
children = [label] + children
|
|
64
|
+
if icon_name:
|
|
65
|
+
children = [v.Icon(left=bool(label), children=[icon_name])] + children
|
|
66
|
+
if "class_" in kwargs:
|
|
67
|
+
kwargs = kwargs.copy()
|
|
68
|
+
class_ = solara.util._combine_classes([*classes, kwargs.pop("class_")])
|
|
69
|
+
else:
|
|
70
|
+
class_ = solara.util._combine_classes(classes)
|
|
71
|
+
kwargs = kwargs.copy()
|
|
72
|
+
style_flat = solara.util._flatten_style(style)
|
|
73
|
+
if "style_" in kwargs:
|
|
74
|
+
style_flat += kwargs.pop("style_")
|
|
75
|
+
if solara.util.ipyvuetify_major_version == 3:
|
|
76
|
+
variant = "elevated"
|
|
77
|
+
if text:
|
|
78
|
+
variant = "text"
|
|
79
|
+
elif outlined:
|
|
80
|
+
variant = "outlined"
|
|
81
|
+
btn = solara.v.Btn(children=children, **kwargs, disabled=disabled, class_=class_, style_=style_flat, color=color, variant=variant)
|
|
82
|
+
else:
|
|
83
|
+
btn = solara.v.Btn(children=children, **kwargs, disabled=disabled, text=text, class_=class_, style_=style_flat, outlined=outlined, color=color)
|
|
84
|
+
ipyvue.use_event(btn, click_event, lambda *_ignore: on_click and on_click())
|
|
85
|
+
return btn
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from typing import Dict, List, Optional, Union
|
|
2
|
+
|
|
3
|
+
import reacton.ipyvuetify as v
|
|
4
|
+
import solara
|
|
5
|
+
from solara.util import _combine_classes
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@solara.component
|
|
9
|
+
def Card(
|
|
10
|
+
title: Optional[str] = None,
|
|
11
|
+
subtitle: Optional[str] = None,
|
|
12
|
+
elevation: int = 2,
|
|
13
|
+
margin=2,
|
|
14
|
+
children: List[solara.Element] = [],
|
|
15
|
+
classes: List[str] = [],
|
|
16
|
+
style: Union[str, Dict[str, str], None] = None,
|
|
17
|
+
):
|
|
18
|
+
"""A card combines a title, subtitle, content and actions into a single unit.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Example
|
|
22
|
+
```solara
|
|
23
|
+
import solara
|
|
24
|
+
|
|
25
|
+
@solara.component
|
|
26
|
+
def Page():
|
|
27
|
+
with solara.Card(title="Card title", subtitle="Card subtitle"):
|
|
28
|
+
solara.Markdown(
|
|
29
|
+
"Lorem ipsum dolor sit amet consectetur adipisicing elit. "\\
|
|
30
|
+
"Commodi, ratione debitis quis est labore voluptatibus! "\\
|
|
31
|
+
"Eaque cupiditate minima, at placeat totam, magni doloremque "\\
|
|
32
|
+
"veniam neque porro libero rerum unde voluptatem!"
|
|
33
|
+
)
|
|
34
|
+
with solara.CardActions():
|
|
35
|
+
solara.Button("Action 1", text=True)
|
|
36
|
+
solara.Button("Action 2", text=True)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Arguments
|
|
41
|
+
|
|
42
|
+
* `title`: Title of the card.
|
|
43
|
+
* `subtitle`: Subtitle of the card.
|
|
44
|
+
* `elevation`: Elevation of the card, gives the appearance of hovering above the page.
|
|
45
|
+
* `margin`: Margin of the card.
|
|
46
|
+
* `children`: Children are placed as the main content of the card.
|
|
47
|
+
* `style`: CSS style to apply to the top level element.
|
|
48
|
+
"""
|
|
49
|
+
class_ = _combine_classes([f"ma-{margin}", *classes])
|
|
50
|
+
style_flat = solara.util._flatten_style(style)
|
|
51
|
+
children_actions = []
|
|
52
|
+
children_text = []
|
|
53
|
+
for child in children:
|
|
54
|
+
if isinstance(child, solara.Element) and child.component == solara.CardActions:
|
|
55
|
+
children_actions.extend(child.kwargs.get("children", []))
|
|
56
|
+
else:
|
|
57
|
+
children_text.append(child)
|
|
58
|
+
with v.Card(elevation=elevation, class_=class_, style_=style_flat) as main:
|
|
59
|
+
if title:
|
|
60
|
+
with v.CardTitle(
|
|
61
|
+
children=[title],
|
|
62
|
+
):
|
|
63
|
+
pass
|
|
64
|
+
if subtitle:
|
|
65
|
+
with v.CardSubtitle(
|
|
66
|
+
children=[subtitle],
|
|
67
|
+
):
|
|
68
|
+
pass
|
|
69
|
+
with v.CardText(children=children_text):
|
|
70
|
+
pass
|
|
71
|
+
if children_actions:
|
|
72
|
+
with v.CardActions(children=children_actions):
|
|
73
|
+
pass
|
|
74
|
+
return main
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@solara.component
|
|
78
|
+
def CardActions(children: List[solara.Element] = []):
|
|
79
|
+
"""Container for actions in a card.
|
|
80
|
+
|
|
81
|
+
See [Card](/documentation/components/layout/card) for an example.
|
|
82
|
+
|
|
83
|
+
# Arguments
|
|
84
|
+
|
|
85
|
+
* `children`: Children are placed as the action area of the card.
|
|
86
|
+
"""
|
|
87
|
+
solara.Error("You should not see this if you add a CardActions as a child component of a Card")
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import Callable, Union
|
|
2
|
+
|
|
3
|
+
import reacton
|
|
4
|
+
import reacton.ipyvuetify as v
|
|
5
|
+
|
|
6
|
+
import solara
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@reacton.value_component(bool)
|
|
10
|
+
def Checkbox(
|
|
11
|
+
*,
|
|
12
|
+
label=None,
|
|
13
|
+
value: Union[bool, solara.Reactive[bool]] = True,
|
|
14
|
+
on_value: Callable[[bool], None] = None,
|
|
15
|
+
disabled=False,
|
|
16
|
+
style: str = None,
|
|
17
|
+
):
|
|
18
|
+
"""A checkbox is a widget that allows the user to toggle a boolean state.
|
|
19
|
+
|
|
20
|
+
Basic examples
|
|
21
|
+
|
|
22
|
+
```solara
|
|
23
|
+
import solara
|
|
24
|
+
|
|
25
|
+
turbo_boost = solara.reactive(True)
|
|
26
|
+
|
|
27
|
+
@solara.component
|
|
28
|
+
def Page():
|
|
29
|
+
checkbox = solara.Checkbox(label="Turbo boost", value=turbo_boost)
|
|
30
|
+
if turbo_boost.value:
|
|
31
|
+
solara.Success("Turbo boost is on")
|
|
32
|
+
else:
|
|
33
|
+
solara.Warning("Turbo boost is off, you might want to turn it on")
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## Arguments
|
|
38
|
+
|
|
39
|
+
* `label`: The label to display next to the checkbox.
|
|
40
|
+
* `value`: The current value of the checkbox (True or False).
|
|
41
|
+
* `on_value`: A callback that is called when the checkbox is toggled.
|
|
42
|
+
* `disabled`: If True, the checkbox is disabled and cannot be used.
|
|
43
|
+
* `style`: A string of CSS styles to apply to the checkbox.
|
|
44
|
+
"""
|
|
45
|
+
reactive_value = solara.use_reactive(value, on_value)
|
|
46
|
+
del value, on_value
|
|
47
|
+
children = []
|
|
48
|
+
if label is not None:
|
|
49
|
+
children = [label]
|
|
50
|
+
return v.Checkbox(label=label, v_model=reactive_value.value, on_v_model=reactive_value.set, disabled=disabled, style_=style, children=children)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
</template>
|
|
3
|
+
|
|
4
|
+
<style id="solara-code-highlight">
|
|
5
|
+
|
|
6
|
+
.solara-code-highlight__box {
|
|
7
|
+
border: var(--jp-border-width, 1px) solid var(--jp-cell-editor-border-color, #e0e0e0);
|
|
8
|
+
border-radius: 0;
|
|
9
|
+
background: var(--jp-cell-editor-background, #f5f5f5);
|
|
10
|
+
padding: 5px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
div.output_area .solara-code-highlight pre {
|
|
14
|
+
padding: 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.solara-code-highlight .highlight .hll { background-color: var(--jp-cell-editor-active-background) }
|
|
18
|
+
.solara-code-highlight .highlight {
|
|
19
|
+
color: var(--jp-mirror-editor-variable-color);
|
|
20
|
+
background: var(--jp-cell-editor-background);
|
|
21
|
+
-webkit-font-smoothing: initial;
|
|
22
|
+
}
|
|
23
|
+
.solara-code-highlight .highlight .c { color: var(--jp-mirror-editor-comment-color, #408080FF); font-style: italic } /* Comment */
|
|
24
|
+
.solara-code-highlight .highlight .err { color: var(--jp-mirror-editor-error-color, #FF0000FF) } /* Error */
|
|
25
|
+
.solara-code-highlight .highlight .k { color: var(--jp-mirror-editor-keyword-color, #008000FF); font-weight: bold } /* Keyword */
|
|
26
|
+
.solara-code-highlight .highlight .o { color: var(--jp-mirror-editor-operator-color, #AA22FFFF); font-weight: bold } /* Operator */
|
|
27
|
+
.solara-code-highlight .highlight .p { color: var(--jp-mirror-editor-punctuation-color, #0055AAFF) } /* Punctuation */
|
|
28
|
+
.solara-code-highlight .highlight .ch { color: var(--jp-mirror-editor-comment-color, #408080FF); font-style: italic } /* Comment.Hashbang */
|
|
29
|
+
.solara-code-highlight .highlight .cm { color: var(--jp-mirror-editor-comment-color, #408080FF); font-style: italic } /* Comment.Multiline */
|
|
30
|
+
.solara-code-highlight .highlight .cp { color: var(--jp-mirror-editor-comment-color, #408080FF); font-style: italic } /* Comment.Preproc */
|
|
31
|
+
.solara-code-highlight .highlight .cpf { color: var(--jp-mirror-editor-comment-color, #408080FF); font-style: italic } /* Comment.PreprocFile */
|
|
32
|
+
.solara-code-highlight .highlight .c1 { color: var(--jp-mirror-editor-comment-color, #408080FF); font-style: italic } /* Comment.Single */
|
|
33
|
+
.solara-code-highlight .highlight .cs { color: var(--jp-mirror-editor-comment-color, #408080FF); font-style: italic } /* Comment.Special */
|
|
34
|
+
.solara-code-highlight .highlight .kc { color: var(--jp-mirror-editor-keyword-color, #008000FF); font-weight: bold } /* Keyword.Constant */
|
|
35
|
+
.solara-code-highlight .highlight .kd { color: var(--jp-mirror-editor-keyword-color, #008000FF); font-weight: bold } /* Keyword.Declaration */
|
|
36
|
+
.solara-code-highlight .highlight .kn { color: var(--jp-mirror-editor-keyword-color, #008000FF); font-weight: bold } /* Keyword.Namespace */
|
|
37
|
+
.solara-code-highlight .highlight .kp { color: var(--jp-mirror-editor-keyword-color, #008000FF); font-weight: bold } /* Keyword.Pseudo */
|
|
38
|
+
.solara-code-highlight .highlight .kr { color: var(--jp-mirror-editor-keyword-color, #008000FF); font-weight: bold } /* Keyword.Reserved */
|
|
39
|
+
.solara-code-highlight .highlight .kt { color: var(--jp-mirror-editor-keyword-color, #008000FF); font-weight: bold } /* Keyword.Type */
|
|
40
|
+
.solara-code-highlight .highlight .m { color: var(--jp-mirror-editor-number-color, #008000FF) } /* Literal.Number */
|
|
41
|
+
.solara-code-highlight .highlight .s { color: var(--jp-mirror-editor-string-color, #008000FF) } /* Literal.String */
|
|
42
|
+
.solara-code-highlight .highlight .ow { color: var(--jp-mirror-editor-operator-color, #AA22FFFF); font-weight: bold } /* Operator.Word */
|
|
43
|
+
.solara-code-highlight .highlight .w { color: var(--jp-mirror-editor-variable-color) } /* Text.Whitespace */
|
|
44
|
+
.solara-code-highlight .highlight .mb { color: var(--jp-mirror-editor-number-color, #008000FF) } /* Literal.Number.Bin */
|
|
45
|
+
.solara-code-highlight .highlight .mf { color: var(--jp-mirror-editor-number-color, #008000FF) } /* Literal.Number.Float */
|
|
46
|
+
.solara-code-highlight .highlight .mh { color: var(--jp-mirror-editor-number-color, #008000FF) } /* Literal.Number.Hex */
|
|
47
|
+
.solara-code-highlight .highlight .mi { color: var(--jp-mirror-editor-number-color, #008000FF) } /* Literal.Number.Integer */
|
|
48
|
+
.solara-code-highlight .highlight .mo { color: var(--jp-mirror-editor-number-color, #008000FF) } /* Literal.Number.Oct */
|
|
49
|
+
.solara-code-highlight .highlight .sa { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Affix */
|
|
50
|
+
.solara-code-highlight .highlight .sb { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Backtick */
|
|
51
|
+
.solara-code-highlight .highlight .sc { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Char */
|
|
52
|
+
.solara-code-highlight .highlight .dl { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Delimiter */
|
|
53
|
+
.solara-code-highlight .highlight .sd { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Doc */
|
|
54
|
+
.solara-code-highlight .highlight .s2 { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Double */
|
|
55
|
+
.solara-code-highlight .highlight .se { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Escape */
|
|
56
|
+
.solara-code-highlight .highlight .sh { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Heredoc */
|
|
57
|
+
.solara-code-highlight .highlight .si { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Interpol */
|
|
58
|
+
.solara-code-highlight .highlight .sx { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Other */
|
|
59
|
+
.solara-code-highlight .highlight .sr { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Regex */
|
|
60
|
+
.solara-code-highlight .highlight .s1 { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Single */
|
|
61
|
+
.solara-code-highlight .highlight .ss { color: var(--jp-mirror-editor-string-color, #BA2121FF) } /* Literal.String.Symbol */
|
|
62
|
+
.solara-code-highlight .highlight .il { color: var(--jp-mirror-editor-number-color, #008000FF) } /* Literal.Number.Integer.Long */
|
|
63
|
+
</style>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
from typing import Dict, List, Union
|
|
3
|
+
|
|
4
|
+
import reacton.ipyvuetify as rv
|
|
5
|
+
|
|
6
|
+
import solara
|
|
7
|
+
from solara.util import _combine_classes
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def cycle(value):
|
|
11
|
+
if value is None:
|
|
12
|
+
return itertools.cycle([None])
|
|
13
|
+
elif isinstance(value, int):
|
|
14
|
+
return itertools.cycle([value])
|
|
15
|
+
elif isinstance(value, (list, tuple)):
|
|
16
|
+
return itertools.cycle(value)
|
|
17
|
+
else:
|
|
18
|
+
raise ValueError(f"Invalid value for columns: {value}, should be None, int, or list/tuple.")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@solara.component
|
|
22
|
+
def Columns(
|
|
23
|
+
widths: List[Union[float, int]] = [1],
|
|
24
|
+
wrap=True,
|
|
25
|
+
gutters=True,
|
|
26
|
+
gutters_dense=False,
|
|
27
|
+
children=[],
|
|
28
|
+
classes: List[str] = [],
|
|
29
|
+
style: Union[str, Dict[str, str], None] = None,
|
|
30
|
+
):
|
|
31
|
+
"""Lays out children in columns, with relative widths specified as a list of floats or ints.
|
|
32
|
+
|
|
33
|
+
Widths are relative to each other, so [1, 2, 1] will result in 1/4, 1/2, 1/4 width columns.
|
|
34
|
+
Columns with a width of 0 will take up the minimal amount of space.
|
|
35
|
+
|
|
36
|
+
If there are more children than widths, the width list will be cycled.
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
with solara.Columns([1, 2, 1]):
|
|
40
|
+
solara.Text("I am on the left")
|
|
41
|
+
with solara.Card("Middle"):
|
|
42
|
+
...
|
|
43
|
+
with solara.Column():
|
|
44
|
+
...
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
When three children are added to this component, they will be laid out in three columns,
|
|
48
|
+
with the first and last column taking up 1/4 of the width, and the middle column taking up 1/2 of the width.
|
|
49
|
+
|
|
50
|
+
```solara
|
|
51
|
+
import solara
|
|
52
|
+
|
|
53
|
+
@solara.component
|
|
54
|
+
def Page():
|
|
55
|
+
with solara.Columns([0, 1, 2]):
|
|
56
|
+
solara.Text("I am as small as possible")
|
|
57
|
+
solara.Select("I stretch", values=["a", "b", "c"], value="a")
|
|
58
|
+
solara.Select("I stretch twice the amount", values=["a", "b", "c"], value="a")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# Arguments
|
|
63
|
+
|
|
64
|
+
* `widths`: List of floats or ints, specifying the relative widths of the columns.
|
|
65
|
+
* `wrap`: Whether to wrap the columns to the next row if there is not enough space available. This only happens when using widths of 0.
|
|
66
|
+
* `gutters`: Whether to add gutters between the columns.
|
|
67
|
+
* `gutters_dense`: Make gutters smaller.
|
|
68
|
+
* `children`: List of children to be laid out in columns.
|
|
69
|
+
* `style`: CSS style to apply to the top level element.
|
|
70
|
+
* `classes`: List of CSS classes to be applied to the top level element.
|
|
71
|
+
|
|
72
|
+
"""
|
|
73
|
+
class_ = _combine_classes([*(["flex-nowrap"] if not wrap else []), *classes])
|
|
74
|
+
style_flat = solara.util._flatten_style(style)
|
|
75
|
+
with rv.Row(class_=class_, no_gutters=not gutters, dense=gutters_dense, style_=style_flat) as main:
|
|
76
|
+
for child, width in zip(children, cycle(widths)):
|
|
77
|
+
# we add height: 100% because this will trigger a chain of height set if it is set on the parent
|
|
78
|
+
# via the style. If we do not set the height, it will have no effect. Furthermore, we only have
|
|
79
|
+
# a single child, so this cannot interfere with other siblings.
|
|
80
|
+
with rv.Col(children=[child], style_=f"height: 100%; flex-grow: {width}; overflow: auto" if width != 0 else "flex-grow: 0"):
|
|
81
|
+
pass
|
|
82
|
+
return main
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@solara.component
|
|
86
|
+
def ColumnsResponsive(
|
|
87
|
+
default=None,
|
|
88
|
+
small=None,
|
|
89
|
+
medium=None,
|
|
90
|
+
large=None,
|
|
91
|
+
xlarge=None,
|
|
92
|
+
children=[],
|
|
93
|
+
wrap=True,
|
|
94
|
+
gutters=True,
|
|
95
|
+
gutters_dense=False,
|
|
96
|
+
classes: List[str] = [],
|
|
97
|
+
style: Union[str, Dict[str, str], None] = None,
|
|
98
|
+
):
|
|
99
|
+
"""Lay our children in columns, on a 12 point grid system that is responsive to screen size.
|
|
100
|
+
|
|
101
|
+
If a single number is specified, or less values than children, the values will be cycled.
|
|
102
|
+
The total width of this system is 12, so if you want to have 3 columns, each taking up 4 points, you would specify [4, 4, 4] or 4.
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
with ColumnsResponsive([4, 4, 4]):
|
|
107
|
+
...
|
|
108
|
+
with ColumnsResponsive(4): # same effect
|
|
109
|
+
...
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If you want the first column to take up 4 points, and the second column to take up the remaining 8 points, you would specify [4, 8].
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
with ColumnsResponsive([4, 8]):
|
|
116
|
+
...
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If you want your columns to be full width on large screen, and next to each other on larger screens.
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
with ColumnsResponsive(12, large=[4, 8]):
|
|
123
|
+
...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
# Arguments
|
|
127
|
+
|
|
128
|
+
* default: Width of column for >= 0 px.
|
|
129
|
+
* small: Width of column for >= 600 px.
|
|
130
|
+
* medium: Width of column >= 960 px.
|
|
131
|
+
* large: Width of column for >= 1264 px.
|
|
132
|
+
* xlarge: Width of column for >= 1904 px.
|
|
133
|
+
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
def cycle(value):
|
|
137
|
+
if value is None:
|
|
138
|
+
return itertools.cycle([None])
|
|
139
|
+
elif isinstance(value, int):
|
|
140
|
+
return itertools.cycle([value])
|
|
141
|
+
elif isinstance(value, (list, tuple)):
|
|
142
|
+
return itertools.cycle(value)
|
|
143
|
+
else:
|
|
144
|
+
raise ValueError(f"Invalid value for columns: {value}, should be None, int, or list/tuple.")
|
|
145
|
+
|
|
146
|
+
class_ = _combine_classes([*(["flex-nowrap"] if not wrap else []), *classes])
|
|
147
|
+
style_flat = solara.util._flatten_style(style)
|
|
148
|
+
with rv.Row(class_=class_ if not wrap else "", style_=style_flat, no_gutters=not gutters, dense=gutters_dense) as main:
|
|
149
|
+
for child, xsmall, small, medium, large, xlarge in zip(children, cycle(default), cycle(small), cycle(medium), cycle(large), cycle(xlarge)):
|
|
150
|
+
with rv.Col(
|
|
151
|
+
cols=xsmall,
|
|
152
|
+
sm=small,
|
|
153
|
+
md=medium,
|
|
154
|
+
lg=large,
|
|
155
|
+
xl=xlarge,
|
|
156
|
+
children=[child],
|
|
157
|
+
):
|
|
158
|
+
pass
|
|
159
|
+
return main
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
import os
|
|
3
|
+
from typing import Any, Callable, Dict, Type
|
|
4
|
+
|
|
5
|
+
import ipyvue as vue
|
|
6
|
+
import ipyvuetify as v
|
|
7
|
+
import ipywidgets as widgets
|
|
8
|
+
import traitlets
|
|
9
|
+
import typing_extensions
|
|
10
|
+
|
|
11
|
+
import solara
|
|
12
|
+
|
|
13
|
+
P = typing_extensions.ParamSpec("P")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _widget_from_signature(classname, base_class: Type[widgets.Widget], func: Callable[..., None], event_prefix: str) -> Type[widgets.Widget]:
|
|
17
|
+
classprops: Dict[str, Any] = {}
|
|
18
|
+
|
|
19
|
+
parameters = inspect.signature(func).parameters
|
|
20
|
+
for name, param in parameters.items():
|
|
21
|
+
if name.startswith("event_"):
|
|
22
|
+
event_name = name[6:]
|
|
23
|
+
|
|
24
|
+
def event_handler(self, data, buffers=None, event_name=event_name, param=param):
|
|
25
|
+
callback = self._event_callbacks.get(event_name, param.default)
|
|
26
|
+
if callback:
|
|
27
|
+
if buffers:
|
|
28
|
+
callback(data, buffers)
|
|
29
|
+
else:
|
|
30
|
+
callback(data)
|
|
31
|
+
|
|
32
|
+
classprops[f"vue_{event_name}"] = event_handler
|
|
33
|
+
elif name.startswith("on_") and name[3:] in parameters:
|
|
34
|
+
# callback, will be handled by reacton
|
|
35
|
+
continue
|
|
36
|
+
else:
|
|
37
|
+
if param.default == inspect.Parameter.empty:
|
|
38
|
+
trait = traitlets.Any()
|
|
39
|
+
else:
|
|
40
|
+
trait = traitlets.Any(default_value=param.default)
|
|
41
|
+
classprops[name] = trait.tag(sync=True, **widgets.widget_serialization)
|
|
42
|
+
# maps event_foo to a callable
|
|
43
|
+
classprops["_event_callbacks"] = traitlets.Dict(default_value={})
|
|
44
|
+
|
|
45
|
+
widget_class = type(classname, (base_class,), classprops)
|
|
46
|
+
return widget_class
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _widget_vue(vue_path: str, vuetify=True) -> Callable[[Callable[P, None]], Type[v.VuetifyTemplate]]:
|
|
50
|
+
def decorator(func: Callable[P, None]):
|
|
51
|
+
class VuetifyWidgetSolara(v.VuetifyTemplate):
|
|
52
|
+
template_file = (os.path.abspath(inspect.getfile(func)), vue_path)
|
|
53
|
+
|
|
54
|
+
class VueWidgetSolara(vue.VueTemplate):
|
|
55
|
+
template_file = (os.path.abspath(inspect.getfile(func)), vue_path)
|
|
56
|
+
|
|
57
|
+
base_class = VuetifyWidgetSolara if vuetify else VueWidgetSolara
|
|
58
|
+
widget_class = _widget_from_signature("VueWidgetSolaraSub", base_class, func, "vue_")
|
|
59
|
+
|
|
60
|
+
return widget_class
|
|
61
|
+
|
|
62
|
+
return decorator
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def component_vue(vue_path: str, vuetify=True) -> Callable[[Callable[P, None]], Callable[P, solara.Element]]:
|
|
66
|
+
"""Decorator to create a component backed by a Vue template.
|
|
67
|
+
|
|
68
|
+
Although many components can be made from the Python side, sometimes it is easier to write components using Vue directly.
|
|
69
|
+
It can also be beneficial for performance, since instead of creating many widgets from the Python side we only send data to
|
|
70
|
+
the frontend. If event handling is also done on the frontend, this reduces latency and makes you app feel much smoother.
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
All arguments of the function are exposed as Vue properties. Argument pairs of the form `foo`, and `on_foo`
|
|
74
|
+
are assumed by refer to the same vue property, with `on_foo` being the event handler when `foo` changes from
|
|
75
|
+
the vue template.
|
|
76
|
+
|
|
77
|
+
Arguments or the form `event_foo` should be callbacks that can be called from the vue template. They are
|
|
78
|
+
available as the function `foo` in the vue template.
|
|
79
|
+
|
|
80
|
+
[See the vue v2 api](https://v2.vuejs.org/v2/api/) for more information on how to use Vue, like `watch`,
|
|
81
|
+
`methods` and lifecycle hooks such as `mounted` and `destroyed`.
|
|
82
|
+
|
|
83
|
+
See the [Vue component example](/documentation/examples/general/vue_component) for an example of how to use this decorator.
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
## Examples
|
|
87
|
+
|
|
88
|
+
A component that takes a `foo` argument and an `on_foo` callback that gets called when `foo` changes (from the frontend).
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
import solara
|
|
92
|
+
|
|
93
|
+
@solara.component_vue("my_foo_component.vue")
|
|
94
|
+
def MyFooComponent(foo: int, on_foo: Callable[[int], None]):
|
|
95
|
+
pass
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The following component only takes in a month argument and an event_date_clicked callback that gets called from
|
|
99
|
+
the vue template using `this.date_clicked({'extra-data': 42, 'day': this.day})`.
|
|
100
|
+
```python
|
|
101
|
+
import solara
|
|
102
|
+
|
|
103
|
+
@solara.component_vue("my_date_component.vue")
|
|
104
|
+
def MyDateComponent(month: int, event_date_clicked: Callable):
|
|
105
|
+
pass
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Arguments
|
|
109
|
+
|
|
110
|
+
* `vue_path`: The path to the Vue template file.
|
|
111
|
+
* `vuetify`: Whether the Vue template uses Vuetify components.
|
|
112
|
+
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
def decorator(func: Callable[P, None]):
|
|
116
|
+
VueWidgetSolaraSub = _widget_vue(vue_path, vuetify=vuetify)(func)
|
|
117
|
+
|
|
118
|
+
def wrapper(*args, **kwargs):
|
|
119
|
+
event_callbacks = {}
|
|
120
|
+
kwargs = kwargs.copy()
|
|
121
|
+
# take out all events named like event_foo and put them in a separate dict
|
|
122
|
+
for name in list(kwargs):
|
|
123
|
+
if name.startswith("event_"):
|
|
124
|
+
event_callbacks[name[6:]] = kwargs.pop(name)
|
|
125
|
+
if event_callbacks:
|
|
126
|
+
kwargs["_event_callbacks"] = event_callbacks
|
|
127
|
+
return VueWidgetSolaraSub.element(*args, **kwargs) # type: ignore
|
|
128
|
+
|
|
129
|
+
return wrapper
|
|
130
|
+
|
|
131
|
+
return decorator
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
_component_vue = component_vue
|