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,456 @@
|
|
|
1
|
+
from typing import Any, Callable, Optional, TypeVar, Union, cast, overload, List, Dict
|
|
2
|
+
|
|
3
|
+
import ipyvue
|
|
4
|
+
import ipyvuetify as vw
|
|
5
|
+
import reacton
|
|
6
|
+
from typing_extensions import Literal
|
|
7
|
+
|
|
8
|
+
import solara
|
|
9
|
+
from solara.alias import rv as v
|
|
10
|
+
|
|
11
|
+
T = TypeVar("T")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def use_change(el: reacton.core.Element, on_value: Callable[[Any], Any], enabled=True, update_events=["focusout", "keyup.enter"]):
|
|
15
|
+
"""Trigger a callback when a blur events occurs or the enter key is pressed."""
|
|
16
|
+
on_value_ref = solara.use_ref(on_value)
|
|
17
|
+
on_value_ref.current = on_value
|
|
18
|
+
|
|
19
|
+
def add_events():
|
|
20
|
+
def on_change(widget, event, data):
|
|
21
|
+
if enabled:
|
|
22
|
+
on_value_ref.current(widget.v_model)
|
|
23
|
+
|
|
24
|
+
widget = cast(ipyvue.VueWidget, solara.get_widget(el))
|
|
25
|
+
if enabled:
|
|
26
|
+
for event in update_events:
|
|
27
|
+
widget.on_event(event, on_change)
|
|
28
|
+
|
|
29
|
+
def cleanup():
|
|
30
|
+
if enabled:
|
|
31
|
+
for event in update_events:
|
|
32
|
+
widget.on_event(event, on_change, remove=True)
|
|
33
|
+
|
|
34
|
+
return cleanup
|
|
35
|
+
|
|
36
|
+
solara.use_effect(add_events, [enabled])
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@solara.component
|
|
40
|
+
def InputText(
|
|
41
|
+
label: str,
|
|
42
|
+
value: Union[str, solara.Reactive[str]] = "",
|
|
43
|
+
on_value: Callable[[str], None] = None,
|
|
44
|
+
disabled: bool = False,
|
|
45
|
+
password: bool = False,
|
|
46
|
+
continuous_update: bool = False,
|
|
47
|
+
update_events: List[str] = ["focusout", "keyup.enter"],
|
|
48
|
+
error: Union[bool, str] = False,
|
|
49
|
+
message: Optional[str] = None,
|
|
50
|
+
classes: List[str] = [],
|
|
51
|
+
style: Optional[Union[str, Dict[str, str]]] = None,
|
|
52
|
+
autofocus: bool = False,
|
|
53
|
+
):
|
|
54
|
+
"""Free form text input.
|
|
55
|
+
|
|
56
|
+
### Basic example:
|
|
57
|
+
|
|
58
|
+
```solara
|
|
59
|
+
import solara
|
|
60
|
+
|
|
61
|
+
text = solara.reactive("Hello world!")
|
|
62
|
+
continuous_update = solara.reactive(True)
|
|
63
|
+
|
|
64
|
+
@solara.component
|
|
65
|
+
def Page():
|
|
66
|
+
solara.Checkbox(label="Continuous update", value=continuous_update)
|
|
67
|
+
solara.InputText("Enter some text", value=text, continuous_update=continuous_update.value)
|
|
68
|
+
with solara.Row():
|
|
69
|
+
solara.Button("Clear", on_click=lambda: text.set(""))
|
|
70
|
+
solara.Button("Reset", on_click=lambda: text.set("Hello world"))
|
|
71
|
+
solara.Markdown(f"**You entered**: {text.value}")
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Password input:
|
|
75
|
+
|
|
76
|
+
This will not show the entered text.
|
|
77
|
+
|
|
78
|
+
```solara
|
|
79
|
+
import solara
|
|
80
|
+
|
|
81
|
+
password = solara.reactive("Super secret")
|
|
82
|
+
continuous_update = solara.reactive(True)
|
|
83
|
+
|
|
84
|
+
@solara.component
|
|
85
|
+
def Page():
|
|
86
|
+
solara.Checkbox(label="Continuous update", value=continuous_update)
|
|
87
|
+
solara.InputText("Enter a password", value=password, continuous_update=continuous_update.value, password=True)
|
|
88
|
+
with solara.Row():
|
|
89
|
+
solara.Button("Clear", on_click=lambda: password.set(""))
|
|
90
|
+
solara.Button("Reset", on_click=lambda: password.set("Super secret"))
|
|
91
|
+
solara.Markdown(f"**You entered**: {password.value}")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## Arguments
|
|
96
|
+
|
|
97
|
+
* `label`: Label to display next to the slider.
|
|
98
|
+
* `value`: The currently entered value.
|
|
99
|
+
* `on_value`: Callback to call when the value changes.
|
|
100
|
+
* `disabled`: Whether the input is disabled.
|
|
101
|
+
* `password`: Whether the input is a password input (typically shows input text obscured with an asterisk).
|
|
102
|
+
* `continuous_update`: Whether to call the `on_value` callback on every change or only when the input loses focus or the enter key is pressed.
|
|
103
|
+
* `update_events`: A list of events that should trigger `on_value`. If continuous update is enabled, this will effectively be ignored,
|
|
104
|
+
since updates will happen every change.
|
|
105
|
+
* `error`: If truthy, show the input as having an error (in red). If a string is passed, it will be shown as the error message.
|
|
106
|
+
* `message`: Message to show below the input. If `error` is a string, this will be ignored.
|
|
107
|
+
* `classes`: List of CSS classes to apply to the input.
|
|
108
|
+
* `style`: CSS style to apply to the input.
|
|
109
|
+
* `autofocus`: Determines if a component is to be autofocused or not (Default is False). Autofocus will occur during page load and only one component per page can have autofocus active.
|
|
110
|
+
"""
|
|
111
|
+
reactive_value = solara.use_reactive(value, on_value)
|
|
112
|
+
del value, on_value
|
|
113
|
+
style_flat = solara.util._flatten_style(style)
|
|
114
|
+
classes_flat = solara.util._combine_classes(classes)
|
|
115
|
+
|
|
116
|
+
def set_value_cast(value):
|
|
117
|
+
reactive_value.value = str(value)
|
|
118
|
+
|
|
119
|
+
def on_v_model(value):
|
|
120
|
+
if continuous_update:
|
|
121
|
+
set_value_cast(value)
|
|
122
|
+
|
|
123
|
+
messages = []
|
|
124
|
+
if error and isinstance(error, str):
|
|
125
|
+
messages.append(error)
|
|
126
|
+
elif message:
|
|
127
|
+
messages.append(message)
|
|
128
|
+
text_field = v.TextField(
|
|
129
|
+
v_model=reactive_value.value,
|
|
130
|
+
on_v_model=on_v_model,
|
|
131
|
+
label=label,
|
|
132
|
+
disabled=disabled,
|
|
133
|
+
type="password" if password else None,
|
|
134
|
+
error=bool(error),
|
|
135
|
+
messages=messages,
|
|
136
|
+
class_=classes_flat,
|
|
137
|
+
style_=style_flat,
|
|
138
|
+
autofocus=autofocus,
|
|
139
|
+
)
|
|
140
|
+
use_change(text_field, set_value_cast, enabled=not continuous_update, update_events=update_events)
|
|
141
|
+
return text_field
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@overload
|
|
145
|
+
@solara.component
|
|
146
|
+
def InputFloat(
|
|
147
|
+
label: str,
|
|
148
|
+
value: Union[float, solara.Reactive[float]] = 0,
|
|
149
|
+
on_value: Optional[Callable[[float], None]] = ...,
|
|
150
|
+
disabled: bool = ...,
|
|
151
|
+
optional: Literal[False] = ...,
|
|
152
|
+
continuous_update: bool = ...,
|
|
153
|
+
clearable: bool = ...,
|
|
154
|
+
classes: List[str] = ...,
|
|
155
|
+
style: Optional[Union[str, Dict[str, str]]] = ...,
|
|
156
|
+
autofocus: bool = False,
|
|
157
|
+
) -> reacton.core.ValueElement[vw.TextField, Any]: ...
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@overload
|
|
161
|
+
@solara.component
|
|
162
|
+
def InputFloat(
|
|
163
|
+
label: str,
|
|
164
|
+
value: Union[Optional[float], solara.Reactive[Optional[float]]] = 0,
|
|
165
|
+
on_value: Optional[Callable[[Optional[float]], None]] = ...,
|
|
166
|
+
disabled: bool = ...,
|
|
167
|
+
optional: Literal[True] = ...,
|
|
168
|
+
continuous_update: bool = ...,
|
|
169
|
+
clearable: bool = ...,
|
|
170
|
+
classes: List[str] = ...,
|
|
171
|
+
style: Optional[Union[str, Dict[str, str]]] = ...,
|
|
172
|
+
autofocus: bool = False,
|
|
173
|
+
) -> reacton.core.ValueElement[vw.TextField, Any]: ...
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@solara.component
|
|
177
|
+
def InputFloat(
|
|
178
|
+
label: str,
|
|
179
|
+
value: Union[None, float, solara.Reactive[float], solara.Reactive[Optional[float]]] = 0,
|
|
180
|
+
on_value: Union[None, Callable[[Optional[float]], None], Callable[[float], None]] = None,
|
|
181
|
+
disabled: bool = False,
|
|
182
|
+
optional: bool = False,
|
|
183
|
+
continuous_update: bool = False,
|
|
184
|
+
clearable: bool = False,
|
|
185
|
+
classes: List[str] = [],
|
|
186
|
+
style: Optional[Union[str, Dict[str, str]]] = None,
|
|
187
|
+
autofocus: bool = False,
|
|
188
|
+
):
|
|
189
|
+
"""Numeric input (floats).
|
|
190
|
+
|
|
191
|
+
Basic example:
|
|
192
|
+
|
|
193
|
+
```solara
|
|
194
|
+
import solara
|
|
195
|
+
|
|
196
|
+
float_value = solara.reactive(42.0)
|
|
197
|
+
continuous_update = solara.reactive(True)
|
|
198
|
+
|
|
199
|
+
@solara.component
|
|
200
|
+
def Page():
|
|
201
|
+
solara.Checkbox(label="Continuous update", value=continuous_update)
|
|
202
|
+
solara.InputFloat("Enter a float number", value=float_value, continuous_update=continuous_update.value)
|
|
203
|
+
with solara.Row():
|
|
204
|
+
solara.Button("Clear", on_click=lambda: float_value.set(42.0))
|
|
205
|
+
solara.Markdown(f"**You entered**: {float_value.value}")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
## Arguments
|
|
210
|
+
|
|
211
|
+
* `label`: Label to display next to the slider.
|
|
212
|
+
* `value`: The currently entered value.
|
|
213
|
+
* `on_value`: Callback to call when the value changes.
|
|
214
|
+
* `disabled`: Whether the input is disabled.
|
|
215
|
+
* `optional`: Whether the value can be None.
|
|
216
|
+
* `continuous_update`: Whether to call the `on_value` callback on every change or only when the input loses focus or the enter key is pressed.
|
|
217
|
+
* `clearable`: Whether the input can be cleared.
|
|
218
|
+
* `classes`: List of CSS classes to apply to the input.
|
|
219
|
+
* `style`: CSS style to apply to the input.
|
|
220
|
+
* `autofocus`: Determines if a component is to be autofocused or not (Default is False). Autofocus will occur either during page load, or when the component becomes visible (for example, dialog being opened). Only one component per page should have autofocus on each such event.
|
|
221
|
+
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
def str_to_float(value: Optional[str]):
|
|
225
|
+
if value:
|
|
226
|
+
try:
|
|
227
|
+
value = value.replace(",", ".")
|
|
228
|
+
return float(value)
|
|
229
|
+
except ValueError:
|
|
230
|
+
raise ValueError("Value must be a number")
|
|
231
|
+
else:
|
|
232
|
+
if optional:
|
|
233
|
+
return None
|
|
234
|
+
else:
|
|
235
|
+
raise ValueError("Value cannot be empty")
|
|
236
|
+
|
|
237
|
+
return _InputNumeric(
|
|
238
|
+
str_to_float,
|
|
239
|
+
label=label,
|
|
240
|
+
value=value,
|
|
241
|
+
on_value=on_value,
|
|
242
|
+
disabled=disabled,
|
|
243
|
+
continuous_update=continuous_update,
|
|
244
|
+
clearable=clearable,
|
|
245
|
+
classes=classes,
|
|
246
|
+
style=style,
|
|
247
|
+
autofocus=autofocus,
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@overload
|
|
252
|
+
@solara.component
|
|
253
|
+
def InputInt(
|
|
254
|
+
label: str,
|
|
255
|
+
value: Union[int, solara.Reactive[int]] = 0,
|
|
256
|
+
on_value: Optional[Callable[[int], None]] = ...,
|
|
257
|
+
disabled: bool = ...,
|
|
258
|
+
optional: Literal[False] = ...,
|
|
259
|
+
continuous_update: bool = ...,
|
|
260
|
+
clearable: bool = ...,
|
|
261
|
+
classes: List[str] = ...,
|
|
262
|
+
style: Optional[Union[str, Dict[str, str]]] = ...,
|
|
263
|
+
autofocus: bool = False,
|
|
264
|
+
) -> reacton.core.ValueElement[vw.TextField, Any]: ...
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
@overload
|
|
268
|
+
@solara.component
|
|
269
|
+
def InputInt(
|
|
270
|
+
label: str,
|
|
271
|
+
value: Union[Optional[int], solara.Reactive[Optional[int]]] = 0,
|
|
272
|
+
on_value: Optional[Callable[[Optional[int]], None]] = ...,
|
|
273
|
+
disabled: bool = ...,
|
|
274
|
+
optional: Literal[True] = ...,
|
|
275
|
+
continuous_update: bool = ...,
|
|
276
|
+
clearable: bool = ...,
|
|
277
|
+
classes: List[str] = ...,
|
|
278
|
+
style: Optional[Union[str, Dict[str, str]]] = ...,
|
|
279
|
+
autofocus: bool = False,
|
|
280
|
+
) -> reacton.core.ValueElement[vw.TextField, Any]: ...
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
@solara.component
|
|
284
|
+
def InputInt(
|
|
285
|
+
label: str,
|
|
286
|
+
value: Union[None, int, solara.Reactive[int], solara.Reactive[Optional[int]]] = 0,
|
|
287
|
+
on_value: Union[None, Callable[[Optional[int]], None], Callable[[int], None]] = None,
|
|
288
|
+
disabled: bool = False,
|
|
289
|
+
optional: bool = False,
|
|
290
|
+
continuous_update: bool = False,
|
|
291
|
+
clearable: bool = False,
|
|
292
|
+
classes: List[str] = [],
|
|
293
|
+
style: Optional[Union[str, Dict[str, str]]] = None,
|
|
294
|
+
autofocus: bool = False,
|
|
295
|
+
):
|
|
296
|
+
"""Numeric input (integers).
|
|
297
|
+
|
|
298
|
+
Basic example:
|
|
299
|
+
|
|
300
|
+
```solara
|
|
301
|
+
import solara
|
|
302
|
+
|
|
303
|
+
int_value = solara.reactive(42)
|
|
304
|
+
continuous_update = solara.reactive(True)
|
|
305
|
+
|
|
306
|
+
@solara.component
|
|
307
|
+
def Page():
|
|
308
|
+
solara.Checkbox(label="Continuous update", value=continuous_update)
|
|
309
|
+
solara.InputInt("Enter an integer number", value=int_value, continuous_update=continuous_update.value)
|
|
310
|
+
with solara.Row():
|
|
311
|
+
solara.Button("Clear", on_click=lambda: int_value.set(42))
|
|
312
|
+
solara.Markdown(f"**You entered**: {int_value.value}")
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Arguments
|
|
316
|
+
|
|
317
|
+
* `label`: Label to display next to the slider.
|
|
318
|
+
* `value`: The currently entered value.
|
|
319
|
+
* `on_value`: Callback to call when the value changes.
|
|
320
|
+
* `disabled`: Whether the input is disabled.
|
|
321
|
+
* `optional`: Whether the value can be None.
|
|
322
|
+
* `continuous_update`: Whether to call the `on_value` callback on every change or only when the input loses focus or the enter key is pressed.
|
|
323
|
+
* `clearable`: Whether the input can be cleared.
|
|
324
|
+
* `classes`: List of CSS classes to apply to the input.
|
|
325
|
+
* `style`: CSS style to apply to the input.
|
|
326
|
+
* `autofocus`: Determines if a component is to be autofocused or not (Default is False). Autofocus will occur either during page load, or when the component becomes visible (for example, dialog being opened). Only one component per page should have autofocus on each such event.
|
|
327
|
+
"""
|
|
328
|
+
|
|
329
|
+
def str_to_int(value: Optional[str]):
|
|
330
|
+
if value:
|
|
331
|
+
try:
|
|
332
|
+
return int(value)
|
|
333
|
+
except ValueError:
|
|
334
|
+
raise ValueError("Value must be an integer")
|
|
335
|
+
else:
|
|
336
|
+
if optional:
|
|
337
|
+
return None
|
|
338
|
+
else:
|
|
339
|
+
raise ValueError("Value cannot be empty")
|
|
340
|
+
|
|
341
|
+
return _InputNumeric(
|
|
342
|
+
str_to_int,
|
|
343
|
+
label=label,
|
|
344
|
+
value=value,
|
|
345
|
+
on_value=on_value,
|
|
346
|
+
disabled=disabled,
|
|
347
|
+
continuous_update=continuous_update,
|
|
348
|
+
clearable=clearable,
|
|
349
|
+
classes=classes,
|
|
350
|
+
style=style,
|
|
351
|
+
autofocus=autofocus,
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def _use_input_type(
|
|
356
|
+
input_value: Union[None, T, solara.Reactive[Optional[T]], solara.Reactive[T]],
|
|
357
|
+
parse: Callable[[Optional[str]], T],
|
|
358
|
+
stringify: Callable[[Optional[T]], str],
|
|
359
|
+
on_value: Union[None, Callable[[Optional[T]], None], Callable[[T], None]] = None,
|
|
360
|
+
):
|
|
361
|
+
reactive_value = solara.use_reactive(input_value, on_value) # type: ignore
|
|
362
|
+
del input_value, on_value
|
|
363
|
+
string_value, set_string_value = solara.use_state(stringify(reactive_value.value) if reactive_value.value is not None else None)
|
|
364
|
+
# Use a ref to make sure sync_back_input_value() does not get a stale string_value
|
|
365
|
+
string_value_ref = solara.use_ref(string_value)
|
|
366
|
+
string_value_ref.current = string_value
|
|
367
|
+
|
|
368
|
+
error_message = cast(Union[str, None], None)
|
|
369
|
+
|
|
370
|
+
try:
|
|
371
|
+
reactive_value.set(parse(string_value))
|
|
372
|
+
except ValueError as e:
|
|
373
|
+
error_message = str(e.args[0])
|
|
374
|
+
|
|
375
|
+
def sync_back_input_value():
|
|
376
|
+
# Make sure we update string_value when the effect is rerun,
|
|
377
|
+
# Since the parsing & stringigying functions might have changed
|
|
378
|
+
set_string_value(stringify(reactive_value.value) if reactive_value.value is not None else None)
|
|
379
|
+
|
|
380
|
+
def on_external_value_change(new_value: Optional[T]):
|
|
381
|
+
new_string_value = stringify(new_value)
|
|
382
|
+
try:
|
|
383
|
+
parse(string_value_ref.current)
|
|
384
|
+
except ValueError:
|
|
385
|
+
# String value could be invalid when external value is changed by a different component
|
|
386
|
+
set_string_value(new_string_value)
|
|
387
|
+
else:
|
|
388
|
+
if new_value != parse(string_value_ref.current):
|
|
389
|
+
set_string_value(new_string_value)
|
|
390
|
+
|
|
391
|
+
return reactive_value.subscribe(on_external_value_change)
|
|
392
|
+
|
|
393
|
+
solara.use_effect(sync_back_input_value, [reactive_value, parse, stringify])
|
|
394
|
+
|
|
395
|
+
return string_value, error_message, set_string_value
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
@solara.component
|
|
399
|
+
def _InputNumeric(
|
|
400
|
+
str_to_numeric: Callable[[Optional[str]], T],
|
|
401
|
+
label: str,
|
|
402
|
+
value: Union[None, T, solara.Reactive[Optional[T]], solara.Reactive[T]],
|
|
403
|
+
on_value: Union[None, Callable[[Optional[T]], None], Callable[[T], None]] = None,
|
|
404
|
+
disabled: bool = False,
|
|
405
|
+
continuous_update: bool = False,
|
|
406
|
+
clearable: bool = False,
|
|
407
|
+
classes: List[str] = [],
|
|
408
|
+
style: Optional[Union[str, Dict[str, str]]] = None,
|
|
409
|
+
autofocus: bool = False,
|
|
410
|
+
):
|
|
411
|
+
"""Numeric input.
|
|
412
|
+
|
|
413
|
+
## Arguments
|
|
414
|
+
|
|
415
|
+
* `label`: Label to display next to the slider.
|
|
416
|
+
* `value`: The currently entered value.
|
|
417
|
+
* `on_value`: Callback to call when the value changes.
|
|
418
|
+
* `disabled`: Whether the input is disabled.
|
|
419
|
+
* `continuous_update`: Whether to call the `on_value` callback on every change or only when the input loses focus or the enter key is pressed.
|
|
420
|
+
* `classes`: List of CSS classes to apply to the input.
|
|
421
|
+
* `style`: CSS style to apply to the input.
|
|
422
|
+
* `autofocus`: Determines if a component is to be autofocused or not (Default is False). Autofocus will occur either during page load, or when the component becomes visible (for example, dialog being opened). Only one component per page should have autofocus on each such event.
|
|
423
|
+
"""
|
|
424
|
+
style_flat = solara.util._flatten_style(style)
|
|
425
|
+
classes_flat = solara.util._combine_classes(classes)
|
|
426
|
+
|
|
427
|
+
internal_value, error, set_value_cast = _use_input_type(
|
|
428
|
+
value,
|
|
429
|
+
str_to_numeric,
|
|
430
|
+
str,
|
|
431
|
+
on_value,
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
def on_v_model(value):
|
|
435
|
+
if continuous_update:
|
|
436
|
+
set_value_cast(value)
|
|
437
|
+
|
|
438
|
+
if error:
|
|
439
|
+
label += f" ({error})"
|
|
440
|
+
text_field = v.TextField(
|
|
441
|
+
v_model=internal_value,
|
|
442
|
+
on_v_model=on_v_model,
|
|
443
|
+
label=label,
|
|
444
|
+
disabled=disabled,
|
|
445
|
+
# we are not using the number type, since we cannot validate invalid input
|
|
446
|
+
# see https://stackoverflow.blog/2022/12/26/why-the-number-input-is-the-worst-input/
|
|
447
|
+
# type="number",
|
|
448
|
+
hide_details=True,
|
|
449
|
+
clearable=clearable,
|
|
450
|
+
error=bool(error),
|
|
451
|
+
class_=classes_flat,
|
|
452
|
+
style_=style_flat,
|
|
453
|
+
autofocus=autofocus,
|
|
454
|
+
)
|
|
455
|
+
use_change(text_field, set_value_cast, enabled=not continuous_update)
|
|
456
|
+
return text_field
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from typing import Callable, Optional, Union, List
|
|
2
|
+
from .input import use_change
|
|
3
|
+
import solara
|
|
4
|
+
from solara.alias import rv as v
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@solara.component
|
|
8
|
+
def InputTextArea(
|
|
9
|
+
label: str,
|
|
10
|
+
value: Union[str, solara.Reactive[str]] = "",
|
|
11
|
+
on_value: Callable[[str], None] = None,
|
|
12
|
+
disabled: bool = False,
|
|
13
|
+
continuous_update: bool = False,
|
|
14
|
+
update_events: List[str] = ["focusout"],
|
|
15
|
+
error: Union[bool, str] = False,
|
|
16
|
+
message: Optional[str] = None,
|
|
17
|
+
auto_grow: bool = True,
|
|
18
|
+
rows: int = 5,
|
|
19
|
+
):
|
|
20
|
+
r"""Free form text area input.
|
|
21
|
+
|
|
22
|
+
### Basic example:
|
|
23
|
+
|
|
24
|
+
```solara
|
|
25
|
+
import solara
|
|
26
|
+
|
|
27
|
+
text = solara.reactive("Hello\nWorld\n!!!")
|
|
28
|
+
continuous_update = solara.reactive(True)
|
|
29
|
+
|
|
30
|
+
@solara.component
|
|
31
|
+
def Page():
|
|
32
|
+
solara.Checkbox(label="Continuous update", value=continuous_update)
|
|
33
|
+
solara.InputTextArea("Enter some text", value=text, continuous_update=continuous_update.value)
|
|
34
|
+
with solara.Row():
|
|
35
|
+
solara.Button("Clear", on_click=lambda: text.set(""))
|
|
36
|
+
solara.Button("Reset", on_click=lambda: text.set("Hello\nWorld\n!!!"))
|
|
37
|
+
solara.Markdown(f"**You entered**: {text.value}")
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Arguments
|
|
42
|
+
|
|
43
|
+
* `label`: Label to display next to the slider.
|
|
44
|
+
* `value`: The currently entered value.
|
|
45
|
+
* `on_value`: Callback to call when the value changes.
|
|
46
|
+
* `disabled`: Whether the input is disabled.
|
|
47
|
+
* `continuous_update`: Whether to call the `on_value` callback on every change or only when the input loses focus or the enter key is pressed.
|
|
48
|
+
* `update_events`: A list of events that should trigger `on_value`. If continuous update is enabled, this will effectively be ignored,
|
|
49
|
+
since updates will happen every change.
|
|
50
|
+
* `auto_grow`: Whether the text area auto grows with more text.
|
|
51
|
+
* `rows`: Number of empty rows to display.
|
|
52
|
+
* `error`: If truthy, show the input as having an error (in red). If a string is passed, it will be shown as the error message.
|
|
53
|
+
* `message`: Message to show below the input. If `error` is a string, this will be ignored.
|
|
54
|
+
* `classes`: List of CSS classes to apply to the input.
|
|
55
|
+
* `style`: CSS style to apply to the input.
|
|
56
|
+
"""
|
|
57
|
+
reactive_value = solara.use_reactive(value, on_value)
|
|
58
|
+
del value, on_value
|
|
59
|
+
|
|
60
|
+
def set_value_cast(value):
|
|
61
|
+
reactive_value.value = str(value)
|
|
62
|
+
|
|
63
|
+
def on_v_model(value):
|
|
64
|
+
if continuous_update:
|
|
65
|
+
set_value_cast(value)
|
|
66
|
+
|
|
67
|
+
messages = []
|
|
68
|
+
if error and isinstance(error, str):
|
|
69
|
+
messages.append(error)
|
|
70
|
+
elif message:
|
|
71
|
+
messages.append(message)
|
|
72
|
+
text_area = v.Textarea(
|
|
73
|
+
v_model=reactive_value.value,
|
|
74
|
+
on_v_model=on_v_model,
|
|
75
|
+
label=label,
|
|
76
|
+
disabled=disabled,
|
|
77
|
+
error=bool(error),
|
|
78
|
+
messages=messages,
|
|
79
|
+
solo=True,
|
|
80
|
+
hide_details=True,
|
|
81
|
+
outlined=True,
|
|
82
|
+
rows=rows,
|
|
83
|
+
auto_grow=auto_grow,
|
|
84
|
+
)
|
|
85
|
+
use_change(text_area, set_value_cast, enabled=not continuous_update, update_events=update_events)
|
|
86
|
+
return text_area
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from typing import Dict, List, Union
|
|
2
|
+
|
|
3
|
+
import ipyvue as vue
|
|
4
|
+
import reacton.ipyvue as vuer
|
|
5
|
+
import solara
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@solara.component
|
|
9
|
+
def Link(
|
|
10
|
+
path_or_route: Union[str, solara.Route],
|
|
11
|
+
children=[],
|
|
12
|
+
nofollow=False,
|
|
13
|
+
style: Union[str, Dict[str, str], None] = None,
|
|
14
|
+
classes: List[str] = [],
|
|
15
|
+
):
|
|
16
|
+
"""Makes clicking on child elements navigate to a route.
|
|
17
|
+
|
|
18
|
+
See also:
|
|
19
|
+
|
|
20
|
+
* [Multipage](/documentation/advanced/howto/multipage).
|
|
21
|
+
* [Understanding Routing](/documentation/advanced/understanding/routing).
|
|
22
|
+
|
|
23
|
+
Most common usage is in combination with a button, e.g.:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
with solara.Link("/fruit/banana"):
|
|
27
|
+
solara.Button("Go to banana")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Arguments
|
|
32
|
+
|
|
33
|
+
* path_or_route: the path or route to navigate to. Paths should be absolute, e.g. '/fruit/banana'.
|
|
34
|
+
If a route is given, [`resolve_path`](/documentation/api/routing/resolve_path)] will be used to resolve to the absolute path.
|
|
35
|
+
* children: the children of the link. If a child is clicked, the link will be followed.
|
|
36
|
+
* nofollow: If True, the link will not be followed by web crawlers (such as google).
|
|
37
|
+
* style: CSS styles to apply to the HTML link element. Either a string or a dictionary.
|
|
38
|
+
* classes: A list of CSS classes to apply to the link.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
path = solara.resolve_path(path_or_route, level=0)
|
|
42
|
+
attributes = {"href": path}
|
|
43
|
+
if nofollow:
|
|
44
|
+
attributes["rel"] = "nofollow"
|
|
45
|
+
style_flat = solara.util._flatten_style(style)
|
|
46
|
+
classes_flat = solara.util._combine_classes(classes)
|
|
47
|
+
|
|
48
|
+
link = vue.Html.element(tag="a", children=children, attributes=attributes, style_=style_flat, class_=classes_flat)
|
|
49
|
+
location = solara.use_context(solara.routing._location_context)
|
|
50
|
+
|
|
51
|
+
def go(*ignore):
|
|
52
|
+
location.pathname = path
|
|
53
|
+
|
|
54
|
+
vuer.use_event(link, "click.prevent.stop", go)
|
|
55
|
+
return link
|