streamlit 1.45.1__py3-none-any.whl → 1.46.1__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/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 +53 -29
- 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.DU9IrB3M.js → ErrorOutline.esm.DitPpe1Y.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.P9rKwKo8.js → FileDownload.esm.AI3watX9.js} +1 -1
- streamlit/static/static/js/{FileHelper.D7RMkx0e.js → FileHelper.kt7mhnu8.js} +5 -5
- streamlit/static/static/js/{FormClearHelper.B67tgll0.js → FormClearHelper.D1M9GM_c.js} +1 -1
- streamlit/static/static/js/{Hooks.ncTJktu9.js → Hooks.BGwHKeUc.js} +1 -1
- streamlit/static/static/js/{InputInstructions.D-Y8geDN.js → InputInstructions.DaZ89mzH.js} +1 -1
- streamlit/static/static/js/{ProgressBar.B-kexwwD.js → ProgressBar.C0zPMe-p.js} +2 -2
- streamlit/static/static/js/{RenderInPortalIfExists.BgaoZgep.js → RenderInPortalIfExists.Ox8gQvdz.js} +1 -1
- streamlit/static/static/js/Toolbar.KhlcEc0K.js +1 -0
- streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
- streamlit/static/static/js/{base-input.BoAa1U94.js → base-input.BJ4qsfSq.js} +4 -4
- streamlit/static/static/js/{checkbox.Z6iSfe5F.js → checkbox.DSDh78Xz.js} +2 -2
- streamlit/static/static/js/{createSuper.B4oGDYRm.js → createSuper.wQ9SIXEJ.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.msYws2Ou.js → data-grid-overlay-editor.DvbdPJ15.js} +1 -1
- streamlit/static/static/js/{downloader.kc14n2Hv.js → downloader.CD9rzih5.js} +1 -1
- streamlit/static/static/js/{es6.CxQz807-.js → es6.48Q9Qjgb.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.B19u0ONI.js → iframeResizer.contentWindow.CKdem3Bn.js} +1 -1
- streamlit/static/static/js/{index.LaIasviC.js → index.6md5Qhod.js} +1 -1
- streamlit/static/static/js/index.7hy6AeJ1.js +1 -0
- streamlit/static/static/js/index.B4CGJiBW.js +1 -0
- streamlit/static/static/js/index.B8oW0ZTD.js +1 -0
- streamlit/static/static/js/index.BU6RnlHI.js +73 -0
- streamlit/static/static/js/index.BUq9Wcf8.js +197 -0
- streamlit/static/static/js/{index.BFz9U2y0.js → index.BXXo-Yoj.js} +1 -1
- streamlit/static/static/js/index.Bae9H0OS.js +1 -0
- streamlit/static/static/js/{index.-5ruC9At.js → index.BhTl2Uyb.js} +1 -1
- streamlit/static/static/js/{index.BpILzHf_.js → index.BiSaCB1o.js} +20 -20
- streamlit/static/static/js/{index.xNQq3Ei5.js → index.BulSAJ9z.js} +1 -1
- streamlit/static/static/js/{index.9V1KdxfP.js → index.Bv-EuTKR.js} +1 -1
- streamlit/static/static/js/index.BvMLYCHi.js +1 -0
- streamlit/static/static/js/index.C1NIn1Y2.js +783 -0
- streamlit/static/static/js/index.CP-fthOJ.js +2 -0
- streamlit/static/static/js/{index.BoigZiu7.js → index.CS9guO3p.js} +1 -1
- streamlit/static/static/js/index.CYTBHth8.js +1 -0
- streamlit/static/static/js/{index.CmTAF0dM.js → index.CcJufcuD.js} +1 -1
- streamlit/static/static/js/index.CnENU1yn.js +1 -0
- streamlit/static/static/js/index.Cns13qBb.js +1 -0
- streamlit/static/static/js/index.Ct_xXq7w.js +1 -0
- streamlit/static/static/js/{index.BqfdT8-Q.js → index.CxGSemHL.js} +1 -1
- streamlit/static/static/js/index.D5S0ldVb.js +1 -0
- streamlit/static/static/js/index.D72B_ksb.js +2 -0
- streamlit/static/static/js/index.DI4yZ27M.js +1 -0
- streamlit/static/static/js/index.DN51vLxR.js +1 -0
- streamlit/static/static/js/index.DRtq5dka.js +1 -0
- streamlit/static/static/js/{index.BHXxWdde.js → index.DX-oiXlb.js} +1 -1
- streamlit/static/static/js/index.DlFE4_Aq.js +12 -0
- streamlit/static/static/js/{index.BHGGDa8K.js → index.J7BJwXOi.js} +2 -2
- streamlit/static/static/js/index.Jg38kJPP.js +1 -0
- streamlit/static/static/js/index.JhIO6abf.js +3 -0
- streamlit/static/static/js/{index.DeB9iKFW.js → index.NkRcWwc5.js} +255 -255
- streamlit/static/static/js/{index.BGga-hcS.js → index.prekPLrm.js} +25 -25
- streamlit/static/static/js/{index.BRXmLIsC.js → index.wyzngKUE.js} +1 -1
- streamlit/static/static/js/index.xW7mVdI8.js +1 -0
- streamlit/static/static/js/index.yk07dYGx.js +1 -0
- streamlit/static/static/js/{input.DsCfafm0.js → input.CxKZ5Wrc.js} +2 -2
- streamlit/static/static/js/{memory.nY_lMTtu.js → memory.DeZ9VUvl.js} +1 -1
- streamlit/static/static/js/{mergeWith.B_7zmsM4.js → mergeWith.CVkhrWUb.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.CSeVhHRU.js → number-overlay-editor.Bpkm3nTq.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.nNhsvgRd.js → possibleConstructorReturn.CIDCId52.js} +1 -1
- streamlit/static/static/js/{sandbox.Cgm3iuL6.js → sandbox.TrkMaokR.js} +1 -1
- streamlit/static/static/js/{textarea.BR8rlyih.js → textarea.QKjxR64N.js} +2 -2
- streamlit/static/static/js/{timepicker.w4XhAenH.js → timepicker.DJYmE1dK.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.CgkEPBwD.js → toConsumableArray.BZoworE-.js} +1 -1
- streamlit/static/static/js/{uniqueId.j-1rlNNH.js → uniqueId.O0UbJ2Bu.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.zXY9CjFS.js → useBasicWidgetState.Ci89jaH5.js} +1 -1
- streamlit/static/static/js/useOnInputChange.Cxh6ExEn.js +1 -0
- streamlit/static/static/js/{withFullScreenWrapper.Ov13692o.js → withFullScreenWrapper.iW37lS8Z.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 +21 -2
- 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 +13 -24
- streamlit/web/server/server_util.py +43 -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.1.dist-info → streamlit-1.46.1.dist-info}/METADATA +4 -4
- streamlit-1.46.1.dist-info/RECORD +559 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/WHEEL +1 -1
- streamlit/elements/lib/event_utils.py +0 -39
- streamlit/static/static/js/Toolbar.D9RUZv9G.js +0 -1
- streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
- streamlit/static/static/js/index.8jhZBWF2.js +0 -3
- streamlit/static/static/js/index.BCx3C6e_.js +0 -1
- streamlit/static/static/js/index.BRuTz_S4.js +0 -1
- streamlit/static/static/js/index.Bcru_ti-.js +0 -1
- streamlit/static/static/js/index.Bl1FMJRd.js +0 -1
- streamlit/static/static/js/index.C1z8KpLA.js +0 -779
- streamlit/static/static/js/index.C32I2PUe.js +0 -2
- streamlit/static/static/js/index.C5GnDRB7.js +0 -1
- streamlit/static/static/js/index.CG4qPaaW.js +0 -2
- streamlit/static/static/js/index.C_msmT1u.js +0 -1
- streamlit/static/static/js/index.CbeNTdd6.js +0 -1
- streamlit/static/static/js/index.CnGQVJcw.js +0 -12
- streamlit/static/static/js/index.CopVVq4l.js +0 -1
- streamlit/static/static/js/index.CtXupx4d.js +0 -197
- streamlit/static/static/js/index.DGmCchO7.js +0 -1
- streamlit/static/static/js/index.DH6zBk0e.js +0 -1
- streamlit/static/static/js/index.DHVlVWsm.js +0 -1
- streamlit/static/static/js/index.DRKIVBoi.js +0 -1
- streamlit/static/static/js/index.DUd-lFXx.js +0 -73
- streamlit/static/static/js/index.D_uRBA4B.js +0 -1
- streamlit/static/static/js/index.QHNfgPJd.js +0 -1
- streamlit/static/static/js/index.a-RJocYL.js +0 -1
- streamlit/static/static/js/index.cvz4B1gy.js +0 -1
- streamlit/static/static/js/index.t--hEgTQ.js +0 -6
- streamlit/static/static/js/useOnInputChange.z04u96A8.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.1.dist-info/RECORD +0 -568
- {streamlit-1.45.1.data → streamlit-1.46.1.data}/scripts/streamlit.cmd +0 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/entry_points.txt +0 -0
- {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/top_level.txt +0 -0
|
@@ -23,6 +23,11 @@ from typing_extensions import TypeAlias
|
|
|
23
23
|
|
|
24
24
|
from streamlit.elements.lib.form_utils import current_form_id
|
|
25
25
|
from streamlit.elements.lib.js_number import JSNumber, JSNumberBoundsException
|
|
26
|
+
from streamlit.elements.lib.layout_utils import (
|
|
27
|
+
LayoutConfig,
|
|
28
|
+
WidthWithoutContent,
|
|
29
|
+
validate_width,
|
|
30
|
+
)
|
|
26
31
|
from streamlit.elements.lib.policies import (
|
|
27
32
|
check_widget_policies,
|
|
28
33
|
maybe_raise_label_warnings,
|
|
@@ -70,9 +75,7 @@ class NumberInputSerde:
|
|
|
70
75
|
def serialize(self, v: Number | None) -> Number | None:
|
|
71
76
|
return v
|
|
72
77
|
|
|
73
|
-
def deserialize(
|
|
74
|
-
self, ui_value: Number | None, widget_id: str = ""
|
|
75
|
-
) -> Number | None:
|
|
78
|
+
def deserialize(self, ui_value: Number | None) -> Number | None:
|
|
76
79
|
val: Number | None = ui_value if ui_value is not None else self.value
|
|
77
80
|
|
|
78
81
|
if val is not None and self.data_type == NumberInputProto.INT:
|
|
@@ -82,10 +85,6 @@ class NumberInputSerde:
|
|
|
82
85
|
|
|
83
86
|
|
|
84
87
|
class NumberInputMixin:
|
|
85
|
-
# For easier readability, all the arguments with un-changing types across these overload signatures have been
|
|
86
|
-
# collapsed onto a single line.
|
|
87
|
-
|
|
88
|
-
# fmt: off
|
|
89
88
|
# If "min_value: int" is given and all other numerical inputs are
|
|
90
89
|
# "int"s or not provided (value optionally being "min"), return "int"
|
|
91
90
|
# If "min_value: int, value: None" is given and all other numerical inputs
|
|
@@ -98,9 +97,19 @@ class NumberInputMixin:
|
|
|
98
97
|
max_value: int | None = None,
|
|
99
98
|
value: IntOrNone | Literal["min"] = "min",
|
|
100
99
|
step: int | None = None,
|
|
101
|
-
format: str | None = None,
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
format: str | None = None,
|
|
101
|
+
key: Key | None = None,
|
|
102
|
+
help: str | None = None,
|
|
103
|
+
on_change: WidgetCallback | None = None,
|
|
104
|
+
args: WidgetArgs | None = None,
|
|
105
|
+
kwargs: WidgetKwargs | None = None,
|
|
106
|
+
*,
|
|
107
|
+
placeholder: str | None = None,
|
|
108
|
+
disabled: bool = False,
|
|
109
|
+
label_visibility: LabelVisibility = "visible",
|
|
110
|
+
icon: str | None = None,
|
|
111
|
+
width: WidthWithoutContent = "stretch",
|
|
112
|
+
) -> int | IntOrNone: ...
|
|
104
113
|
|
|
105
114
|
# If "max_value: int" is given and all other numerical inputs are
|
|
106
115
|
# "int"s or not provided (value optionally being "min"), return "int"
|
|
@@ -110,14 +119,23 @@ class NumberInputMixin:
|
|
|
110
119
|
def number_input(
|
|
111
120
|
self,
|
|
112
121
|
label: str,
|
|
113
|
-
min_value:
|
|
122
|
+
min_value: None = None,
|
|
114
123
|
*,
|
|
115
124
|
max_value: int,
|
|
116
125
|
value: IntOrNone | Literal["min"] = "min",
|
|
117
126
|
step: int | None = None,
|
|
118
|
-
format: str | None = None,
|
|
119
|
-
|
|
120
|
-
|
|
127
|
+
format: str | None = None,
|
|
128
|
+
key: Key | None = None,
|
|
129
|
+
help: str | None = None,
|
|
130
|
+
on_change: WidgetCallback | None = None,
|
|
131
|
+
args: WidgetArgs | None = None,
|
|
132
|
+
kwargs: WidgetKwargs | None = None,
|
|
133
|
+
placeholder: str | None = None,
|
|
134
|
+
disabled: bool = False,
|
|
135
|
+
label_visibility: LabelVisibility = "visible",
|
|
136
|
+
icon: str | None = None,
|
|
137
|
+
width: WidthWithoutContent = "stretch",
|
|
138
|
+
) -> int | IntOrNone: ...
|
|
121
139
|
|
|
122
140
|
# If "value=int" is given and all other numerical inputs are "int"s
|
|
123
141
|
# or not provided, return "int"
|
|
@@ -130,9 +148,18 @@ class NumberInputMixin:
|
|
|
130
148
|
*,
|
|
131
149
|
value: int,
|
|
132
150
|
step: int | None = None,
|
|
133
|
-
format: str | None = None,
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
format: str | None = None,
|
|
152
|
+
key: Key | None = None,
|
|
153
|
+
help: str | None = None,
|
|
154
|
+
on_change: WidgetCallback | None = None,
|
|
155
|
+
args: WidgetArgs | None = None,
|
|
156
|
+
kwargs: WidgetKwargs | None = None,
|
|
157
|
+
placeholder: str | None = None,
|
|
158
|
+
disabled: bool = False,
|
|
159
|
+
label_visibility: LabelVisibility = "visible",
|
|
160
|
+
icon: str | None = None,
|
|
161
|
+
width: WidthWithoutContent = "stretch",
|
|
162
|
+
) -> int: ...
|
|
136
163
|
|
|
137
164
|
# If "step=int" is given and all other numerical inputs are "int"s
|
|
138
165
|
# or not provided (value optionally being "min"), return "int"
|
|
@@ -142,14 +169,23 @@ class NumberInputMixin:
|
|
|
142
169
|
def number_input(
|
|
143
170
|
self,
|
|
144
171
|
label: str,
|
|
145
|
-
min_value:
|
|
146
|
-
max_value:
|
|
172
|
+
min_value: None = None,
|
|
173
|
+
max_value: None = None,
|
|
147
174
|
value: IntOrNone | Literal["min"] = "min",
|
|
148
175
|
*,
|
|
149
176
|
step: int,
|
|
150
|
-
format: str | None = None,
|
|
151
|
-
|
|
152
|
-
|
|
177
|
+
format: str | None = None,
|
|
178
|
+
key: Key | None = None,
|
|
179
|
+
help: str | None = None,
|
|
180
|
+
on_change: WidgetCallback | None = None,
|
|
181
|
+
args: WidgetArgs | None = None,
|
|
182
|
+
kwargs: WidgetKwargs | None = None,
|
|
183
|
+
placeholder: str | None = None,
|
|
184
|
+
disabled: bool = False,
|
|
185
|
+
label_visibility: LabelVisibility = "visible",
|
|
186
|
+
icon: str | None = None,
|
|
187
|
+
width: WidthWithoutContent = "stretch",
|
|
188
|
+
) -> int | IntOrNone: ...
|
|
153
189
|
|
|
154
190
|
# If all numerical inputs are floats (with value optionally being "min")
|
|
155
191
|
# or are not provided, return "float"
|
|
@@ -163,10 +199,19 @@ class NumberInputMixin:
|
|
|
163
199
|
max_value: float | None = None,
|
|
164
200
|
value: FloatOrNone | Literal["min"] = "min",
|
|
165
201
|
step: float | None = None,
|
|
166
|
-
format: str | None = None,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
202
|
+
format: str | None = None,
|
|
203
|
+
key: Key | None = None,
|
|
204
|
+
help: str | None = None,
|
|
205
|
+
on_change: WidgetCallback | None = None,
|
|
206
|
+
args: WidgetArgs | None = None,
|
|
207
|
+
kwargs: WidgetKwargs | None = None,
|
|
208
|
+
*,
|
|
209
|
+
placeholder: str | None = None,
|
|
210
|
+
disabled: bool = False,
|
|
211
|
+
label_visibility: LabelVisibility = "visible",
|
|
212
|
+
icon: str | None = None,
|
|
213
|
+
width: WidthWithoutContent = "stretch",
|
|
214
|
+
) -> float | FloatOrNone: ...
|
|
170
215
|
|
|
171
216
|
@gather_metrics("number_input")
|
|
172
217
|
def number_input(
|
|
@@ -187,12 +232,13 @@ class NumberInputMixin:
|
|
|
187
232
|
disabled: bool = False,
|
|
188
233
|
label_visibility: LabelVisibility = "visible",
|
|
189
234
|
icon: str | None = None,
|
|
235
|
+
width: WidthWithoutContent = "stretch",
|
|
190
236
|
) -> Number | None:
|
|
191
237
|
r"""Display a numeric input widget.
|
|
192
238
|
|
|
193
239
|
.. note::
|
|
194
240
|
Integer values exceeding +/- ``(1<<53) - 1`` cannot be accurately
|
|
195
|
-
stored or returned by the widget due to serialization
|
|
241
|
+
stored or returned by the widget due to serialization constraints
|
|
196
242
|
between the Python server and JavaScript client. You must handle
|
|
197
243
|
such numbers as floats, leading to a loss in precision.
|
|
198
244
|
|
|
@@ -288,7 +334,7 @@ class NumberInputMixin:
|
|
|
288
334
|
label_visibility : "visible", "hidden", or "collapsed"
|
|
289
335
|
The visibility of the label. The default is ``"visible"``. If this
|
|
290
336
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
291
|
-
label, which can help keep the widget
|
|
337
|
+
label, which can help keep the widget aligned with other widgets.
|
|
292
338
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
293
339
|
|
|
294
340
|
icon : str, None
|
|
@@ -309,6 +355,17 @@ class NumberInputMixin:
|
|
|
309
355
|
<https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
|
|
310
356
|
font library.
|
|
311
357
|
|
|
358
|
+
width : "stretch" or int
|
|
359
|
+
The width of the number input widget. This can be one of the
|
|
360
|
+
following:
|
|
361
|
+
|
|
362
|
+
- ``"stretch"`` (default): The width of the widget matches the
|
|
363
|
+
width of the parent container.
|
|
364
|
+
- An integer specifying the width in pixels: The widget has a
|
|
365
|
+
fixed width. If the specified width is greater than the width of
|
|
366
|
+
the parent container, the width of the widget matches the width
|
|
367
|
+
of the parent container.
|
|
368
|
+
|
|
312
369
|
Returns
|
|
313
370
|
-------
|
|
314
371
|
int or float or None
|
|
@@ -357,6 +414,7 @@ class NumberInputMixin:
|
|
|
357
414
|
disabled=disabled,
|
|
358
415
|
label_visibility=label_visibility,
|
|
359
416
|
icon=icon,
|
|
417
|
+
width=width,
|
|
360
418
|
ctx=ctx,
|
|
361
419
|
)
|
|
362
420
|
|
|
@@ -378,6 +436,7 @@ class NumberInputMixin:
|
|
|
378
436
|
disabled: bool = False,
|
|
379
437
|
label_visibility: LabelVisibility = "visible",
|
|
380
438
|
icon: str | None = None,
|
|
439
|
+
width: WidthWithoutContent = "stretch",
|
|
381
440
|
ctx: ScriptRunContext | None = None,
|
|
382
441
|
) -> Number | None:
|
|
383
442
|
key = to_key(key)
|
|
@@ -394,6 +453,7 @@ class NumberInputMixin:
|
|
|
394
453
|
"number_input",
|
|
395
454
|
user_key=key,
|
|
396
455
|
form_id=current_form_id(self.dg),
|
|
456
|
+
dg=self.dg,
|
|
397
457
|
label=label,
|
|
398
458
|
min_value=min_value,
|
|
399
459
|
max_value=max_value,
|
|
@@ -403,6 +463,7 @@ class NumberInputMixin:
|
|
|
403
463
|
help=help,
|
|
404
464
|
placeholder=None if placeholder is None else str(placeholder),
|
|
405
465
|
icon=icon,
|
|
466
|
+
width=width,
|
|
406
467
|
)
|
|
407
468
|
|
|
408
469
|
# Ensure that all arguments are of the same type.
|
|
@@ -418,7 +479,9 @@ class NumberInputMixin:
|
|
|
418
479
|
)
|
|
419
480
|
|
|
420
481
|
if not all_int_args and not all_float_args:
|
|
421
|
-
raise StreamlitMixedNumericTypesError(
|
|
482
|
+
raise StreamlitMixedNumericTypesError(
|
|
483
|
+
value=value, min_value=min_value, max_value=max_value, step=step
|
|
484
|
+
)
|
|
422
485
|
|
|
423
486
|
session_state = get_session_state().filtered_state
|
|
424
487
|
if key is not None and key in session_state and session_state[key] is None:
|
|
@@ -445,33 +508,32 @@ class NumberInputMixin:
|
|
|
445
508
|
# Otherwise, defaults to float:
|
|
446
509
|
float_value = True
|
|
447
510
|
|
|
448
|
-
if format
|
|
449
|
-
|
|
511
|
+
# Use default format depending on value type if format was not provided:
|
|
512
|
+
number_format = ("%d" if int_value else "%0.2f") if format is None else format
|
|
450
513
|
|
|
451
514
|
# Warn user if they format an int type as a float or vice versa.
|
|
452
|
-
if
|
|
515
|
+
if number_format in ["%d", "%u", "%i"] and float_value:
|
|
453
516
|
import streamlit as st
|
|
454
517
|
|
|
455
518
|
st.warning(
|
|
456
519
|
"Warning: NumberInput value below has type float,"
|
|
457
|
-
f" but format {
|
|
520
|
+
f" but format {number_format} displays as integer."
|
|
458
521
|
)
|
|
459
|
-
elif
|
|
522
|
+
elif number_format[-1] == "f" and int_value:
|
|
460
523
|
import streamlit as st
|
|
461
524
|
|
|
462
525
|
st.warning(
|
|
463
526
|
"Warning: NumberInput value below has type int so is"
|
|
464
|
-
f" displayed as int despite format string {
|
|
527
|
+
f" displayed as int despite format string {number_format}."
|
|
465
528
|
)
|
|
466
529
|
|
|
467
530
|
if step is None:
|
|
468
531
|
step = 1 if int_value else 0.01
|
|
469
532
|
|
|
470
533
|
try:
|
|
471
|
-
float(
|
|
534
|
+
float(number_format % 2)
|
|
472
535
|
except (TypeError, ValueError):
|
|
473
|
-
raise StreamlitInvalidNumberFormatError(
|
|
474
|
-
|
|
536
|
+
raise StreamlitInvalidNumberFormatError(number_format)
|
|
475
537
|
|
|
476
538
|
# Ensure that the value matches arguments' types.
|
|
477
539
|
all_ints = int_value and all_int_args
|
|
@@ -549,8 +611,7 @@ class NumberInputMixin:
|
|
|
549
611
|
if step is not None:
|
|
550
612
|
number_input_proto.step = step
|
|
551
613
|
|
|
552
|
-
|
|
553
|
-
number_input_proto.format = format
|
|
614
|
+
number_input_proto.format = number_format
|
|
554
615
|
|
|
555
616
|
if icon is not None:
|
|
556
617
|
number_input_proto.icon = validate_icon_or_emoji(icon)
|
|
@@ -564,22 +625,37 @@ class NumberInputMixin:
|
|
|
564
625
|
deserializer=serde.deserialize,
|
|
565
626
|
serializer=serde.serialize,
|
|
566
627
|
ctx=ctx,
|
|
567
|
-
value_type="double_value"
|
|
628
|
+
value_type="double_value",
|
|
568
629
|
)
|
|
569
630
|
|
|
570
631
|
if widget_state.value_changed:
|
|
571
632
|
if widget_state.value is not None:
|
|
572
633
|
# Min/Max bounds checks when the value is updated.
|
|
573
|
-
if
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
raise
|
|
634
|
+
if (
|
|
635
|
+
number_input_proto.has_min
|
|
636
|
+
and widget_state.value < number_input_proto.min
|
|
637
|
+
):
|
|
638
|
+
raise StreamlitValueBelowMinError(
|
|
639
|
+
value=widget_state.value, min_value=number_input_proto.min
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
if (
|
|
643
|
+
number_input_proto.has_max
|
|
644
|
+
and widget_state.value > number_input_proto.max
|
|
645
|
+
):
|
|
646
|
+
raise StreamlitValueAboveMaxError(
|
|
647
|
+
value=widget_state.value, max_value=number_input_proto.max
|
|
648
|
+
)
|
|
578
649
|
|
|
579
650
|
number_input_proto.value = widget_state.value
|
|
580
651
|
number_input_proto.set_value = True
|
|
581
652
|
|
|
582
|
-
|
|
653
|
+
validate_width(width)
|
|
654
|
+
layout_config = LayoutConfig(width=width)
|
|
655
|
+
|
|
656
|
+
self.dg._enqueue(
|
|
657
|
+
"number_input", number_input_proto, layout_config=layout_config
|
|
658
|
+
)
|
|
583
659
|
return widget_state.value
|
|
584
660
|
|
|
585
661
|
@property
|
|
@@ -18,8 +18,15 @@ from dataclasses import dataclass
|
|
|
18
18
|
from textwrap import dedent
|
|
19
19
|
from typing import TYPE_CHECKING, Any, Callable, Generic, cast, overload
|
|
20
20
|
|
|
21
|
+
from typing_extensions import Never
|
|
22
|
+
|
|
21
23
|
from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
|
|
22
24
|
from streamlit.elements.lib.form_utils import current_form_id
|
|
25
|
+
from streamlit.elements.lib.layout_utils import (
|
|
26
|
+
LayoutConfig,
|
|
27
|
+
Width,
|
|
28
|
+
validate_width,
|
|
29
|
+
)
|
|
23
30
|
from streamlit.elements.lib.options_selector_utils import index_, maybe_coerce_enum
|
|
24
31
|
from streamlit.elements.lib.policies import (
|
|
25
32
|
check_widget_policies,
|
|
@@ -66,11 +73,7 @@ class RadioSerde(Generic[T]):
|
|
|
66
73
|
|
|
67
74
|
return 0 if len(self.options) == 0 else index_(self.options, v)
|
|
68
75
|
|
|
69
|
-
def deserialize(
|
|
70
|
-
self,
|
|
71
|
-
ui_value: int | None,
|
|
72
|
-
widget_id: str = "",
|
|
73
|
-
) -> T | None:
|
|
76
|
+
def deserialize(self, ui_value: int | None) -> T | None:
|
|
74
77
|
idx = ui_value if ui_value is not None else self.index
|
|
75
78
|
|
|
76
79
|
return (
|
|
@@ -83,6 +86,26 @@ class RadioSerde(Generic[T]):
|
|
|
83
86
|
|
|
84
87
|
|
|
85
88
|
class RadioMixin:
|
|
89
|
+
@overload
|
|
90
|
+
def radio(
|
|
91
|
+
self,
|
|
92
|
+
label: str,
|
|
93
|
+
options: Sequence[Never],
|
|
94
|
+
index: int = 0,
|
|
95
|
+
format_func: Callable[[Any], Any] = str,
|
|
96
|
+
key: Key | None = None,
|
|
97
|
+
help: str | None = None,
|
|
98
|
+
on_change: WidgetCallback | None = None,
|
|
99
|
+
args: WidgetArgs | None = None,
|
|
100
|
+
kwargs: WidgetKwargs | None = None,
|
|
101
|
+
*, # keyword-only args:
|
|
102
|
+
disabled: bool = False,
|
|
103
|
+
horizontal: bool = False,
|
|
104
|
+
captions: Sequence[str] | None = None,
|
|
105
|
+
label_visibility: LabelVisibility = "visible",
|
|
106
|
+
width: Width = "content",
|
|
107
|
+
) -> None: ...
|
|
108
|
+
|
|
86
109
|
@overload
|
|
87
110
|
def radio(
|
|
88
111
|
self,
|
|
@@ -100,6 +123,7 @@ class RadioMixin:
|
|
|
100
123
|
horizontal: bool = False,
|
|
101
124
|
captions: Sequence[str] | None = None,
|
|
102
125
|
label_visibility: LabelVisibility = "visible",
|
|
126
|
+
width: Width = "content",
|
|
103
127
|
) -> T: ...
|
|
104
128
|
|
|
105
129
|
@overload
|
|
@@ -119,6 +143,7 @@ class RadioMixin:
|
|
|
119
143
|
horizontal: bool = False,
|
|
120
144
|
captions: Sequence[str] | None = None,
|
|
121
145
|
label_visibility: LabelVisibility = "visible",
|
|
146
|
+
width: Width = "content",
|
|
122
147
|
) -> T | None: ...
|
|
123
148
|
|
|
124
149
|
@gather_metrics("radio")
|
|
@@ -138,6 +163,7 @@ class RadioMixin:
|
|
|
138
163
|
horizontal: bool = False,
|
|
139
164
|
captions: Sequence[str] | None = None,
|
|
140
165
|
label_visibility: LabelVisibility = "visible",
|
|
166
|
+
width: Width = "content",
|
|
141
167
|
) -> T | None:
|
|
142
168
|
r"""Display a radio button widget.
|
|
143
169
|
|
|
@@ -223,9 +249,23 @@ class RadioMixin:
|
|
|
223
249
|
label_visibility : "visible", "hidden", or "collapsed"
|
|
224
250
|
The visibility of the label. The default is ``"visible"``. If this
|
|
225
251
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
226
|
-
label, which can help keep the widget
|
|
252
|
+
label, which can help keep the widget aligned with other widgets.
|
|
227
253
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
228
254
|
|
|
255
|
+
width : "content", "stretch", or int
|
|
256
|
+
The width of the radio button widget. This can be one of the
|
|
257
|
+
following:
|
|
258
|
+
|
|
259
|
+
- ``"content"`` (default): The width of the widget matches the
|
|
260
|
+
width of its content, but doesn't exceed the width of the parent
|
|
261
|
+
container.
|
|
262
|
+
- ``"stretch"``: The width of the widget matches the width of the
|
|
263
|
+
parent container.
|
|
264
|
+
- An integer specifying the width in pixels: The widget has a
|
|
265
|
+
fixed width. If the specified width is greater than the width of
|
|
266
|
+
the parent container, the width of the widget matches the width
|
|
267
|
+
of the parent container.
|
|
268
|
+
|
|
229
269
|
Returns
|
|
230
270
|
-------
|
|
231
271
|
any
|
|
@@ -287,6 +327,7 @@ class RadioMixin:
|
|
|
287
327
|
captions=captions,
|
|
288
328
|
label_visibility=label_visibility,
|
|
289
329
|
ctx=ctx,
|
|
330
|
+
width=width,
|
|
290
331
|
)
|
|
291
332
|
|
|
292
333
|
def _radio(
|
|
@@ -306,6 +347,7 @@ class RadioMixin:
|
|
|
306
347
|
label_visibility: LabelVisibility = "visible",
|
|
307
348
|
captions: Sequence[str] | None = None,
|
|
308
349
|
ctx: ScriptRunContext | None,
|
|
350
|
+
width: Width = "content",
|
|
309
351
|
) -> T | None:
|
|
310
352
|
key = to_key(key)
|
|
311
353
|
|
|
@@ -317,6 +359,9 @@ class RadioMixin:
|
|
|
317
359
|
)
|
|
318
360
|
maybe_raise_label_warnings(label, label_visibility)
|
|
319
361
|
|
|
362
|
+
validate_width(width, allow_content=True)
|
|
363
|
+
layout_config = LayoutConfig(width=width)
|
|
364
|
+
|
|
320
365
|
opt = convert_anything_to_list(options)
|
|
321
366
|
check_python_comparable(opt)
|
|
322
367
|
|
|
@@ -324,17 +369,19 @@ class RadioMixin:
|
|
|
324
369
|
"radio",
|
|
325
370
|
user_key=key,
|
|
326
371
|
form_id=current_form_id(self.dg),
|
|
372
|
+
dg=self.dg,
|
|
327
373
|
label=label,
|
|
328
374
|
options=[str(format_func(option)) for option in opt],
|
|
329
375
|
index=index,
|
|
330
376
|
help=help,
|
|
331
377
|
horizontal=horizontal,
|
|
332
378
|
captions=captions,
|
|
379
|
+
width=width,
|
|
333
380
|
)
|
|
334
381
|
|
|
335
382
|
if not isinstance(index, int) and index is not None:
|
|
336
383
|
raise StreamlitAPIException(
|
|
337
|
-
"Radio Value has invalid type:
|
|
384
|
+
f"Radio Value has invalid type: {type(index).__name__}"
|
|
338
385
|
)
|
|
339
386
|
|
|
340
387
|
if index is not None and len(opt) > 0 and not 0 <= index < len(opt):
|
|
@@ -345,12 +392,11 @@ class RadioMixin:
|
|
|
345
392
|
def handle_captions(caption: str | None) -> str:
|
|
346
393
|
if caption is None:
|
|
347
394
|
return ""
|
|
348
|
-
|
|
395
|
+
if isinstance(caption, str):
|
|
349
396
|
return caption
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
)
|
|
397
|
+
raise StreamlitAPIException(
|
|
398
|
+
f"Radio captions must be strings. Passed type: {type(caption).__name__}"
|
|
399
|
+
)
|
|
354
400
|
|
|
355
401
|
session_state = get_session_state().filtered_state
|
|
356
402
|
if key is not None and key in session_state and session_state[key] is None:
|
|
@@ -398,7 +444,7 @@ class RadioMixin:
|
|
|
398
444
|
|
|
399
445
|
if ctx:
|
|
400
446
|
save_for_app_testing(ctx, element_id, format_func)
|
|
401
|
-
self.dg._enqueue("radio", radio_proto)
|
|
447
|
+
self.dg._enqueue("radio", radio_proto, layout_config=layout_config)
|
|
402
448
|
return widget_state.value
|
|
403
449
|
|
|
404
450
|
@property
|
|
@@ -29,6 +29,7 @@ from typing_extensions import TypeGuard
|
|
|
29
29
|
|
|
30
30
|
from streamlit.dataframe_util import OptionSequence, convert_anything_to_list
|
|
31
31
|
from streamlit.elements.lib.form_utils import current_form_id
|
|
32
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig, validate_width
|
|
32
33
|
from streamlit.elements.lib.options_selector_utils import (
|
|
33
34
|
index_,
|
|
34
35
|
maybe_coerce_enum,
|
|
@@ -62,6 +63,7 @@ if TYPE_CHECKING:
|
|
|
62
63
|
from collections.abc import Sequence
|
|
63
64
|
|
|
64
65
|
from streamlit.delta_generator import DeltaGenerator
|
|
66
|
+
from streamlit.elements.lib.layout_utils import WidthWithoutContent
|
|
65
67
|
from streamlit.runtime.state.common import RegisterWidgetResult
|
|
66
68
|
|
|
67
69
|
|
|
@@ -78,11 +80,7 @@ class SelectSliderSerde(Generic[T]):
|
|
|
78
80
|
def serialize(self, v: object) -> list[int]:
|
|
79
81
|
return self._as_index_list(v)
|
|
80
82
|
|
|
81
|
-
def deserialize(
|
|
82
|
-
self,
|
|
83
|
-
ui_value: list[int] | None,
|
|
84
|
-
widget_id: str = "",
|
|
85
|
-
) -> T | tuple[T, T]:
|
|
83
|
+
def deserialize(self, ui_value: list[int] | None) -> T | tuple[T, T]:
|
|
86
84
|
if not ui_value:
|
|
87
85
|
# Widget has not been used; fallback to the original value,
|
|
88
86
|
ui_value = self.value
|
|
@@ -103,13 +101,12 @@ class SelectSliderSerde(Generic[T]):
|
|
|
103
101
|
if start > end:
|
|
104
102
|
slider_value = [end, start]
|
|
105
103
|
return slider_value
|
|
106
|
-
|
|
107
|
-
return [index_(self.options, v)]
|
|
104
|
+
return [index_(self.options, v)]
|
|
108
105
|
|
|
109
106
|
|
|
110
107
|
class SelectSliderMixin:
|
|
111
108
|
@overload
|
|
112
|
-
def select_slider(
|
|
109
|
+
def select_slider(
|
|
113
110
|
self,
|
|
114
111
|
label: str,
|
|
115
112
|
options: OptionSequence[T],
|
|
@@ -123,20 +120,9 @@ class SelectSliderMixin:
|
|
|
123
120
|
*, # keyword-only arguments:
|
|
124
121
|
disabled: bool = False,
|
|
125
122
|
label_visibility: LabelVisibility = "visible",
|
|
123
|
+
width: WidthWithoutContent = "stretch",
|
|
126
124
|
) -> tuple[T, T]: ...
|
|
127
125
|
|
|
128
|
-
# The overload-overlap error given by mypy here stems from
|
|
129
|
-
# the fact that
|
|
130
|
-
#
|
|
131
|
-
# opt:List[object] = [1, 2, "3"]
|
|
132
|
-
# select_slider("foo", options=opt, value=[1, 2])
|
|
133
|
-
#
|
|
134
|
-
# matches both overloads; "opt" matches
|
|
135
|
-
# OptionsSequence[T] in each case, binding T to object.
|
|
136
|
-
# However, the list[int] type of "value" can be interpreted
|
|
137
|
-
# as subtype of object, or as a subtype of List[object],
|
|
138
|
-
# meaning it matches both signatures.
|
|
139
|
-
|
|
140
126
|
@overload
|
|
141
127
|
def select_slider(
|
|
142
128
|
self,
|
|
@@ -152,6 +138,7 @@ class SelectSliderMixin:
|
|
|
152
138
|
*, # keyword-only arguments:
|
|
153
139
|
disabled: bool = False,
|
|
154
140
|
label_visibility: LabelVisibility = "visible",
|
|
141
|
+
width: WidthWithoutContent = "stretch",
|
|
155
142
|
) -> T: ...
|
|
156
143
|
|
|
157
144
|
@gather_metrics("select_slider")
|
|
@@ -169,6 +156,7 @@ class SelectSliderMixin:
|
|
|
169
156
|
*, # keyword-only arguments:
|
|
170
157
|
disabled: bool = False,
|
|
171
158
|
label_visibility: LabelVisibility = "visible",
|
|
159
|
+
width: WidthWithoutContent = "stretch",
|
|
172
160
|
) -> T | tuple[T, T]:
|
|
173
161
|
r"""
|
|
174
162
|
Display a slider widget to select items from a list.
|
|
@@ -253,9 +241,20 @@ class SelectSliderMixin:
|
|
|
253
241
|
label_visibility : "visible", "hidden", or "collapsed"
|
|
254
242
|
The visibility of the label. The default is ``"visible"``. If this
|
|
255
243
|
is ``"hidden"``, Streamlit displays an empty spacer instead of the
|
|
256
|
-
label, which can help keep the widget
|
|
244
|
+
label, which can help keep the widget aligned with other widgets.
|
|
257
245
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
|
258
246
|
|
|
247
|
+
width : "stretch" or int
|
|
248
|
+
The width of the slider widget. This can be one of the
|
|
249
|
+
following:
|
|
250
|
+
|
|
251
|
+
- ``"stretch"`` (default): The width of the widget matches the
|
|
252
|
+
width of the parent container.
|
|
253
|
+
- An integer specifying the width in pixels: The widget has a
|
|
254
|
+
fixed width. If the specified width is greater than the width of
|
|
255
|
+
the parent container, the width of the widget matches the width
|
|
256
|
+
of the parent container.
|
|
257
|
+
|
|
259
258
|
Returns
|
|
260
259
|
-------
|
|
261
260
|
any value or tuple of any value
|
|
@@ -318,6 +317,7 @@ class SelectSliderMixin:
|
|
|
318
317
|
disabled=disabled,
|
|
319
318
|
label_visibility=label_visibility,
|
|
320
319
|
ctx=ctx,
|
|
320
|
+
width=width,
|
|
321
321
|
)
|
|
322
322
|
|
|
323
323
|
def _select_slider(
|
|
@@ -334,6 +334,7 @@ class SelectSliderMixin:
|
|
|
334
334
|
disabled: bool = False,
|
|
335
335
|
label_visibility: LabelVisibility = "visible",
|
|
336
336
|
ctx: ScriptRunContext | None = None,
|
|
337
|
+
width: WidthWithoutContent = "stretch",
|
|
337
338
|
) -> T | tuple[T, T]:
|
|
338
339
|
key = to_key(key)
|
|
339
340
|
|
|
@@ -358,15 +359,14 @@ class SelectSliderMixin:
|
|
|
358
359
|
if start > end:
|
|
359
360
|
slider_value = [end, start]
|
|
360
361
|
return slider_value
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
raise
|
|
362
|
+
# Simplify future logic by always making value a list
|
|
363
|
+
try:
|
|
364
|
+
return [index_(opt, v)]
|
|
365
|
+
except ValueError:
|
|
366
|
+
if value is not None:
|
|
367
|
+
raise
|
|
368
368
|
|
|
369
|
-
|
|
369
|
+
return [0]
|
|
370
370
|
|
|
371
371
|
# Convert element to index of the elements
|
|
372
372
|
slider_value = as_index_list(value)
|
|
@@ -375,10 +375,12 @@ class SelectSliderMixin:
|
|
|
375
375
|
"select_slider",
|
|
376
376
|
user_key=key,
|
|
377
377
|
form_id=current_form_id(self.dg),
|
|
378
|
+
dg=self.dg,
|
|
378
379
|
label=label,
|
|
379
380
|
options=[str(format_func(option)) for option in opt],
|
|
380
381
|
value=slider_value,
|
|
381
382
|
help=help,
|
|
383
|
+
width=width,
|
|
382
384
|
)
|
|
383
385
|
|
|
384
386
|
slider_proto = SliderProto()
|
|
@@ -400,6 +402,9 @@ class SelectSliderMixin:
|
|
|
400
402
|
if help is not None:
|
|
401
403
|
slider_proto.help = dedent(help)
|
|
402
404
|
|
|
405
|
+
validate_width(width)
|
|
406
|
+
layout_config = LayoutConfig(width=width)
|
|
407
|
+
|
|
403
408
|
serde = SelectSliderSerde(opt, slider_value, _is_range_value(value))
|
|
404
409
|
|
|
405
410
|
widget_state = register_widget(
|
|
@@ -426,7 +431,7 @@ class SelectSliderMixin:
|
|
|
426
431
|
if ctx:
|
|
427
432
|
save_for_app_testing(ctx, element_id, format_func)
|
|
428
433
|
|
|
429
|
-
self.dg._enqueue("slider", slider_proto)
|
|
434
|
+
self.dg._enqueue("slider", slider_proto, layout_config=layout_config)
|
|
430
435
|
return widget_state.value
|
|
431
436
|
|
|
432
437
|
@property
|