streamlit-nightly 1.45.2.dev20250602__py3-none-any.whl → 1.45.2.dev20250605__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/config.py +56 -26
- streamlit/config_option.py +4 -2
- streamlit/elements/arrow.py +2 -4
- streamlit/elements/deck_gl_json_chart.py +1 -1
- streamlit/elements/heading.py +32 -0
- streamlit/elements/metric.py +11 -1
- streamlit/elements/plotly_chart.py +1 -1
- streamlit/elements/text.py +13 -1
- streamlit/elements/vega_charts.py +27 -2
- streamlit/elements/widgets/checkbox.py +23 -1
- streamlit/elements/widgets/color_picker.py +20 -1
- streamlit/file_util.py +14 -0
- streamlit/proto/ClientState_pb2.py +4 -4
- streamlit/proto/ClientState_pb2.pyi +7 -2
- streamlit/proto/NewSession_pb2.py +16 -16
- streamlit/proto/NewSession_pb2.pyi +7 -2
- streamlit/runtime/context.py +33 -1
- streamlit/static/index.html +1 -1
- streamlit/static/manifest.json +214 -214
- streamlit/static/static/js/{ErrorOutline.esm.D5NgCh5m.js → ErrorOutline.esm.tNLvotRM.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.NuObx1Tl.js → FileDownload.esm.C_4VXOrN.js} +1 -1
- streamlit/static/static/js/{FileHelper.BH7o4_P9.js → FileHelper.60q2rqnv.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.BAxB8JFY.js → FormClearHelper.NJdi-ZLd.js} +1 -1
- streamlit/static/static/js/{Hooks.Bjt8oBOT.js → Hooks.CaYtegs-.js} +1 -1
- streamlit/static/static/js/{InputInstructions.BZZLp6t9.js → InputInstructions.WOkLURYg.js} +1 -1
- streamlit/static/static/js/{ProgressBar.BwRgGfI0.js → ProgressBar.C8qv5JmE.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.C_c286r8.js → RenderInPortalIfExists.tUlEGlzo.js} +1 -1
- streamlit/static/static/js/{Toolbar.5tXjF_eX.js → Toolbar.CMYJPS_Q.js} +1 -1
- streamlit/static/static/js/{base-input.wfBDFTlB.js → base-input.DFrC09vO.js} +1 -1
- streamlit/static/static/js/{checkbox.D1GhNngU.js → checkbox.BnwpL_LT.js} +1 -1
- streamlit/static/static/js/{createSuper.CudEEVs2.js → createSuper.NiynzP3k.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.DUTI_Rbg.js → data-grid-overlay-editor.CYEI83P5.js} +1 -1
- streamlit/static/static/js/{downloader.BwLpAoXN.js → downloader.9Wy4dgxg.js} +1 -1
- streamlit/static/static/js/{es6.B_HLnUb9.js → es6.JGDen1xD.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.BNcjOcan.js → iframeResizer.contentWindow.nFuzbEci.js} +1 -1
- streamlit/static/static/js/{index.DA7wmIe4.js → index.3h_mMb74.js} +1 -1
- streamlit/static/static/js/{index.jyqBAhvH.js → index.5Z_KRF3q.js} +1 -1
- streamlit/static/static/js/{index.D3wYqvI6.js → index.91OyW-Gr.js} +1 -1
- streamlit/static/static/js/{index.flyQEkeT.js → index.B7S_H7I8.js} +1 -1
- streamlit/static/static/js/{index.BJQPxOFd.js → index.BBDrA2tn.js} +1 -1
- streamlit/static/static/js/{index.B4PbMsBe.js → index.BFYl-rZt.js} +1 -1
- streamlit/static/static/js/{index.PR2mcvVR.js → index.BNZGa4XA.js} +1 -1
- streamlit/static/static/js/{index.D8i27llu.js → index.BRvAGIBI.js} +1 -1
- streamlit/static/static/js/{index.BkvVxUIW.js → index.BfYf3Wpe.js} +1 -1
- streamlit/static/static/js/{index.CxtkoiKl.js → index.Bj3saWDN.js} +1 -1
- streamlit/static/static/js/{index.Bj6uLiaA.js → index.BtrjwWEk.js} +1 -1
- streamlit/static/static/js/{index.Ca-9xoC2.js → index.C064I556.js} +1 -1
- streamlit/static/static/js/{index.CfzaRR6P.js → index.C37654wn.js} +1 -1
- streamlit/static/static/js/{index.df4uuSoD.js → index.C4zPKjq1.js} +1 -1
- streamlit/static/static/js/{index.BPGAPI9w.js → index.CBPqvzle.js} +1 -1
- streamlit/static/static/js/{index.CL0UH4WF.js → index.CIqU--y_.js} +1 -1
- streamlit/static/static/js/{index.Cf8KcH2X.js → index.CRliFDNK.js} +1 -1
- streamlit/static/static/js/{index.B0h616Th.js → index.CX-fCNEA.js} +1 -1
- streamlit/static/static/js/{index.NveskZ7j.js → index.C_U6DmFf.js} +1 -1
- streamlit/static/static/js/{index.BtpsTdHN.js → index.CgzkiPeB.js} +76 -76
- streamlit/static/static/js/{index.BGKVW2u9.js → index.Chouo5Qe.js} +1 -1
- streamlit/static/static/js/{index.DNR4wKJg.js → index.CsrXF9Cj.js} +1 -1
- streamlit/static/static/js/{index.sYLAHlH0.js → index.DM5GB-cu.js} +1 -1
- streamlit/static/static/js/{index.B3vWaIrN.js → index.DOOJNTFS.js} +1 -1
- streamlit/static/static/js/{index.CXP5ffxh.js → index.DOmrs5iq.js} +1 -1
- streamlit/static/static/js/{index.B0paBg5x.js → index.DQLD-hJX.js} +1 -1
- streamlit/static/static/js/{index.DIG9Mo9J.js → index.DdiZdMRx.js} +1 -1
- streamlit/static/static/js/{index.BOHEcsVb.js → index.DlPy-f9y.js} +1 -1
- streamlit/static/static/js/{index.CjRwuAdg.js → index.DsBk6ofW.js} +1 -1
- streamlit/static/static/js/{index.C1GNiWbH.js → index.DwohHcrt.js} +1 -1
- streamlit/static/static/js/{index.iF9jUtwl.js → index.FqXTo5A0.js} +1 -1
- streamlit/static/static/js/{index.3WJoJFGb.js → index.OVkzDHNi.js} +1 -1
- streamlit/static/static/js/{index.DNS8a-dx.js → index.fuysp8C5.js} +26 -26
- streamlit/static/static/js/{index.Cdd7Ri21.js → index.o3iaAZx6.js} +25 -25
- streamlit/static/static/js/{index.Bs0m0eUy.js → index.ttXUdWmg.js} +1 -1
- streamlit/static/static/js/{index.zq3LdRhj.js → index.yBwY5kh0.js} +1 -1
- streamlit/static/static/js/{index.CkOUlPYT.js → index.yUKivH8E.js} +1 -1
- streamlit/static/static/js/{input.CtZjQ6Pv.js → input.Bfr-6m-t.js} +1 -1
- streamlit/static/static/js/{memory.Ddl3R0up.js → memory.Dbw4SfUa.js} +1 -1
- streamlit/static/static/js/{mergeWith.D-TqDY0-.js → mergeWith.moXRXMIt.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.Dndf05Hx.js → number-overlay-editor.xIeRsh_h.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.DNEY6J9G.js → possibleConstructorReturn.BpF6cUQr.js} +1 -1
- streamlit/static/static/js/{sandbox.B_XDPkfx.js → sandbox.CD6NZtqo.js} +1 -1
- streamlit/static/static/js/{textarea.BZ9lTMhV.js → textarea.45gncRdV.js} +1 -1
- streamlit/static/static/js/{timepicker.D9UUwpRT.js → timepicker.T96XABz2.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.DNJjbOUS.js → toConsumableArray.De5UEugE.js} +1 -1
- streamlit/static/static/js/{uniqueId.psBJ_tSg.js → uniqueId.sYiuwCOd.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.CTpx4w-3.js → useBasicWidgetState.BdPzYDh_.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.WKTDSC4O.js → useOnInputChange.B9Jrbmab.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.oyWCn2-3.js → withFullScreenWrapper.BJVHzNAl.js} +1 -1
- streamlit/util.py +24 -0
- streamlit/web/bootstrap.py +2 -2
- streamlit/web/cli.py +8 -5
- streamlit/web/server/server.py +0 -12
- streamlit/web/server/server_util.py +1 -1
- {streamlit_nightly-1.45.2.dev20250602.dist-info → streamlit_nightly-1.45.2.dev20250605.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.45.2.dev20250602.dist-info → streamlit_nightly-1.45.2.dev20250605.dist-info}/RECORD +96 -97
- streamlit/elements/lib/event_utils.py +0 -39
- {streamlit_nightly-1.45.2.dev20250602.data → streamlit_nightly-1.45.2.dev20250605.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.2.dev20250602.dist-info → streamlit_nightly-1.45.2.dev20250605.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.45.2.dev20250602.dist-info → streamlit_nightly-1.45.2.dev20250605.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.2.dev20250602.dist-info → streamlit_nightly-1.45.2.dev20250605.dist-info}/top_level.txt +0 -0
streamlit/config.py
CHANGED
@@ -54,6 +54,9 @@ _config_options_template: dict[str, ConfigOption] = OrderedDict()
|
|
54
54
|
# Stores the current state of config options.
|
55
55
|
_config_options: dict[str, ConfigOption] | None = None
|
56
56
|
|
57
|
+
# Stores the path to the main script. This is used to
|
58
|
+
# resolve config and secret files relative to the main script:
|
59
|
+
_main_script_path: str | None = None
|
57
60
|
|
58
61
|
# Indicates that a config option was defined by the user.
|
59
62
|
_USER_DEFINED: Final = "<user defined>"
|
@@ -243,6 +246,7 @@ def _create_option(
|
|
243
246
|
replaced_by: str | None = None,
|
244
247
|
type_: type = str,
|
245
248
|
sensitive: bool = False,
|
249
|
+
multiple: bool = False,
|
246
250
|
) -> ConfigOption:
|
247
251
|
'''Create a ConfigOption and store it globally in this module.
|
248
252
|
|
@@ -291,6 +295,7 @@ def _create_option(
|
|
291
295
|
replaced_by=replaced_by,
|
292
296
|
type_=type_,
|
293
297
|
sensitive=sensitive,
|
298
|
+
multiple=multiple,
|
294
299
|
)
|
295
300
|
if option.section not in _section_descriptions:
|
296
301
|
raise RuntimeError(
|
@@ -384,6 +389,7 @@ _create_option(
|
|
384
389
|
|
385
390
|
|
386
391
|
@_create_option("global.developmentMode", visibility="hidden", type_=bool)
|
392
|
+
@util.memoize
|
387
393
|
def _global_development_mode() -> bool:
|
388
394
|
"""Are we in development mode.
|
389
395
|
|
@@ -492,6 +498,7 @@ def _logger_message_format() -> str:
|
|
492
498
|
type_=bool,
|
493
499
|
scriptable=True,
|
494
500
|
)
|
501
|
+
@util.memoize
|
495
502
|
def _logger_enable_rich() -> bool:
|
496
503
|
"""
|
497
504
|
Controls whether uncaught app exceptions are logged via the rich library.
|
@@ -677,6 +684,7 @@ _create_option(
|
|
677
684
|
Note: This is a list of absolute paths.
|
678
685
|
""",
|
679
686
|
default_val=[],
|
687
|
+
multiple=True,
|
680
688
|
)
|
681
689
|
|
682
690
|
_create_option(
|
@@ -689,6 +697,7 @@ _create_option(
|
|
689
697
|
Example: ['/home/user1/env', 'relative/path/to/folder']
|
690
698
|
""",
|
691
699
|
default_val=[],
|
700
|
+
multiple=True,
|
692
701
|
)
|
693
702
|
|
694
703
|
_create_option(
|
@@ -774,8 +783,6 @@ _create_option(
|
|
774
783
|
"server.port",
|
775
784
|
description="""
|
776
785
|
The port where the server will listen for browser connections.
|
777
|
-
|
778
|
-
Don't use port 3000 which is reserved for internal development.
|
779
786
|
""",
|
780
787
|
default_val=8501,
|
781
788
|
type_=int,
|
@@ -831,6 +838,7 @@ _create_option(
|
|
831
838
|
Example: ['http://example.com', 'https://streamlit.io']
|
832
839
|
""",
|
833
840
|
default_val=[],
|
841
|
+
multiple=True,
|
834
842
|
)
|
835
843
|
|
836
844
|
_create_option(
|
@@ -954,8 +962,7 @@ def _browser_server_port() -> int:
|
|
954
962
|
- Open the browser automatically (part of `streamlit run`).
|
955
963
|
|
956
964
|
This option is for advanced use cases. To change the port of your app, use
|
957
|
-
`server.Port` instead.
|
958
|
-
development.
|
965
|
+
`server.Port` instead.
|
959
966
|
|
960
967
|
Default: whatever value is set in server.port.
|
961
968
|
"""
|
@@ -1020,6 +1027,7 @@ _create_option(
|
|
1020
1027
|
to pass the Mapbox API token.
|
1021
1028
|
""",
|
1022
1029
|
default_val="",
|
1030
|
+
type_=str,
|
1023
1031
|
sensitive=True,
|
1024
1032
|
deprecated=True,
|
1025
1033
|
deprecation_text="""
|
@@ -1251,6 +1259,14 @@ _create_theme_options(
|
|
1251
1259
|
""",
|
1252
1260
|
)
|
1253
1261
|
|
1262
|
+
_create_theme_options(
|
1263
|
+
"dataframeBorderColor",
|
1264
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1265
|
+
description="""
|
1266
|
+
The color of the border around dataframes and tables.
|
1267
|
+
""",
|
1268
|
+
)
|
1269
|
+
|
1254
1270
|
_create_theme_options(
|
1255
1271
|
"showWidgetBorder",
|
1256
1272
|
categories=["theme", CustomThemeCategories.SIDEBAR],
|
@@ -1287,23 +1303,17 @@ _create_theme_options(
|
|
1287
1303
|
|
1288
1304
|
_create_section("secrets", "Secrets configuration.")
|
1289
1305
|
|
1290
|
-
_create_option(
|
1291
|
-
"secrets.files",
|
1292
|
-
description="""
|
1293
|
-
List of locations where secrets are searched.
|
1294
1306
|
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
],
|
1306
|
-
)
|
1307
|
+
@_create_option("secrets.files", multiple=True)
|
1308
|
+
def _secrets_files() -> list[str]:
|
1309
|
+
"""List of locations where secrets are searched.
|
1310
|
+
|
1311
|
+
An entry can be a path to a TOML file or directory path where
|
1312
|
+
Kubernetes style secrets are saved. Order is important, import is
|
1313
|
+
first to last, so secrets in later files will take precedence over
|
1314
|
+
earlier ones.
|
1315
|
+
"""
|
1316
|
+
return get_config_files("secrets.toml")
|
1307
1317
|
|
1308
1318
|
|
1309
1319
|
def get_where_defined(key: str) -> str:
|
@@ -1553,10 +1563,30 @@ def _maybe_convert_to_number(v: Any) -> Any:
|
|
1553
1563
|
# something.
|
1554
1564
|
_on_config_parsed = Signal(doc="Emitted when the config file is parsed.")
|
1555
1565
|
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1566
|
+
|
1567
|
+
def get_config_files(file_name: str) -> list[str]:
|
1568
|
+
"""Return the list of config files (e.g. config.toml or secrets.toml) to be parsed.
|
1569
|
+
|
1570
|
+
Order is important, import is first to last, so options in later files
|
1571
|
+
will take precedence over earlier ones.
|
1572
|
+
"""
|
1573
|
+
# script-level config files overwrite project-level config
|
1574
|
+
# files, which in turn overwrite global config files.
|
1575
|
+
config_files = [
|
1576
|
+
file_util.get_streamlit_file_path(file_name),
|
1577
|
+
file_util.get_project_streamlit_file_path(file_name),
|
1578
|
+
]
|
1579
|
+
|
1580
|
+
if _main_script_path is not None:
|
1581
|
+
script_level_config = file_util.get_main_script_streamlit_file_path(
|
1582
|
+
_main_script_path, file_name
|
1583
|
+
)
|
1584
|
+
if script_level_config not in config_files:
|
1585
|
+
# We need to append the script-level config file to the list
|
1586
|
+
# so that it overwrites project & global level config files:
|
1587
|
+
config_files.append(script_level_config)
|
1588
|
+
|
1589
|
+
return config_files
|
1560
1590
|
|
1561
1591
|
|
1562
1592
|
def get_config_options(
|
@@ -1607,7 +1637,7 @@ def get_config_options(
|
|
1607
1637
|
|
1608
1638
|
# Values set in files later in the CONFIG_FILENAMES list overwrite those
|
1609
1639
|
# set earlier.
|
1610
|
-
for filename in
|
1640
|
+
for filename in get_config_files("config.toml"):
|
1611
1641
|
if not os.path.exists(filename):
|
1612
1642
|
continue
|
1613
1643
|
|
@@ -1643,7 +1673,7 @@ def _check_conflicts() -> None:
|
|
1643
1673
|
# When using the Node server, we must always connect to 8501 (this is
|
1644
1674
|
# hard-coded in JS). Otherwise, the browser would decide what port to
|
1645
1675
|
# connect to based on window.location.port, which in dev is going
|
1646
|
-
# to be
|
1676
|
+
# to be 3000.
|
1647
1677
|
|
1648
1678
|
# Import logger locally to prevent circular references
|
1649
1679
|
from streamlit.logger import get_logger
|
streamlit/config_option.py
CHANGED
@@ -108,6 +108,7 @@ class ConfigOption:
|
|
108
108
|
replaced_by: str | None = None,
|
109
109
|
type_: type = str,
|
110
110
|
sensitive: bool = False,
|
111
|
+
multiple: bool = False,
|
111
112
|
) -> None:
|
112
113
|
"""Create a ConfigOption with the given name.
|
113
114
|
|
@@ -142,6 +143,8 @@ class ConfigOption:
|
|
142
143
|
Useful to cast the config params sent by cmd option parameter.
|
143
144
|
sensitive: bool
|
144
145
|
Sensitive configuration options cannot be set by CLI parameter.
|
146
|
+
multiple: bool
|
147
|
+
Whether this config option can have multiple values.
|
145
148
|
"""
|
146
149
|
# Parse out the section and name.
|
147
150
|
self.key = key
|
@@ -183,8 +186,7 @@ class ConfigOption:
|
|
183
186
|
self.where_defined = ConfigOption.DEFAULT_DEFINITION
|
184
187
|
self.type = type_
|
185
188
|
self.sensitive = sensitive
|
186
|
-
|
187
|
-
self.multiple = isinstance(default_val, (list, tuple))
|
189
|
+
self.multiple = multiple
|
188
190
|
|
189
191
|
if self.replaced_by:
|
190
192
|
self.deprecated = True
|
streamlit/elements/arrow.py
CHANGED
@@ -37,7 +37,6 @@ from streamlit.elements.lib.column_config_utils import (
|
|
37
37
|
process_config_mapping,
|
38
38
|
update_column_config,
|
39
39
|
)
|
40
|
-
from streamlit.elements.lib.event_utils import AttributeDictionary
|
41
40
|
from streamlit.elements.lib.form_utils import current_form_id
|
42
41
|
from streamlit.elements.lib.pandas_styler_utils import marshall_styler
|
43
42
|
from streamlit.elements.lib.policies import check_widget_policies
|
@@ -51,6 +50,7 @@ from streamlit.runtime.scriptrunner_utils.script_run_context import (
|
|
51
50
|
get_script_run_ctx,
|
52
51
|
)
|
53
52
|
from streamlit.runtime.state import WidgetCallback, register_widget
|
53
|
+
from streamlit.util import AttributeDictionary
|
54
54
|
|
55
55
|
if TYPE_CHECKING:
|
56
56
|
from collections.abc import Hashable, Iterable
|
@@ -823,9 +823,7 @@ def _prep_data_for_add_rows(
|
|
823
823
|
def _arrow_add_rows(
|
824
824
|
dg: DeltaGenerator,
|
825
825
|
data: Data = None,
|
826
|
-
**kwargs:
|
827
|
-
DataFrame | npt.NDArray[Any] | Iterable[Any] | dict[Hashable, Any] | None
|
828
|
-
),
|
826
|
+
**kwargs: DataFrame | npt.NDArray[Any] | Iterable[Any] | dict[Hashable, Any] | None,
|
829
827
|
) -> DeltaGenerator | None:
|
830
828
|
"""Concatenate a dataframe to the bottom of the current one.
|
831
829
|
|
@@ -29,7 +29,6 @@ from typing import (
|
|
29
29
|
from typing_extensions import TypeAlias
|
30
30
|
|
31
31
|
from streamlit import config
|
32
|
-
from streamlit.elements.lib.event_utils import AttributeDictionary
|
33
32
|
from streamlit.elements.lib.form_utils import current_form_id
|
34
33
|
from streamlit.elements.lib.policies import check_widget_policies
|
35
34
|
from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
|
@@ -41,6 +40,7 @@ from streamlit.runtime.state import (
|
|
41
40
|
WidgetCallback,
|
42
41
|
register_widget,
|
43
42
|
)
|
43
|
+
from streamlit.util import AttributeDictionary
|
44
44
|
|
45
45
|
if TYPE_CHECKING:
|
46
46
|
from collections.abc import Iterable, Mapping
|
streamlit/elements/heading.py
CHANGED
@@ -19,6 +19,7 @@ from typing import TYPE_CHECKING, Literal, Union, cast
|
|
19
19
|
|
20
20
|
from typing_extensions import TypeAlias
|
21
21
|
|
22
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig, validate_width
|
22
23
|
from streamlit.errors import StreamlitAPIException
|
23
24
|
from streamlit.proto.Heading_pb2 import Heading as HeadingProto
|
24
25
|
from streamlit.runtime.metrics_util import gather_metrics
|
@@ -26,6 +27,7 @@ from streamlit.string_util import clean_text
|
|
26
27
|
|
27
28
|
if TYPE_CHECKING:
|
28
29
|
from streamlit.delta_generator import DeltaGenerator
|
30
|
+
from streamlit.elements.lib.layout_utils import Width
|
29
31
|
from streamlit.type_util import SupportsStr
|
30
32
|
|
31
33
|
|
@@ -48,6 +50,7 @@ class HeadingMixin:
|
|
48
50
|
*, # keyword-only arguments:
|
49
51
|
help: str | None = None,
|
50
52
|
divider: Divider = False,
|
53
|
+
width: Width = "stretch",
|
51
54
|
) -> DeltaGenerator:
|
52
55
|
"""Display text in header formatting.
|
53
56
|
|
@@ -84,6 +87,11 @@ class HeadingMixin:
|
|
84
87
|
the following: blue, green, orange, red, violet, gray/grey, or
|
85
88
|
rainbow.
|
86
89
|
|
90
|
+
width : int or "stretch" or "content"
|
91
|
+
The width of the header. Can be an integer (pixels), "stretch" to
|
92
|
+
use the full width of the container, or "content" (default) to size
|
93
|
+
based on the content.
|
94
|
+
|
87
95
|
Examples
|
88
96
|
--------
|
89
97
|
>>> import streamlit as st
|
@@ -101,6 +109,9 @@ class HeadingMixin:
|
|
101
109
|
height: 600px
|
102
110
|
|
103
111
|
"""
|
112
|
+
validate_width(width, allow_content=True)
|
113
|
+
layout_config = LayoutConfig(width=width)
|
114
|
+
|
104
115
|
return self.dg._enqueue(
|
105
116
|
"heading",
|
106
117
|
HeadingMixin._create_heading_proto(
|
@@ -110,6 +121,7 @@ class HeadingMixin:
|
|
110
121
|
help=help,
|
111
122
|
divider=divider,
|
112
123
|
),
|
124
|
+
layout_config=layout_config,
|
113
125
|
)
|
114
126
|
|
115
127
|
@gather_metrics("subheader")
|
@@ -120,6 +132,7 @@ class HeadingMixin:
|
|
120
132
|
*, # keyword-only arguments:
|
121
133
|
help: str | None = None,
|
122
134
|
divider: Divider = False,
|
135
|
+
width: Width = "stretch",
|
123
136
|
) -> DeltaGenerator:
|
124
137
|
"""Display text in subheader formatting.
|
125
138
|
|
@@ -156,6 +169,11 @@ class HeadingMixin:
|
|
156
169
|
the following: blue, green, orange, red, violet, gray/grey, or
|
157
170
|
rainbow.
|
158
171
|
|
172
|
+
width : int or "stretch" or "content"
|
173
|
+
The width of the subheader. Can be an integer (pixels), "stretch" to
|
174
|
+
use the full width of the container, or "content" (default) to size
|
175
|
+
based on the content.
|
176
|
+
|
159
177
|
Examples
|
160
178
|
--------
|
161
179
|
>>> import streamlit as st
|
@@ -173,6 +191,9 @@ class HeadingMixin:
|
|
173
191
|
height: 500px
|
174
192
|
|
175
193
|
"""
|
194
|
+
validate_width(width, allow_content=True)
|
195
|
+
layout_config = LayoutConfig(width=width)
|
196
|
+
|
176
197
|
return self.dg._enqueue(
|
177
198
|
"heading",
|
178
199
|
HeadingMixin._create_heading_proto(
|
@@ -182,6 +203,7 @@ class HeadingMixin:
|
|
182
203
|
help=help,
|
183
204
|
divider=divider,
|
184
205
|
),
|
206
|
+
layout_config=layout_config,
|
185
207
|
)
|
186
208
|
|
187
209
|
@gather_metrics("title")
|
@@ -191,6 +213,7 @@ class HeadingMixin:
|
|
191
213
|
anchor: Anchor = None,
|
192
214
|
*, # keyword-only arguments:
|
193
215
|
help: str | None = None,
|
216
|
+
width: Width = "stretch",
|
194
217
|
) -> DeltaGenerator:
|
195
218
|
"""Display text in title formatting.
|
196
219
|
|
@@ -222,6 +245,11 @@ class HeadingMixin:
|
|
222
245
|
including the Markdown directives described in the ``body``
|
223
246
|
parameter of ``st.markdown``.
|
224
247
|
|
248
|
+
width : int or "stretch" or "content"
|
249
|
+
The width of the title. Can be an integer (pixels), "stretch" to
|
250
|
+
use the full width of the container, or "content" (default) to size
|
251
|
+
based on the content.
|
252
|
+
|
225
253
|
Examples
|
226
254
|
--------
|
227
255
|
>>> import streamlit as st
|
@@ -234,11 +262,15 @@ class HeadingMixin:
|
|
234
262
|
height: 220px
|
235
263
|
|
236
264
|
"""
|
265
|
+
validate_width(width, allow_content=True)
|
266
|
+
layout_config = LayoutConfig(width=width)
|
267
|
+
|
237
268
|
return self.dg._enqueue(
|
238
269
|
"heading",
|
239
270
|
HeadingMixin._create_heading_proto(
|
240
271
|
tag=HeadingProtoTag.TITLE_TAG, body=body, anchor=anchor, help=help
|
241
272
|
),
|
273
|
+
layout_config=layout_config,
|
242
274
|
)
|
243
275
|
|
244
276
|
@property
|
streamlit/elements/metric.py
CHANGED
@@ -20,6 +20,7 @@ from typing import TYPE_CHECKING, Any, Literal, Union, cast
|
|
20
20
|
|
21
21
|
from typing_extensions import TypeAlias
|
22
22
|
|
23
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig, Width, validate_width
|
23
24
|
from streamlit.elements.lib.policies import maybe_raise_label_warnings
|
24
25
|
from streamlit.elements.lib.utils import (
|
25
26
|
LabelVisibility,
|
@@ -58,6 +59,7 @@ class MetricMixin:
|
|
58
59
|
help: str | None = None,
|
59
60
|
label_visibility: LabelVisibility = "visible",
|
60
61
|
border: bool = False,
|
62
|
+
width: Width = "stretch",
|
61
63
|
) -> DeltaGenerator:
|
62
64
|
r"""Display a metric in big bold font, with an optional indicator of how the metric changed.
|
63
65
|
|
@@ -122,6 +124,11 @@ class MetricMixin:
|
|
122
124
|
``False`` (default), no border is shown. If this is ``True``, a
|
123
125
|
border is shown.
|
124
126
|
|
127
|
+
width : int or "stretch" or "content"
|
128
|
+
The width of the metric. Can be either an integer (pixels), "stretch", or "content".
|
129
|
+
Defaults to "stretch". If "stretch", the metric will stretch to fill the available
|
130
|
+
space. If "content", the metric will adjust its width to fit its content.
|
131
|
+
|
125
132
|
Examples
|
126
133
|
--------
|
127
134
|
**Example 1: Show a metric**
|
@@ -204,7 +211,10 @@ class MetricMixin:
|
|
204
211
|
label_visibility
|
205
212
|
)
|
206
213
|
|
207
|
-
|
214
|
+
validate_width(width, allow_content=True)
|
215
|
+
layout_config = LayoutConfig(width=width)
|
216
|
+
|
217
|
+
return self.dg._enqueue("metric", metric_proto, layout_config=layout_config)
|
208
218
|
|
209
219
|
@property
|
210
220
|
def dg(self) -> DeltaGenerator:
|
@@ -33,7 +33,6 @@ from typing_extensions import Required, TypeAlias
|
|
33
33
|
|
34
34
|
from streamlit import type_util
|
35
35
|
from streamlit.deprecation_util import show_deprecation_warning
|
36
|
-
from streamlit.elements.lib.event_utils import AttributeDictionary
|
37
36
|
from streamlit.elements.lib.form_utils import current_form_id
|
38
37
|
from streamlit.elements.lib.policies import check_widget_policies
|
39
38
|
from streamlit.elements.lib.streamlit_plotly_theme import (
|
@@ -45,6 +44,7 @@ from streamlit.proto.PlotlyChart_pb2 import PlotlyChart as PlotlyChartProto
|
|
45
44
|
from streamlit.runtime.metrics_util import gather_metrics
|
46
45
|
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
47
46
|
from streamlit.runtime.state import WidgetCallback, register_widget
|
47
|
+
from streamlit.util import AttributeDictionary
|
48
48
|
|
49
49
|
if TYPE_CHECKING:
|
50
50
|
from collections.abc import Iterable
|
streamlit/elements/text.py
CHANGED
@@ -16,12 +16,14 @@ from __future__ import annotations
|
|
16
16
|
|
17
17
|
from typing import TYPE_CHECKING, cast
|
18
18
|
|
19
|
+
from streamlit.elements.lib.layout_utils import LayoutConfig, validate_width
|
19
20
|
from streamlit.proto.Text_pb2 import Text as TextProto
|
20
21
|
from streamlit.runtime.metrics_util import gather_metrics
|
21
22
|
from streamlit.string_util import clean_text
|
22
23
|
|
23
24
|
if TYPE_CHECKING:
|
24
25
|
from streamlit.delta_generator import DeltaGenerator
|
26
|
+
from streamlit.elements.lib.layout_utils import Width
|
25
27
|
from streamlit.type_util import SupportsStr
|
26
28
|
|
27
29
|
|
@@ -32,6 +34,7 @@ class TextMixin:
|
|
32
34
|
body: SupportsStr,
|
33
35
|
*, # keyword-only arguments:
|
34
36
|
help: str | None = None,
|
37
|
+
width: Width = "content",
|
35
38
|
) -> DeltaGenerator:
|
36
39
|
r"""Write text without Markdown or HTML parsing.
|
37
40
|
|
@@ -53,6 +56,11 @@ class TextMixin:
|
|
53
56
|
including the Markdown directives described in the ``body``
|
54
57
|
parameter of ``st.markdown``.
|
55
58
|
|
59
|
+
width : int or "stretch" or "content"
|
60
|
+
The width of the text element. Can be an integer (pixels), "stretch" to
|
61
|
+
use the full width of the container, or "content" (default) to size
|
62
|
+
based on the content.
|
63
|
+
|
56
64
|
Example
|
57
65
|
-------
|
58
66
|
>>> import streamlit as st
|
@@ -68,7 +76,11 @@ class TextMixin:
|
|
68
76
|
text_proto.body = clean_text(body)
|
69
77
|
if help:
|
70
78
|
text_proto.help = help
|
71
|
-
|
79
|
+
|
80
|
+
validate_width(width, allow_content=True)
|
81
|
+
layout_config = LayoutConfig(width=width)
|
82
|
+
|
83
|
+
return self.dg._enqueue("text", text_proto, layout_config=layout_config)
|
72
84
|
|
73
85
|
@property
|
74
86
|
def dg(self) -> DeltaGenerator:
|
@@ -42,7 +42,6 @@ from streamlit.elements.lib.built_in_chart_utils import (
|
|
42
42
|
generate_chart,
|
43
43
|
maybe_raise_stack_warning,
|
44
44
|
)
|
45
|
-
from streamlit.elements.lib.event_utils import AttributeDictionary
|
46
45
|
from streamlit.elements.lib.form_utils import current_form_id
|
47
46
|
from streamlit.elements.lib.policies import check_widget_policies
|
48
47
|
from streamlit.elements.lib.utils import Key, compute_and_register_element_id, to_key
|
@@ -53,7 +52,7 @@ from streamlit.proto.ArrowVegaLiteChart_pb2 import (
|
|
53
52
|
from streamlit.runtime.metrics_util import gather_metrics
|
54
53
|
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
55
54
|
from streamlit.runtime.state import WidgetCallback, register_widget
|
56
|
-
from streamlit.util import calc_md5
|
55
|
+
from streamlit.util import AttributeDictionary, calc_md5
|
57
56
|
|
58
57
|
if TYPE_CHECKING:
|
59
58
|
from collections.abc import Iterable, Sequence
|
@@ -250,6 +249,30 @@ class VegaLiteStateSerde:
|
|
250
249
|
return json.dumps(selection_state, default=str)
|
251
250
|
|
252
251
|
|
252
|
+
def _patch_null_legend_titles(spec: VegaLiteSpec) -> None:
|
253
|
+
"""Patches null legend titles in the 'color' channel of the spec.
|
254
|
+
This is a fix for the Vega-Lite bug where null legend titles
|
255
|
+
cause a wrong formatting of the chart as shown on the issue #9339.
|
256
|
+
"""
|
257
|
+
|
258
|
+
encoding = spec.get("encoding")
|
259
|
+
if not isinstance(encoding, dict):
|
260
|
+
return
|
261
|
+
|
262
|
+
color_spec = encoding.get("color")
|
263
|
+
if not isinstance(color_spec, dict):
|
264
|
+
return
|
265
|
+
|
266
|
+
if "title" in color_spec and color_spec.get("title") is None:
|
267
|
+
# Patch legend title given null value directly in the encoding
|
268
|
+
color_spec["title"] = " "
|
269
|
+
|
270
|
+
legend = color_spec.get("legend")
|
271
|
+
if isinstance(legend, dict) and "title" in legend and legend.get("title") is None:
|
272
|
+
# Patch legend title given null value in the legend
|
273
|
+
legend["title"] = " "
|
274
|
+
|
275
|
+
|
253
276
|
def _prepare_vega_lite_spec(
|
254
277
|
spec: VegaLiteSpec,
|
255
278
|
use_container_width: bool,
|
@@ -278,6 +301,8 @@ def _prepare_vega_lite_spec(
|
|
278
301
|
else:
|
279
302
|
spec["autosize"] = {"type": "fit", "contains": "padding"}
|
280
303
|
|
304
|
+
_patch_null_legend_titles(spec)
|
305
|
+
|
281
306
|
return spec
|
282
307
|
|
283
308
|
|
@@ -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,
|
@@ -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
|
|
@@ -133,6 +139,10 @@ class CheckboxMixin:
|
|
133
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 : Width
|
143
|
+
The width of the widget. Can be an integer for pixel width,
|
144
|
+
or one of "content" or "stretch". Defaults to "content".
|
145
|
+
|
136
146
|
Returns
|
137
147
|
-------
|
138
148
|
bool
|
@@ -165,6 +175,7 @@ class CheckboxMixin:
|
|
165
175
|
label_visibility=label_visibility,
|
166
176
|
type=CheckboxProto.StyleType.DEFAULT,
|
167
177
|
ctx=ctx,
|
178
|
+
width=width,
|
168
179
|
)
|
169
180
|
|
170
181
|
@gather_metrics("toggle")
|
@@ -180,6 +191,7 @@ class CheckboxMixin:
|
|
180
191
|
*, # keyword-only arguments:
|
181
192
|
disabled: bool = False,
|
182
193
|
label_visibility: LabelVisibility = "visible",
|
194
|
+
width: Width = "content",
|
183
195
|
) -> bool:
|
184
196
|
r"""Display a toggle widget.
|
185
197
|
|
@@ -244,6 +256,10 @@ class CheckboxMixin:
|
|
244
256
|
label, which can help keep the widget aligned with other widgets.
|
245
257
|
If this is ``"collapsed"``, Streamlit displays no label or spacer.
|
246
258
|
|
259
|
+
width : Width
|
260
|
+
The width of the widget. Can be an integer for pixel width,
|
261
|
+
or one of "content" or "stretch". Defaults to "content".
|
262
|
+
|
247
263
|
Returns
|
248
264
|
-------
|
249
265
|
bool
|
@@ -276,6 +292,7 @@ class CheckboxMixin:
|
|
276
292
|
label_visibility=label_visibility,
|
277
293
|
type=CheckboxProto.StyleType.TOGGLE,
|
278
294
|
ctx=ctx,
|
295
|
+
width=width,
|
279
296
|
)
|
280
297
|
|
281
298
|
def _checkbox(
|
@@ -292,6 +309,7 @@ class CheckboxMixin:
|
|
292
309
|
label_visibility: LabelVisibility = "visible",
|
293
310
|
type: CheckboxProto.StyleType.ValueType = CheckboxProto.StyleType.DEFAULT,
|
294
311
|
ctx: ScriptRunContext | None = None,
|
312
|
+
width: Width = "content",
|
295
313
|
) -> bool:
|
296
314
|
key = to_key(key)
|
297
315
|
|
@@ -311,6 +329,7 @@ class CheckboxMixin:
|
|
311
329
|
label=label,
|
312
330
|
value=bool(value),
|
313
331
|
help=help,
|
332
|
+
width=width,
|
314
333
|
)
|
315
334
|
|
316
335
|
checkbox_proto = CheckboxProto()
|
@@ -327,6 +346,9 @@ class CheckboxMixin:
|
|
327
346
|
if help is not None:
|
328
347
|
checkbox_proto.help = dedent(help)
|
329
348
|
|
349
|
+
validate_width(width, allow_content=True)
|
350
|
+
layout_config = LayoutConfig(width=width)
|
351
|
+
|
330
352
|
serde = CheckboxSerde(value)
|
331
353
|
|
332
354
|
checkbox_state = register_widget(
|
@@ -344,7 +366,7 @@ class CheckboxMixin:
|
|
344
366
|
checkbox_proto.value = checkbox_state.value
|
345
367
|
checkbox_proto.set_value = True
|
346
368
|
|
347
|
-
self.dg._enqueue("checkbox", checkbox_proto)
|
369
|
+
self.dg._enqueue("checkbox", checkbox_proto, layout_config=layout_config)
|
348
370
|
return checkbox_state.value
|
349
371
|
|
350
372
|
@property
|