streamlit 1.49.1__py3-none-any.whl → 1.50.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 (155) hide show
  1. streamlit/column_config.py +2 -0
  2. streamlit/commands/navigation.py +3 -1
  3. streamlit/components/v1/custom_component.py +17 -42
  4. streamlit/config.py +306 -0
  5. streamlit/connections/base_connection.py +4 -2
  6. streamlit/dataframe_util.py +3 -2
  7. streamlit/delta_generator.py +2 -3
  8. streamlit/elements/arrow.py +63 -43
  9. streamlit/elements/deck_gl_json_chart.py +1 -0
  10. streamlit/elements/form.py +6 -6
  11. streamlit/elements/graphviz_chart.py +23 -6
  12. streamlit/elements/iframe.py +0 -2
  13. streamlit/elements/image.py +10 -9
  14. streamlit/elements/layouts.py +58 -11
  15. streamlit/elements/lib/built_in_chart_utils.py +95 -29
  16. streamlit/elements/lib/column_config_utils.py +5 -0
  17. streamlit/elements/lib/column_types.py +563 -144
  18. streamlit/elements/lib/dialog.py +1 -0
  19. streamlit/elements/lib/pandas_styler_utils.py +30 -14
  20. streamlit/elements/lib/utils.py +17 -5
  21. streamlit/elements/map.py +1 -3
  22. streamlit/elements/media.py +2 -0
  23. streamlit/elements/metric.py +10 -32
  24. streamlit/elements/plotly_chart.py +17 -9
  25. streamlit/elements/pyplot.py +6 -6
  26. streamlit/elements/vega_charts.py +110 -44
  27. streamlit/elements/widgets/audio_input.py +48 -0
  28. streamlit/elements/widgets/button.py +27 -25
  29. streamlit/elements/widgets/button_group.py +1 -0
  30. streamlit/elements/widgets/camera_input.py +1 -0
  31. streamlit/elements/widgets/chat.py +1 -0
  32. streamlit/elements/widgets/checkbox.py +1 -0
  33. streamlit/elements/widgets/color_picker.py +1 -0
  34. streamlit/elements/widgets/data_editor.py +6 -5
  35. streamlit/elements/widgets/file_uploader.py +1 -0
  36. streamlit/elements/widgets/multiselect.py +10 -0
  37. streamlit/elements/widgets/number_input.py +3 -0
  38. streamlit/elements/widgets/radio.py +1 -0
  39. streamlit/elements/widgets/select_slider.py +1 -0
  40. streamlit/elements/widgets/selectbox.py +4 -0
  41. streamlit/elements/widgets/slider.py +1 -0
  42. streamlit/elements/widgets/text_widgets.py +6 -0
  43. streamlit/elements/widgets/time_widgets.py +9 -0
  44. streamlit/elements/write.py +1 -17
  45. streamlit/git_util.py +65 -43
  46. streamlit/material_icon_names.py +1 -1
  47. streamlit/proto/Arrow_pb2.py +10 -8
  48. streamlit/proto/Arrow_pb2.pyi +31 -2
  49. streamlit/proto/AudioInput_pb2.py +2 -2
  50. streamlit/proto/AudioInput_pb2.pyi +6 -2
  51. streamlit/proto/Block_pb2.py +11 -11
  52. streamlit/proto/Block_pb2.pyi +5 -0
  53. streamlit/proto/NewSession_pb2.py +18 -16
  54. streamlit/proto/NewSession_pb2.pyi +135 -2
  55. streamlit/runtime/app_session.py +18 -5
  56. streamlit/runtime/theme_util.py +148 -0
  57. streamlit/static/index.html +2 -2
  58. streamlit/static/manifest.json +222 -222
  59. streamlit/static/static/css/index.CHEnSPGk.css +1 -0
  60. streamlit/static/static/css/{index.C8X8rNzw.css → index.CIiu7Ygf.css} +1 -1
  61. streamlit/static/static/js/{ErrorOutline.esm.DcGrhbBP.js → ErrorOutline.esm.DUpR0_Ka.js} +1 -1
  62. streamlit/static/static/js/{FileDownload.esm.DgBvV6Pq.js → FileDownload.esm.CN4j9-1w.js} +1 -1
  63. streamlit/static/static/js/{FileHelper.M6AAaeuA.js → FileHelper.CaIUKG91.js} +1 -1
  64. streamlit/static/static/js/{FormClearHelper.DHh1GFzm.js → FormClearHelper.DTcdrasw.js} +1 -1
  65. streamlit/static/static/js/{Hooks.DGu1od_L.js → Hooks.BRba_Own.js} +1 -1
  66. streamlit/static/static/js/InputInstructions.xnSDuYeQ.js +1 -0
  67. streamlit/static/static/js/{Particles.DDVT-6Qc.js → Particles.CElH0XX2.js} +1 -1
  68. streamlit/static/static/js/{ProgressBar.BEY0cXXV.js → ProgressBar.DetlP5aY.js} +2 -2
  69. streamlit/static/static/js/Toolbar.C77ar7rq.js +1 -0
  70. streamlit/static/static/js/{base-input.CK3UVGp1.js → base-input.BQft14La.js} +3 -3
  71. streamlit/static/static/js/{checkbox.D8W881TL.js → checkbox.yZOfXCeX.js} +1 -1
  72. streamlit/static/static/js/{createSuper.B6W-Dh9S.js → createSuper.Dh9w1cs8.js} +1 -1
  73. streamlit/static/static/js/data-grid-overlay-editor.DcuHuCyW.js +1 -0
  74. streamlit/static/static/js/{downloader.DiKpuU_S.js → downloader.MeHtkq8r.js} +1 -1
  75. streamlit/static/static/js/{es6.B8zRNPZ-.js → es6.VpBPGCnM.js} +2 -2
  76. streamlit/static/static/js/{iframeResizer.contentWindow.DIewJmmh.js → iframeResizer.contentWindow.yMw_ARIL.js} +1 -1
  77. streamlit/static/static/js/{index.B9mjBcgE.js → index.64ejlaaT.js} +1 -1
  78. streamlit/static/static/js/{index.CD8HuT3N.js → index.6xX1278W.js} +90 -91
  79. streamlit/static/static/js/index.B-hiXRzw.js +1 -0
  80. streamlit/static/static/js/{index.Ch7MBCx0.js → index.B0H9IXUJ.js} +47 -47
  81. streamlit/static/static/js/{index.4eF4NxG2.js → index.B4cAbHP6.js} +1 -1
  82. streamlit/static/static/js/{index.Dk4C7X3i.js → index.B4dUQfni.js} +1 -1
  83. streamlit/static/static/js/{index.CvYYtxD_.js → index.BPQo7BKk.js} +1 -1
  84. streamlit/static/static/js/index.Baqa90pe.js +2 -0
  85. streamlit/static/static/js/{index.D5naqx-J.js → index.Bj9JgOEC.js} +1 -1
  86. streamlit/static/static/js/index.BjCwMzj4.js +3 -0
  87. streamlit/static/static/js/{index.C_tmcx4B.js → index.Bm3VbPB5.js} +1 -1
  88. streamlit/static/static/js/{index.C7fRKRs4.js → index.Bxz2yX3P.js} +1 -1
  89. streamlit/static/static/js/{index.ho6NIXGl.js → index.BycLveZ4.js} +1 -1
  90. streamlit/static/static/js/{index.452cqrrL.js → index.C9BdUqTi.js} +1 -1
  91. streamlit/static/static/js/index.CFMf5_ez.js +197 -0
  92. streamlit/static/static/js/index.CGYqqs6j.js +1 -0
  93. streamlit/static/static/js/{index.zecpGxtj.js → index.CH1tqnSs.js} +1 -1
  94. streamlit/static/static/js/{index.CjXWwH-y.js → index.CMItVsFA.js} +1 -1
  95. streamlit/static/static/js/{index.B6U8LQo3.js → index.CTBk8Vk2.js} +1 -1
  96. streamlit/static/static/js/index.CiAQIz1H.js +7 -0
  97. streamlit/static/static/js/index.Cj7DSzVR.js +73 -0
  98. streamlit/static/static/js/index.Ck8rQ9OL.js +1 -0
  99. streamlit/static/static/js/{index.Ts_0SdB9.js → index.ClELlchS.js} +2 -2
  100. streamlit/static/static/js/{index.Bte_9Lyq.js → index.Cnpi3o3E.js} +1 -1
  101. streamlit/static/static/js/{index.CcJf6BCU.js → index.Ctn27_AE.js} +1 -1
  102. streamlit/static/static/js/{index.CP5TD2z1.js → index.D2QEXQq_.js} +1 -1
  103. streamlit/static/static/js/index.DH71Ezyj.js +1 -0
  104. streamlit/static/static/js/{index.D2-atlaQ.js → index.DHh-U0dK.js} +2 -2
  105. streamlit/static/static/js/{index.DtYN2x4k.js → index.DK7hD7_w.js} +1 -1
  106. streamlit/static/static/js/{index.qhs54UAB.js → index.DKv_lNO7.js} +1 -1
  107. streamlit/static/static/js/index.DNLrMXgm.js +12 -0
  108. streamlit/static/static/js/index.DW0Grddz.js +1 -0
  109. streamlit/static/static/js/{index.cnnXF7xQ.js → index.Dbe-Q3C-.js} +1 -1
  110. streamlit/static/static/js/index.DcPNYEUo.js +1 -0
  111. streamlit/static/static/js/index.DuxqVQpd.js +1 -0
  112. streamlit/static/static/js/{index.CejBxbg1.js → index.FFOzOWzC.js} +1 -1
  113. streamlit/static/static/js/{index.BnEpvLEz.js → index.GRUzrudl.js} +1 -1
  114. streamlit/static/static/js/{input.nzVJphXi.js → input.s6pjQ49A.js} +1 -1
  115. streamlit/static/static/js/{memory.CjCgTQz3.js → memory.Cuvsdfrl.js} +1 -1
  116. streamlit/static/static/js/{number-overlay-editor.DaRFzZEO.js → number-overlay-editor.DdgVR5m3.js} +1 -1
  117. streamlit/static/static/js/{possibleConstructorReturn.DgiPnZ9N.js → possibleConstructorReturn.CqidKeei.js} +1 -1
  118. streamlit/static/static/js/{sandbox.mithfq7Z.js → sandbox.CCQREcJx.js} +1 -1
  119. streamlit/static/static/js/{timepicker.Dbl5KFh6.js → timepicker.mkJF97Bb.js} +4 -4
  120. streamlit/static/static/js/{toConsumableArray.D-Dx88BQ.js → toConsumableArray.De7I7KVR.js} +1 -1
  121. streamlit/static/static/js/{uniqueId.Bh26R_3S.js → uniqueId.RI1LJdtz.js} +1 -1
  122. streamlit/static/static/js/{useBasicWidgetState.DeK-QJpD.js → useBasicWidgetState.CedkNjUW.js} +1 -1
  123. streamlit/static/static/js/{useTextInputAutoExpand.4iAdLWD-.js → useTextInputAutoExpand.Ca7w8dVs.js} +2 -2
  124. streamlit/static/static/js/{useUpdateUiValue.CmT7_nJN.js → useUpdateUiValue.DeXelfRH.js} +1 -1
  125. streamlit/static/static/js/withFullScreenWrapper.C3561XxJ.js +1 -0
  126. streamlit/static/static/media/MaterialSymbols-Rounded.DeCZgS-4.woff2 +0 -0
  127. streamlit/string_util.py +58 -1
  128. streamlit/web/bootstrap.py +0 -31
  129. streamlit/web/server/routes.py +17 -4
  130. streamlit/web/server/server.py +1 -0
  131. {streamlit-1.49.1.dist-info → streamlit-1.50.0.dist-info}/METADATA +1 -1
  132. {streamlit-1.49.1.dist-info → streamlit-1.50.0.dist-info}/RECORD +136 -135
  133. streamlit/static/static/css/index.COe1010n.css +0 -1
  134. streamlit/static/static/js/InputInstructions.z6sVgyYt.js +0 -1
  135. streamlit/static/static/js/Toolbar.DSnK1fUh.js +0 -1
  136. streamlit/static/static/js/data-grid-overlay-editor.DRTHOydk.js +0 -1
  137. streamlit/static/static/js/index.BXYmrqnf.js +0 -1
  138. streamlit/static/static/js/index.B_8AnktO.js +0 -1
  139. streamlit/static/static/js/index.Bl7zGQSh.js +0 -7
  140. streamlit/static/static/js/index.BnJIOYn9.js +0 -73
  141. streamlit/static/static/js/index.C1HcTl5K.js +0 -1
  142. streamlit/static/static/js/index.C7lSmSOP.js +0 -1
  143. streamlit/static/static/js/index.D3K5nOu9.js +0 -197
  144. streamlit/static/static/js/index.DkKT3LUI.js +0 -1
  145. streamlit/static/static/js/index.MTPPBDHk.js +0 -2
  146. streamlit/static/static/js/index.pqW9AMJD.js +0 -3
  147. streamlit/static/static/js/index.urHgTgMQ.js +0 -12
  148. streamlit/static/static/js/index.wzkv_11M.js +0 -1
  149. streamlit/static/static/js/index.yF5AncHY.js +0 -1
  150. streamlit/static/static/js/withFullScreenWrapper.DLp1ENGm.js +0 -1
  151. streamlit/static/static/media/MaterialSymbols-Rounded.CBxVaFdk.woff2 +0 -0
  152. {streamlit-1.49.1.data → streamlit-1.50.0.data}/scripts/streamlit.cmd +0 -0
  153. {streamlit-1.49.1.dist-info → streamlit-1.50.0.dist-info}/WHEEL +0 -0
  154. {streamlit-1.49.1.dist-info → streamlit-1.50.0.dist-info}/entry_points.txt +0 -0
  155. {streamlit-1.49.1.dist-info → streamlit-1.50.0.dist-info}/top_level.txt +0 -0
@@ -16,15 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  import json
18
18
  from dataclasses import dataclass
19
- from typing import (
20
- TYPE_CHECKING,
21
- Any,
22
- Final,
23
- Literal,
24
- TypedDict,
25
- cast,
26
- overload,
27
- )
19
+ from typing import TYPE_CHECKING, Any, Final, Literal, TypedDict, cast, overload
28
20
 
29
21
  from typing_extensions import TypeAlias
30
22
 
@@ -51,7 +43,7 @@ from streamlit.elements.lib.layout_utils import (
51
43
  from streamlit.elements.lib.pandas_styler_utils import marshall_styler
52
44
  from streamlit.elements.lib.policies import check_widget_policies
53
45
  from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
54
- from streamlit.errors import StreamlitAPIException
46
+ from streamlit.errors import StreamlitAPIException, StreamlitValueError
55
47
  from streamlit.proto.Arrow_pb2 import Arrow as ArrowProto
56
48
  from streamlit.proto.ForwardMsg_pb2 import ForwardMsg
57
49
  from streamlit.runtime.metrics_util import gather_metrics
@@ -270,6 +262,17 @@ def parse_selection_mode(
270
262
  return set(parsed_selection_modes)
271
263
 
272
264
 
265
+ def parse_border_mode(
266
+ border: bool | Literal["horizontal"],
267
+ ) -> ArrowProto.BorderMode.ValueType:
268
+ """Parse and check the user provided border mode."""
269
+ if isinstance(border, bool):
270
+ return ArrowProto.BorderMode.ALL if border else ArrowProto.BorderMode.NONE
271
+ if border == "horizontal":
272
+ return ArrowProto.BorderMode.HORIZONTAL
273
+ raise StreamlitValueError("border", ["True", "False", "'horizontal'"])
274
+
275
+
273
276
  class ArrowMixin:
274
277
  @overload
275
278
  def dataframe(
@@ -396,6 +399,11 @@ class ArrowMixin:
396
399
  this is ``False``, Streamlit sets the dataframe's width according
397
400
  to ``width``.
398
401
 
402
+ .. deprecated::
403
+ ``use_container_width`` is deprecated and will be removed in a
404
+ future release. For ``use_container_width=True``, use
405
+ ``width="stretch"``.
406
+
399
407
  hide_index : bool or None
400
408
  Whether to hide the index column(s). If ``hide_index`` is ``None``
401
409
  (default), the visibility of index columns is automatically
@@ -487,11 +495,6 @@ class ArrowMixin:
487
495
  is ``None`` (default), Streamlit will use a default row height,
488
496
  which fits one line of text.
489
497
 
490
- .. deprecated::
491
- ``use_container_width`` is deprecated and will be removed in a
492
- future release. For ``use_container_width=True``, use
493
- ``width="stretch"``.
494
-
495
498
  Returns
496
499
  -------
497
500
  element or dict
@@ -725,6 +728,7 @@ class ArrowMixin:
725
728
  proto.id = compute_and_register_element_id(
726
729
  "dataframe",
727
730
  user_key=key,
731
+ key_as_main_identity=False,
728
732
  dg=self.dg,
729
733
  data=proto.data,
730
734
  width=width,
@@ -751,7 +755,9 @@ class ArrowMixin:
751
755
  return self.dg._enqueue("arrow_data_frame", proto, layout_config=layout_config)
752
756
 
753
757
  @gather_metrics("table")
754
- def table(self, data: Data = None) -> DeltaGenerator:
758
+ def table(
759
+ self, data: Data = None, *, border: bool | Literal["horizontal"] = True
760
+ ) -> DeltaGenerator:
755
761
  """Display a static table.
756
762
 
757
763
  While ``st.dataframe`` is geared towards large datasets and interactive
@@ -775,49 +781,60 @@ class ArrowMixin:
775
781
  .. |st.markdown| replace:: ``st.markdown``
776
782
  .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown
777
783
 
784
+ border : bool or "horizontal"
785
+ Whether to show borders around the table and between cells. This can be one
786
+ of the following:
787
+
788
+ - ``True`` (default): Show borders around the table and between cells.
789
+ - ``False``: Don't show any borders.
790
+ - ``"horizontal"``: Show only horizontal borders between rows.
791
+
778
792
  Examples
779
793
  --------
780
- **Example 1: Display a simple dataframe as a static table**
794
+ **Example 1: Display a confusion matrix as a static table**
781
795
 
782
796
  >>> import pandas as pd
783
797
  >>> import streamlit as st
784
- >>> from numpy.random import default_rng as rng
785
798
  >>>
786
- >>> df = pd.DataFrame(
787
- ... rng(0).standard_normal(size=(10, 5)),
788
- ... columns=("col %d" % i for i in range(5)),
799
+ >>> confusion_matrix = pd.DataFrame(
800
+ ... {
801
+ ... "Predicted Cat": [85, 3, 2, 1],
802
+ ... "Predicted Dog": [2, 78, 4, 0],
803
+ ... "Predicted Bird": [1, 5, 72, 3],
804
+ ... "Predicted Fish": [0, 2, 1, 89],
805
+ ... },
806
+ ... index=["Actual Cat", "Actual Dog", "Actual Bird", "Actual Fish"],
789
807
  ... )
790
- >>>
791
- >>> st.table(df)
808
+ >>> st.table(confusion_matrix)
792
809
 
793
810
  .. output::
794
- https://doc-table.streamlit.app/
795
- height: 480px
811
+ https://doc-table-confusion.streamlit.app/
812
+ height: 250px
796
813
 
797
- **Example 2: Display a table of Markdown strings**
814
+ **Example 2: Display a product leaderboard with Markdown and horizontal borders**
798
815
 
799
- >>> import pandas as pd
800
816
  >>> import streamlit as st
801
817
  >>>
802
- >>> df = pd.DataFrame(
803
- ... {
804
- ... "Command": ["**st.table**", "*st.dataframe*"],
805
- ... "Type": ["`static`", "`interactive`"],
806
- ... "Docs": [
807
- ... "[:rainbow[docs]](https://docs.streamlit.io"
808
- ... "/develop/api-reference/data/st.dataframe)",
809
- ... "[:open_book:](https://docs.streamlit.io"
810
- ... "/develop/api-reference/data/st.table)",
811
- ... ],
812
- ... }
813
- ... )
814
- >>>
815
- >>> st.table(df)
818
+ >>> product_data = {
819
+ ... "Product": [
820
+ ... ":material/devices: Widget Pro",
821
+ ... ":material/smart_toy: Smart Device",
822
+ ... ":material/inventory: Premium Kit",
823
+ ... ],
824
+ ... "Category": [":blue[Electronics]", ":green[IoT]", ":violet[Bundle]"],
825
+ ... "Stock": ["🟢 Full", "🟡 Low", "🔴 Empty"],
826
+ ... "Units sold": [1247, 892, 654],
827
+ ... "Revenue": [125000, 89000, 98000],
828
+ ... }
829
+ >>> st.table(product_data, border="horizontal")
816
830
 
817
831
  .. output::
818
- https://doc-table-markdown.streamlit.app/
832
+ https://doc-table-horizontal-border.streamlit.app/
819
833
  height: 200px
834
+
820
835
  """
836
+ # Parse border parameter to enum value
837
+ border_mode = parse_border_mode(border)
821
838
 
822
839
  # Check if data is uncollected, and collect it but with 100 rows max, instead of
823
840
  # 10k rows, which is done in all other cases.
@@ -843,6 +860,7 @@ class ArrowMixin:
843
860
 
844
861
  proto = ArrowProto()
845
862
  marshall(proto, data, default_uuid)
863
+ proto.border_mode = border_mode
846
864
  return self.dg._enqueue("arrow_table", proto, layout_config=layout_config)
847
865
 
848
866
  @gather_metrics("add_rows")
@@ -1034,8 +1052,10 @@ def _arrow_add_rows(
1034
1052
 
1035
1053
  if metadata.chart_command == "bar_chart":
1036
1054
  kwargs["horizontal"] = metadata.horizontal
1055
+ kwargs["sort"] = metadata.sort
1037
1056
 
1038
- kwargs["use_container_width"] = metadata.use_container_width
1057
+ if metadata.use_container_width is not None:
1058
+ kwargs["use_container_width"] = metadata.use_container_width
1039
1059
 
1040
1060
  st_method(data, **kwargs)
1041
1061
  return None
@@ -516,6 +516,7 @@ class PydeckMixin:
516
516
  pydeck_proto.id = compute_and_register_element_id(
517
517
  "deck_gl_json_chart",
518
518
  user_key=key,
519
+ key_as_main_identity=False,
519
520
  dg=self.dg,
520
521
  is_selection_activated=is_selection_activated,
521
522
  selection_mode=selection_mode,
@@ -350,6 +350,12 @@ class FormMixin:
350
350
  In both cases, if the contents of the button are wider than the
351
351
  parent container, the contents will line wrap.
352
352
 
353
+ .. deprecated::
354
+ ``use_container_width`` is deprecated and will be removed in a
355
+ future release. For ``use_container_width=True``, use
356
+ ``width="stretch"``. For ``use_container_width=False``, use
357
+ ``width="content"``.
358
+
353
359
  width : "content", "stretch", or int
354
360
  The width of the button. This can be one of the following:
355
361
 
@@ -363,12 +369,6 @@ class FormMixin:
363
369
  the parent container, the width of the button matches the width
364
370
  of the parent container.
365
371
 
366
- .. deprecated::
367
- ``use_container_width`` is deprecated and will be removed in a
368
- future release. For ``use_container_width=True``, use
369
- ``width="stretch"``. For ``use_container_width=False``, use
370
- ``width="content"``.
371
-
372
372
  Returns
373
373
  -------
374
374
  bool
@@ -26,8 +26,10 @@ from streamlit.deprecation_util import (
26
26
  show_deprecation_warning,
27
27
  )
28
28
  from streamlit.elements.lib.layout_utils import (
29
+ Height,
29
30
  LayoutConfig,
30
31
  Width,
32
+ validate_height,
31
33
  validate_width,
32
34
  )
33
35
  from streamlit.errors import StreamlitAPIException
@@ -53,6 +55,7 @@ class GraphvizMixin:
53
55
  use_container_width: bool | None = None,
54
56
  *, # keyword-only arguments:
55
57
  width: Width = "content",
58
+ height: Height = "content",
56
59
  ) -> DeltaGenerator:
57
60
  """Display a graph using the dagre-d3 library.
58
61
 
@@ -78,6 +81,12 @@ class GraphvizMixin:
78
81
  container. If ``use_container_width`` is ``True``, Streamlit sets
79
82
  the width of the figure to match the width of the parent container.
80
83
 
84
+ .. deprecated::
85
+ ``use_container_width`` is deprecated and will be removed in a
86
+ future release. For ``use_container_width=True``, use
87
+ ``width="stretch"``. For ``use_container_width=False``, use
88
+ ``width="content"``.
89
+
81
90
  width : "content", "stretch", or int
82
91
  The width of the chart element. This can be one of the following:
83
92
 
@@ -91,11 +100,18 @@ class GraphvizMixin:
91
100
  the parent container, the width of the element matches the width
92
101
  of the parent container.
93
102
 
94
- .. deprecated::
95
- ``use_container_width`` is deprecated and will be removed in a
96
- future release. For ``use_container_width=True``, use
97
- ``width="stretch"``. For ``use_container_width=False``, use
98
- ``width="content"``.
103
+ height : "content", "stretch", or int
104
+ The height of the chart element. This can be one of the following:
105
+
106
+ - ``"content"`` (default): The height of the element matches the
107
+ height of its content.
108
+ - ``"stretch"``: The height of the element matches the height of
109
+ its content or the height of the parent container, whichever is
110
+ larger. If the element is not in a parent container, the height
111
+ of the element matches the height of its content.
112
+ - An integer specifying the height in pixels: The element has a
113
+ fixed height. If the content is larger than the specified
114
+ height, scrolling is enabled.
99
115
 
100
116
  Example
101
117
  -------
@@ -170,7 +186,8 @@ class GraphvizMixin:
170
186
 
171
187
  # Validate and set layout configuration
172
188
  validate_width(width, allow_content=True)
173
- layout_config = LayoutConfig(width=width)
189
+ validate_height(height, allow_content=True)
190
+ layout_config = LayoutConfig(width=width, height=height)
174
191
 
175
192
  return self.dg._enqueue(
176
193
  "graphviz_chart", graphviz_chart_proto, layout_config=layout_config
@@ -99,7 +99,6 @@ class IframeMixin:
99
99
  scrolling=scrolling,
100
100
  tab_index=tab_index,
101
101
  )
102
- # When no width is specified, we want the iframe to stretch to fill the container.
103
102
  layout_config = LayoutConfig(
104
103
  width=width if width is not None else "stretch",
105
104
  height=height if height is not None else 150,
@@ -184,7 +183,6 @@ class IframeMixin:
184
183
  scrolling=scrolling,
185
184
  tab_index=tab_index,
186
185
  )
187
- # When no width is specified, we want the html to stretch to fill the container.
188
186
  layout_config = LayoutConfig(
189
187
  width=width if width is not None else "stretch",
190
188
  height=height if height is not None else 150,
@@ -115,6 +115,11 @@ class ImageMixin:
115
115
  If "always" or True, set the image's width to the column width.
116
116
  If "never" or False, set the image's width to its natural size.
117
117
  Note: if set, `use_column_width` takes precedence over the `width` parameter.
118
+
119
+ .. deprecated::
120
+ ``use_column_width`` is deprecated and will be removed in a future
121
+ release. Please use the ``width`` parameter instead.
122
+
118
123
  clamp : bool
119
124
  Whether to clamp image pixel values to a valid range (0-255 per
120
125
  channel). This is only used for byte array images; the parameter is
@@ -142,15 +147,11 @@ class ImageMixin:
142
147
  ``use_container_width`` is ``True``, Streamlit sets the width of
143
148
  the image to match the width of the parent container.
144
149
 
145
- .. deprecated::
146
- ``use_container_width`` is deprecated and will be removed in a
147
- future release. For ``use_container_width=True``, use
148
- ``width="stretch"``. For ``use_container_width=False``, use
149
- ``width="content"``.
150
-
151
- .. deprecated::
152
- ``use_column_width`` is deprecated and will be removed in a future
153
- release. Please use the ``width`` parameter instead.
150
+ .. deprecated::
151
+ ``use_container_width`` is deprecated and will be removed in a
152
+ future release. For ``use_container_width=True``, use
153
+ ``width="stretch"``. For ``use_container_width=False``, use
154
+ ``width="content"``.
154
155
 
155
156
  Example
156
157
  -------
@@ -323,7 +323,7 @@ class LayoutsMixin:
323
323
  # in the future. This might require including more container
324
324
  # parameters in the ID calculation.
325
325
  block_proto.id = compute_and_register_element_id(
326
- "container", user_key=key, dg=None
326
+ "container", user_key=key, dg=None, key_as_main_identity=False
327
327
  )
328
328
 
329
329
  return self.dg._block(block_proto)
@@ -559,6 +559,7 @@ class LayoutsMixin:
559
559
  tabs: Sequence[str],
560
560
  *,
561
561
  width: WidthWithoutContent = "stretch",
562
+ default: str | None = None,
562
563
  ) -> Sequence[DeltaGenerator]:
563
564
  r"""Insert containers separated into tabs.
564
565
 
@@ -568,7 +569,7 @@ class LayoutsMixin:
568
569
 
569
570
  To add elements to the returned containers, you can use the ``with`` notation
570
571
  (preferred) or just call methods directly on the returned object. See
571
- examples below.
572
+ the examples below.
572
573
 
573
574
  .. note::
574
575
  All content within every tab is computed and sent to the frontend,
@@ -608,6 +609,12 @@ class LayoutsMixin:
608
609
  the parent container, the width of the container matches the width
609
610
  of the parent container.
610
611
 
612
+ default : str or None
613
+ The default tab to select. If this is ``None`` (default), the first
614
+ tab is selected. If this is a string, it must be one of the tab
615
+ labels. If two tabs have the same label as ``default``, the first
616
+ one is selected.
617
+
611
618
  Returns
612
619
  -------
613
620
  list of containers
@@ -615,7 +622,9 @@ class LayoutsMixin:
615
622
 
616
623
  Examples
617
624
  --------
618
- You can use the ``with`` notation to insert any element into a tab:
625
+ *Example 1: Use context management*
626
+
627
+ You can use ``with`` notation to insert any element into a tab:
619
628
 
620
629
  >>> import streamlit as st
621
630
  >>>
@@ -635,7 +644,9 @@ class LayoutsMixin:
635
644
  https://doc-tabs1.streamlit.app/
636
645
  height: 620px
637
646
 
638
- Or you can just call methods directly on the returned objects:
647
+ *Example 2: Call methods directly*
648
+
649
+ You can call methods directly on the returned objects:
639
650
 
640
651
  >>> import streamlit as st
641
652
  >>> from numpy.random import default_rng as rng
@@ -654,12 +665,42 @@ class LayoutsMixin:
654
665
  https://doc-tabs2.streamlit.app/
655
666
  height: 700px
656
667
 
668
+ *Example 3: Set the default tab and style the tab labels*
669
+
670
+ Use the ``default`` parameter to set the default tab. You can also use
671
+ Markdown in the tab labels.
672
+
673
+ >>> import streamlit as st
674
+ >>>
675
+ >>> tab1, tab2, tab3 = st.tabs(
676
+ ... [":cat: Cat", ":dog: Dog", ":rainbow[Owl]"], default=":rainbow[Owl]"
677
+ ... )
678
+ >>>
679
+ >>> with tab1:
680
+ >>> st.header("A cat")
681
+ >>> st.image("https://static.streamlit.io/examples/cat.jpg", width=200)
682
+ >>> with tab2:
683
+ >>> st.header("A dog")
684
+ >>> st.image("https://static.streamlit.io/examples/dog.jpg", width=200)
685
+ >>> with tab3:
686
+ >>> st.header("An owl")
687
+ >>> st.image("https://static.streamlit.io/examples/owl.jpg", width=200)
688
+
689
+ .. output ::
690
+ https://doc-tabs3.streamlit.app/
691
+ height: 620px
692
+
657
693
  """
658
694
  if not tabs:
659
695
  raise StreamlitAPIException(
660
696
  "The input argument to st.tabs must contain at least one tab label."
661
697
  )
662
698
 
699
+ if default and default not in tabs:
700
+ raise StreamlitAPIException(
701
+ f"The default tab '{default}' is not in the list of tabs."
702
+ )
703
+
663
704
  if any(not isinstance(tab, str) for tab in tabs):
664
705
  raise StreamlitAPIException(
665
706
  "The tabs input list to st.tabs is only allowed to contain strings."
@@ -675,8 +716,14 @@ class LayoutsMixin:
675
716
  block_proto.tab_container.SetInParent()
676
717
  validate_width(width)
677
718
  block_proto.width_config.CopyFrom(get_width_config(width))
719
+
720
+ default_index = tabs.index(default) if default else 0
721
+
722
+ block_proto.tab_container.default_tab_index = default_index
723
+
678
724
  tab_container = self.dg._block(block_proto)
679
- return tuple(tab_container._block(tab_proto(tab_label)) for tab_label in tabs)
725
+
726
+ return tuple(tab_container._block(tab_proto(tab)) for tab in tabs)
680
727
 
681
728
  @gather_metrics("expander")
682
729
  def expander(
@@ -899,6 +946,12 @@ class LayoutsMixin:
899
946
  button. The popover container may be wider than its button to fit
900
947
  the container's content.
901
948
 
949
+ .. deprecated::
950
+ ``use_container_width`` is deprecated and will be removed in a
951
+ future release. For ``use_container_width=True``, use
952
+ ``width="stretch"``. For ``use_container_width=False``, use
953
+ ``width="content"``.
954
+
902
955
  width : int, "stretch", or "content"
903
956
  The width of the button. This can be one of the following:
904
957
 
@@ -916,12 +969,6 @@ class LayoutsMixin:
916
969
  button. The popover container may be wider than its button to fit
917
970
  the container's contents.
918
971
 
919
- .. deprecated::
920
- ``use_container_width`` is deprecated and will be removed in a
921
- future release. For ``use_container_width=True``, use
922
- ``width="stretch"``. For ``use_container_width=False``, use
923
- ``width="content"``.
924
-
925
972
  Examples
926
973
  --------
927
974
  You can use the ``with`` notation to insert any element into a popover: