streamlit 1.48.1__py3-none-any.whl → 1.49.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 (203) hide show
  1. streamlit/__init__.py +3 -10
  2. streamlit/commands/logo.py +4 -3
  3. streamlit/commands/navigation.py +1 -1
  4. streamlit/commands/page_config.py +4 -1
  5. streamlit/components/v1/custom_component.py +2 -2
  6. streamlit/config.py +82 -1
  7. streamlit/connections/snowflake_connection.py +3 -1
  8. streamlit/delta_generator.py +3 -0
  9. streamlit/elements/arrow.py +155 -70
  10. streamlit/elements/bokeh_chart.py +13 -3
  11. streamlit/elements/deck_gl_json_chart.py +0 -1
  12. streamlit/elements/dialog_decorator.py +7 -59
  13. streamlit/elements/form.py +10 -1
  14. streamlit/elements/graphviz_chart.py +57 -6
  15. streamlit/elements/heading.py +17 -16
  16. streamlit/elements/image.py +64 -37
  17. streamlit/elements/layouts.py +2 -2
  18. streamlit/elements/lib/built_in_chart_utils.py +2 -5
  19. streamlit/elements/lib/column_config_utils.py +18 -4
  20. streamlit/elements/lib/column_types.py +75 -30
  21. streamlit/elements/lib/dialog.py +3 -3
  22. streamlit/elements/lib/image_utils.py +19 -11
  23. streamlit/elements/lib/layout_utils.py +19 -6
  24. streamlit/elements/lib/utils.py +20 -41
  25. streamlit/elements/markdown.py +7 -6
  26. streamlit/elements/media.py +6 -13
  27. streamlit/elements/metric.py +78 -1
  28. streamlit/elements/pdf.py +192 -0
  29. streamlit/elements/plotly_chart.py +3 -2
  30. streamlit/elements/pyplot.py +53 -11
  31. streamlit/elements/toast.py +81 -5
  32. streamlit/elements/vega_charts.py +3 -8
  33. streamlit/elements/widgets/audio_input.py +0 -1
  34. streamlit/elements/widgets/button.py +0 -4
  35. streamlit/elements/widgets/button_group.py +5 -4
  36. streamlit/elements/widgets/camera_input.py +0 -1
  37. streamlit/elements/widgets/chat.py +11 -13
  38. streamlit/elements/widgets/checkbox.py +0 -1
  39. streamlit/elements/widgets/color_picker.py +0 -1
  40. streamlit/elements/widgets/data_editor.py +142 -62
  41. streamlit/elements/widgets/file_uploader.py +74 -37
  42. streamlit/elements/widgets/multiselect.py +0 -1
  43. streamlit/elements/widgets/number_input.py +0 -1
  44. streamlit/elements/widgets/radio.py +0 -1
  45. streamlit/elements/widgets/select_slider.py +0 -1
  46. streamlit/elements/widgets/selectbox.py +0 -1
  47. streamlit/elements/widgets/slider.py +0 -1
  48. streamlit/elements/widgets/text_widgets.py +0 -2
  49. streamlit/elements/widgets/time_widgets.py +0 -2
  50. streamlit/errors.py +11 -0
  51. streamlit/material_icon_names.py +1 -1
  52. streamlit/proto/Arrow_pb2.py +14 -8
  53. streamlit/proto/Arrow_pb2.pyi +11 -3
  54. streamlit/proto/Block_pb2.py +16 -16
  55. streamlit/proto/Block_pb2.pyi +2 -0
  56. streamlit/proto/ChatInput_pb2.py +3 -3
  57. streamlit/proto/ChatInput_pb2.pyi +2 -0
  58. streamlit/proto/FileUploader_pb2.py +2 -2
  59. streamlit/proto/FileUploader_pb2.pyi +5 -1
  60. streamlit/proto/GraphVizChart_pb2.py +4 -2
  61. streamlit/proto/GraphVizChart_pb2.pyi +1 -1
  62. streamlit/proto/Image_pb2.py +4 -2
  63. streamlit/proto/Image_pb2.pyi +1 -10
  64. streamlit/proto/Metric_pb2.py +8 -6
  65. streamlit/proto/Metric_pb2.pyi +34 -10
  66. streamlit/proto/Toast_pb2.py +2 -2
  67. streamlit/proto/Toast_pb2.pyi +10 -1
  68. streamlit/runtime/caching/__init__.py +14 -2
  69. streamlit/runtime/caching/cache_data_api.py +0 -17
  70. streamlit/runtime/caching/cache_resource_api.py +0 -16
  71. streamlit/runtime/caching/cached_message_replay.py +8 -20
  72. streamlit/runtime/caching/hashing.py +31 -1
  73. streamlit/runtime/credentials.py +4 -4
  74. streamlit/runtime/fragment.py +0 -42
  75. streamlit/runtime/websocket_session_manager.py +1 -1
  76. streamlit/static/index.html +2 -2
  77. streamlit/static/manifest.json +223 -251
  78. streamlit/static/static/css/{index.CJVRHjQZ.css → index.C8X8rNzw.css} +1 -1
  79. streamlit/static/static/css/index.COe1010n.css +1 -0
  80. streamlit/static/static/js/{ErrorOutline.esm.DjObtx4K.js → ErrorOutline.esm.DcGrhbBP.js} +1 -1
  81. streamlit/static/static/js/{FileDownload.esm.Bz9nxNC5.js → FileDownload.esm.DgBvV6Pq.js} +1 -1
  82. streamlit/static/static/js/FileHelper.M6AAaeuA.js +5 -0
  83. streamlit/static/static/js/FormClearHelper.DHh1GFzm.js +1 -0
  84. streamlit/static/static/js/{Hooks.DEoLCfOE.js → Hooks.DGu1od_L.js} +1 -1
  85. streamlit/static/static/js/InputInstructions.z6sVgyYt.js +1 -0
  86. streamlit/static/static/js/Particles.DDVT-6Qc.js +1 -0
  87. streamlit/static/static/js/ProgressBar.BEY0cXXV.js +2 -0
  88. streamlit/static/static/js/Toolbar.DSnK1fUh.js +1 -0
  89. streamlit/static/static/js/{base-input.BmvSaPd2.js → base-input.CK3UVGp1.js} +4 -4
  90. streamlit/static/static/js/{checkbox.Cgxgc0et.js → checkbox.D8W881TL.js} +2 -2
  91. streamlit/static/static/js/createSuper.B6W-Dh9S.js +1 -0
  92. streamlit/static/static/js/data-grid-overlay-editor.DRTHOydk.js +1 -0
  93. streamlit/static/static/js/{downloader.M6jQeNDf.js → downloader.DiKpuU_S.js} +1 -1
  94. streamlit/static/static/js/es6.B8zRNPZ-.js +2 -0
  95. streamlit/static/static/js/iframeResizer.contentWindow.DIewJmmh.js +1 -0
  96. streamlit/static/static/js/index.452cqrrL.js +1 -0
  97. streamlit/static/static/js/index.4eF4NxG2.js +1 -0
  98. streamlit/static/static/js/index.B6U8LQo3.js +1 -0
  99. streamlit/static/static/js/index.B9mjBcgE.js +1 -0
  100. streamlit/static/static/js/index.BXYmrqnf.js +1 -0
  101. streamlit/static/static/js/index.B_8AnktO.js +1 -0
  102. streamlit/static/static/js/index.Bl7zGQSh.js +7 -0
  103. streamlit/static/static/js/index.BnEpvLEz.js +1 -0
  104. streamlit/static/static/js/{index.D1EayrNh.js → index.BnJIOYn9.js} +2 -2
  105. streamlit/static/static/js/index.Bte_9Lyq.js +1 -0
  106. streamlit/static/static/js/index.C1HcTl5K.js +1 -0
  107. streamlit/static/static/js/index.C7fRKRs4.js +1 -0
  108. streamlit/static/static/js/index.C7lSmSOP.js +1 -0
  109. streamlit/static/static/js/index.CD8HuT3N.js +976 -0
  110. streamlit/static/static/js/index.CP5TD2z1.js +1 -0
  111. streamlit/static/static/js/index.C_tmcx4B.js +1 -0
  112. streamlit/static/static/js/index.CcJf6BCU.js +3858 -0
  113. streamlit/static/static/js/{index.CbdWnLqS.js → index.CejBxbg1.js} +3 -3
  114. streamlit/static/static/js/index.Ch7MBCx0.js +5367 -0
  115. streamlit/static/static/js/index.CjXWwH-y.js +1 -0
  116. streamlit/static/static/js/index.CvYYtxD_.js +1 -0
  117. streamlit/static/static/js/index.D2-atlaQ.js +3 -0
  118. streamlit/static/static/js/index.D3K5nOu9.js +197 -0
  119. streamlit/static/static/js/index.D5naqx-J.js +1 -0
  120. streamlit/static/static/js/index.Dk4C7X3i.js +1 -0
  121. streamlit/static/static/js/index.DkKT3LUI.js +1 -0
  122. streamlit/static/static/js/index.DtYN2x4k.js +1 -0
  123. streamlit/static/static/js/index.MTPPBDHk.js +2 -0
  124. streamlit/static/static/js/{index.Cqa4gqqN.js → index.Ts_0SdB9.js} +1 -1
  125. streamlit/static/static/js/{index.CgZDfhN4.js → index.cnnXF7xQ.js} +2 -2
  126. streamlit/static/static/js/index.ho6NIXGl.js +1 -0
  127. streamlit/static/static/js/index.pqW9AMJD.js +3 -0
  128. streamlit/static/static/js/{index.D1jHqUJq.js → index.qhs54UAB.js} +1 -1
  129. streamlit/static/static/js/{index.tsvTLdio.js → index.urHgTgMQ.js} +9 -9
  130. streamlit/static/static/js/index.wzkv_11M.js +1 -0
  131. streamlit/static/static/js/index.yF5AncHY.js +1 -0
  132. streamlit/static/static/js/{index.BXDq9dj4.js → index.zecpGxtj.js} +1 -1
  133. streamlit/static/static/js/{input.DZd6EQlV.js → input.nzVJphXi.js} +2 -2
  134. streamlit/static/static/js/{memory.ptkfuI71.js → memory.CjCgTQz3.js} +1 -1
  135. streamlit/static/static/js/number-overlay-editor.DaRFzZEO.js +9 -0
  136. streamlit/static/static/js/{possibleConstructorReturn.Bd4ImlQ9.js → possibleConstructorReturn.DgiPnZ9N.js} +1 -1
  137. streamlit/static/static/js/{sandbox.DsH8LuID.js → sandbox.mithfq7Z.js} +1 -1
  138. streamlit/static/static/js/{timepicker.QVekV78C.js → timepicker.Dbl5KFh6.js} +4 -4
  139. streamlit/static/static/js/{toConsumableArray.BJvaP8gb.js → toConsumableArray.D-Dx88BQ.js} +3 -3
  140. streamlit/static/static/js/uniqueId.Bh26R_3S.js +1 -0
  141. streamlit/static/static/js/{useBasicWidgetState.DB3vMS9V.js → useBasicWidgetState.DeK-QJpD.js} +1 -1
  142. streamlit/static/static/js/{useTextInputAutoExpand.CBkGkaRt.js → useTextInputAutoExpand.4iAdLWD-.js} +2 -2
  143. streamlit/static/static/js/useUpdateUiValue.CmT7_nJN.js +1 -0
  144. streamlit/static/static/js/withFullScreenWrapper.DLp1ENGm.js +1 -0
  145. streamlit/static/static/media/MaterialSymbols-Rounded.CBxVaFdk.woff2 +0 -0
  146. streamlit/user_info.py +3 -1
  147. streamlit/web/server/browser_websocket_handler.py +15 -0
  148. {streamlit-1.48.1.dist-info → streamlit-1.49.1.dist-info}/METADATA +4 -2
  149. {streamlit-1.48.1.dist-info → streamlit-1.49.1.dist-info}/RECORD +153 -156
  150. streamlit/static/static/css/index.CQt5TjGB.css +0 -1
  151. streamlit/static/static/js/FileHelper.BrQvUXVD.js +0 -5
  152. streamlit/static/static/js/FormClearHelper.DF4gFAOO.js +0 -1
  153. streamlit/static/static/js/InputInstructions.D8zoMog9.js +0 -1
  154. streamlit/static/static/js/Particles.CCFySwdL.js +0 -1
  155. streamlit/static/static/js/ProgressBar.COK9j1l0.js +0 -2
  156. streamlit/static/static/js/Toolbar.Dt4jIKlY.js +0 -1
  157. streamlit/static/static/js/createSuper.siQeagI2.js +0 -1
  158. streamlit/static/static/js/data-grid-overlay-editor.Ct51iCb_.js +0 -1
  159. streamlit/static/static/js/es6.CMaUdEZ5.js +0 -2
  160. streamlit/static/static/js/iframeResizer.contentWindow.C33BryyP.js +0 -1
  161. streamlit/static/static/js/index.8GJD0eeD.js +0 -1
  162. streamlit/static/static/js/index.8QEYHMQD.js +0 -1
  163. streamlit/static/static/js/index.Ay41Wnu9.js +0 -1
  164. streamlit/static/static/js/index.BLiKiJ7_.js +0 -1
  165. streamlit/static/static/js/index.BT78cJmU.js +0 -1
  166. streamlit/static/static/js/index.BdGvnhlM.js +0 -1
  167. streamlit/static/static/js/index.BfasrT0d.js +0 -1
  168. streamlit/static/static/js/index.CCdtFMFG.js +0 -1
  169. streamlit/static/static/js/index.CFRGZDz1.js +0 -1
  170. streamlit/static/static/js/index.CFSFYiPA.js +0 -5366
  171. streamlit/static/static/js/index.CeiIiXap.js +0 -1
  172. streamlit/static/static/js/index.CzX2xpyc.js +0 -1
  173. streamlit/static/static/js/index.D1ErX5go.js +0 -2
  174. streamlit/static/static/js/index.D5gweoL5.js +0 -7
  175. streamlit/static/static/js/index.DByVKZgq.js +0 -1
  176. streamlit/static/static/js/index.DEND45D1.js +0 -3
  177. streamlit/static/static/js/index.DKN5MVff.js +0 -781
  178. streamlit/static/static/js/index.DfoxW1gP.js +0 -3855
  179. streamlit/static/static/js/index.Dtf1Ac0x.js +0 -1
  180. streamlit/static/static/js/index.DxrLhpeO.js +0 -1
  181. streamlit/static/static/js/index.J7o-_HIh.js +0 -1
  182. streamlit/static/static/js/index.LU8juINp.js +0 -197
  183. streamlit/static/static/js/index.L_N2iylt.js +0 -1
  184. streamlit/static/static/js/index.PZUX2kRz.js +0 -3
  185. streamlit/static/static/js/index.ROjU6K0k.js +0 -1
  186. streamlit/static/static/js/index.WSNLkF94.js +0 -1
  187. streamlit/static/static/js/index.X5W3gJLn.js +0 -1
  188. streamlit/static/static/js/index.k9LYqfSL.js +0 -1
  189. streamlit/static/static/js/index.pnHtHv_c.js +0 -203
  190. streamlit/static/static/js/index.tPUXqsfW.js +0 -1
  191. streamlit/static/static/js/mergeWith.GRNk8iwv.js +0 -1
  192. streamlit/static/static/js/number-overlay-editor.DXS2qb1U.js +0 -9
  193. streamlit/static/static/js/threshold.DjX0wlsa.js +0 -1
  194. streamlit/static/static/js/timer.CAwTRJ_g.js +0 -1
  195. streamlit/static/static/js/uniqueId.D_5M8Dgf.js +0 -1
  196. streamlit/static/static/js/useUpdateUiValue.C7ZKpLQK.js +0 -1
  197. streamlit/static/static/js/value.CgPGBV_l.js +0 -1
  198. streamlit/static/static/js/withFullScreenWrapper.C-gXt0Rl.js +0 -1
  199. streamlit/static/static/media/MaterialSymbols-Rounded.DsbC8sYI.woff2 +0 -0
  200. {streamlit-1.48.1.data → streamlit-1.49.1.data}/scripts/streamlit.cmd +0 -0
  201. {streamlit-1.48.1.dist-info → streamlit-1.49.1.dist-info}/WHEEL +0 -0
  202. {streamlit-1.48.1.dist-info → streamlit-1.49.1.dist-info}/entry_points.txt +0 -0
  203. {streamlit-1.48.1.dist-info → streamlit-1.49.1.dist-info}/top_level.txt +0 -0
@@ -18,7 +18,7 @@
18
18
  from __future__ import annotations
19
19
 
20
20
  import datetime
21
- from typing import TYPE_CHECKING, Literal, TypedDict, Union
21
+ from typing import TYPE_CHECKING, Callable, Literal, TypedDict, Union
22
22
 
23
23
  from typing_extensions import NotRequired, TypeAlias
24
24
 
@@ -84,9 +84,17 @@ class CheckboxColumnConfig(TypedDict):
84
84
  type: Literal["checkbox"]
85
85
 
86
86
 
87
+ SelectboxOptionValue: TypeAlias = Union[str, int, float, bool]
88
+
89
+
90
+ class SelectboxOption(TypedDict):
91
+ value: SelectboxOptionValue
92
+ label: NotRequired[str | None]
93
+
94
+
87
95
  class SelectboxColumnConfig(TypedDict):
88
96
  type: Literal["selectbox"]
89
- options: NotRequired[list[str | int | float] | None]
97
+ options: NotRequired[list[SelectboxOptionValue | SelectboxOption] | None]
90
98
 
91
99
 
92
100
  class LinkColumnConfig(TypedDict):
@@ -190,8 +198,7 @@ class ColumnConfig(TypedDict, total=False):
190
198
 
191
199
  disabled: bool or None
192
200
  Whether editing should be disabled for this column. If this is ``None``
193
- (default), Streamlit will decide: indices are disabled and data columns
194
- are not.
201
+ (default), Streamlit will enable editing wherever possible.
195
202
 
196
203
  If a column has mixed types, it may become uneditable regardless of
197
204
  ``disabled``.
@@ -227,7 +234,7 @@ class ColumnConfig(TypedDict, total=False):
227
234
  disabled: bool | None
228
235
  required: bool | None
229
236
  pinned: bool | None
230
- default: str | bool | int | float | None
237
+ default: str | bool | int | float | list[str] | None
231
238
  alignment: Literal["left", "center", "right"] | None
232
239
  type_config: (
233
240
  NumberColumnConfig
@@ -295,8 +302,7 @@ def Column(
295
302
 
296
303
  disabled: bool or None
297
304
  Whether editing should be disabled for this column. If this is ``None``
298
- (default), Streamlit will decide: indices are disabled and data columns
299
- are not.
305
+ (default), Streamlit will enable editing wherever possible.
300
306
 
301
307
  If a column has mixed types, it may become uneditable regardless of
302
308
  ``disabled``.
@@ -400,8 +406,7 @@ def NumberColumn(
400
406
 
401
407
  disabled: bool or None
402
408
  Whether editing should be disabled for this column. If this is ``None``
403
- (default), Streamlit will decide: indices are disabled and data columns
404
- are not.
409
+ (default), Streamlit will enable editing wherever possible.
405
410
 
406
411
  If a column has mixed types, it may become uneditable regardless of
407
412
  ``disabled``.
@@ -563,8 +568,7 @@ def TextColumn(
563
568
 
564
569
  disabled: bool or None
565
570
  Whether editing should be disabled for this column. If this is ``None``
566
- (default), Streamlit will decide: indices are disabled and data columns
567
- are not.
571
+ (default), Streamlit will enable editing wherever possible.
568
572
 
569
573
  If a column has mixed types, it may become uneditable regardless of
570
574
  ``disabled``.
@@ -686,8 +690,7 @@ def LinkColumn(
686
690
 
687
691
  disabled: bool or None
688
692
  Whether editing should be disabled for this column. If this is ``None``
689
- (default), Streamlit will decide: indices are disabled and data columns
690
- are not.
693
+ (default), Streamlit will enable editing wherever possible.
691
694
 
692
695
  If a column has mixed types, it may become uneditable regardless of
693
696
  ``disabled``.
@@ -845,8 +848,7 @@ def CheckboxColumn(
845
848
 
846
849
  disabled: bool or None
847
850
  Whether editing should be disabled for this column. If this is ``None``
848
- (default), Streamlit will decide: indices are disabled and data columns
849
- are not.
851
+ (default), Streamlit will enable editing wherever possible.
850
852
 
851
853
  If a column has mixed types, it may become uneditable regardless of
852
854
  ``disabled``.
@@ -919,8 +921,9 @@ def SelectboxColumn(
919
921
  disabled: bool | None = None,
920
922
  required: bool | None = None,
921
923
  pinned: bool | None = None,
922
- default: str | int | float | None = None,
923
- options: Iterable[str | int | float] | None = None,
924
+ default: SelectboxOptionValue | None = None,
925
+ options: Iterable[SelectboxOptionValue] | None = None,
926
+ format_func: Callable[[SelectboxOptionValue], str] | None = None,
924
927
  ) -> ColumnConfig:
925
928
  """Configure a selectbox column in ``st.dataframe`` or ``st.data_editor``.
926
929
 
@@ -954,8 +957,7 @@ def SelectboxColumn(
954
957
 
955
958
  disabled: bool or None
956
959
  Whether editing should be disabled for this column. If this is ``None``
957
- (default), Streamlit will decide: indices are disabled and data columns
958
- are not.
960
+ (default), Streamlit will enable editing wherever possible.
959
961
 
960
962
  If a column has mixed types, it may become uneditable regardless of
961
963
  ``disabled``.
@@ -977,12 +979,19 @@ def SelectboxColumn(
977
979
  Specifies the default value in this column when a new row is added by
978
980
  the user. This defaults to ``None``.
979
981
 
980
- options: Iterable of str or None
982
+ options: Iterable[str, int, float, bool] or None
981
983
  The options that can be selected during editing. If this is ``None``
982
984
  (default), the options will be inferred from the underlying dataframe
983
985
  column if its dtype is "category". For more information, see `Pandas docs
984
986
  <https://pandas.pydata.org/docs/user_guide/categorical.html>`_).
985
987
 
988
+ format_func: function or None
989
+ Function to modify the display of the options. It receives
990
+ the raw option defined in ``options`` as an argument and should output
991
+ the label to be shown for that option. If this is ``None`` (default),
992
+ the raw option is used as the label.
993
+
994
+
986
995
  Examples
987
996
  --------
988
997
  >>> import pandas as pd
@@ -1022,6 +1031,15 @@ def SelectboxColumn(
1022
1031
  height: 300px
1023
1032
  """
1024
1033
 
1034
+ # Process options with format_func
1035
+ processed_options: Iterable[str | int | float | SelectboxOption] | None = options
1036
+ if options and format_func is not None:
1037
+ processed_options = []
1038
+ for option in options:
1039
+ processed_options.append(
1040
+ SelectboxOption(value=option, label=format_func(option))
1041
+ )
1042
+
1025
1043
  return ColumnConfig(
1026
1044
  label=label,
1027
1045
  width=width,
@@ -1031,7 +1049,8 @@ def SelectboxColumn(
1031
1049
  pinned=pinned,
1032
1050
  default=default,
1033
1051
  type_config=SelectboxColumnConfig(
1034
- type="selectbox", options=list(options) if options is not None else None
1052
+ type="selectbox",
1053
+ options=list(processed_options) if processed_options is not None else None,
1035
1054
  ),
1036
1055
  )
1037
1056
 
@@ -1427,12 +1446,20 @@ def ListColumn(
1427
1446
  width: ColumnWidth | None = None,
1428
1447
  help: str | None = None,
1429
1448
  pinned: bool | None = None,
1449
+ disabled: bool | None = None,
1450
+ required: bool | None = None,
1451
+ default: Iterable[str] | None = None,
1430
1452
  ) -> ColumnConfig:
1431
1453
  """Configure a list column in ``st.dataframe`` or ``st.data_editor``.
1432
1454
 
1433
- This is the default column type for list-like values. List columns are not editable
1434
- at the moment. This command needs to be used in the ``column_config`` parameter of
1435
- ``st.dataframe`` or ``st.data_editor``.
1455
+ This is the default column type for list-like values. This command needs to
1456
+ be used in the ``column_config`` parameter of ``st.dataframe`` or
1457
+ ``st.data_editor``.
1458
+
1459
+ .. Note::
1460
+ Editing for non-string or mixed type lists can cause issues with Arrow
1461
+ serialization. We recommend you disable editing for these columns or
1462
+ convert of all list values to strings.
1436
1463
 
1437
1464
  Parameters
1438
1465
  ----------
@@ -1464,6 +1491,24 @@ def ListColumn(
1464
1491
  (default), Streamlit will decide: index columns are pinned, and data
1465
1492
  columns are not pinned.
1466
1493
 
1494
+ disabled: bool or None
1495
+ Whether editing should be disabled for this column. If this is ``None``
1496
+ (default), Streamlit will enable editing wherever possible.
1497
+
1498
+ If a column has mixed types, it may become uneditable regardless of
1499
+ ``disabled``.
1500
+
1501
+ required: bool or None
1502
+ Whether edited cells in the column need to have a value. If this is
1503
+ ``False`` (default), the user can submit empty values for this column.
1504
+ If this is ``True``, an edited cell in this column can only be
1505
+ submitted if its value is not ``None``, and a new row will only be
1506
+ submitted after the user fills in this column.
1507
+
1508
+ default: Iterable of str or None
1509
+ Specifies the default value in this column when a new row is added by
1510
+ the user. This defaults to ``None``.
1511
+
1467
1512
  Examples
1468
1513
  --------
1469
1514
  >>> import pandas as pd
@@ -1501,6 +1546,9 @@ def ListColumn(
1501
1546
  width=width,
1502
1547
  help=help,
1503
1548
  pinned=pinned,
1549
+ disabled=disabled,
1550
+ required=required,
1551
+ default=None if default is None else list(default),
1504
1552
  type_config=ListColumnConfig(type="list"),
1505
1553
  )
1506
1554
 
@@ -1554,8 +1602,7 @@ def DatetimeColumn(
1554
1602
 
1555
1603
  disabled: bool or None
1556
1604
  Whether editing should be disabled for this column. If this is ``None``
1557
- (default), Streamlit will decide: indices are disabled and data columns
1558
- are not.
1605
+ (default), Streamlit will enable editing wherever possible.
1559
1606
 
1560
1607
  If a column has mixed types, it may become uneditable regardless of
1561
1608
  ``disabled``.
@@ -1717,8 +1764,7 @@ def TimeColumn(
1717
1764
 
1718
1765
  disabled: bool or None
1719
1766
  Whether editing should be disabled for this column. If this is ``None``
1720
- (default), Streamlit will decide: indices are disabled and data columns
1721
- are not.
1767
+ (default), Streamlit will enable editing wherever possible.
1722
1768
 
1723
1769
  If a column has mixed types, it may become uneditable regardless of
1724
1770
  ``disabled``.
@@ -1871,8 +1917,7 @@ def DateColumn(
1871
1917
 
1872
1918
  disabled: bool or None
1873
1919
  Whether editing should be disabled for this column. If this is ``None``
1874
- (default), Streamlit will decide: indices are disabled and data columns
1875
- are not.
1920
+ (default), Streamlit will enable editing wherever possible.
1876
1921
 
1877
1922
  If a column has mixed types, it may become uneditable regardless of
1878
1923
  ``disabled``.
@@ -35,7 +35,7 @@ if TYPE_CHECKING:
35
35
  from streamlit.cursor import Cursor
36
36
  from streamlit.runtime.state import WidgetCallback
37
37
 
38
- DialogWidth: TypeAlias = Literal["small", "large"]
38
+ DialogWidth: TypeAlias = Literal["small", "large", "medium"]
39
39
 
40
40
 
41
41
  def _process_dialog_width_input(
@@ -47,6 +47,8 @@ def _process_dialog_width_input(
47
47
  """
48
48
  if width == "large":
49
49
  return BlockProto.Dialog.DialogWidth.LARGE
50
+ if width == "medium":
51
+ return BlockProto.Dialog.DialogWidth.MEDIUM
50
52
 
51
53
  return BlockProto.Dialog.DialogWidth.SMALL
52
54
 
@@ -110,8 +112,6 @@ class Dialog(DeltaGenerator):
110
112
  element_id = compute_and_register_element_id(
111
113
  "dialog",
112
114
  user_key=None,
113
- # Dialogs within forms still trigger a normal rerun:
114
- form_id="",
115
115
  dg=parent,
116
116
  title=title,
117
117
  dismissible=dismissible,
@@ -34,6 +34,7 @@ if TYPE_CHECKING:
34
34
  import numpy.typing as npt
35
35
  from PIL import GifImagePlugin, Image, ImageFile
36
36
 
37
+ from streamlit.elements.lib.layout_utils import LayoutConfig
37
38
  from streamlit.proto.Image_pb2 import ImageList as ImageListProto
38
39
  from streamlit.type_util import NumpyShape
39
40
 
@@ -176,7 +177,7 @@ def _get_image_format_mimetype(image_format: ImageFormat) -> str:
176
177
 
177
178
 
178
179
  def _ensure_image_size_and_format(
179
- image_data: bytes, width: int, image_format: ImageFormat
180
+ image_data: bytes, layout_config: LayoutConfig, image_format: ImageFormat
180
181
  ) -> bytes:
181
182
  """Resize an image if it exceeds the given width, or if exceeds
182
183
  MAXIMUM_CONTENT_WIDTH. Ensure the image's format corresponds to the given
@@ -187,17 +188,25 @@ def _ensure_image_size_and_format(
187
188
  pil_image: PILImage = Image.open(io.BytesIO(image_data))
188
189
  actual_width, actual_height = pil_image.size
189
190
 
190
- if width < 0 and actual_width > MAXIMUM_CONTENT_WIDTH:
191
- width = MAXIMUM_CONTENT_WIDTH
191
+ target_width = (
192
+ layout_config.width
193
+ if isinstance(layout_config.width, int)
194
+ else MAXIMUM_CONTENT_WIDTH
195
+ )
192
196
 
193
- if width > 0 and actual_width > width:
197
+ # Resizing the image down if the embedded width is greater than
198
+ # the target width.
199
+ if target_width > 0 and actual_width > target_width:
194
200
  # We need to resize the image.
195
- new_height = int(1.0 * actual_height * width / actual_width)
201
+ new_height = int(1.0 * actual_height * target_width / actual_width)
196
202
  # pillow reexports Image.Resampling.BILINEAR as Image.BILINEAR for backwards
197
203
  # compatibility reasons, so we use the reexport to support older pillow
198
204
  # versions. The types don't seem to reflect this, though, hence the type: ignore
199
205
  # below.
200
- pil_image = pil_image.resize((width, new_height), resample=Image.BILINEAR) # type: ignore[attr-defined]
206
+ pil_image = pil_image.resize(
207
+ (target_width, new_height),
208
+ resample=Image.BILINEAR, # type: ignore[attr-defined]
209
+ )
201
210
  return _pil_to_bytes(pil_image, format=image_format, quality=90)
202
211
 
203
212
  if pil_image.format != image_format:
@@ -227,7 +236,7 @@ def _clip_image(image: npt.NDArray[Any], clamp: bool) -> npt.NDArray[Any]:
227
236
 
228
237
  def image_to_url(
229
238
  image: AtomicImage,
230
- width: int,
239
+ layout_config: LayoutConfig,
231
240
  clamp: bool,
232
241
  channels: Channels,
233
242
  output_format: ImageFormatOrAuto,
@@ -327,7 +336,7 @@ def image_to_url(
327
336
 
328
337
  # Determine the image's format, resize it, and get its mimetype
329
338
  image_format = _validate_image_format_string(image_data, output_format)
330
- image_data = _ensure_image_size_and_format(image_data, width, image_format)
339
+ image_data = _ensure_image_size_and_format(image_data, layout_config, image_format)
331
340
  mimetype = _get_image_format_mimetype(image_format)
332
341
 
333
342
  if runtime.exists():
@@ -346,7 +355,7 @@ def marshall_images(
346
355
  coordinates: str,
347
356
  image: ImageOrImageList,
348
357
  caption: str | npt.NDArray[Any] | list[str] | None,
349
- width: int | WidthBehavior,
358
+ layout_config: LayoutConfig,
350
359
  proto_imgs: ImageListProto,
351
360
  clamp: bool,
352
361
  channels: Channels = "RGB",
@@ -423,7 +432,6 @@ def marshall_images(
423
432
  f"Cannot pair {len(captions)} captions with {len(images)} images."
424
433
  )
425
434
 
426
- proto_imgs.width = int(width)
427
435
  # Each image in an image list needs to be kept track of at its own coordinates.
428
436
  for coord_suffix, (single_image, single_caption) in enumerate(
429
437
  zip(images, captions)
@@ -437,5 +445,5 @@ def marshall_images(
437
445
  image_id = f"{coordinates}-{coord_suffix}"
438
446
 
439
447
  proto_img.url = image_to_url(
440
- single_image, width, clamp, channels, output_format, image_id
448
+ single_image, layout_config, clamp, channels, output_format, image_id
441
449
  )
@@ -74,7 +74,12 @@ def validate_width(width: Width, allow_content: bool = False) -> None:
74
74
  raise StreamlitInvalidWidthError(width, allow_content)
75
75
 
76
76
 
77
- def validate_height(height: Height, allow_content: bool = False) -> None:
77
+ def validate_height(
78
+ height: Height | Literal["auto"],
79
+ allow_content: bool = False,
80
+ allow_stretch: bool = True,
81
+ additional_allowed: list[str] | None = None,
82
+ ) -> None:
78
83
  """Validate the height parameter.
79
84
 
80
85
  Parameters
@@ -83,6 +88,10 @@ def validate_height(height: Height, allow_content: bool = False) -> None:
83
88
  The height value to validate.
84
89
  allow_content : bool
85
90
  Whether to allow "content" as a valid height value.
91
+ allow_stretch : bool
92
+ Whether to allow "stretch" as a valid height value.
93
+ additional_allowed : list[str] or None
94
+ Additional string values to allow beyond the base allowed values.
86
95
 
87
96
  Raises
88
97
  ------
@@ -93,9 +102,13 @@ def validate_height(height: Height, allow_content: bool = False) -> None:
93
102
  raise StreamlitInvalidHeightError(height, allow_content)
94
103
 
95
104
  if isinstance(height, str):
96
- valid_strings = ["stretch"]
105
+ valid_strings = []
106
+ if allow_stretch:
107
+ valid_strings.append("stretch")
97
108
  if allow_content:
98
109
  valid_strings.append("content")
110
+ if additional_allowed:
111
+ valid_strings.extend(additional_allowed)
99
112
 
100
113
  if height not in valid_strings:
101
114
  raise StreamlitInvalidHeightError(height, allow_content)
@@ -106,8 +119,8 @@ def validate_height(height: Height, allow_content: bool = False) -> None:
106
119
 
107
120
  def get_width_config(width: Width) -> WidthConfig:
108
121
  width_config = WidthConfig()
109
- if isinstance(width, int):
110
- width_config.pixel_width = width
122
+ if isinstance(width, (int, float)):
123
+ width_config.pixel_width = int(width)
111
124
  elif width == "content":
112
125
  width_config.use_content = True
113
126
  else:
@@ -117,8 +130,8 @@ def get_width_config(width: Width) -> WidthConfig:
117
130
 
118
131
  def get_height_config(height: Height) -> HeightConfig:
119
132
  height_config = HeightConfig()
120
- if isinstance(height, int):
121
- height_config.pixel_height = height
133
+ if isinstance(height, (int, float)):
134
+ height_config.pixel_height = int(height)
122
135
  elif height == "content":
123
136
  height_config.use_content = True
124
137
  else:
@@ -28,10 +28,10 @@ from google.protobuf.message import Message
28
28
  from typing_extensions import TypeAlias
29
29
 
30
30
  from streamlit import config
31
+ from streamlit.elements.lib.form_utils import current_form_id
31
32
  from streamlit.errors import StreamlitDuplicateElementId, StreamlitDuplicateElementKey
32
33
  from streamlit.proto.ChatInput_pb2 import ChatInput
33
34
  from streamlit.proto.LabelVisibilityMessage_pb2 import LabelVisibilityMessage
34
- from streamlit.proto.RootContainer_pb2 import RootContainer
35
35
  from streamlit.runtime.scriptrunner_utils.script_run_context import (
36
36
  ScriptRunContext,
37
37
  get_script_run_ctx,
@@ -82,7 +82,7 @@ def get_label_visibility_proto_value(
82
82
 
83
83
 
84
84
  def get_chat_input_accept_file_proto_value(
85
- accept_file_value: bool | Literal["multiple"],
85
+ accept_file_value: Literal["multiple", "directory"] | bool,
86
86
  ) -> ChatInput.AcceptFile.ValueType:
87
87
  """Returns one of ChatInput.AcceptFile enum value based on string value."""
88
88
 
@@ -92,6 +92,8 @@ def get_chat_input_accept_file_proto_value(
92
92
  return ChatInput.AcceptFile.SINGLE
93
93
  if accept_file_value == "multiple":
94
94
  return ChatInput.AcceptFile.MULTIPLE
95
+ if accept_file_value == "directory":
96
+ return ChatInput.AcceptFile.DIRECTORY
95
97
 
96
98
  raise ValueError(f"Unknown accept file value: {accept_file_value}")
97
99
 
@@ -184,9 +186,8 @@ def compute_and_register_element_id(
184
186
  element_type: str,
185
187
  *,
186
188
  user_key: str | None,
187
- form_id: str | None,
188
- dg: DeltaGenerator | None = None,
189
- style: str | None = None,
189
+ dg: DeltaGenerator | None,
190
+ key_as_main_identity: bool = False,
190
191
  **kwargs: SAFE_VALUES | Iterable[SAFE_VALUES],
191
192
  ) -> str:
192
193
  """Compute and register the ID for the given element.
@@ -213,65 +214,43 @@ def compute_and_register_element_id(
213
214
  The user-specified key for the element. `None` if no key is provided
214
215
  or if the element doesn't support a specifying a key.
215
216
 
216
- form_id : str | None
217
- The ID of the form that the element belongs to. `None` or empty string
218
- if the element doesn't belong to a form or doesn't support forms.
219
-
220
217
  dg : DeltaGenerator | None
221
218
  The DeltaGenerator of each element. `None` if the element is not a widget.
222
219
 
223
- style: str | None
224
- The style of the element, to provide more context to the user in the
225
- error message. This should be `None` if the element does not support
226
- the style parameter.
227
-
228
220
  kwargs : SAFE_VALUES | Iterable[SAFE_VALUES]
229
221
  The arguments to use to compute the element ID.
230
222
  The arguments must be stable, deterministic values.
231
223
  Some common parameters like key, disabled,
232
224
  format_func, label_visibility, args, kwargs, on_change, and
233
225
  the active_script_hash are not supposed to be added here
226
+
227
+ key_as_main_identity : bool
228
+ If True, if a key is provided by the user, we don't include
229
+ command kwargs in the element ID computation.
234
230
  """
235
231
  ctx = get_script_run_ctx()
236
232
 
237
- kwargs_to_use = {**kwargs}
238
- if form_id:
239
- kwargs_to_use["form_id"] = form_id
240
- if style:
241
- kwargs_to_use["style"] = style
242
-
243
- # If style is provided, use it for the error message, to provide more
244
- # context to the user.
245
- if style == "borderless":
246
- # The borderless style is used by st.feedback, but users expect to see
247
- # "feedback" in errors
248
- element_type_for_error = "feedback"
249
- elif style:
250
- element_type_for_error = style
251
- else:
252
- element_type_for_error = element_type
233
+ ignore_command_kwargs = key_as_main_identity and user_key
234
+
235
+ kwargs_to_use = {} if ignore_command_kwargs else {**kwargs}
253
236
 
254
237
  if ctx:
255
238
  # Add the active script hash to give elements on different
256
- # pages unique IDs.
239
+ # pages unique IDs. This is added even if
240
+ # key_as_main_identity is specified.
257
241
  kwargs_to_use["active_script_hash"] = ctx.active_script_hash
258
242
 
259
- if dg:
243
+ if dg and not ignore_command_kwargs:
244
+ kwargs_to_use["form_id"] = current_form_id(dg)
260
245
  # If no key is provided and the widget element is inside the sidebar area
261
246
  # add it to the kwargs
262
247
  # allowing the same widget to be both in main area and sidebar.
263
- active_dg_root_container = dg._active_dg._root_container
264
- if active_dg_root_container == RootContainer.SIDEBAR and user_key is None:
265
- kwargs_to_use["active_dg_root_container"] = str(active_dg_root_container)
248
+ kwargs_to_use["active_dg_root_container"] = dg._active_dg._root_container
266
249
 
267
- element_id = _compute_element_id(
268
- element_type,
269
- user_key,
270
- **kwargs_to_use,
271
- )
250
+ element_id = _compute_element_id(element_type, user_key, **kwargs_to_use)
272
251
 
273
252
  if ctx:
274
- _register_element_id(ctx, element_type_for_error, element_id)
253
+ _register_element_id(ctx, element_type, element_id)
275
254
  return element_id
276
255
 
277
256
 
@@ -80,7 +80,7 @@ class MarkdownMixin:
80
80
  - Colored text and background colors for text, using the syntax
81
81
  ``:color[text to be colored]`` and ``:color-background[text to be colored]``,
82
82
  respectively. ``color`` must be replaced with any of the following
83
- supported colors: blue, green, orange, red, violet, gray/grey,
83
+ supported colors: red, orange, yellow, green, blue, violet, gray/grey,
84
84
  rainbow, or primary. For example, you can use
85
85
  ``:orange[your text here]`` or ``:blue-background[your text here]``.
86
86
  If you use "primary" for color, Streamlit will use the default
@@ -89,7 +89,7 @@ class MarkdownMixin:
89
89
 
90
90
  - Colored badges, using the syntax ``:color-badge[text in the badge]``.
91
91
  ``color`` must be replaced with any of the following supported
92
- colors: blue, green, orange, red, violet, gray/grey, or primary.
92
+ colors: red, orange, yellow, green, blue, violet, gray/grey, or primary.
93
93
  For example, you can use ``:orange-badge[your text here]`` or
94
94
  ``:blue-badge[your text here]``.
95
95
 
@@ -359,10 +359,11 @@ class MarkdownMixin:
359
359
  *, # keyword-only arguments:
360
360
  icon: str | None = None,
361
361
  color: Literal[
362
+ "red",
363
+ "orange",
364
+ "yellow",
362
365
  "blue",
363
366
  "green",
364
- "orange",
365
- "red",
366
367
  "violet",
367
368
  "gray",
368
369
  "grey",
@@ -418,8 +419,8 @@ class MarkdownMixin:
418
419
  color : str
419
420
  The color to use for the badge. This defaults to ``"blue"``.
420
421
 
421
- This can be one of the following supported colors: blue, green,
422
- orange, red, violet, gray/grey, or primary. If you use
422
+ This can be one of the following supported colors: red, orange,
423
+ yellow, blue, green, violet, gray/grey, or primary. If you use
423
424
  ``"primary"``, Streamlit will use the default primary accent color
424
425
  unless you set the ``theme.primaryColor`` configuration option.
425
426