streamlit 1.45.0__py3-none-any.whl → 1.46.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.
- streamlit/__init__.py +5 -1
- streamlit/auth_util.py +12 -12
- streamlit/cli_util.py +4 -3
- streamlit/column_config.py +11 -9
- streamlit/commands/echo.py +6 -4
- streamlit/commands/execution_control.py +33 -32
- streamlit/commands/experimental_query_params.py +2 -2
- streamlit/commands/logo.py +9 -4
- streamlit/commands/navigation.py +61 -18
- streamlit/commands/page_config.py +57 -47
- streamlit/components/types/base_custom_component.py +7 -7
- streamlit/components/v1/component_registry.py +7 -3
- streamlit/components/v1/components.py +1 -1
- streamlit/components/v1/custom_component.py +8 -8
- streamlit/config.py +289 -144
- streamlit/config_option.py +19 -15
- streamlit/config_util.py +29 -23
- streamlit/connections/__init__.py +2 -2
- streamlit/connections/base_connection.py +5 -5
- streamlit/connections/snowflake_connection.py +13 -11
- streamlit/connections/snowpark_connection.py +3 -3
- streamlit/connections/sql_connection.py +20 -18
- streamlit/connections/util.py +2 -2
- streamlit/cursor.py +6 -6
- streamlit/dataframe_util.py +52 -52
- streamlit/delta_generator.py +46 -48
- streamlit/delta_generator_singletons.py +3 -3
- streamlit/deprecation_util.py +6 -6
- streamlit/elements/alert.py +37 -29
- streamlit/elements/arrow.py +40 -22
- streamlit/elements/code.py +46 -13
- streamlit/elements/deck_gl_json_chart.py +38 -27
- streamlit/elements/dialog_decorator.py +3 -4
- streamlit/elements/doc_string.py +64 -58
- streamlit/elements/exception.py +23 -27
- streamlit/elements/form.py +41 -0
- streamlit/elements/graphviz_chart.py +1 -1
- streamlit/elements/heading.py +60 -9
- streamlit/elements/html.py +3 -4
- streamlit/elements/image.py +8 -9
- streamlit/elements/json.py +21 -2
- streamlit/elements/layouts.py +120 -31
- streamlit/elements/lib/built_in_chart_utils.py +96 -73
- streamlit/elements/lib/color_util.py +3 -3
- streamlit/elements/lib/column_config_utils.py +2 -4
- streamlit/elements/lib/column_types.py +14 -8
- streamlit/elements/lib/dialog.py +9 -5
- streamlit/elements/lib/file_uploader_utils.py +7 -2
- streamlit/elements/lib/image_utils.py +39 -40
- streamlit/elements/lib/js_number.py +4 -4
- streamlit/elements/lib/layout_utils.py +65 -1
- streamlit/elements/lib/mutable_status_container.py +14 -3
- streamlit/elements/lib/options_selector_utils.py +22 -12
- streamlit/elements/lib/pandas_styler_utils.py +25 -21
- streamlit/elements/lib/policies.py +6 -5
- streamlit/elements/lib/streamlit_plotly_theme.py +54 -53
- streamlit/elements/lib/subtitle_utils.py +6 -9
- streamlit/elements/lib/utils.py +20 -5
- streamlit/elements/map.py +32 -56
- streamlit/elements/markdown.py +101 -12
- streamlit/elements/media.py +78 -21
- streamlit/elements/metric.py +32 -16
- streamlit/elements/plotly_chart.py +15 -15
- streamlit/elements/progress.py +33 -15
- streamlit/elements/spinner.py +31 -6
- streamlit/elements/text.py +21 -1
- streamlit/elements/toast.py +1 -2
- streamlit/elements/vega_charts.py +54 -23
- streamlit/elements/widgets/audio_input.py +24 -7
- streamlit/elements/widgets/button.py +26 -19
- streamlit/elements/widgets/button_group.py +10 -15
- streamlit/elements/widgets/camera_input.py +27 -7
- streamlit/elements/widgets/chat.py +91 -38
- streamlit/elements/widgets/checkbox.py +45 -4
- streamlit/elements/widgets/color_picker.py +40 -17
- streamlit/elements/widgets/data_editor.py +76 -37
- streamlit/elements/widgets/file_uploader.py +42 -13
- streamlit/elements/widgets/multiselect.py +7 -10
- streamlit/elements/widgets/number_input.py +123 -47
- streamlit/elements/widgets/radio.py +59 -13
- streamlit/elements/widgets/select_slider.py +35 -30
- streamlit/elements/widgets/selectbox.py +56 -9
- streamlit/elements/widgets/slider.py +190 -99
- streamlit/elements/widgets/text_widgets.py +54 -8
- streamlit/elements/widgets/time_widgets.py +53 -14
- streamlit/elements/write.py +5 -8
- streamlit/env_util.py +2 -7
- streamlit/error_util.py +16 -9
- streamlit/errors.py +69 -48
- streamlit/external/langchain/streamlit_callback_handler.py +10 -5
- streamlit/file_util.py +27 -10
- streamlit/git_util.py +29 -24
- streamlit/hello/animation_demo.py +9 -9
- streamlit/hello/dataframe_demo.py +5 -5
- streamlit/hello/hello.py +1 -0
- streamlit/hello/mapping_demo.py +7 -8
- streamlit/hello/plotting_demo.py +3 -3
- streamlit/hello/streamlit_app.py +28 -26
- streamlit/hello/utils.py +2 -1
- streamlit/logger.py +10 -11
- streamlit/navigation/page.py +11 -8
- streamlit/proto/Audio_pb2.py +4 -3
- streamlit/proto/Audio_pb2.pyi +8 -1
- streamlit/proto/Block_pb2.py +38 -29
- streamlit/proto/Block_pb2.pyi +72 -4
- streamlit/proto/ClientState_pb2.py +4 -4
- streamlit/proto/ClientState_pb2.pyi +7 -2
- streamlit/proto/Code_pb2.py +4 -2
- streamlit/proto/Code_pb2.pyi +1 -0
- streamlit/proto/DataFrame_pb2.pyi +1 -1
- streamlit/proto/DeckGlJsonChart_pb2.pyi +1 -1
- streamlit/proto/Element_pb2.py +5 -3
- streamlit/proto/Element_pb2.pyi +20 -3
- streamlit/proto/GapSize_pb2.py +29 -0
- streamlit/proto/GapSize_pb2.pyi +70 -0
- streamlit/proto/HeightConfig_pb2.py +27 -0
- streamlit/proto/HeightConfig_pb2.pyi +48 -0
- streamlit/proto/NamedDataSet_pb2.pyi +1 -1
- streamlit/proto/Navigation_pb2.py +3 -3
- streamlit/proto/Navigation_pb2.pyi +4 -0
- streamlit/proto/NewSession_pb2.py +18 -16
- streamlit/proto/NewSession_pb2.pyi +29 -3
- streamlit/proto/PageConfig_pb2.py +7 -7
- streamlit/proto/PageConfig_pb2.pyi +21 -1
- streamlit/proto/Video_pb2.py +8 -7
- streamlit/proto/Video_pb2.pyi +8 -1
- streamlit/proto/WidthConfig_pb2.py +2 -2
- streamlit/proto/WidthConfig_pb2.pyi +15 -1
- streamlit/runtime/__init__.py +1 -1
- streamlit/runtime/app_session.py +53 -40
- streamlit/runtime/caching/__init__.py +9 -9
- streamlit/runtime/caching/cache_data_api.py +36 -30
- streamlit/runtime/caching/cache_errors.py +4 -4
- streamlit/runtime/caching/cache_resource_api.py +8 -8
- streamlit/runtime/caching/cache_utils.py +15 -14
- streamlit/runtime/caching/cached_message_replay.py +14 -8
- streamlit/runtime/caching/hashing.py +91 -97
- streamlit/runtime/caching/legacy_cache_api.py +2 -2
- streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
- streamlit/runtime/caching/storage/dummy_cache_storage.py +1 -1
- streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +12 -14
- streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -6
- streamlit/runtime/connection_factory.py +36 -36
- streamlit/runtime/context.py +58 -9
- streamlit/runtime/credentials.py +29 -40
- streamlit/runtime/forward_msg_queue.py +11 -11
- streamlit/runtime/fragment.py +7 -7
- streamlit/runtime/media_file_manager.py +3 -4
- streamlit/runtime/memory_media_file_storage.py +6 -5
- streamlit/runtime/memory_uploaded_file_manager.py +2 -2
- streamlit/runtime/metrics_util.py +11 -12
- streamlit/runtime/pages_manager.py +4 -6
- streamlit/runtime/runtime.py +8 -6
- streamlit/runtime/runtime_util.py +7 -6
- streamlit/runtime/scriptrunner/__init__.py +4 -4
- streamlit/runtime/scriptrunner/exec_code.py +12 -5
- streamlit/runtime/scriptrunner/magic.py +16 -12
- streamlit/runtime/scriptrunner/script_cache.py +1 -1
- streamlit/runtime/scriptrunner/script_runner.py +55 -34
- streamlit/runtime/scriptrunner_utils/exceptions.py +1 -1
- streamlit/runtime/scriptrunner_utils/script_requests.py +7 -4
- streamlit/runtime/scriptrunner_utils/script_run_context.py +10 -23
- streamlit/runtime/secrets.py +40 -35
- streamlit/runtime/session_manager.py +2 -1
- streamlit/runtime/state/__init__.py +5 -5
- streamlit/runtime/state/common.py +2 -2
- streamlit/runtime/state/query_params.py +13 -15
- streamlit/runtime/state/query_params_proxy.py +17 -13
- streamlit/runtime/state/safe_session_state.py +2 -2
- streamlit/runtime/state/session_state.py +52 -34
- streamlit/runtime/stats.py +2 -2
- streamlit/runtime/uploaded_file_manager.py +1 -1
- streamlit/runtime/websocket_session_manager.py +10 -6
- streamlit/source_util.py +8 -6
- streamlit/static/index.html +3 -17
- streamlit/static/manifest.json +1180 -0
- streamlit/static/static/css/{index.DqDwtg6_.css → index.CJVRHjQZ.css} +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.DyIfDYvY.js → ErrorOutline.esm.6PVAQvlT.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.kF1FCxeJ.js → FileDownload.esm.BZQHC61b.js} +1 -1
- streamlit/static/static/js/{FileHelper.DKt6tIeO.js → FileHelper.Bn1VShMJ.js} +5 -5
- streamlit/static/static/js/{FormClearHelper.DpJR9YCu.js → FormClearHelper.CsFEiTNN.js} +1 -1
- streamlit/static/static/js/{Hooks.BT6PF2Zi.js → Hooks.DguOHQL1.js} +1 -1
- streamlit/static/static/js/{InputInstructions.BmnD4oa3.js → InputInstructions.CTYn2BJQ.js} +1 -1
- streamlit/static/static/js/{ProgressBar.Ch7VNdkM.js → ProgressBar.CPOGBKCi.js} +2 -2
- streamlit/static/static/js/{RenderInPortalIfExists.43tDswzK.js → RenderInPortalIfExists.BYu_CZaF.js} +1 -1
- streamlit/static/static/js/Toolbar.gXKw7ANv.js +1 -0
- streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
- streamlit/static/static/js/{base-input.BjeC3XFX.js → base-input.DBYPj91R.js} +4 -4
- streamlit/static/static/js/{checkbox.DIVN0GOS.js → checkbox.BUm2vnNv.js} +2 -2
- streamlit/static/static/js/{createSuper.CKyBiJe0.js → createSuper.KD4RuZ-W.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.CXpaXRk5.js → data-grid-overlay-editor.CUwpDfvI.js} +1 -1
- streamlit/static/static/js/{downloader.B-uWAyLB.js → downloader.CkDtclup.js} +1 -1
- streamlit/static/static/js/{es6._eGNfJ2i.js → es6.Dlcvh_r0.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.CebQfV1Q.js → iframeResizer.contentWindow.DOXlFfve.js} +1 -1
- streamlit/static/static/js/{index.EbMzSayc.js → index.B0cuGMAB.js} +25 -25
- streamlit/static/static/js/index.BCWTclSV.js +73 -0
- streamlit/static/static/js/index.BJY_fap7.js +1 -0
- streamlit/static/static/js/index.BL3l6dnk.js +1 -0
- streamlit/static/static/js/{index.CpV1hnf8.js → index.BMZzRZjB.js} +1 -1
- streamlit/static/static/js/{index.l6QfBDTC.js → index.BOzUTGDe.js} +1 -1
- streamlit/static/static/js/index.BYI5iO-o.js +1 -0
- streamlit/static/static/js/index.BYo0ywlm.js +783 -0
- streamlit/static/static/js/{index.CuUJHsRK.js → index.BYz9btsY.js} +1 -1
- streamlit/static/static/js/{index.C_nMqHLH.js → index.CCVzQz0Z.js} +2 -2
- streamlit/static/static/js/index.CD6FydK9.js +1 -0
- streamlit/static/static/js/index.CDYEqgC8.js +2 -0
- streamlit/static/static/js/{index.BAdBHmJD.js → index.CMP9c4xA.js} +1 -1
- streamlit/static/static/js/index.CN30QAPD.js +1 -0
- streamlit/static/static/js/{index.CtTgot1Z.js → index.CNqWQkTe.js} +1 -1
- streamlit/static/static/js/index.CaxS67Xz.js +1 -0
- streamlit/static/static/js/{index.HsXxdgGd.js → index.CbsT4sGW.js} +1 -1
- streamlit/static/static/js/index.ChAVlxpQ.js +1 -0
- streamlit/static/static/js/{index.BaYSBSaz.js → index.ClLMMmDd.js} +1 -1
- streamlit/static/static/js/{index.CxxktCLw.js → index.D-O9rQmV.js} +1 -1
- streamlit/static/static/js/{index.Coc8OVG7.js → index.D4k7VZZL.js} +1 -1
- streamlit/static/static/js/index.DLBi0Ar1.js +1 -0
- streamlit/static/static/js/index.DVq5XmJo.js +197 -0
- streamlit/static/static/js/{index.ClX0ambk.js → index.DZKmKXWw.js} +1 -1
- streamlit/static/static/js/index.DkaVx80F.js +1 -0
- streamlit/static/static/js/index.Dr968Klx.js +1 -0
- streamlit/static/static/js/{index.BaozEIL-.js → index.DtUYLn9j.js} +20 -20
- streamlit/static/static/js/index.DwjYSyhs.js +1 -0
- streamlit/static/static/js/index.DzrImxu4.js +1 -0
- streamlit/static/static/js/index.HyGsn4VM.js +1 -0
- streamlit/static/static/js/index.OwxC65od.js +12 -0
- streamlit/static/static/js/index.PZs7VZkC.js +1 -0
- streamlit/static/static/js/index.Voiqpj4q.js +1 -0
- streamlit/static/static/js/index.bSROvR-J.js +3 -0
- streamlit/static/static/js/index.oT9GD3l4.js +1 -0
- streamlit/static/static/js/{index.schmj9D9.js → index.qb-yAPH6.js} +255 -255
- streamlit/static/static/js/index.rJFy_Ygy.js +2 -0
- streamlit/static/static/js/{input.VQEe_bZy.js → input.CwQtEnFN.js} +2 -2
- streamlit/static/static/js/{memory.DGVHab07.js → memory.C5XaFIjR.js} +1 -1
- streamlit/static/static/js/{mergeWith.-RIuUGoA.js → mergeWith.DzwwH6AG.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.wzFLIbEE.js → number-overlay-editor.Dx0XqCkD.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.GIObu6rf.js → possibleConstructorReturn.CVfSu9Ws.js} +1 -1
- streamlit/static/static/js/{sandbox.DpjSeqe2.js → sandbox.BT0gdMXk.js} +1 -1
- streamlit/static/static/js/{textarea.Dz0J9LZe.js → textarea.DNCbrtbM.js} +2 -2
- streamlit/static/static/js/{timepicker.BLgJZnzX.js → timepicker.4UYJD9Ts.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.0OZlxz7U.js → toConsumableArray.DUmnaVWV.js} +1 -1
- streamlit/static/static/js/{uniqueId.DbzplC8D.js → uniqueId.DUvh-GL8.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.COJZng1S.js → useBasicWidgetState.Cwd7-jJa.js} +1 -1
- streamlit/static/static/js/useOnInputChange.DvemQrOM.js +1 -0
- streamlit/static/static/js/{withFullScreenWrapper.CzWvNbvi.js → withFullScreenWrapper.CiQ10ByU.js} +1 -1
- streamlit/static/static/media/SourceCodeVF-Italic.ttf.Ba1oaZG1.woff2 +0 -0
- streamlit/static/static/media/SourceCodeVF-Upright.ttf.BjWn63N-.woff2 +0 -0
- streamlit/static/static/media/SourceSansVF-Italic.ttf.Bt9VkdQ3.woff2 +0 -0
- streamlit/static/static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2 +0 -0
- streamlit/static/static/media/SourceSerifVariable-Italic.ttf.CVdzAtxO.woff2 +0 -0
- streamlit/static/static/media/SourceSerifVariable-Roman.ttf.mdpVL9bi.woff2 +0 -0
- streamlit/string_util.py +14 -19
- streamlit/temporary_directory.py +13 -4
- streamlit/testing/v1/app_test.py +15 -10
- streamlit/testing/v1/element_tree.py +157 -178
- streamlit/testing/v1/local_script_runner.py +11 -15
- streamlit/testing/v1/util.py +11 -4
- streamlit/type_util.py +8 -12
- streamlit/url_util.py +1 -1
- streamlit/user_info.py +6 -5
- streamlit/util.py +25 -1
- streamlit/vendor/pympler/asizeof.py +3 -2
- streamlit/watcher/event_based_path_watcher.py +15 -1
- streamlit/watcher/folder_black_list.py +2 -2
- streamlit/watcher/local_sources_watcher.py +64 -18
- streamlit/watcher/path_watcher.py +6 -10
- streamlit/watcher/polling_path_watcher.py +8 -7
- streamlit/watcher/util.py +7 -6
- streamlit/web/bootstrap.py +16 -14
- streamlit/web/cli.py +52 -45
- streamlit/web/server/__init__.py +7 -3
- streamlit/web/server/app_static_file_handler.py +1 -1
- streamlit/web/server/authlib_tornado_integration.py +9 -4
- streamlit/web/server/browser_websocket_handler.py +8 -2
- streamlit/web/server/component_request_handler.py +14 -10
- streamlit/web/server/media_file_handler.py +14 -7
- streamlit/web/server/oauth_authlib_routes.py +41 -9
- streamlit/web/server/oidc_mixin.py +35 -17
- streamlit/web/server/routes.py +32 -22
- streamlit/web/server/server.py +6 -18
- streamlit/web/server/server_util.py +19 -9
- streamlit/web/server/stats_request_handler.py +7 -5
- streamlit/web/server/upload_file_request_handler.py +22 -19
- streamlit/web/server/websocket_headers.py +1 -1
- {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/METADATA +4 -4
- streamlit-1.46.0.dist-info/RECORD +559 -0
- {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/WHEEL +1 -1
- streamlit/elements/lib/event_utils.py +0 -39
- streamlit/static/static/js/Toolbar.HTGsjfCP.js +0 -1
- streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
- streamlit/static/static/js/index.B5TWFN5r.js +0 -1
- streamlit/static/static/js/index.BI9-p_-s.js +0 -3
- streamlit/static/static/js/index.BYHnDZYn.js +0 -1
- streamlit/static/static/js/index.B_M97aPz.js +0 -1
- streamlit/static/static/js/index.BdN5swP0.js +0 -1
- streamlit/static/static/js/index.BfCAp_Sj.js +0 -1
- streamlit/static/static/js/index.BqDl3eRM.js +0 -779
- streamlit/static/static/js/index.C0VtYb3T.js +0 -2
- streamlit/static/static/js/index.C1qW_Owy.js +0 -1
- streamlit/static/static/js/index.C4AcBARa.js +0 -1
- streamlit/static/static/js/index.CCOiJRk1.js +0 -1
- streamlit/static/static/js/index.COvpza5W.js +0 -1
- streamlit/static/static/js/index.C_9qGjbK.js +0 -2
- streamlit/static/static/js/index.CqISBfsc.js +0 -197
- streamlit/static/static/js/index.D1WOs2Ce.js +0 -1
- streamlit/static/static/js/index.DQljs-9e.js +0 -1
- streamlit/static/static/js/index.DZqX4P_2.js +0 -1
- streamlit/static/static/js/index.DajIfBOb.js +0 -1
- streamlit/static/static/js/index.DuOXre0H.js +0 -1
- streamlit/static/static/js/index.EWD98YhP.js +0 -1
- streamlit/static/static/js/index.LaZloCTl.js +0 -73
- streamlit/static/static/js/index.S_1klBoy.js +0 -1
- streamlit/static/static/js/index.b0Gf958T.js +0 -12
- streamlit/static/static/js/index.t--hEgTQ.js +0 -6
- streamlit/static/static/js/useOnInputChange.CgOwAHyw.js +0 -1
- streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
- streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
- streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
- streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
- streamlit-1.45.0.dist-info/RECORD +0 -568
- {streamlit-1.45.0.data → streamlit-1.46.0.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/entry_points.txt +0 -0
- {streamlit-1.45.0.dist-info → streamlit-1.46.0.dist-info}/top_level.txt +0 -0
|
@@ -107,11 +107,7 @@ class _MultiSelectSerde(Generic[T]):
|
|
|
107
107
|
indices = check_and_convert_to_indices(self.options, value)
|
|
108
108
|
return indices if indices is not None else []
|
|
109
109
|
|
|
110
|
-
def deserialize(
|
|
111
|
-
self,
|
|
112
|
-
ui_value: list[int] | None,
|
|
113
|
-
widget_id: str = "",
|
|
114
|
-
) -> list[T]:
|
|
110
|
+
def deserialize(self, ui_value: list[int] | None) -> list[T]:
|
|
115
111
|
current_value: list[int] = (
|
|
116
112
|
ui_value if ui_value is not None else self.default_value
|
|
117
113
|
)
|
|
@@ -145,8 +141,8 @@ class _SingleSelectSerde(Generic[T]):
|
|
|
145
141
|
_value = [value] if value is not None else []
|
|
146
142
|
return self.multiselect_serde.serialize(_value)
|
|
147
143
|
|
|
148
|
-
def deserialize(self, ui_value: list[int] | None
|
|
149
|
-
deserialized = self.multiselect_serde.deserialize(ui_value
|
|
144
|
+
def deserialize(self, ui_value: list[int] | None) -> T | None:
|
|
145
|
+
deserialized = self.multiselect_serde.deserialize(ui_value)
|
|
150
146
|
|
|
151
147
|
if len(deserialized) == 0:
|
|
152
148
|
return None
|
|
@@ -169,7 +165,7 @@ class ButtonGroupSerde(Generic[T]):
|
|
|
169
165
|
options: Sequence[T],
|
|
170
166
|
default_values: list[int],
|
|
171
167
|
type: Literal["single", "multi"],
|
|
172
|
-
):
|
|
168
|
+
) -> None:
|
|
173
169
|
self.options = options
|
|
174
170
|
self.default_values = default_values
|
|
175
171
|
self.type = type
|
|
@@ -182,10 +178,8 @@ class ButtonGroupSerde(Generic[T]):
|
|
|
182
178
|
def serialize(self, value: T | list[T] | None) -> list[int]:
|
|
183
179
|
return self.serde.serialize(cast("Any", value))
|
|
184
180
|
|
|
185
|
-
def deserialize(
|
|
186
|
-
self
|
|
187
|
-
) -> list[T] | T | None:
|
|
188
|
-
return self.serde.deserialize(ui_value, widget_id)
|
|
181
|
+
def deserialize(self, ui_value: list[int] | None) -> list[T] | T | None:
|
|
182
|
+
return self.serde.deserialize(ui_value)
|
|
189
183
|
|
|
190
184
|
|
|
191
185
|
def get_mapped_options(
|
|
@@ -256,7 +250,7 @@ def _build_proto(
|
|
|
256
250
|
return proto
|
|
257
251
|
|
|
258
252
|
|
|
259
|
-
def _maybe_raise_selection_mode_warning(selection_mode: SelectionMode):
|
|
253
|
+
def _maybe_raise_selection_mode_warning(selection_mode: SelectionMode) -> None:
|
|
260
254
|
"""Check if the selection_mode value is valid or raise exception otherwise."""
|
|
261
255
|
if selection_mode not in ["single", "multi"]:
|
|
262
256
|
raise StreamlitAPIException(
|
|
@@ -556,7 +550,7 @@ class ButtonGroupMixin:
|
|
|
556
550
|
label_visibility: "visible", "hidden", or "collapsed"
|
|
557
551
|
The visibility of the label. The default is ``"visible"``. If this
|
|
558
552
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
559
|
-
label, which can help keep the widget
|
|
553
|
+
label, which can help keep the widget aligned with other widgets.
|
|
560
554
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
561
555
|
|
|
562
556
|
Returns
|
|
@@ -765,7 +759,7 @@ class ButtonGroupMixin:
|
|
|
765
759
|
label_visibility: "visible", "hidden", or "collapsed"
|
|
766
760
|
The visibility of the label. The default is ``"visible"``. If this
|
|
767
761
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
768
|
-
label, which can help keep the widget
|
|
762
|
+
label, which can help keep the widget aligned with other widgets.
|
|
769
763
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
770
764
|
|
|
771
765
|
Returns
|
|
@@ -990,6 +984,7 @@ class ButtonGroupMixin:
|
|
|
990
984
|
widget_name,
|
|
991
985
|
user_key=key,
|
|
992
986
|
form_id=form_id,
|
|
987
|
+
dg=self.dg,
|
|
993
988
|
options=formatted_options,
|
|
994
989
|
default=default,
|
|
995
990
|
click_mode=parsed_selection_mode,
|
|
@@ -22,6 +22,7 @@ from typing_extensions import TypeAlias
|
|
|
22
22
|
|
|
23
23
|
from streamlit.elements.lib.file_uploader_utils import enforce_filename_restriction
|
|
24
24
|
from streamlit.elements.lib.form_utils import current_form_id
|
|
25
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig, validate_width
|
|
25
26
|
from streamlit.elements.lib.policies import (
|
|
26
27
|
check_widget_policies,
|
|
27
28
|
maybe_raise_label_warnings,
|
|
@@ -49,6 +50,7 @@ from streamlit.runtime.uploaded_file_manager import DeletedFile, UploadedFile
|
|
|
49
50
|
|
|
50
51
|
if TYPE_CHECKING:
|
|
51
52
|
from streamlit.delta_generator import DeltaGenerator
|
|
53
|
+
from streamlit.elements.lib.layout_utils import WidthWithoutContent
|
|
52
54
|
|
|
53
55
|
SomeUploadedSnapshotFile: TypeAlias = Union[UploadedFile, DeletedFile, None]
|
|
54
56
|
|
|
@@ -73,13 +75,10 @@ class CameraInputSerde:
|
|
|
73
75
|
return state_proto
|
|
74
76
|
|
|
75
77
|
def deserialize(
|
|
76
|
-
self, ui_value: FileUploaderStateProto | None
|
|
78
|
+
self, ui_value: FileUploaderStateProto | None
|
|
77
79
|
) -> SomeUploadedSnapshotFile:
|
|
78
80
|
upload_files = _get_upload_files(ui_value)
|
|
79
|
-
if len(upload_files) == 0
|
|
80
|
-
return_value = None
|
|
81
|
-
else:
|
|
82
|
-
return_value = upload_files[0]
|
|
81
|
+
return_value = None if len(upload_files) == 0 else upload_files[0]
|
|
83
82
|
if return_value is not None and not isinstance(return_value, DeletedFile):
|
|
84
83
|
enforce_filename_restriction(return_value.name, [".jpg"])
|
|
85
84
|
return return_value
|
|
@@ -98,6 +97,7 @@ class CameraInputMixin:
|
|
|
98
97
|
*, # keyword-only arguments:
|
|
99
98
|
disabled: bool = False,
|
|
100
99
|
label_visibility: LabelVisibility = "visible",
|
|
100
|
+
width: WidthWithoutContent = "stretch",
|
|
101
101
|
) -> UploadedFile | None:
|
|
102
102
|
r"""Display a widget that returns pictures from the user's webcam.
|
|
103
103
|
|
|
@@ -156,9 +156,20 @@ class CameraInputMixin:
|
|
|
156
156
|
label_visibility : "visible", "hidden", or "collapsed"
|
|
157
157
|
The visibility of the label. The default is ``"visible"``. If this
|
|
158
158
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
159
|
-
label, which can help keep the widget
|
|
159
|
+
label, which can help keep the widget aligned with other widgets.
|
|
160
160
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
161
161
|
|
|
162
|
+
width : "stretch" or int
|
|
163
|
+
The width of the camera input widget. This can be one of the
|
|
164
|
+
following:
|
|
165
|
+
|
|
166
|
+
- ``"stretch"`` (default): The width of the widget matches the
|
|
167
|
+
width of the parent container.
|
|
168
|
+
- An integer specifying the width in pixels: The widget has a
|
|
169
|
+
fixed width. If the specified width is greater than the width of
|
|
170
|
+
the parent container, the width of the widget matches the width
|
|
171
|
+
of the parent container.
|
|
172
|
+
|
|
162
173
|
Returns
|
|
163
174
|
-------
|
|
164
175
|
None or UploadedFile
|
|
@@ -191,6 +202,7 @@ class CameraInputMixin:
|
|
|
191
202
|
kwargs=kwargs,
|
|
192
203
|
disabled=disabled,
|
|
193
204
|
label_visibility=label_visibility,
|
|
205
|
+
width=width,
|
|
194
206
|
ctx=ctx,
|
|
195
207
|
)
|
|
196
208
|
|
|
@@ -205,6 +217,7 @@ class CameraInputMixin:
|
|
|
205
217
|
*, # keyword-only arguments:
|
|
206
218
|
disabled: bool = False,
|
|
207
219
|
label_visibility: LabelVisibility = "visible",
|
|
220
|
+
width: WidthWithoutContent = "stretch",
|
|
208
221
|
ctx: ScriptRunContext | None = None,
|
|
209
222
|
) -> UploadedFile | None:
|
|
210
223
|
key = to_key(key)
|
|
@@ -222,8 +235,10 @@ class CameraInputMixin:
|
|
|
222
235
|
"camera_input",
|
|
223
236
|
user_key=key,
|
|
224
237
|
form_id=current_form_id(self.dg),
|
|
238
|
+
dg=self.dg,
|
|
225
239
|
label=label,
|
|
226
240
|
help=help,
|
|
241
|
+
width=width,
|
|
227
242
|
)
|
|
228
243
|
|
|
229
244
|
camera_input_proto = CameraInputProto()
|
|
@@ -238,6 +253,9 @@ class CameraInputMixin:
|
|
|
238
253
|
if help is not None:
|
|
239
254
|
camera_input_proto.help = dedent(help)
|
|
240
255
|
|
|
256
|
+
validate_width(width)
|
|
257
|
+
layout_config = LayoutConfig(width=width)
|
|
258
|
+
|
|
241
259
|
serde = CameraInputSerde()
|
|
242
260
|
|
|
243
261
|
camera_input_state = register_widget(
|
|
@@ -251,7 +269,9 @@ class CameraInputMixin:
|
|
|
251
269
|
value_type="file_uploader_state_value",
|
|
252
270
|
)
|
|
253
271
|
|
|
254
|
-
self.dg._enqueue(
|
|
272
|
+
self.dg._enqueue(
|
|
273
|
+
"camera_input", camera_input_proto, layout_config=layout_config
|
|
274
|
+
)
|
|
255
275
|
|
|
256
276
|
if isinstance(camera_input_state.value, DeletedFile):
|
|
257
277
|
return None
|
|
@@ -33,6 +33,12 @@ from streamlit.elements.lib.file_uploader_utils import (
|
|
|
33
33
|
)
|
|
34
34
|
from streamlit.elements.lib.form_utils import is_in_form
|
|
35
35
|
from streamlit.elements.lib.image_utils import AtomicImage, WidthBehavior, image_to_url
|
|
36
|
+
from streamlit.elements.lib.layout_utils import (
|
|
37
|
+
LayoutConfig,
|
|
38
|
+
Width,
|
|
39
|
+
WidthWithoutContent,
|
|
40
|
+
validate_width,
|
|
41
|
+
)
|
|
36
42
|
from streamlit.elements.lib.policies import check_widget_policies
|
|
37
43
|
from streamlit.elements.lib.utils import (
|
|
38
44
|
Key,
|
|
@@ -47,6 +53,7 @@ from streamlit.proto.ChatInput_pb2 import ChatInput as ChatInputProto
|
|
|
47
53
|
from streamlit.proto.Common_pb2 import ChatInputValue as ChatInputValueProto
|
|
48
54
|
from streamlit.proto.Common_pb2 import FileUploaderState as FileUploaderStateProto
|
|
49
55
|
from streamlit.proto.RootContainer_pb2 import RootContainer
|
|
56
|
+
from streamlit.proto.WidthConfig_pb2 import WidthConfig
|
|
50
57
|
from streamlit.runtime.metrics_util import gather_metrics
|
|
51
58
|
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
|
52
59
|
from streamlit.runtime.state import (
|
|
@@ -117,11 +124,11 @@ def _process_avatar_input(
|
|
|
117
124
|
Tuple[AvatarType, str]
|
|
118
125
|
The detected avatar type and the prepared avatar data.
|
|
119
126
|
"""
|
|
120
|
-
AvatarType = BlockProto.ChatMessage.AvatarType
|
|
127
|
+
AvatarType = BlockProto.ChatMessage.AvatarType # noqa: N806
|
|
121
128
|
|
|
122
129
|
if avatar is None:
|
|
123
130
|
return AvatarType.ICON, ""
|
|
124
|
-
|
|
131
|
+
if isinstance(avatar, str) and avatar in {item.value for item in PresetNames}:
|
|
125
132
|
# On the frontend, we only support "assistant" and "user" for the avatar.
|
|
126
133
|
return (
|
|
127
134
|
AvatarType.ICON,
|
|
@@ -131,25 +138,24 @@ def _process_avatar_input(
|
|
|
131
138
|
else "user"
|
|
132
139
|
),
|
|
133
140
|
)
|
|
134
|
-
|
|
141
|
+
if isinstance(avatar, str) and is_emoji(avatar):
|
|
135
142
|
return AvatarType.EMOJI, avatar
|
|
136
143
|
|
|
137
|
-
|
|
144
|
+
if isinstance(avatar, str) and avatar.startswith(":material"):
|
|
138
145
|
return AvatarType.ICON, validate_material_icon(avatar)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
) from ex
|
|
146
|
+
try:
|
|
147
|
+
return AvatarType.IMAGE, image_to_url(
|
|
148
|
+
avatar,
|
|
149
|
+
width=WidthBehavior.ORIGINAL,
|
|
150
|
+
clamp=False,
|
|
151
|
+
channels="RGB",
|
|
152
|
+
output_format="auto",
|
|
153
|
+
image_id=delta_path,
|
|
154
|
+
)
|
|
155
|
+
except Exception as ex:
|
|
156
|
+
raise StreamlitAPIException(
|
|
157
|
+
"Failed to load the provided avatar value as an image."
|
|
158
|
+
) from ex
|
|
153
159
|
|
|
154
160
|
|
|
155
161
|
def _pop_upload_files(
|
|
@@ -196,24 +202,21 @@ class ChatInputSerde:
|
|
|
196
202
|
allowed_types: Sequence[str] | None = None
|
|
197
203
|
|
|
198
204
|
def deserialize(
|
|
199
|
-
self,
|
|
200
|
-
ui_value: ChatInputValueProto | None,
|
|
201
|
-
widget_id: str = "",
|
|
205
|
+
self, ui_value: ChatInputValueProto | None
|
|
202
206
|
) -> str | ChatInputValue | None:
|
|
203
207
|
if ui_value is None or not ui_value.HasField("data"):
|
|
204
208
|
return None
|
|
205
209
|
if not self.accept_files:
|
|
206
210
|
return ui_value.data
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
)
|
|
211
|
+
uploaded_files = _pop_upload_files(ui_value.file_uploader_state)
|
|
212
|
+
for file in uploaded_files:
|
|
213
|
+
if self.allowed_types and not isinstance(file, DeletedFile):
|
|
214
|
+
enforce_filename_restriction(file.name, self.allowed_types)
|
|
215
|
+
|
|
216
|
+
return ChatInputValue(
|
|
217
|
+
text=ui_value.data,
|
|
218
|
+
files=uploaded_files,
|
|
219
|
+
)
|
|
217
220
|
|
|
218
221
|
def serialize(self, v: str | None) -> ChatInputValueProto:
|
|
219
222
|
return ChatInputValueProto(data=v)
|
|
@@ -226,6 +229,7 @@ class ChatMixin:
|
|
|
226
229
|
name: Literal["user", "assistant", "ai", "human"] | str,
|
|
227
230
|
*,
|
|
228
231
|
avatar: Literal["user", "assistant"] | str | AtomicImage | None = None,
|
|
232
|
+
width: Width = "stretch",
|
|
229
233
|
) -> DeltaGenerator:
|
|
230
234
|
"""Insert a chat message container.
|
|
231
235
|
|
|
@@ -233,6 +237,10 @@ class ChatMixin:
|
|
|
233
237
|
(preferred) or just call methods directly on the returned object. See the
|
|
234
238
|
examples below.
|
|
235
239
|
|
|
240
|
+
.. note::
|
|
241
|
+
To follow best design practices and maintain a good appearance on
|
|
242
|
+
all screen sizes, don't nest chat message containers.
|
|
243
|
+
|
|
236
244
|
Parameters
|
|
237
245
|
----------
|
|
238
246
|
name : "user", "assistant", "ai", "human", or str
|
|
@@ -276,6 +284,18 @@ class ChatMixin:
|
|
|
276
284
|
.. |st.image| replace:: ``st.image``
|
|
277
285
|
.. _st.image: https://docs.streamlit.io/develop/api-reference/media/st.image
|
|
278
286
|
|
|
287
|
+
width : "stretch", "content", or int
|
|
288
|
+
The width of the chat message container. This can be one of the following:
|
|
289
|
+
|
|
290
|
+
- ``"stretch"`` (default): The width of the container matches the
|
|
291
|
+
width of the parent container.
|
|
292
|
+
- ``"content"``: The width of the container matches the width of its
|
|
293
|
+
content, but doesn't exceed the width of the parent container.
|
|
294
|
+
- An integer specifying the width in pixels: The container has a
|
|
295
|
+
fixed width. If the specified width is greater than the width of
|
|
296
|
+
the parent container, the width of the container matches the width
|
|
297
|
+
of the parent container.
|
|
298
|
+
|
|
279
299
|
Returns
|
|
280
300
|
-------
|
|
281
301
|
Container
|
|
@@ -324,13 +344,26 @@ class ChatMixin:
|
|
|
324
344
|
avatar, self.dg._get_delta_path_str()
|
|
325
345
|
)
|
|
326
346
|
|
|
347
|
+
validate_width(width, allow_content=True)
|
|
348
|
+
|
|
327
349
|
message_container_proto = BlockProto.ChatMessage()
|
|
328
350
|
message_container_proto.name = name
|
|
329
351
|
message_container_proto.avatar = converted_avatar
|
|
330
352
|
message_container_proto.avatar_type = avatar_type
|
|
353
|
+
|
|
354
|
+
# Set up width configuration
|
|
355
|
+
width_config = WidthConfig()
|
|
356
|
+
if isinstance(width, int):
|
|
357
|
+
width_config.pixel_width = width
|
|
358
|
+
elif width == "content":
|
|
359
|
+
width_config.use_content = True
|
|
360
|
+
else:
|
|
361
|
+
width_config.use_stretch = True
|
|
362
|
+
|
|
331
363
|
block_proto = BlockProto()
|
|
332
364
|
block_proto.allow_empty = True
|
|
333
365
|
block_proto.chat_message.CopyFrom(message_container_proto)
|
|
366
|
+
block_proto.width_config.CopyFrom(width_config)
|
|
334
367
|
|
|
335
368
|
return self.dg._block(block_proto=block_proto)
|
|
336
369
|
|
|
@@ -347,6 +380,7 @@ class ChatMixin:
|
|
|
347
380
|
on_submit: WidgetCallback | None = None,
|
|
348
381
|
args: WidgetArgs | None = None,
|
|
349
382
|
kwargs: WidgetKwargs | None = None,
|
|
383
|
+
width: WidthWithoutContent = "stretch",
|
|
350
384
|
) -> str | None: ...
|
|
351
385
|
|
|
352
386
|
@overload
|
|
@@ -362,6 +396,7 @@ class ChatMixin:
|
|
|
362
396
|
on_submit: WidgetCallback | None = None,
|
|
363
397
|
args: WidgetArgs | None = None,
|
|
364
398
|
kwargs: WidgetKwargs | None = None,
|
|
399
|
+
width: WidthWithoutContent = "stretch",
|
|
365
400
|
) -> ChatInputValue | None: ...
|
|
366
401
|
|
|
367
402
|
@gather_metrics("chat_input")
|
|
@@ -377,6 +412,7 @@ class ChatMixin:
|
|
|
377
412
|
on_submit: WidgetCallback | None = None,
|
|
378
413
|
args: WidgetArgs | None = None,
|
|
379
414
|
kwargs: WidgetKwargs | None = None,
|
|
415
|
+
width: WidthWithoutContent = "stretch",
|
|
380
416
|
) -> str | ChatInputValue | None:
|
|
381
417
|
"""Display a chat input widget.
|
|
382
418
|
|
|
@@ -441,6 +477,17 @@ class ChatMixin:
|
|
|
441
477
|
kwargs : dict
|
|
442
478
|
An optional dict of kwargs to pass to the callback.
|
|
443
479
|
|
|
480
|
+
width : "stretch" or int
|
|
481
|
+
The width of the chat input widget. This can be one of the
|
|
482
|
+
following:
|
|
483
|
+
|
|
484
|
+
- ``"stretch"`` (default): The width of the widget matches the
|
|
485
|
+
width of the parent container.
|
|
486
|
+
- An integer specifying the width in pixels: The widget has a
|
|
487
|
+
fixed width. If the specified width is greater than the width of
|
|
488
|
+
the parent container, the width of the widget matches the width
|
|
489
|
+
of the parent container.
|
|
490
|
+
|
|
444
491
|
Returns
|
|
445
492
|
-------
|
|
446
493
|
None, str, or dict-like
|
|
@@ -560,10 +607,12 @@ class ChatMixin:
|
|
|
560
607
|
user_key=key,
|
|
561
608
|
# chat_input is not allowed to be used in a form.
|
|
562
609
|
form_id=None,
|
|
610
|
+
dg=self.dg,
|
|
563
611
|
placeholder=placeholder,
|
|
564
612
|
max_chars=max_chars,
|
|
565
613
|
accept_file=accept_file,
|
|
566
614
|
file_type=file_type,
|
|
615
|
+
width=width,
|
|
567
616
|
)
|
|
568
617
|
|
|
569
618
|
if file_type:
|
|
@@ -573,11 +622,10 @@ class ChatMixin:
|
|
|
573
622
|
# We throw an error to warn the user about this.
|
|
574
623
|
# We omit this check for scripts running outside streamlit, because
|
|
575
624
|
# they will have no script_run_ctx.
|
|
576
|
-
if runtime.exists():
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
)
|
|
625
|
+
if runtime.exists() and is_in_form(self.dg):
|
|
626
|
+
raise StreamlitAPIException(
|
|
627
|
+
"`st.chat_input()` can't be used in a `st.form()`."
|
|
628
|
+
)
|
|
581
629
|
|
|
582
630
|
# Determine the position of the chat input:
|
|
583
631
|
# Use bottom position if chat input is within the main container
|
|
@@ -623,6 +671,9 @@ class ChatMixin:
|
|
|
623
671
|
value_type="chat_input_value",
|
|
624
672
|
)
|
|
625
673
|
|
|
674
|
+
validate_width(width)
|
|
675
|
+
layout_config = LayoutConfig(width=width)
|
|
676
|
+
|
|
626
677
|
chat_input_proto.disabled = disabled
|
|
627
678
|
if widget_state.value_changed and widget_state.value is not None:
|
|
628
679
|
chat_input_proto.value = widget_state.value
|
|
@@ -634,10 +685,12 @@ class ChatMixin:
|
|
|
634
685
|
# We need to enqueue the chat input into the bottom container
|
|
635
686
|
# instead of the currently active dg.
|
|
636
687
|
get_dg_singleton_instance().bottom_dg._enqueue(
|
|
637
|
-
"chat_input", chat_input_proto
|
|
688
|
+
"chat_input", chat_input_proto, layout_config=layout_config
|
|
638
689
|
)
|
|
639
690
|
else:
|
|
640
|
-
self.dg._enqueue(
|
|
691
|
+
self.dg._enqueue(
|
|
692
|
+
"chat_input", chat_input_proto, layout_config=layout_config
|
|
693
|
+
)
|
|
641
694
|
|
|
642
695
|
return widget_state.value if not widget_state.value_changed else None
|
|
643
696
|
|
|
@@ -19,6 +19,11 @@ from textwrap import dedent
|
|
|
19
19
|
from typing import TYPE_CHECKING, cast
|
|
20
20
|
|
|
21
21
|
from streamlit.elements.lib.form_utils import current_form_id
|
|
22
|
+
from streamlit.elements.lib.layout_utils import (
|
|
23
|
+
LayoutConfig,
|
|
24
|
+
Width,
|
|
25
|
+
validate_width,
|
|
26
|
+
)
|
|
22
27
|
from streamlit.elements.lib.policies import (
|
|
23
28
|
check_widget_policies,
|
|
24
29
|
maybe_raise_label_warnings,
|
|
@@ -51,7 +56,7 @@ class CheckboxSerde:
|
|
|
51
56
|
def serialize(self, v: bool) -> bool:
|
|
52
57
|
return bool(v)
|
|
53
58
|
|
|
54
|
-
def deserialize(self, ui_value: bool | None
|
|
59
|
+
def deserialize(self, ui_value: bool | None) -> bool:
|
|
55
60
|
return bool(ui_value if ui_value is not None else self.value)
|
|
56
61
|
|
|
57
62
|
|
|
@@ -69,6 +74,7 @@ class CheckboxMixin:
|
|
|
69
74
|
*, # keyword-only arguments:
|
|
70
75
|
disabled: bool = False,
|
|
71
76
|
label_visibility: LabelVisibility = "visible",
|
|
77
|
+
width: Width = "content",
|
|
72
78
|
) -> bool:
|
|
73
79
|
r"""Display a checkbox widget.
|
|
74
80
|
|
|
@@ -130,9 +136,22 @@ class CheckboxMixin:
|
|
|
130
136
|
label_visibility : "visible", "hidden", or "collapsed"
|
|
131
137
|
The visibility of the label. The default is ``"visible"``. If this
|
|
132
138
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
133
|
-
label, which can help keep the widget
|
|
139
|
+
label, which can help keep the widget aligned with other widgets.
|
|
134
140
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
135
141
|
|
|
142
|
+
width : "content", "stretch", or int
|
|
143
|
+
The width of the checkbox widget. This can be one of the following:
|
|
144
|
+
|
|
145
|
+
- ``"content"`` (default): The width of the widget matches the
|
|
146
|
+
width of its content, but doesn't exceed the width of the parent
|
|
147
|
+
container.
|
|
148
|
+
- ``"stretch"``: The width of the widget matches the width of the
|
|
149
|
+
parent container.
|
|
150
|
+
- An integer specifying the width in pixels: The widget has a
|
|
151
|
+
fixed width. If the specified width is greater than the width of
|
|
152
|
+
the parent container, the width of the widget matches the width
|
|
153
|
+
of the parent container.
|
|
154
|
+
|
|
136
155
|
Returns
|
|
137
156
|
-------
|
|
138
157
|
bool
|
|
@@ -165,6 +184,7 @@ class CheckboxMixin:
|
|
|
165
184
|
label_visibility=label_visibility,
|
|
166
185
|
type=CheckboxProto.StyleType.DEFAULT,
|
|
167
186
|
ctx=ctx,
|
|
187
|
+
width=width,
|
|
168
188
|
)
|
|
169
189
|
|
|
170
190
|
@gather_metrics("toggle")
|
|
@@ -180,6 +200,7 @@ class CheckboxMixin:
|
|
|
180
200
|
*, # keyword-only arguments:
|
|
181
201
|
disabled: bool = False,
|
|
182
202
|
label_visibility: LabelVisibility = "visible",
|
|
203
|
+
width: Width = "content",
|
|
183
204
|
) -> bool:
|
|
184
205
|
r"""Display a toggle widget.
|
|
185
206
|
|
|
@@ -241,9 +262,22 @@ class CheckboxMixin:
|
|
|
241
262
|
label_visibility : "visible", "hidden", or "collapsed"
|
|
242
263
|
The visibility of the label. The default is ``"visible"``. If this
|
|
243
264
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
244
|
-
label, which can help keep the widget
|
|
265
|
+
label, which can help keep the widget aligned with other widgets.
|
|
245
266
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
246
267
|
|
|
268
|
+
width : "content", "stretch", or int
|
|
269
|
+
The width of the toggle widget. This can be one of the following:
|
|
270
|
+
|
|
271
|
+
- ``"content"`` (default): The width of the widget matches the
|
|
272
|
+
width of its content, but doesn't exceed the width of the parent
|
|
273
|
+
container.
|
|
274
|
+
- ``"stretch"``: The width of the widget matches the width of the
|
|
275
|
+
parent container.
|
|
276
|
+
- An integer specifying the width in pixels: The widget has a
|
|
277
|
+
fixed width. If the specified width is greater than the width of
|
|
278
|
+
the parent container, the width of the widget matches the width
|
|
279
|
+
of the parent container.
|
|
280
|
+
|
|
247
281
|
Returns
|
|
248
282
|
-------
|
|
249
283
|
bool
|
|
@@ -276,6 +310,7 @@ class CheckboxMixin:
|
|
|
276
310
|
label_visibility=label_visibility,
|
|
277
311
|
type=CheckboxProto.StyleType.TOGGLE,
|
|
278
312
|
ctx=ctx,
|
|
313
|
+
width=width,
|
|
279
314
|
)
|
|
280
315
|
|
|
281
316
|
def _checkbox(
|
|
@@ -292,6 +327,7 @@ class CheckboxMixin:
|
|
|
292
327
|
label_visibility: LabelVisibility = "visible",
|
|
293
328
|
type: CheckboxProto.StyleType.ValueType = CheckboxProto.StyleType.DEFAULT,
|
|
294
329
|
ctx: ScriptRunContext | None = None,
|
|
330
|
+
width: Width = "content",
|
|
295
331
|
) -> bool:
|
|
296
332
|
key = to_key(key)
|
|
297
333
|
|
|
@@ -307,9 +343,11 @@ class CheckboxMixin:
|
|
|
307
343
|
"toggle" if type == CheckboxProto.StyleType.TOGGLE else "checkbox",
|
|
308
344
|
user_key=key,
|
|
309
345
|
form_id=current_form_id(self.dg),
|
|
346
|
+
dg=self.dg,
|
|
310
347
|
label=label,
|
|
311
348
|
value=bool(value),
|
|
312
349
|
help=help,
|
|
350
|
+
width=width,
|
|
313
351
|
)
|
|
314
352
|
|
|
315
353
|
checkbox_proto = CheckboxProto()
|
|
@@ -326,6 +364,9 @@ class CheckboxMixin:
|
|
|
326
364
|
if help is not None:
|
|
327
365
|
checkbox_proto.help = dedent(help)
|
|
328
366
|
|
|
367
|
+
validate_width(width, allow_content=True)
|
|
368
|
+
layout_config = LayoutConfig(width=width)
|
|
369
|
+
|
|
329
370
|
serde = CheckboxSerde(value)
|
|
330
371
|
|
|
331
372
|
checkbox_state = register_widget(
|
|
@@ -343,7 +384,7 @@ class CheckboxMixin:
|
|
|
343
384
|
checkbox_proto.value = checkbox_state.value
|
|
344
385
|
checkbox_proto.set_value = True
|
|
345
386
|
|
|
346
|
-
self.dg._enqueue("checkbox", checkbox_proto)
|
|
387
|
+
self.dg._enqueue("checkbox", checkbox_proto, layout_config=layout_config)
|
|
347
388
|
return checkbox_state.value
|
|
348
389
|
|
|
349
390
|
@property
|