streamlit 1.45.1__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.
Files changed (335) hide show
  1. streamlit/__init__.py +5 -1
  2. streamlit/auth_util.py +12 -12
  3. streamlit/cli_util.py +4 -3
  4. streamlit/column_config.py +11 -9
  5. streamlit/commands/echo.py +6 -4
  6. streamlit/commands/execution_control.py +33 -32
  7. streamlit/commands/experimental_query_params.py +2 -2
  8. streamlit/commands/logo.py +9 -4
  9. streamlit/commands/navigation.py +61 -18
  10. streamlit/commands/page_config.py +57 -47
  11. streamlit/components/types/base_custom_component.py +7 -7
  12. streamlit/components/v1/component_registry.py +7 -3
  13. streamlit/components/v1/components.py +1 -1
  14. streamlit/components/v1/custom_component.py +8 -8
  15. streamlit/config.py +289 -144
  16. streamlit/config_option.py +19 -15
  17. streamlit/config_util.py +29 -23
  18. streamlit/connections/__init__.py +2 -2
  19. streamlit/connections/base_connection.py +5 -5
  20. streamlit/connections/snowflake_connection.py +13 -11
  21. streamlit/connections/snowpark_connection.py +3 -3
  22. streamlit/connections/sql_connection.py +20 -18
  23. streamlit/connections/util.py +2 -2
  24. streamlit/cursor.py +6 -6
  25. streamlit/dataframe_util.py +52 -52
  26. streamlit/delta_generator.py +46 -48
  27. streamlit/delta_generator_singletons.py +3 -3
  28. streamlit/deprecation_util.py +6 -6
  29. streamlit/elements/alert.py +37 -29
  30. streamlit/elements/arrow.py +40 -22
  31. streamlit/elements/code.py +46 -13
  32. streamlit/elements/deck_gl_json_chart.py +38 -27
  33. streamlit/elements/dialog_decorator.py +3 -4
  34. streamlit/elements/doc_string.py +64 -58
  35. streamlit/elements/exception.py +23 -27
  36. streamlit/elements/form.py +41 -0
  37. streamlit/elements/graphviz_chart.py +1 -1
  38. streamlit/elements/heading.py +60 -9
  39. streamlit/elements/html.py +3 -4
  40. streamlit/elements/image.py +8 -9
  41. streamlit/elements/json.py +21 -2
  42. streamlit/elements/layouts.py +120 -31
  43. streamlit/elements/lib/built_in_chart_utils.py +96 -73
  44. streamlit/elements/lib/color_util.py +3 -3
  45. streamlit/elements/lib/column_config_utils.py +2 -4
  46. streamlit/elements/lib/column_types.py +14 -8
  47. streamlit/elements/lib/dialog.py +9 -5
  48. streamlit/elements/lib/image_utils.py +39 -40
  49. streamlit/elements/lib/js_number.py +4 -4
  50. streamlit/elements/lib/layout_utils.py +65 -1
  51. streamlit/elements/lib/mutable_status_container.py +14 -3
  52. streamlit/elements/lib/options_selector_utils.py +22 -12
  53. streamlit/elements/lib/pandas_styler_utils.py +25 -21
  54. streamlit/elements/lib/policies.py +6 -5
  55. streamlit/elements/lib/streamlit_plotly_theme.py +54 -53
  56. streamlit/elements/lib/subtitle_utils.py +6 -9
  57. streamlit/elements/lib/utils.py +20 -5
  58. streamlit/elements/map.py +32 -56
  59. streamlit/elements/markdown.py +101 -12
  60. streamlit/elements/media.py +78 -21
  61. streamlit/elements/metric.py +32 -16
  62. streamlit/elements/plotly_chart.py +15 -15
  63. streamlit/elements/progress.py +33 -15
  64. streamlit/elements/spinner.py +31 -6
  65. streamlit/elements/text.py +21 -1
  66. streamlit/elements/toast.py +1 -2
  67. streamlit/elements/vega_charts.py +54 -23
  68. streamlit/elements/widgets/audio_input.py +24 -7
  69. streamlit/elements/widgets/button.py +26 -19
  70. streamlit/elements/widgets/button_group.py +10 -15
  71. streamlit/elements/widgets/camera_input.py +27 -7
  72. streamlit/elements/widgets/chat.py +91 -38
  73. streamlit/elements/widgets/checkbox.py +45 -4
  74. streamlit/elements/widgets/color_picker.py +40 -17
  75. streamlit/elements/widgets/data_editor.py +76 -37
  76. streamlit/elements/widgets/file_uploader.py +42 -13
  77. streamlit/elements/widgets/multiselect.py +7 -10
  78. streamlit/elements/widgets/number_input.py +123 -47
  79. streamlit/elements/widgets/radio.py +59 -13
  80. streamlit/elements/widgets/select_slider.py +35 -30
  81. streamlit/elements/widgets/selectbox.py +56 -9
  82. streamlit/elements/widgets/slider.py +190 -99
  83. streamlit/elements/widgets/text_widgets.py +54 -8
  84. streamlit/elements/widgets/time_widgets.py +53 -14
  85. streamlit/elements/write.py +5 -8
  86. streamlit/env_util.py +2 -7
  87. streamlit/error_util.py +16 -9
  88. streamlit/errors.py +69 -48
  89. streamlit/external/langchain/streamlit_callback_handler.py +10 -5
  90. streamlit/file_util.py +27 -10
  91. streamlit/git_util.py +29 -24
  92. streamlit/hello/animation_demo.py +9 -9
  93. streamlit/hello/dataframe_demo.py +5 -5
  94. streamlit/hello/hello.py +1 -0
  95. streamlit/hello/mapping_demo.py +7 -8
  96. streamlit/hello/plotting_demo.py +3 -3
  97. streamlit/hello/streamlit_app.py +28 -26
  98. streamlit/hello/utils.py +2 -1
  99. streamlit/logger.py +10 -11
  100. streamlit/navigation/page.py +11 -8
  101. streamlit/proto/Audio_pb2.py +4 -3
  102. streamlit/proto/Audio_pb2.pyi +8 -1
  103. streamlit/proto/Block_pb2.py +38 -29
  104. streamlit/proto/Block_pb2.pyi +72 -4
  105. streamlit/proto/ClientState_pb2.py +4 -4
  106. streamlit/proto/ClientState_pb2.pyi +7 -2
  107. streamlit/proto/Code_pb2.py +4 -2
  108. streamlit/proto/Code_pb2.pyi +1 -0
  109. streamlit/proto/DataFrame_pb2.pyi +1 -1
  110. streamlit/proto/DeckGlJsonChart_pb2.pyi +1 -1
  111. streamlit/proto/Element_pb2.py +5 -3
  112. streamlit/proto/Element_pb2.pyi +20 -3
  113. streamlit/proto/GapSize_pb2.py +29 -0
  114. streamlit/proto/GapSize_pb2.pyi +70 -0
  115. streamlit/proto/HeightConfig_pb2.py +27 -0
  116. streamlit/proto/HeightConfig_pb2.pyi +48 -0
  117. streamlit/proto/NamedDataSet_pb2.pyi +1 -1
  118. streamlit/proto/Navigation_pb2.py +3 -3
  119. streamlit/proto/Navigation_pb2.pyi +4 -0
  120. streamlit/proto/NewSession_pb2.py +18 -16
  121. streamlit/proto/NewSession_pb2.pyi +29 -3
  122. streamlit/proto/PageConfig_pb2.py +7 -7
  123. streamlit/proto/PageConfig_pb2.pyi +21 -1
  124. streamlit/proto/Video_pb2.py +8 -7
  125. streamlit/proto/Video_pb2.pyi +8 -1
  126. streamlit/proto/WidthConfig_pb2.py +2 -2
  127. streamlit/proto/WidthConfig_pb2.pyi +15 -1
  128. streamlit/runtime/__init__.py +1 -1
  129. streamlit/runtime/app_session.py +53 -40
  130. streamlit/runtime/caching/__init__.py +9 -9
  131. streamlit/runtime/caching/cache_data_api.py +36 -30
  132. streamlit/runtime/caching/cache_errors.py +4 -4
  133. streamlit/runtime/caching/cache_resource_api.py +8 -8
  134. streamlit/runtime/caching/cache_utils.py +15 -14
  135. streamlit/runtime/caching/cached_message_replay.py +14 -8
  136. streamlit/runtime/caching/hashing.py +91 -97
  137. streamlit/runtime/caching/legacy_cache_api.py +2 -2
  138. streamlit/runtime/caching/storage/cache_storage_protocol.py +1 -1
  139. streamlit/runtime/caching/storage/dummy_cache_storage.py +1 -1
  140. streamlit/runtime/caching/storage/in_memory_cache_storage_wrapper.py +12 -14
  141. streamlit/runtime/caching/storage/local_disk_cache_storage.py +6 -6
  142. streamlit/runtime/connection_factory.py +36 -36
  143. streamlit/runtime/context.py +58 -9
  144. streamlit/runtime/credentials.py +29 -40
  145. streamlit/runtime/forward_msg_queue.py +11 -11
  146. streamlit/runtime/fragment.py +7 -7
  147. streamlit/runtime/media_file_manager.py +3 -4
  148. streamlit/runtime/memory_media_file_storage.py +6 -5
  149. streamlit/runtime/memory_uploaded_file_manager.py +2 -2
  150. streamlit/runtime/metrics_util.py +11 -12
  151. streamlit/runtime/pages_manager.py +4 -6
  152. streamlit/runtime/runtime.py +8 -6
  153. streamlit/runtime/runtime_util.py +7 -6
  154. streamlit/runtime/scriptrunner/__init__.py +4 -4
  155. streamlit/runtime/scriptrunner/exec_code.py +12 -5
  156. streamlit/runtime/scriptrunner/magic.py +16 -12
  157. streamlit/runtime/scriptrunner/script_cache.py +1 -1
  158. streamlit/runtime/scriptrunner/script_runner.py +53 -29
  159. streamlit/runtime/scriptrunner_utils/exceptions.py +1 -1
  160. streamlit/runtime/scriptrunner_utils/script_requests.py +7 -4
  161. streamlit/runtime/scriptrunner_utils/script_run_context.py +10 -23
  162. streamlit/runtime/secrets.py +40 -35
  163. streamlit/runtime/session_manager.py +2 -1
  164. streamlit/runtime/state/__init__.py +5 -5
  165. streamlit/runtime/state/common.py +2 -2
  166. streamlit/runtime/state/query_params.py +13 -15
  167. streamlit/runtime/state/query_params_proxy.py +17 -13
  168. streamlit/runtime/state/safe_session_state.py +2 -2
  169. streamlit/runtime/state/session_state.py +52 -34
  170. streamlit/runtime/stats.py +2 -2
  171. streamlit/runtime/uploaded_file_manager.py +1 -1
  172. streamlit/runtime/websocket_session_manager.py +10 -6
  173. streamlit/source_util.py +8 -6
  174. streamlit/static/index.html +3 -17
  175. streamlit/static/manifest.json +1180 -0
  176. streamlit/static/static/css/{index.DqDwtg6_.css → index.CJVRHjQZ.css} +1 -1
  177. streamlit/static/static/js/{ErrorOutline.esm.DU9IrB3M.js → ErrorOutline.esm.6PVAQvlT.js} +1 -1
  178. streamlit/static/static/js/{FileDownload.esm.P9rKwKo8.js → FileDownload.esm.BZQHC61b.js} +1 -1
  179. streamlit/static/static/js/{FileHelper.D7RMkx0e.js → FileHelper.Bn1VShMJ.js} +5 -5
  180. streamlit/static/static/js/{FormClearHelper.B67tgll0.js → FormClearHelper.CsFEiTNN.js} +1 -1
  181. streamlit/static/static/js/{Hooks.ncTJktu9.js → Hooks.DguOHQL1.js} +1 -1
  182. streamlit/static/static/js/{InputInstructions.D-Y8geDN.js → InputInstructions.CTYn2BJQ.js} +1 -1
  183. streamlit/static/static/js/{ProgressBar.B-kexwwD.js → ProgressBar.CPOGBKCi.js} +2 -2
  184. streamlit/static/static/js/{RenderInPortalIfExists.BgaoZgep.js → RenderInPortalIfExists.BYu_CZaF.js} +1 -1
  185. streamlit/static/static/js/Toolbar.gXKw7ANv.js +1 -0
  186. streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
  187. streamlit/static/static/js/{base-input.BoAa1U94.js → base-input.DBYPj91R.js} +4 -4
  188. streamlit/static/static/js/{checkbox.Z6iSfe5F.js → checkbox.BUm2vnNv.js} +2 -2
  189. streamlit/static/static/js/{createSuper.B4oGDYRm.js → createSuper.KD4RuZ-W.js} +1 -1
  190. streamlit/static/static/js/{data-grid-overlay-editor.msYws2Ou.js → data-grid-overlay-editor.CUwpDfvI.js} +1 -1
  191. streamlit/static/static/js/{downloader.kc14n2Hv.js → downloader.CkDtclup.js} +1 -1
  192. streamlit/static/static/js/{es6.CxQz807-.js → es6.Dlcvh_r0.js} +2 -2
  193. streamlit/static/static/js/{iframeResizer.contentWindow.B19u0ONI.js → iframeResizer.contentWindow.DOXlFfve.js} +1 -1
  194. streamlit/static/static/js/{index.BGga-hcS.js → index.B0cuGMAB.js} +25 -25
  195. streamlit/static/static/js/index.BCWTclSV.js +73 -0
  196. streamlit/static/static/js/index.BJY_fap7.js +1 -0
  197. streamlit/static/static/js/index.BL3l6dnk.js +1 -0
  198. streamlit/static/static/js/{index.BFz9U2y0.js → index.BMZzRZjB.js} +1 -1
  199. streamlit/static/static/js/{index.-5ruC9At.js → index.BOzUTGDe.js} +1 -1
  200. streamlit/static/static/js/index.BYI5iO-o.js +1 -0
  201. streamlit/static/static/js/index.BYo0ywlm.js +783 -0
  202. streamlit/static/static/js/{index.CmTAF0dM.js → index.BYz9btsY.js} +1 -1
  203. streamlit/static/static/js/{index.BHGGDa8K.js → index.CCVzQz0Z.js} +2 -2
  204. streamlit/static/static/js/index.CD6FydK9.js +1 -0
  205. streamlit/static/static/js/index.CDYEqgC8.js +2 -0
  206. streamlit/static/static/js/{index.BRXmLIsC.js → index.CMP9c4xA.js} +1 -1
  207. streamlit/static/static/js/index.CN30QAPD.js +1 -0
  208. streamlit/static/static/js/{index.LaIasviC.js → index.CNqWQkTe.js} +1 -1
  209. streamlit/static/static/js/index.CaxS67Xz.js +1 -0
  210. streamlit/static/static/js/{index.xNQq3Ei5.js → index.CbsT4sGW.js} +1 -1
  211. streamlit/static/static/js/index.ChAVlxpQ.js +1 -0
  212. streamlit/static/static/js/{index.BqfdT8-Q.js → index.ClLMMmDd.js} +1 -1
  213. streamlit/static/static/js/{index.BHXxWdde.js → index.D-O9rQmV.js} +1 -1
  214. streamlit/static/static/js/{index.9V1KdxfP.js → index.D4k7VZZL.js} +1 -1
  215. streamlit/static/static/js/index.DLBi0Ar1.js +1 -0
  216. streamlit/static/static/js/index.DVq5XmJo.js +197 -0
  217. streamlit/static/static/js/{index.BoigZiu7.js → index.DZKmKXWw.js} +1 -1
  218. streamlit/static/static/js/index.DkaVx80F.js +1 -0
  219. streamlit/static/static/js/index.Dr968Klx.js +1 -0
  220. streamlit/static/static/js/{index.BpILzHf_.js → index.DtUYLn9j.js} +20 -20
  221. streamlit/static/static/js/index.DwjYSyhs.js +1 -0
  222. streamlit/static/static/js/index.DzrImxu4.js +1 -0
  223. streamlit/static/static/js/index.HyGsn4VM.js +1 -0
  224. streamlit/static/static/js/index.OwxC65od.js +12 -0
  225. streamlit/static/static/js/index.PZs7VZkC.js +1 -0
  226. streamlit/static/static/js/index.Voiqpj4q.js +1 -0
  227. streamlit/static/static/js/index.bSROvR-J.js +3 -0
  228. streamlit/static/static/js/index.oT9GD3l4.js +1 -0
  229. streamlit/static/static/js/{index.DeB9iKFW.js → index.qb-yAPH6.js} +255 -255
  230. streamlit/static/static/js/index.rJFy_Ygy.js +2 -0
  231. streamlit/static/static/js/{input.DsCfafm0.js → input.CwQtEnFN.js} +2 -2
  232. streamlit/static/static/js/{memory.nY_lMTtu.js → memory.C5XaFIjR.js} +1 -1
  233. streamlit/static/static/js/{mergeWith.B_7zmsM4.js → mergeWith.DzwwH6AG.js} +1 -1
  234. streamlit/static/static/js/{number-overlay-editor.CSeVhHRU.js → number-overlay-editor.Dx0XqCkD.js} +1 -1
  235. streamlit/static/static/js/{possibleConstructorReturn.nNhsvgRd.js → possibleConstructorReturn.CVfSu9Ws.js} +1 -1
  236. streamlit/static/static/js/{sandbox.Cgm3iuL6.js → sandbox.BT0gdMXk.js} +1 -1
  237. streamlit/static/static/js/{textarea.BR8rlyih.js → textarea.DNCbrtbM.js} +2 -2
  238. streamlit/static/static/js/{timepicker.w4XhAenH.js → timepicker.4UYJD9Ts.js} +1 -1
  239. streamlit/static/static/js/{toConsumableArray.CgkEPBwD.js → toConsumableArray.DUmnaVWV.js} +1 -1
  240. streamlit/static/static/js/{uniqueId.j-1rlNNH.js → uniqueId.DUvh-GL8.js} +1 -1
  241. streamlit/static/static/js/{useBasicWidgetState.zXY9CjFS.js → useBasicWidgetState.Cwd7-jJa.js} +1 -1
  242. streamlit/static/static/js/useOnInputChange.DvemQrOM.js +1 -0
  243. streamlit/static/static/js/{withFullScreenWrapper.Ov13692o.js → withFullScreenWrapper.CiQ10ByU.js} +1 -1
  244. streamlit/static/static/media/SourceCodeVF-Italic.ttf.Ba1oaZG1.woff2 +0 -0
  245. streamlit/static/static/media/SourceCodeVF-Upright.ttf.BjWn63N-.woff2 +0 -0
  246. streamlit/static/static/media/SourceSansVF-Italic.ttf.Bt9VkdQ3.woff2 +0 -0
  247. streamlit/static/static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2 +0 -0
  248. streamlit/static/static/media/SourceSerifVariable-Italic.ttf.CVdzAtxO.woff2 +0 -0
  249. streamlit/static/static/media/SourceSerifVariable-Roman.ttf.mdpVL9bi.woff2 +0 -0
  250. streamlit/string_util.py +14 -19
  251. streamlit/temporary_directory.py +13 -4
  252. streamlit/testing/v1/app_test.py +15 -10
  253. streamlit/testing/v1/element_tree.py +157 -178
  254. streamlit/testing/v1/local_script_runner.py +11 -15
  255. streamlit/testing/v1/util.py +11 -4
  256. streamlit/type_util.py +8 -12
  257. streamlit/url_util.py +1 -1
  258. streamlit/user_info.py +6 -5
  259. streamlit/util.py +25 -1
  260. streamlit/vendor/pympler/asizeof.py +3 -2
  261. streamlit/watcher/event_based_path_watcher.py +15 -1
  262. streamlit/watcher/folder_black_list.py +2 -2
  263. streamlit/watcher/local_sources_watcher.py +64 -18
  264. streamlit/watcher/path_watcher.py +6 -10
  265. streamlit/watcher/polling_path_watcher.py +8 -7
  266. streamlit/watcher/util.py +7 -6
  267. streamlit/web/bootstrap.py +16 -14
  268. streamlit/web/cli.py +52 -45
  269. streamlit/web/server/__init__.py +7 -3
  270. streamlit/web/server/app_static_file_handler.py +1 -1
  271. streamlit/web/server/authlib_tornado_integration.py +9 -4
  272. streamlit/web/server/browser_websocket_handler.py +8 -2
  273. streamlit/web/server/component_request_handler.py +14 -10
  274. streamlit/web/server/media_file_handler.py +14 -7
  275. streamlit/web/server/oauth_authlib_routes.py +41 -9
  276. streamlit/web/server/oidc_mixin.py +35 -17
  277. streamlit/web/server/routes.py +32 -22
  278. streamlit/web/server/server.py +6 -18
  279. streamlit/web/server/server_util.py +19 -9
  280. streamlit/web/server/stats_request_handler.py +7 -5
  281. streamlit/web/server/upload_file_request_handler.py +22 -19
  282. streamlit/web/server/websocket_headers.py +1 -1
  283. {streamlit-1.45.1.dist-info → streamlit-1.46.0.dist-info}/METADATA +4 -4
  284. streamlit-1.46.0.dist-info/RECORD +559 -0
  285. {streamlit-1.45.1.dist-info → streamlit-1.46.0.dist-info}/WHEEL +1 -1
  286. streamlit/elements/lib/event_utils.py +0 -39
  287. streamlit/static/static/js/Toolbar.D9RUZv9G.js +0 -1
  288. streamlit/static/static/js/UploadFileInfo.C-jY39rj.js +0 -1
  289. streamlit/static/static/js/index.8jhZBWF2.js +0 -3
  290. streamlit/static/static/js/index.BCx3C6e_.js +0 -1
  291. streamlit/static/static/js/index.BRuTz_S4.js +0 -1
  292. streamlit/static/static/js/index.Bcru_ti-.js +0 -1
  293. streamlit/static/static/js/index.Bl1FMJRd.js +0 -1
  294. streamlit/static/static/js/index.C1z8KpLA.js +0 -779
  295. streamlit/static/static/js/index.C32I2PUe.js +0 -2
  296. streamlit/static/static/js/index.C5GnDRB7.js +0 -1
  297. streamlit/static/static/js/index.CG4qPaaW.js +0 -2
  298. streamlit/static/static/js/index.C_msmT1u.js +0 -1
  299. streamlit/static/static/js/index.CbeNTdd6.js +0 -1
  300. streamlit/static/static/js/index.CnGQVJcw.js +0 -12
  301. streamlit/static/static/js/index.CopVVq4l.js +0 -1
  302. streamlit/static/static/js/index.CtXupx4d.js +0 -197
  303. streamlit/static/static/js/index.DGmCchO7.js +0 -1
  304. streamlit/static/static/js/index.DH6zBk0e.js +0 -1
  305. streamlit/static/static/js/index.DHVlVWsm.js +0 -1
  306. streamlit/static/static/js/index.DRKIVBoi.js +0 -1
  307. streamlit/static/static/js/index.DUd-lFXx.js +0 -73
  308. streamlit/static/static/js/index.D_uRBA4B.js +0 -1
  309. streamlit/static/static/js/index.QHNfgPJd.js +0 -1
  310. streamlit/static/static/js/index.a-RJocYL.js +0 -1
  311. streamlit/static/static/js/index.cvz4B1gy.js +0 -1
  312. streamlit/static/static/js/index.t--hEgTQ.js +0 -6
  313. streamlit/static/static/js/useOnInputChange.z04u96A8.js +0 -1
  314. streamlit/static/static/media/SourceCodePro-Bold.CFEfr7-q.woff2 +0 -0
  315. streamlit/static/static/media/SourceCodePro-BoldItalic.C-LkFXxa.woff2 +0 -0
  316. streamlit/static/static/media/SourceCodePro-Italic.CxFOx7N-.woff2 +0 -0
  317. streamlit/static/static/media/SourceCodePro-Regular.CBOlD63d.woff2 +0 -0
  318. streamlit/static/static/media/SourceCodePro-SemiBold.CFHwW3Wd.woff2 +0 -0
  319. streamlit/static/static/media/SourceCodePro-SemiBoldItalic.Cg2yRu82.woff2 +0 -0
  320. streamlit/static/static/media/SourceSansPro-Bold.-6c9oR8J.woff2 +0 -0
  321. streamlit/static/static/media/SourceSansPro-BoldItalic.DmM_grLY.woff2 +0 -0
  322. streamlit/static/static/media/SourceSansPro-Italic.I1ipWe7Q.woff2 +0 -0
  323. streamlit/static/static/media/SourceSansPro-Regular.DZLUzqI4.woff2 +0 -0
  324. streamlit/static/static/media/SourceSansPro-SemiBold.sKQIyTMz.woff2 +0 -0
  325. streamlit/static/static/media/SourceSansPro-SemiBoldItalic.C0wP0icr.woff2 +0 -0
  326. streamlit/static/static/media/SourceSerifPro-Bold.8TUnKj4x.woff2 +0 -0
  327. streamlit/static/static/media/SourceSerifPro-BoldItalic.CBVO7Ve7.woff2 +0 -0
  328. streamlit/static/static/media/SourceSerifPro-Italic.DkFgL2HZ.woff2 +0 -0
  329. streamlit/static/static/media/SourceSerifPro-Regular.CNJNET2S.woff2 +0 -0
  330. streamlit/static/static/media/SourceSerifPro-SemiBold.CHyh9GC5.woff2 +0 -0
  331. streamlit/static/static/media/SourceSerifPro-SemiBoldItalic.CBtz8sWN.woff2 +0 -0
  332. streamlit-1.45.1.dist-info/RECORD +0 -568
  333. {streamlit-1.45.1.data → streamlit-1.46.0.data}/scripts/streamlit.cmd +0 -0
  334. {streamlit-1.45.1.dist-info → streamlit-1.46.0.dist-info}/entry_points.txt +0 -0
  335. {streamlit-1.45.1.dist-info → streamlit-1.46.0.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, key: Key | None = None, help: str | None = None, on_change: WidgetCallback | None = None, args: WidgetArgs | None = None, kwargs: WidgetKwargs | None = None, *, placeholder: str | None = None, disabled: bool = False, label_visibility: LabelVisibility = "visible", icon: str | None = None
102
- ) -> int | IntOrNone:
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: int | None = None,
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, key: Key | None = None, help: str | None = None, on_change: WidgetCallback | None = None, args: WidgetArgs | None = None, kwargs: WidgetKwargs | None = None, placeholder: str | None = None, disabled: bool = False, label_visibility: LabelVisibility = "visible", icon: str | None = None
119
- ) -> int | IntOrNone:
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, key: Key | None = None, help: str | None = None, on_change: WidgetCallback | None = None, args: WidgetArgs | None = None, kwargs: WidgetKwargs | None = None, placeholder: str | None = None, disabled: bool = False, label_visibility: LabelVisibility = "visible", icon: str | None = None
134
- ) -> int:
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: int | None = None,
146
- max_value: int | None = None,
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, key: Key | None = None, help: str | None = None, on_change: WidgetCallback | None = None, args: WidgetArgs | None = None, kwargs: WidgetKwargs | None = None, placeholder: str | None = None, disabled: bool = False, label_visibility: LabelVisibility = "visible", icon: str | None = None
151
- ) -> int | IntOrNone:
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, key: Key | None = None, help: str | None = None, on_change: WidgetCallback | None = None, args: WidgetArgs | None = None, kwargs: WidgetKwargs | None = None, *, placeholder: str | None = None, disabled: bool = False, label_visibility: LabelVisibility = "visible", icon: str | None = None
167
- ) -> float | FloatOrNone:
168
- ...
169
- # # fmt: on
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 contstraints
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 alligned with other widgets.
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(value=value, min_value=min_value, max_value=max_value, step=step)
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 is None:
449
- format = "%d" if int_value else "%0.2f"
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 format in ["%d", "%u", "%i"] and float_value:
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 {format} displays as integer."
520
+ f" but format {number_format} displays as integer."
458
521
  )
459
- elif format[-1] == "f" and int_value:
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 {format}."
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(format % 2)
534
+ float(number_format % 2)
472
535
  except (TypeError, ValueError):
473
- raise StreamlitInvalidNumberFormatError(format)
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
- if format is not None:
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 number_input_proto.has_min and widget_state.value < number_input_proto.min:
574
- raise StreamlitValueBelowMinError(value=widget_state.value, min_value=number_input_proto.min)
575
-
576
- if number_input_proto.has_max and widget_state.value > number_input_proto.max:
577
- raise StreamlitValueAboveMaxError(value=widget_state.value, max_value=number_input_proto.max)
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
- self.dg._enqueue("number_input", number_input_proto)
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 alligned with other widgets.
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: %s" % type(index).__name__
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
- elif isinstance(caption, str):
395
+ if isinstance(caption, str):
349
396
  return caption
350
- else:
351
- raise StreamlitAPIException(
352
- f"Radio captions must be strings. Passed type: {type(caption).__name__}"
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
- else:
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( # type: ignore[overload-overlap]
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 alligned with other widgets.
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
- else:
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
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
- return [0]
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