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.
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.DitPpe1Y.js} +1 -1
  178. streamlit/static/static/js/{FileDownload.esm.P9rKwKo8.js → FileDownload.esm.AI3watX9.js} +1 -1
  179. streamlit/static/static/js/{FileHelper.D7RMkx0e.js → FileHelper.kt7mhnu8.js} +5 -5
  180. streamlit/static/static/js/{FormClearHelper.B67tgll0.js → FormClearHelper.D1M9GM_c.js} +1 -1
  181. streamlit/static/static/js/{Hooks.ncTJktu9.js → Hooks.BGwHKeUc.js} +1 -1
  182. streamlit/static/static/js/{InputInstructions.D-Y8geDN.js → InputInstructions.DaZ89mzH.js} +1 -1
  183. streamlit/static/static/js/{ProgressBar.B-kexwwD.js → ProgressBar.C0zPMe-p.js} +2 -2
  184. streamlit/static/static/js/{RenderInPortalIfExists.BgaoZgep.js → RenderInPortalIfExists.Ox8gQvdz.js} +1 -1
  185. streamlit/static/static/js/Toolbar.KhlcEc0K.js +1 -0
  186. streamlit/static/static/js/UploadFileInfo.0DCkpDDf.js +6 -0
  187. streamlit/static/static/js/{base-input.BoAa1U94.js → base-input.BJ4qsfSq.js} +4 -4
  188. streamlit/static/static/js/{checkbox.Z6iSfe5F.js → checkbox.DSDh78Xz.js} +2 -2
  189. streamlit/static/static/js/{createSuper.B4oGDYRm.js → createSuper.wQ9SIXEJ.js} +1 -1
  190. streamlit/static/static/js/{data-grid-overlay-editor.msYws2Ou.js → data-grid-overlay-editor.DvbdPJ15.js} +1 -1
  191. streamlit/static/static/js/{downloader.kc14n2Hv.js → downloader.CD9rzih5.js} +1 -1
  192. streamlit/static/static/js/{es6.CxQz807-.js → es6.48Q9Qjgb.js} +2 -2
  193. streamlit/static/static/js/{iframeResizer.contentWindow.B19u0ONI.js → iframeResizer.contentWindow.CKdem3Bn.js} +1 -1
  194. streamlit/static/static/js/{index.LaIasviC.js → index.6md5Qhod.js} +1 -1
  195. streamlit/static/static/js/index.7hy6AeJ1.js +1 -0
  196. streamlit/static/static/js/index.B4CGJiBW.js +1 -0
  197. streamlit/static/static/js/index.B8oW0ZTD.js +1 -0
  198. streamlit/static/static/js/index.BU6RnlHI.js +73 -0
  199. streamlit/static/static/js/index.BUq9Wcf8.js +197 -0
  200. streamlit/static/static/js/{index.BFz9U2y0.js → index.BXXo-Yoj.js} +1 -1
  201. streamlit/static/static/js/index.Bae9H0OS.js +1 -0
  202. streamlit/static/static/js/{index.-5ruC9At.js → index.BhTl2Uyb.js} +1 -1
  203. streamlit/static/static/js/{index.BpILzHf_.js → index.BiSaCB1o.js} +20 -20
  204. streamlit/static/static/js/{index.xNQq3Ei5.js → index.BulSAJ9z.js} +1 -1
  205. streamlit/static/static/js/{index.9V1KdxfP.js → index.Bv-EuTKR.js} +1 -1
  206. streamlit/static/static/js/index.BvMLYCHi.js +1 -0
  207. streamlit/static/static/js/index.C1NIn1Y2.js +783 -0
  208. streamlit/static/static/js/index.CP-fthOJ.js +2 -0
  209. streamlit/static/static/js/{index.BoigZiu7.js → index.CS9guO3p.js} +1 -1
  210. streamlit/static/static/js/index.CYTBHth8.js +1 -0
  211. streamlit/static/static/js/{index.CmTAF0dM.js → index.CcJufcuD.js} +1 -1
  212. streamlit/static/static/js/index.CnENU1yn.js +1 -0
  213. streamlit/static/static/js/index.Cns13qBb.js +1 -0
  214. streamlit/static/static/js/index.Ct_xXq7w.js +1 -0
  215. streamlit/static/static/js/{index.BqfdT8-Q.js → index.CxGSemHL.js} +1 -1
  216. streamlit/static/static/js/index.D5S0ldVb.js +1 -0
  217. streamlit/static/static/js/index.D72B_ksb.js +2 -0
  218. streamlit/static/static/js/index.DI4yZ27M.js +1 -0
  219. streamlit/static/static/js/index.DN51vLxR.js +1 -0
  220. streamlit/static/static/js/index.DRtq5dka.js +1 -0
  221. streamlit/static/static/js/{index.BHXxWdde.js → index.DX-oiXlb.js} +1 -1
  222. streamlit/static/static/js/index.DlFE4_Aq.js +12 -0
  223. streamlit/static/static/js/{index.BHGGDa8K.js → index.J7BJwXOi.js} +2 -2
  224. streamlit/static/static/js/index.Jg38kJPP.js +1 -0
  225. streamlit/static/static/js/index.JhIO6abf.js +3 -0
  226. streamlit/static/static/js/{index.DeB9iKFW.js → index.NkRcWwc5.js} +255 -255
  227. streamlit/static/static/js/{index.BGga-hcS.js → index.prekPLrm.js} +25 -25
  228. streamlit/static/static/js/{index.BRXmLIsC.js → index.wyzngKUE.js} +1 -1
  229. streamlit/static/static/js/index.xW7mVdI8.js +1 -0
  230. streamlit/static/static/js/index.yk07dYGx.js +1 -0
  231. streamlit/static/static/js/{input.DsCfafm0.js → input.CxKZ5Wrc.js} +2 -2
  232. streamlit/static/static/js/{memory.nY_lMTtu.js → memory.DeZ9VUvl.js} +1 -1
  233. streamlit/static/static/js/{mergeWith.B_7zmsM4.js → mergeWith.CVkhrWUb.js} +1 -1
  234. streamlit/static/static/js/{number-overlay-editor.CSeVhHRU.js → number-overlay-editor.Bpkm3nTq.js} +1 -1
  235. streamlit/static/static/js/{possibleConstructorReturn.nNhsvgRd.js → possibleConstructorReturn.CIDCId52.js} +1 -1
  236. streamlit/static/static/js/{sandbox.Cgm3iuL6.js → sandbox.TrkMaokR.js} +1 -1
  237. streamlit/static/static/js/{textarea.BR8rlyih.js → textarea.QKjxR64N.js} +2 -2
  238. streamlit/static/static/js/{timepicker.w4XhAenH.js → timepicker.DJYmE1dK.js} +1 -1
  239. streamlit/static/static/js/{toConsumableArray.CgkEPBwD.js → toConsumableArray.BZoworE-.js} +1 -1
  240. streamlit/static/static/js/{uniqueId.j-1rlNNH.js → uniqueId.O0UbJ2Bu.js} +1 -1
  241. streamlit/static/static/js/{useBasicWidgetState.zXY9CjFS.js → useBasicWidgetState.Ci89jaH5.js} +1 -1
  242. streamlit/static/static/js/useOnInputChange.Cxh6ExEn.js +1 -0
  243. streamlit/static/static/js/{withFullScreenWrapper.Ov13692o.js → withFullScreenWrapper.iW37lS8Z.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 +21 -2
  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 +13 -24
  279. streamlit/web/server/server_util.py +43 -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.1.dist-info}/METADATA +4 -4
  284. streamlit-1.46.1.dist-info/RECORD +559 -0
  285. {streamlit-1.45.1.dist-info → streamlit-1.46.1.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.1.data}/scripts/streamlit.cmd +0 -0
  334. {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/entry_points.txt +0 -0
  335. {streamlit-1.45.1.dist-info → streamlit-1.46.1.dist-info}/top_level.txt +0 -0
@@ -107,11 +107,7 @@ class _MultiSelectSerde(Generic[T]):
107
107
  indices = check_and_convert_to_indices(self.options, value)
108
108
  return indices if indices is not None else []
109
109
 
110
- def deserialize(
111
- self,
112
- ui_value: list[int] | None,
113
- widget_id: str = "",
114
- ) -> list[T]:
110
+ def deserialize(self, ui_value: list[int] | None) -> list[T]:
115
111
  current_value: list[int] = (
116
112
  ui_value if ui_value is not None else self.default_value
117
113
  )
@@ -145,8 +141,8 @@ class _SingleSelectSerde(Generic[T]):
145
141
  _value = [value] if value is not None else []
146
142
  return self.multiselect_serde.serialize(_value)
147
143
 
148
- def deserialize(self, ui_value: list[int] | None, widget_id: str = "") -> T | None:
149
- deserialized = self.multiselect_serde.deserialize(ui_value, widget_id)
144
+ def deserialize(self, ui_value: list[int] | None) -> T | None:
145
+ deserialized = self.multiselect_serde.deserialize(ui_value)
150
146
 
151
147
  if len(deserialized) == 0:
152
148
  return None
@@ -169,7 +165,7 @@ class ButtonGroupSerde(Generic[T]):
169
165
  options: Sequence[T],
170
166
  default_values: list[int],
171
167
  type: Literal["single", "multi"],
172
- ):
168
+ ) -> None:
173
169
  self.options = options
174
170
  self.default_values = default_values
175
171
  self.type = type
@@ -182,10 +178,8 @@ class ButtonGroupSerde(Generic[T]):
182
178
  def serialize(self, value: T | list[T] | None) -> list[int]:
183
179
  return self.serde.serialize(cast("Any", value))
184
180
 
185
- def deserialize(
186
- self, ui_value: list[int] | None, widget_id: str = ""
187
- ) -> list[T] | T | None:
188
- return self.serde.deserialize(ui_value, widget_id)
181
+ def deserialize(self, ui_value: list[int] | None) -> list[T] | T | None:
182
+ return self.serde.deserialize(ui_value)
189
183
 
190
184
 
191
185
  def get_mapped_options(
@@ -256,7 +250,7 @@ def _build_proto(
256
250
  return proto
257
251
 
258
252
 
259
- def _maybe_raise_selection_mode_warning(selection_mode: SelectionMode):
253
+ def _maybe_raise_selection_mode_warning(selection_mode: SelectionMode) -> None:
260
254
  """Check if the selection_mode value is valid or raise exception otherwise."""
261
255
  if selection_mode not in ["single", "multi"]:
262
256
  raise StreamlitAPIException(
@@ -556,7 +550,7 @@ class ButtonGroupMixin:
556
550
  label_visibility: "visible", "hidden", or "collapsed"
557
551
  The visibility of the label. The default is ``"visible"``. If this
558
552
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
559
- label, which can help keep the widget alligned with other widgets.
553
+ label, which can help keep the widget aligned with other widgets.
560
554
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
561
555
 
562
556
  Returns
@@ -765,7 +759,7 @@ class ButtonGroupMixin:
765
759
  label_visibility: "visible", "hidden", or "collapsed"
766
760
  The visibility of the label. The default is ``"visible"``. If this
767
761
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
768
- label, which can help keep the widget alligned with other widgets.
762
+ label, which can help keep the widget aligned with other widgets.
769
763
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
770
764
 
771
765
  Returns
@@ -990,6 +984,7 @@ class ButtonGroupMixin:
990
984
  widget_name,
991
985
  user_key=key,
992
986
  form_id=form_id,
987
+ dg=self.dg,
993
988
  options=formatted_options,
994
989
  default=default,
995
990
  click_mode=parsed_selection_mode,
@@ -22,6 +22,7 @@ from typing_extensions import TypeAlias
22
22
 
23
23
  from streamlit.elements.lib.file_uploader_utils import enforce_filename_restriction
24
24
  from streamlit.elements.lib.form_utils import current_form_id
25
+ from streamlit.elements.lib.layout_utils import LayoutConfig, validate_width
25
26
  from streamlit.elements.lib.policies import (
26
27
  check_widget_policies,
27
28
  maybe_raise_label_warnings,
@@ -49,6 +50,7 @@ from streamlit.runtime.uploaded_file_manager import DeletedFile, UploadedFile
49
50
 
50
51
  if TYPE_CHECKING:
51
52
  from streamlit.delta_generator import DeltaGenerator
53
+ from streamlit.elements.lib.layout_utils import WidthWithoutContent
52
54
 
53
55
  SomeUploadedSnapshotFile: TypeAlias = Union[UploadedFile, DeletedFile, None]
54
56
 
@@ -73,13 +75,10 @@ class CameraInputSerde:
73
75
  return state_proto
74
76
 
75
77
  def deserialize(
76
- self, ui_value: FileUploaderStateProto | None, widget_id: str
78
+ self, ui_value: FileUploaderStateProto | None
77
79
  ) -> SomeUploadedSnapshotFile:
78
80
  upload_files = _get_upload_files(ui_value)
79
- if len(upload_files) == 0:
80
- return_value = None
81
- else:
82
- return_value = upload_files[0]
81
+ return_value = None if len(upload_files) == 0 else upload_files[0]
83
82
  if return_value is not None and not isinstance(return_value, DeletedFile):
84
83
  enforce_filename_restriction(return_value.name, [".jpg"])
85
84
  return return_value
@@ -98,6 +97,7 @@ class CameraInputMixin:
98
97
  *, # keyword-only arguments:
99
98
  disabled: bool = False,
100
99
  label_visibility: LabelVisibility = "visible",
100
+ width: WidthWithoutContent = "stretch",
101
101
  ) -> UploadedFile | None:
102
102
  r"""Display a widget that returns pictures from the user's webcam.
103
103
 
@@ -156,9 +156,20 @@ class CameraInputMixin:
156
156
  label_visibility : "visible", "hidden", or "collapsed"
157
157
  The visibility of the label. The default is ``"visible"``. If this
158
158
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
159
- label, which can help keep the widget alligned with other widgets.
159
+ label, which can help keep the widget aligned with other widgets.
160
160
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
161
161
 
162
+ width : "stretch" or int
163
+ The width of the camera input widget. This can be one of the
164
+ following:
165
+
166
+ - ``"stretch"`` (default): The width of the widget matches the
167
+ width of the parent container.
168
+ - An integer specifying the width in pixels: The widget has a
169
+ fixed width. If the specified width is greater than the width of
170
+ the parent container, the width of the widget matches the width
171
+ of the parent container.
172
+
162
173
  Returns
163
174
  -------
164
175
  None or UploadedFile
@@ -191,6 +202,7 @@ class CameraInputMixin:
191
202
  kwargs=kwargs,
192
203
  disabled=disabled,
193
204
  label_visibility=label_visibility,
205
+ width=width,
194
206
  ctx=ctx,
195
207
  )
196
208
 
@@ -205,6 +217,7 @@ class CameraInputMixin:
205
217
  *, # keyword-only arguments:
206
218
  disabled: bool = False,
207
219
  label_visibility: LabelVisibility = "visible",
220
+ width: WidthWithoutContent = "stretch",
208
221
  ctx: ScriptRunContext | None = None,
209
222
  ) -> UploadedFile | None:
210
223
  key = to_key(key)
@@ -222,8 +235,10 @@ class CameraInputMixin:
222
235
  "camera_input",
223
236
  user_key=key,
224
237
  form_id=current_form_id(self.dg),
238
+ dg=self.dg,
225
239
  label=label,
226
240
  help=help,
241
+ width=width,
227
242
  )
228
243
 
229
244
  camera_input_proto = CameraInputProto()
@@ -238,6 +253,9 @@ class CameraInputMixin:
238
253
  if help is not None:
239
254
  camera_input_proto.help = dedent(help)
240
255
 
256
+ validate_width(width)
257
+ layout_config = LayoutConfig(width=width)
258
+
241
259
  serde = CameraInputSerde()
242
260
 
243
261
  camera_input_state = register_widget(
@@ -251,7 +269,9 @@ class CameraInputMixin:
251
269
  value_type="file_uploader_state_value",
252
270
  )
253
271
 
254
- self.dg._enqueue("camera_input", camera_input_proto)
272
+ self.dg._enqueue(
273
+ "camera_input", camera_input_proto, layout_config=layout_config
274
+ )
255
275
 
256
276
  if isinstance(camera_input_state.value, DeletedFile):
257
277
  return None
@@ -33,6 +33,12 @@ from streamlit.elements.lib.file_uploader_utils import (
33
33
  )
34
34
  from streamlit.elements.lib.form_utils import is_in_form
35
35
  from streamlit.elements.lib.image_utils import AtomicImage, WidthBehavior, image_to_url
36
+ from streamlit.elements.lib.layout_utils import (
37
+ LayoutConfig,
38
+ Width,
39
+ WidthWithoutContent,
40
+ validate_width,
41
+ )
36
42
  from streamlit.elements.lib.policies import check_widget_policies
37
43
  from streamlit.elements.lib.utils import (
38
44
  Key,
@@ -47,6 +53,7 @@ from streamlit.proto.ChatInput_pb2 import ChatInput as ChatInputProto
47
53
  from streamlit.proto.Common_pb2 import ChatInputValue as ChatInputValueProto
48
54
  from streamlit.proto.Common_pb2 import FileUploaderState as FileUploaderStateProto
49
55
  from streamlit.proto.RootContainer_pb2 import RootContainer
56
+ from streamlit.proto.WidthConfig_pb2 import WidthConfig
50
57
  from streamlit.runtime.metrics_util import gather_metrics
51
58
  from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
52
59
  from streamlit.runtime.state import (
@@ -117,11 +124,11 @@ def _process_avatar_input(
117
124
  Tuple[AvatarType, str]
118
125
  The detected avatar type and the prepared avatar data.
119
126
  """
120
- AvatarType = BlockProto.ChatMessage.AvatarType
127
+ AvatarType = BlockProto.ChatMessage.AvatarType # noqa: N806
121
128
 
122
129
  if avatar is None:
123
130
  return AvatarType.ICON, ""
124
- elif isinstance(avatar, str) and avatar in {item.value for item in PresetNames}:
131
+ if isinstance(avatar, str) and avatar in {item.value for item in PresetNames}:
125
132
  # On the frontend, we only support "assistant" and "user" for the avatar.
126
133
  return (
127
134
  AvatarType.ICON,
@@ -131,25 +138,24 @@ def _process_avatar_input(
131
138
  else "user"
132
139
  ),
133
140
  )
134
- elif isinstance(avatar, str) and is_emoji(avatar):
141
+ if isinstance(avatar, str) and is_emoji(avatar):
135
142
  return AvatarType.EMOJI, avatar
136
143
 
137
- elif isinstance(avatar, str) and avatar.startswith(":material"):
144
+ if isinstance(avatar, str) and avatar.startswith(":material"):
138
145
  return AvatarType.ICON, validate_material_icon(avatar)
139
- else:
140
- try:
141
- return AvatarType.IMAGE, image_to_url(
142
- avatar,
143
- width=WidthBehavior.ORIGINAL,
144
- clamp=False,
145
- channels="RGB",
146
- output_format="auto",
147
- image_id=delta_path,
148
- )
149
- except Exception as ex:
150
- raise StreamlitAPIException(
151
- "Failed to load the provided avatar value as an image."
152
- ) from ex
146
+ try:
147
+ return AvatarType.IMAGE, image_to_url(
148
+ avatar,
149
+ width=WidthBehavior.ORIGINAL,
150
+ clamp=False,
151
+ channels="RGB",
152
+ output_format="auto",
153
+ image_id=delta_path,
154
+ )
155
+ except Exception as ex:
156
+ raise StreamlitAPIException(
157
+ "Failed to load the provided avatar value as an image."
158
+ ) from ex
153
159
 
154
160
 
155
161
  def _pop_upload_files(
@@ -196,24 +202,21 @@ class ChatInputSerde:
196
202
  allowed_types: Sequence[str] | None = None
197
203
 
198
204
  def deserialize(
199
- self,
200
- ui_value: ChatInputValueProto | None,
201
- widget_id: str = "",
205
+ self, ui_value: ChatInputValueProto | None
202
206
  ) -> str | ChatInputValue | None:
203
207
  if ui_value is None or not ui_value.HasField("data"):
204
208
  return None
205
209
  if not self.accept_files:
206
210
  return ui_value.data
207
- else:
208
- uploaded_files = _pop_upload_files(ui_value.file_uploader_state)
209
- for file in uploaded_files:
210
- if self.allowed_types and not isinstance(file, DeletedFile):
211
- enforce_filename_restriction(file.name, self.allowed_types)
212
-
213
- return ChatInputValue(
214
- text=ui_value.data,
215
- files=uploaded_files,
216
- )
211
+ uploaded_files = _pop_upload_files(ui_value.file_uploader_state)
212
+ for file in uploaded_files:
213
+ if self.allowed_types and not isinstance(file, DeletedFile):
214
+ enforce_filename_restriction(file.name, self.allowed_types)
215
+
216
+ return ChatInputValue(
217
+ text=ui_value.data,
218
+ files=uploaded_files,
219
+ )
217
220
 
218
221
  def serialize(self, v: str | None) -> ChatInputValueProto:
219
222
  return ChatInputValueProto(data=v)
@@ -226,6 +229,7 @@ class ChatMixin:
226
229
  name: Literal["user", "assistant", "ai", "human"] | str,
227
230
  *,
228
231
  avatar: Literal["user", "assistant"] | str | AtomicImage | None = None,
232
+ width: Width = "stretch",
229
233
  ) -> DeltaGenerator:
230
234
  """Insert a chat message container.
231
235
 
@@ -233,6 +237,10 @@ class ChatMixin:
233
237
  (preferred) or just call methods directly on the returned object. See the
234
238
  examples below.
235
239
 
240
+ .. note::
241
+ To follow best design practices and maintain a good appearance on
242
+ all screen sizes, don't nest chat message containers.
243
+
236
244
  Parameters
237
245
  ----------
238
246
  name : "user", "assistant", "ai", "human", or str
@@ -276,6 +284,18 @@ class ChatMixin:
276
284
  .. |st.image| replace:: ``st.image``
277
285
  .. _st.image: https://docs.streamlit.io/develop/api-reference/media/st.image
278
286
 
287
+ width : "stretch", "content", or int
288
+ The width of the chat message container. This can be one of the following:
289
+
290
+ - ``"stretch"`` (default): The width of the container matches the
291
+ width of the parent container.
292
+ - ``"content"``: The width of the container matches the width of its
293
+ content, but doesn't exceed the width of the parent container.
294
+ - An integer specifying the width in pixels: The container has a
295
+ fixed width. If the specified width is greater than the width of
296
+ the parent container, the width of the container matches the width
297
+ of the parent container.
298
+
279
299
  Returns
280
300
  -------
281
301
  Container
@@ -324,13 +344,26 @@ class ChatMixin:
324
344
  avatar, self.dg._get_delta_path_str()
325
345
  )
326
346
 
347
+ validate_width(width, allow_content=True)
348
+
327
349
  message_container_proto = BlockProto.ChatMessage()
328
350
  message_container_proto.name = name
329
351
  message_container_proto.avatar = converted_avatar
330
352
  message_container_proto.avatar_type = avatar_type
353
+
354
+ # Set up width configuration
355
+ width_config = WidthConfig()
356
+ if isinstance(width, int):
357
+ width_config.pixel_width = width
358
+ elif width == "content":
359
+ width_config.use_content = True
360
+ else:
361
+ width_config.use_stretch = True
362
+
331
363
  block_proto = BlockProto()
332
364
  block_proto.allow_empty = True
333
365
  block_proto.chat_message.CopyFrom(message_container_proto)
366
+ block_proto.width_config.CopyFrom(width_config)
334
367
 
335
368
  return self.dg._block(block_proto=block_proto)
336
369
 
@@ -347,6 +380,7 @@ class ChatMixin:
347
380
  on_submit: WidgetCallback | None = None,
348
381
  args: WidgetArgs | None = None,
349
382
  kwargs: WidgetKwargs | None = None,
383
+ width: WidthWithoutContent = "stretch",
350
384
  ) -> str | None: ...
351
385
 
352
386
  @overload
@@ -362,6 +396,7 @@ class ChatMixin:
362
396
  on_submit: WidgetCallback | None = None,
363
397
  args: WidgetArgs | None = None,
364
398
  kwargs: WidgetKwargs | None = None,
399
+ width: WidthWithoutContent = "stretch",
365
400
  ) -> ChatInputValue | None: ...
366
401
 
367
402
  @gather_metrics("chat_input")
@@ -377,6 +412,7 @@ class ChatMixin:
377
412
  on_submit: WidgetCallback | None = None,
378
413
  args: WidgetArgs | None = None,
379
414
  kwargs: WidgetKwargs | None = None,
415
+ width: WidthWithoutContent = "stretch",
380
416
  ) -> str | ChatInputValue | None:
381
417
  """Display a chat input widget.
382
418
 
@@ -441,6 +477,17 @@ class ChatMixin:
441
477
  kwargs : dict
442
478
  An optional dict of kwargs to pass to the callback.
443
479
 
480
+ width : "stretch" or int
481
+ The width of the chat input widget. This can be one of the
482
+ following:
483
+
484
+ - ``"stretch"`` (default): The width of the widget matches the
485
+ width of the parent container.
486
+ - An integer specifying the width in pixels: The widget has a
487
+ fixed width. If the specified width is greater than the width of
488
+ the parent container, the width of the widget matches the width
489
+ of the parent container.
490
+
444
491
  Returns
445
492
  -------
446
493
  None, str, or dict-like
@@ -560,10 +607,12 @@ class ChatMixin:
560
607
  user_key=key,
561
608
  # chat_input is not allowed to be used in a form.
562
609
  form_id=None,
610
+ dg=self.dg,
563
611
  placeholder=placeholder,
564
612
  max_chars=max_chars,
565
613
  accept_file=accept_file,
566
614
  file_type=file_type,
615
+ width=width,
567
616
  )
568
617
 
569
618
  if file_type:
@@ -573,11 +622,10 @@ class ChatMixin:
573
622
  # We throw an error to warn the user about this.
574
623
  # We omit this check for scripts running outside streamlit, because
575
624
  # they will have no script_run_ctx.
576
- if runtime.exists():
577
- if is_in_form(self.dg):
578
- raise StreamlitAPIException(
579
- "`st.chat_input()` can't be used in a `st.form()`."
580
- )
625
+ if runtime.exists() and is_in_form(self.dg):
626
+ raise StreamlitAPIException(
627
+ "`st.chat_input()` can't be used in a `st.form()`."
628
+ )
581
629
 
582
630
  # Determine the position of the chat input:
583
631
  # Use bottom position if chat input is within the main container
@@ -623,6 +671,9 @@ class ChatMixin:
623
671
  value_type="chat_input_value",
624
672
  )
625
673
 
674
+ validate_width(width)
675
+ layout_config = LayoutConfig(width=width)
676
+
626
677
  chat_input_proto.disabled = disabled
627
678
  if widget_state.value_changed and widget_state.value is not None:
628
679
  chat_input_proto.value = widget_state.value
@@ -634,10 +685,12 @@ class ChatMixin:
634
685
  # We need to enqueue the chat input into the bottom container
635
686
  # instead of the currently active dg.
636
687
  get_dg_singleton_instance().bottom_dg._enqueue(
637
- "chat_input", chat_input_proto
688
+ "chat_input", chat_input_proto, layout_config=layout_config
638
689
  )
639
690
  else:
640
- self.dg._enqueue("chat_input", chat_input_proto)
691
+ self.dg._enqueue(
692
+ "chat_input", chat_input_proto, layout_config=layout_config
693
+ )
641
694
 
642
695
  return widget_state.value if not widget_state.value_changed else None
643
696
 
@@ -19,6 +19,11 @@ from textwrap import dedent
19
19
  from typing import TYPE_CHECKING, cast
20
20
 
21
21
  from streamlit.elements.lib.form_utils import current_form_id
22
+ from streamlit.elements.lib.layout_utils import (
23
+ LayoutConfig,
24
+ Width,
25
+ validate_width,
26
+ )
22
27
  from streamlit.elements.lib.policies import (
23
28
  check_widget_policies,
24
29
  maybe_raise_label_warnings,
@@ -51,7 +56,7 @@ class CheckboxSerde:
51
56
  def serialize(self, v: bool) -> bool:
52
57
  return bool(v)
53
58
 
54
- def deserialize(self, ui_value: bool | None, widget_id: str = "") -> bool:
59
+ def deserialize(self, ui_value: bool | None) -> bool:
55
60
  return bool(ui_value if ui_value is not None else self.value)
56
61
 
57
62
 
@@ -69,6 +74,7 @@ class CheckboxMixin:
69
74
  *, # keyword-only arguments:
70
75
  disabled: bool = False,
71
76
  label_visibility: LabelVisibility = "visible",
77
+ width: Width = "content",
72
78
  ) -> bool:
73
79
  r"""Display a checkbox widget.
74
80
 
@@ -130,9 +136,22 @@ class CheckboxMixin:
130
136
  label_visibility : "visible", "hidden", or "collapsed"
131
137
  The visibility of the label. The default is ``"visible"``. If this
132
138
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
133
- label, which can help keep the widget alligned with other widgets.
139
+ label, which can help keep the widget aligned with other widgets.
134
140
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
135
141
 
142
+ width : "content", "stretch", or int
143
+ The width of the checkbox widget. This can be one of the following:
144
+
145
+ - ``"content"`` (default): The width of the widget matches the
146
+ width of its content, but doesn't exceed the width of the parent
147
+ container.
148
+ - ``"stretch"``: The width of the widget matches the width of the
149
+ parent container.
150
+ - An integer specifying the width in pixels: The widget has a
151
+ fixed width. If the specified width is greater than the width of
152
+ the parent container, the width of the widget matches the width
153
+ of the parent container.
154
+
136
155
  Returns
137
156
  -------
138
157
  bool
@@ -165,6 +184,7 @@ class CheckboxMixin:
165
184
  label_visibility=label_visibility,
166
185
  type=CheckboxProto.StyleType.DEFAULT,
167
186
  ctx=ctx,
187
+ width=width,
168
188
  )
169
189
 
170
190
  @gather_metrics("toggle")
@@ -180,6 +200,7 @@ class CheckboxMixin:
180
200
  *, # keyword-only arguments:
181
201
  disabled: bool = False,
182
202
  label_visibility: LabelVisibility = "visible",
203
+ width: Width = "content",
183
204
  ) -> bool:
184
205
  r"""Display a toggle widget.
185
206
 
@@ -241,9 +262,22 @@ class CheckboxMixin:
241
262
  label_visibility : "visible", "hidden", or "collapsed"
242
263
  The visibility of the label. The default is ``"visible"``. If this
243
264
  is ``"hidden"``, Streamlit displays an empty spacer instead of the
244
- label, which can help keep the widget alligned with other widgets.
265
+ label, which can help keep the widget aligned with other widgets.
245
266
  If this is ``"collapsed"``, Streamlit displays no label or spacer.
246
267
 
268
+ width : "content", "stretch", or int
269
+ The width of the toggle widget. This can be one of the following:
270
+
271
+ - ``"content"`` (default): The width of the widget matches the
272
+ width of its content, but doesn't exceed the width of the parent
273
+ container.
274
+ - ``"stretch"``: The width of the widget matches the width of the
275
+ parent container.
276
+ - An integer specifying the width in pixels: The widget has a
277
+ fixed width. If the specified width is greater than the width of
278
+ the parent container, the width of the widget matches the width
279
+ of the parent container.
280
+
247
281
  Returns
248
282
  -------
249
283
  bool
@@ -276,6 +310,7 @@ class CheckboxMixin:
276
310
  label_visibility=label_visibility,
277
311
  type=CheckboxProto.StyleType.TOGGLE,
278
312
  ctx=ctx,
313
+ width=width,
279
314
  )
280
315
 
281
316
  def _checkbox(
@@ -292,6 +327,7 @@ class CheckboxMixin:
292
327
  label_visibility: LabelVisibility = "visible",
293
328
  type: CheckboxProto.StyleType.ValueType = CheckboxProto.StyleType.DEFAULT,
294
329
  ctx: ScriptRunContext | None = None,
330
+ width: Width = "content",
295
331
  ) -> bool:
296
332
  key = to_key(key)
297
333
 
@@ -307,9 +343,11 @@ class CheckboxMixin:
307
343
  "toggle" if type == CheckboxProto.StyleType.TOGGLE else "checkbox",
308
344
  user_key=key,
309
345
  form_id=current_form_id(self.dg),
346
+ dg=self.dg,
310
347
  label=label,
311
348
  value=bool(value),
312
349
  help=help,
350
+ width=width,
313
351
  )
314
352
 
315
353
  checkbox_proto = CheckboxProto()
@@ -326,6 +364,9 @@ class CheckboxMixin:
326
364
  if help is not None:
327
365
  checkbox_proto.help = dedent(help)
328
366
 
367
+ validate_width(width, allow_content=True)
368
+ layout_config = LayoutConfig(width=width)
369
+
329
370
  serde = CheckboxSerde(value)
330
371
 
331
372
  checkbox_state = register_widget(
@@ -343,7 +384,7 @@ class CheckboxMixin:
343
384
  checkbox_proto.value = checkbox_state.value
344
385
  checkbox_proto.set_value = True
345
386
 
346
- self.dg._enqueue("checkbox", checkbox_proto)
387
+ self.dg._enqueue("checkbox", checkbox_proto, layout_config=layout_config)
347
388
  return checkbox_state.value
348
389
 
349
390
  @property