streamlit-nightly 1.38.1.dev20240917__py2.py3-none-any.whl → 1.38.1.dev20240919__py2.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/commands/navigation.py +9 -0
- streamlit/components/v1/custom_component.py +2 -6
- streamlit/elements/arrow.py +1 -3
- streamlit/elements/deck_gl_json_chart.py +26 -2
- streamlit/elements/form.py +10 -1
- streamlit/elements/layouts.py +6 -1
- streamlit/elements/lib/utils.py +52 -6
- streamlit/elements/map.py +27 -1
- streamlit/elements/media.py +16 -5
- streamlit/elements/plotly_chart.py +1 -3
- streamlit/elements/vega_charts.py +1 -3
- streamlit/elements/widgets/button.py +7 -5
- streamlit/elements/widgets/button_group.py +1 -3
- streamlit/elements/widgets/camera_input.py +1 -3
- streamlit/elements/widgets/chat.py +2 -2
- streamlit/elements/widgets/checkbox.py +1 -3
- streamlit/elements/widgets/color_picker.py +1 -3
- streamlit/elements/widgets/data_editor.py +1 -3
- streamlit/elements/widgets/file_uploader.py +1 -3
- streamlit/elements/widgets/multiselect.py +1 -3
- streamlit/elements/widgets/number_input.py +1 -3
- streamlit/elements/widgets/radio.py +1 -3
- streamlit/elements/widgets/select_slider.py +1 -3
- streamlit/elements/widgets/selectbox.py +1 -3
- streamlit/elements/widgets/slider.py +1 -3
- streamlit/elements/widgets/text_widgets.py +2 -6
- streamlit/elements/widgets/time_widgets.py +2 -6
- streamlit/navigation/page.py +10 -6
- streamlit/proto/Block_pb2.py +13 -13
- streamlit/proto/Block_pb2.pyi +4 -1
- streamlit/proto/DeckGlJsonChart_pb2.py +3 -3
- streamlit/proto/DeckGlJsonChart_pb2.pyi +9 -1
- streamlit/proto/Navigation_pb2.py +4 -4
- streamlit/proto/Navigation_pb2.pyi +4 -1
- streamlit/static/asset-manifest.json +12 -11
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{1086.b7ec1344.chunk.js → 1086.464de8f9.chunk.js} +1 -1
- streamlit/static/static/js/{1260.eaaa4e75.chunk.js → 1260.e6289cc2.chunk.js} +1 -1
- streamlit/static/static/js/2055.bca43613.chunk.js +1 -0
- streamlit/static/static/js/{5618.f7838309.chunk.js → 5618.0a42d599.chunk.js} +1 -1
- streamlit/static/static/js/{7077.e21833ae.chunk.js → 6789.f8dde736.chunk.js} +2 -2
- streamlit/static/static/js/8485.81bdf474.chunk.js +1 -0
- streamlit/static/static/js/{954.88cae675.chunk.js → 954.1da91b19.chunk.js} +2 -2
- streamlit/static/static/js/9943.d18fdff1.chunk.js +1 -0
- streamlit/static/static/js/{main.50e02474.js → main.61ca8755.js} +5 -5
- {streamlit_nightly-1.38.1.dev20240917.dist-info → streamlit_nightly-1.38.1.dev20240919.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.38.1.dev20240917.dist-info → streamlit_nightly-1.38.1.dev20240919.dist-info}/RECORD +55 -54
- streamlit/static/static/js/3156.002c6ee0.chunk.js +0 -1
- streamlit/static/static/js/7493.95e79b96.chunk.js +0 -1
- /streamlit/static/static/css/{7077.81b3d18f.chunk.css → 6789.81b3d18f.chunk.css} +0 -0
- /streamlit/static/static/css/{3156.93909c7e.chunk.css → 9943.93909c7e.chunk.css} +0 -0
- /streamlit/static/static/js/{7077.e21833ae.chunk.js.LICENSE.txt → 6789.f8dde736.chunk.js.LICENSE.txt} +0 -0
- /streamlit/static/static/js/{main.50e02474.js.LICENSE.txt → main.61ca8755.js.LICENSE.txt} +0 -0
- {streamlit_nightly-1.38.1.dev20240917.data → streamlit_nightly-1.38.1.dev20240919.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.38.1.dev20240917.dist-info → streamlit_nightly-1.38.1.dev20240919.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.38.1.dev20240917.dist-info → streamlit_nightly-1.38.1.dev20240919.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.38.1.dev20240917.dist-info → streamlit_nightly-1.38.1.dev20240919.dist-info}/top_level.txt +0 -0
streamlit/commands/navigation.py
CHANGED
@@ -57,6 +57,7 @@ def navigation(
|
|
57
57
|
pages: list[StreamlitPage] | dict[SectionHeader, list[StreamlitPage]],
|
58
58
|
*,
|
59
59
|
position: Literal["sidebar", "hidden"] = "sidebar",
|
60
|
+
expanded: bool = False,
|
60
61
|
) -> StreamlitPage:
|
61
62
|
"""
|
62
63
|
Configure the available pages in a multipage app.
|
@@ -102,6 +103,12 @@ def navigation(
|
|
102
103
|
If there is only one page in ``pages``, the navigation will be hidden
|
103
104
|
for any value of ``position``.
|
104
105
|
|
106
|
+
expanded: bool
|
107
|
+
Whether the navigation menu should be expanded. If ``True``,
|
108
|
+
the navigation menu will always be expanded. If ``False``, the
|
109
|
+
navigation menu will be collapsed and will include a button
|
110
|
+
to view more options.
|
111
|
+
|
105
112
|
Returns
|
106
113
|
-------
|
107
114
|
StreamlitPage
|
@@ -215,6 +222,8 @@ def navigation(
|
|
215
222
|
msg.navigation.position = NavigationProto.Position.HIDDEN
|
216
223
|
else:
|
217
224
|
msg.navigation.position = NavigationProto.Position.SIDEBAR
|
225
|
+
|
226
|
+
msg.navigation.expanded = expanded
|
218
227
|
msg.navigation.sections[:] = nav_sections.keys()
|
219
228
|
for section_header in nav_sections:
|
220
229
|
for page in nav_sections[section_header]:
|
@@ -173,23 +173,19 @@ And if you're using Streamlit Cloud, add "pyarrow" to your requirements.txt."""
|
|
173
173
|
computed_id = compute_and_register_element_id(
|
174
174
|
"component_instance",
|
175
175
|
user_key=key,
|
176
|
-
name=self.name,
|
177
176
|
form_id=current_form_id(dg),
|
177
|
+
name=self.name,
|
178
178
|
url=self.url,
|
179
|
-
key=key,
|
180
179
|
json_args=serialized_json_args,
|
181
180
|
special_args=special_args,
|
182
|
-
page=ctx.active_script_hash if ctx else None,
|
183
181
|
)
|
184
182
|
else:
|
185
183
|
computed_id = compute_and_register_element_id(
|
186
184
|
"component_instance",
|
187
185
|
user_key=key,
|
188
|
-
name=self.name,
|
189
186
|
form_id=current_form_id(dg),
|
187
|
+
name=self.name,
|
190
188
|
url=self.url,
|
191
|
-
key=key,
|
192
|
-
page=ctx.active_script_hash if ctx else None,
|
193
189
|
)
|
194
190
|
element.component_instance.id = computed_id
|
195
191
|
|
streamlit/elements/arrow.py
CHANGED
@@ -568,17 +568,15 @@ class ArrowMixin:
|
|
568
568
|
proto.id = compute_and_register_element_id(
|
569
569
|
"dataframe",
|
570
570
|
user_key=key,
|
571
|
+
form_id=proto.form_id,
|
571
572
|
data=proto.data,
|
572
573
|
width=width,
|
573
574
|
height=height,
|
574
575
|
use_container_width=use_container_width,
|
575
576
|
column_order=proto.column_order,
|
576
577
|
column_config=proto.columns,
|
577
|
-
key=key,
|
578
578
|
selection_mode=selection_mode,
|
579
579
|
is_selection_activated=is_selection_activated,
|
580
|
-
form_id=proto.form_id,
|
581
|
-
page=ctx.active_script_hash if ctx else None,
|
582
580
|
)
|
583
581
|
|
584
582
|
serde = DataframeSelectionSerde()
|
@@ -39,6 +39,8 @@ class PydeckMixin:
|
|
39
39
|
self,
|
40
40
|
pydeck_obj: Deck | None = None,
|
41
41
|
use_container_width: bool = False,
|
42
|
+
width: int | None = None,
|
43
|
+
height: int | None = None,
|
42
44
|
) -> DeltaGenerator:
|
43
45
|
"""Draw a chart using the PyDeck library.
|
44
46
|
|
@@ -68,7 +70,7 @@ class PydeckMixin:
|
|
68
70
|
|
69
71
|
Parameters
|
70
72
|
----------
|
71
|
-
pydeck_obj: pydeck.Deck or None
|
73
|
+
pydeck_obj : pydeck.Deck or None
|
72
74
|
Object specifying the PyDeck chart to draw.
|
73
75
|
use_container_width : bool
|
74
76
|
Whether to override the figure's native width with the width of
|
@@ -77,6 +79,19 @@ class PydeckMixin:
|
|
77
79
|
according to the plotting library, up to the width of the parent
|
78
80
|
container. If ``use_container_width`` is ``True``, Streamlit sets
|
79
81
|
the width of the figure to match the width of the parent container.
|
82
|
+
width : int or None
|
83
|
+
Desired width of the chart expressed in pixels. If ``width`` is
|
84
|
+
``None`` (default), Streamlit sets the width of the chart to fit
|
85
|
+
its contents according to the plotting library, up to the width of
|
86
|
+
the parent container. If ``width`` is greater than the width of the
|
87
|
+
parent container, Streamlit sets the chart width to match the width
|
88
|
+
of the parent container.
|
89
|
+
|
90
|
+
To use ``width``, you must set ``use_container_width=False``.
|
91
|
+
height : int or None
|
92
|
+
Desired height of the chart expressed in pixels. If ``height`` is
|
93
|
+
``None`` (default), Streamlit sets the height of the chart to fit
|
94
|
+
its contents according to the plotting library.
|
80
95
|
|
81
96
|
Example
|
82
97
|
-------
|
@@ -134,7 +149,9 @@ class PydeckMixin:
|
|
134
149
|
|
135
150
|
"""
|
136
151
|
pydeck_proto = PydeckProto()
|
137
|
-
marshall(
|
152
|
+
marshall(
|
153
|
+
pydeck_proto, pydeck_obj, use_container_width, width=width, height=height
|
154
|
+
)
|
138
155
|
return self.dg._enqueue("deck_gl_json_chart", pydeck_proto)
|
139
156
|
|
140
157
|
@property
|
@@ -165,6 +182,8 @@ def marshall(
|
|
165
182
|
pydeck_proto: PydeckProto,
|
166
183
|
pydeck_obj: Deck | None,
|
167
184
|
use_container_width: bool,
|
185
|
+
width: int | None = None,
|
186
|
+
height: int | None = None,
|
168
187
|
) -> None:
|
169
188
|
if pydeck_obj is None:
|
170
189
|
spec = json.dumps(EMPTY_MAP)
|
@@ -174,6 +193,11 @@ def marshall(
|
|
174
193
|
pydeck_proto.json = spec
|
175
194
|
pydeck_proto.use_container_width = use_container_width
|
176
195
|
|
196
|
+
if width:
|
197
|
+
pydeck_proto.width = width
|
198
|
+
if height:
|
199
|
+
pydeck_proto.height = height
|
200
|
+
|
177
201
|
pydeck_proto.id = ""
|
178
202
|
|
179
203
|
tooltip = _get_pydeck_tooltip(pydeck_obj)
|
streamlit/elements/form.py
CHANGED
@@ -61,7 +61,12 @@ def _build_duplicate_form_message(user_key: str | None = None) -> str:
|
|
61
61
|
class FormMixin:
|
62
62
|
@gather_metrics("form")
|
63
63
|
def form(
|
64
|
-
self,
|
64
|
+
self,
|
65
|
+
key: str,
|
66
|
+
clear_on_submit: bool = False,
|
67
|
+
*,
|
68
|
+
enter_to_submit: bool = True,
|
69
|
+
border: bool = True,
|
65
70
|
) -> DeltaGenerator:
|
66
71
|
"""Create a form that batches elements together with a "Submit" button.
|
67
72
|
|
@@ -93,6 +98,9 @@ class FormMixin:
|
|
93
98
|
values after the user presses the Submit button. Defaults to False.
|
94
99
|
(Note that Custom Components are unaffected by this flag, and
|
95
100
|
will not be reset to their defaults on form submission.)
|
101
|
+
enter_to_submit : bool
|
102
|
+
Whether to submit the form when a user presses Enter while
|
103
|
+
interacting with a widget inside the form. Defaults to True.
|
96
104
|
border : bool
|
97
105
|
Whether to show a border around the form. Defaults to True.
|
98
106
|
|
@@ -159,6 +167,7 @@ class FormMixin:
|
|
159
167
|
block_proto = Block_pb2.Block()
|
160
168
|
block_proto.form.form_id = form_id
|
161
169
|
block_proto.form.clear_on_submit = clear_on_submit
|
170
|
+
block_proto.form.enter_to_submit = enter_to_submit
|
162
171
|
block_proto.form.border = border
|
163
172
|
block_dg = self.dg._block(block_proto)
|
164
173
|
|
streamlit/elements/layouts.py
CHANGED
@@ -162,8 +162,13 @@ class LayoutsMixin:
|
|
162
162
|
block_proto.vertical.border = True
|
163
163
|
|
164
164
|
if key:
|
165
|
+
# At the moment, the ID is only used for extracting the
|
166
|
+
# key on the frontend and setting it as CSS class.
|
167
|
+
# There are plans to use the ID for other container features
|
168
|
+
# in the future. This might require including more container
|
169
|
+
# parameters in the ID calculation.
|
165
170
|
block_proto.id = compute_and_register_element_id(
|
166
|
-
"container", user_key=key,
|
171
|
+
"container", user_key=key, form_id=None
|
167
172
|
)
|
168
173
|
|
169
174
|
return self.dg._block(block_proto)
|
streamlit/elements/lib/utils.py
CHANGED
@@ -90,7 +90,9 @@ def to_key(key: Key | None) -> str | None:
|
|
90
90
|
return None if key is None else str(key)
|
91
91
|
|
92
92
|
|
93
|
-
def _register_element_id(
|
93
|
+
def _register_element_id(
|
94
|
+
ctx: ScriptRunContext, element_type: str, element_id: str
|
95
|
+
) -> None:
|
94
96
|
"""Register the element ID and key for the given element.
|
95
97
|
|
96
98
|
If the element ID or key is not unique, an error is raised.
|
@@ -114,8 +116,8 @@ def _register_element_id(element_type: str, element_id: str) -> None:
|
|
114
116
|
If the element ID is not unique.
|
115
117
|
|
116
118
|
"""
|
117
|
-
|
118
|
-
if
|
119
|
+
|
120
|
+
if not element_id:
|
119
121
|
return
|
120
122
|
|
121
123
|
if user_key := user_key_from_element_id(element_id):
|
@@ -148,6 +150,12 @@ def _compute_element_id(
|
|
148
150
|
"""
|
149
151
|
h = hashlib.new("md5", **HASHLIB_KWARGS)
|
150
152
|
h.update(element_type.encode("utf-8"))
|
153
|
+
if user_key:
|
154
|
+
# Adding this to the hash isn't necessary for uniqueness since the
|
155
|
+
# key is also appended to the ID as raw text. But since the hash and
|
156
|
+
# the appending of the key are two slightly different aspects, it
|
157
|
+
# still gets put into the hash.
|
158
|
+
h.update(user_key.encode("utf-8"))
|
151
159
|
# This will iterate in a consistent order when the provided arguments have
|
152
160
|
# consistent order; dicts are always in insertion order.
|
153
161
|
for k, v in kwargs.items():
|
@@ -158,7 +166,9 @@ def _compute_element_id(
|
|
158
166
|
|
159
167
|
def compute_and_register_element_id(
|
160
168
|
element_type: str,
|
161
|
-
|
169
|
+
*,
|
170
|
+
user_key: str | None,
|
171
|
+
form_id: str | None,
|
162
172
|
**kwargs: SAFE_VALUES | Iterable[SAFE_VALUES],
|
163
173
|
) -> str:
|
164
174
|
"""Compute and register the ID for the given element.
|
@@ -175,9 +185,45 @@ def compute_and_register_element_id(
|
|
175
185
|
The element ID gets registered to make sure that only one ID and user-specified
|
176
186
|
key exists at the same time. If there are duplicated IDs or keys, an error
|
177
187
|
is raised.
|
188
|
+
|
189
|
+
Parameters
|
190
|
+
----------
|
191
|
+
element_type : str
|
192
|
+
The type (command name) of the element to register.
|
193
|
+
|
194
|
+
user_key : str | None
|
195
|
+
The user-specified key for the element. `None` if no key is provided
|
196
|
+
or if the element doesn't support a specifying a key.
|
197
|
+
|
198
|
+
form_id : str | None
|
199
|
+
The ID of the form that the element belongs to. `None` or empty string
|
200
|
+
if the element doesn't belong to a form or doesn't support forms.
|
201
|
+
|
202
|
+
kwargs : SAFE_VALUES | Iterable[SAFE_VALUES]
|
203
|
+
The arguments to use to compute the element ID.
|
204
|
+
The arguments must be stable, deterministic values.
|
205
|
+
Some common parameters like key, disabled,
|
206
|
+
format_func, label_visibility, args, kwargs, on_change, and
|
207
|
+
the active_script_hash are not supposed to be added here
|
178
208
|
"""
|
179
|
-
|
180
|
-
|
209
|
+
ctx = get_script_run_ctx()
|
210
|
+
|
211
|
+
# If form_id is provided, add it to the kwargs.
|
212
|
+
kwargs_to_use = {"form_id": form_id, **kwargs} if form_id else kwargs
|
213
|
+
|
214
|
+
if ctx:
|
215
|
+
# Add the active script hash to give elements on different
|
216
|
+
# pages unique IDs.
|
217
|
+
kwargs_to_use["active_script_hash"] = ctx.active_script_hash
|
218
|
+
|
219
|
+
element_id = _compute_element_id(
|
220
|
+
element_type,
|
221
|
+
user_key,
|
222
|
+
**kwargs_to_use,
|
223
|
+
)
|
224
|
+
|
225
|
+
if ctx:
|
226
|
+
_register_element_id(ctx, element_type, element_id)
|
181
227
|
return element_id
|
182
228
|
|
183
229
|
|
streamlit/elements/map.py
CHANGED
@@ -84,6 +84,8 @@ class MapMixin:
|
|
84
84
|
size: None | str | float = None,
|
85
85
|
zoom: int | None = None,
|
86
86
|
use_container_width: bool = True,
|
87
|
+
width: int | None = None,
|
88
|
+
height: int | None = None,
|
87
89
|
) -> DeltaGenerator:
|
88
90
|
"""Display a map with a scatterplot overlaid onto it.
|
89
91
|
|
@@ -162,6 +164,21 @@ class MapMixin:
|
|
162
164
|
Streamlit sets the width of the chart to fit its contents according
|
163
165
|
to the plotting library, up to the width of the parent container.
|
164
166
|
|
167
|
+
width : int or None
|
168
|
+
Desired width of the chart expressed in pixels. If ``width`` is
|
169
|
+
``None`` (default), Streamlit sets the width of the chart to fit
|
170
|
+
its contents according to the plotting library, up to the width of
|
171
|
+
the parent container. If ``width`` is greater than the width of the
|
172
|
+
parent container, Streamlit sets the chart width to match the width
|
173
|
+
of the parent container.
|
174
|
+
|
175
|
+
To use ``width``, you must set ``use_container_width=False``.
|
176
|
+
|
177
|
+
height : int or None
|
178
|
+
Desired height of the chart expressed in pixels. If ``height`` is
|
179
|
+
``None`` (default), Streamlit sets the height of the chart to fit
|
180
|
+
its contents according to the plotting library.
|
181
|
+
|
165
182
|
Examples
|
166
183
|
--------
|
167
184
|
>>> import streamlit as st
|
@@ -223,7 +240,9 @@ class MapMixin:
|
|
223
240
|
deck_gl_json = to_deckgl_json(
|
224
241
|
data, latitude, longitude, size, color, map_style, zoom
|
225
242
|
)
|
226
|
-
marshall(
|
243
|
+
marshall(
|
244
|
+
map_proto, deck_gl_json, use_container_width, width=width, height=height
|
245
|
+
)
|
227
246
|
return self.dg._enqueue("deck_gl_json_chart", map_proto)
|
228
247
|
|
229
248
|
@property
|
@@ -471,8 +490,15 @@ def marshall(
|
|
471
490
|
pydeck_proto: DeckGlJsonChartProto,
|
472
491
|
pydeck_json: str,
|
473
492
|
use_container_width: bool,
|
493
|
+
height: int | None = None,
|
494
|
+
width: int | None = None,
|
474
495
|
) -> None:
|
475
496
|
pydeck_proto.json = pydeck_json
|
476
497
|
pydeck_proto.use_container_width = use_container_width
|
477
498
|
|
499
|
+
if width:
|
500
|
+
pydeck_proto.width = width
|
501
|
+
if height:
|
502
|
+
pydeck_proto.height = height
|
503
|
+
|
478
504
|
pydeck_proto.id = ""
|
streamlit/elements/media.py
CHANGED
@@ -23,6 +23,7 @@ from typing import TYPE_CHECKING, Dict, Final, Union, cast
|
|
23
23
|
from typing_extensions import TypeAlias
|
24
24
|
|
25
25
|
from streamlit import runtime, type_util, url_util
|
26
|
+
from streamlit.elements.lib.form_utils import current_form_id
|
26
27
|
from streamlit.elements.lib.subtitle_utils import process_subtitle_data
|
27
28
|
from streamlit.elements.lib.utils import compute_and_register_element_id
|
28
29
|
from streamlit.errors import StreamlitAPIException
|
@@ -30,7 +31,6 @@ from streamlit.proto.Audio_pb2 import Audio as AudioProto
|
|
30
31
|
from streamlit.proto.Video_pb2 import Video as VideoProto
|
31
32
|
from streamlit.runtime import caching
|
32
33
|
from streamlit.runtime.metrics_util import gather_metrics
|
33
|
-
from streamlit.runtime.scriptrunner_utils.script_run_context import get_script_run_ctx
|
34
34
|
from streamlit.time_util import time_to_seconds
|
35
35
|
from streamlit.type_util import NumpyShape
|
36
36
|
|
@@ -191,6 +191,7 @@ class MediaMixin:
|
|
191
191
|
end_time,
|
192
192
|
loop,
|
193
193
|
autoplay,
|
194
|
+
form_id=current_form_id(self.dg),
|
194
195
|
)
|
195
196
|
return self.dg._enqueue("audio", audio_proto)
|
196
197
|
|
@@ -349,6 +350,7 @@ class MediaMixin:
|
|
349
350
|
loop,
|
350
351
|
autoplay,
|
351
352
|
muted,
|
353
|
+
form_id=current_form_id(self.dg),
|
352
354
|
)
|
353
355
|
return self.dg._enqueue("video", video_proto)
|
354
356
|
|
@@ -457,6 +459,7 @@ def marshall_video(
|
|
457
459
|
loop: bool = False,
|
458
460
|
autoplay: bool = False,
|
459
461
|
muted: bool = False,
|
462
|
+
form_id: str | None = None,
|
460
463
|
) -> None:
|
461
464
|
"""Marshalls a video proto, using url processors as needed.
|
462
465
|
|
@@ -499,6 +502,9 @@ def marshall_video(
|
|
499
502
|
muted: bool
|
500
503
|
Whether the video should play with the audio silenced. This can be used to
|
501
504
|
enable autoplay without user interaction. Defaults to False.
|
505
|
+
form_id: str | None
|
506
|
+
The ID of the form that this element is placed in. Provide None if
|
507
|
+
the element is not placed in a form.
|
502
508
|
"""
|
503
509
|
|
504
510
|
if start_time < 0 or (end_time is not None and end_time <= start_time):
|
@@ -565,10 +571,12 @@ def marshall_video(
|
|
565
571
|
) from original_err
|
566
572
|
|
567
573
|
if autoplay:
|
568
|
-
ctx = get_script_run_ctx()
|
569
574
|
proto.autoplay = autoplay
|
570
575
|
proto.id = compute_and_register_element_id(
|
571
576
|
"video",
|
577
|
+
# video does not yet allow setting a user-defined key
|
578
|
+
user_key=None,
|
579
|
+
form_id=form_id,
|
572
580
|
url=proto.url,
|
573
581
|
mimetype=mimetype,
|
574
582
|
start_time=start_time,
|
@@ -576,7 +584,6 @@ def marshall_video(
|
|
576
584
|
loop=loop,
|
577
585
|
autoplay=autoplay,
|
578
586
|
muted=muted,
|
579
|
-
page=ctx.active_script_hash if ctx else None,
|
580
587
|
)
|
581
588
|
|
582
589
|
|
@@ -696,6 +703,7 @@ def marshall_audio(
|
|
696
703
|
end_time: int | None = None,
|
697
704
|
loop: bool = False,
|
698
705
|
autoplay: bool = False,
|
706
|
+
form_id: str | None = None,
|
699
707
|
) -> None:
|
700
708
|
"""Marshalls an audio proto, using data and url processors as needed.
|
701
709
|
|
@@ -722,6 +730,9 @@ def marshall_audio(
|
|
722
730
|
autoplay : bool
|
723
731
|
Whether the audio should start playing automatically.
|
724
732
|
Browsers will not autoplay audio files if the user has not interacted with the page yet.
|
733
|
+
form_id: str | None
|
734
|
+
The ID of the form that this element is placed in. Provide None if
|
735
|
+
the element is not placed in a form.
|
725
736
|
"""
|
726
737
|
|
727
738
|
proto.start_time = start_time
|
@@ -739,10 +750,11 @@ def marshall_audio(
|
|
739
750
|
_marshall_av_media(coordinates, proto, data, mimetype)
|
740
751
|
|
741
752
|
if autoplay:
|
742
|
-
ctx = get_script_run_ctx()
|
743
753
|
proto.autoplay = autoplay
|
744
754
|
proto.id = compute_and_register_element_id(
|
745
755
|
"audio",
|
756
|
+
user_key=None,
|
757
|
+
form_id=form_id,
|
746
758
|
url=proto.url,
|
747
759
|
mimetype=mimetype,
|
748
760
|
start_time=start_time,
|
@@ -750,5 +762,4 @@ def marshall_audio(
|
|
750
762
|
end_time=end_time,
|
751
763
|
loop=loop,
|
752
764
|
autoplay=autoplay,
|
753
|
-
page=ctx.active_script_hash if ctx else None,
|
754
765
|
)
|
@@ -506,15 +506,13 @@ class PlotlyMixin:
|
|
506
506
|
plotly_chart_proto.id = compute_and_register_element_id(
|
507
507
|
"plotly_chart",
|
508
508
|
user_key=key,
|
509
|
-
|
509
|
+
form_id=plotly_chart_proto.form_id,
|
510
510
|
plotly_spec=plotly_chart_proto.spec,
|
511
511
|
plotly_config=plotly_chart_proto.config,
|
512
512
|
selection_mode=selection_mode,
|
513
513
|
is_selection_activated=is_selection_activated,
|
514
514
|
theme=theme,
|
515
|
-
form_id=plotly_chart_proto.form_id,
|
516
515
|
use_container_width=use_container_width,
|
517
|
-
page=ctx.active_script_hash if ctx else None,
|
518
516
|
)
|
519
517
|
|
520
518
|
if is_selection_activated:
|
@@ -1894,7 +1894,7 @@ class VegaChartsMixin:
|
|
1894
1894
|
vega_lite_proto.id = compute_and_register_element_id(
|
1895
1895
|
"arrow_vega_lite_chart",
|
1896
1896
|
user_key=key,
|
1897
|
-
|
1897
|
+
form_id=vega_lite_proto.form_id,
|
1898
1898
|
vega_lite_spec=vega_lite_proto.spec,
|
1899
1899
|
# The data is either in vega_lite_proto.data.data
|
1900
1900
|
# or in a named dataset in vega_lite_proto.datasets
|
@@ -1905,8 +1905,6 @@ class VegaChartsMixin:
|
|
1905
1905
|
theme=theme,
|
1906
1906
|
use_container_width=use_container_width,
|
1907
1907
|
selection_mode=parsed_selection_modes,
|
1908
|
-
form_id=vega_lite_proto.form_id,
|
1909
|
-
page=ctx.active_script_hash if ctx else None,
|
1910
1908
|
)
|
1911
1909
|
|
1912
1910
|
serde = VegaLiteStateSerde(parsed_selection_modes)
|
@@ -673,15 +673,15 @@ class ButtonMixin:
|
|
673
673
|
element_id = compute_and_register_element_id(
|
674
674
|
"download_button",
|
675
675
|
user_key=key,
|
676
|
+
# download_button is not allowed to be used in a form.
|
677
|
+
form_id=None,
|
676
678
|
label=label,
|
677
679
|
icon=icon,
|
678
680
|
file_name=file_name,
|
679
681
|
mime=mime,
|
680
|
-
key=key,
|
681
682
|
help=help,
|
682
683
|
type=type,
|
683
684
|
use_container_width=use_container_width,
|
684
|
-
page=ctx.active_script_hash if ctx else None,
|
685
685
|
)
|
686
686
|
|
687
687
|
if is_in_form(self.dg):
|
@@ -853,17 +853,19 @@ class ButtonMixin:
|
|
853
853
|
enable_check_callback_rules=not is_form_submitter,
|
854
854
|
)
|
855
855
|
|
856
|
+
# Only the form submitter button needs a form ID at the moment.
|
857
|
+
form_id = current_form_id(self.dg) if is_form_submitter else ""
|
856
858
|
element_id = compute_and_register_element_id(
|
857
859
|
"button",
|
858
860
|
user_key=key,
|
861
|
+
# Only the
|
862
|
+
form_id=form_id,
|
859
863
|
label=label,
|
860
864
|
icon=icon,
|
861
|
-
key=key,
|
862
865
|
help=help,
|
863
866
|
is_form_submitter=is_form_submitter,
|
864
867
|
type=type,
|
865
868
|
use_container_width=use_container_width,
|
866
|
-
page=ctx.active_script_hash if ctx else None,
|
867
869
|
)
|
868
870
|
|
869
871
|
# It doesn't make sense to create a button inside a form (except
|
@@ -886,7 +888,7 @@ class ButtonMixin:
|
|
886
888
|
button_proto.label = label
|
887
889
|
button_proto.default = False
|
888
890
|
button_proto.is_form_submitter = is_form_submitter
|
889
|
-
button_proto.form_id =
|
891
|
+
button_proto.form_id = form_id
|
890
892
|
button_proto.type = type
|
891
893
|
button_proto.use_container_width = use_container_width
|
892
894
|
button_proto.disabled = disabled
|
@@ -399,12 +399,10 @@ class ButtonGroupMixin:
|
|
399
399
|
element_id = compute_and_register_element_id(
|
400
400
|
widget_name,
|
401
401
|
user_key=key,
|
402
|
-
|
402
|
+
form_id=form_id,
|
403
403
|
options=formatted_options,
|
404
404
|
default=default,
|
405
|
-
form_id=form_id,
|
406
405
|
click_mode=click_mode,
|
407
|
-
page=ctx.active_script_hash if ctx else None,
|
408
406
|
)
|
409
407
|
|
410
408
|
proto = _build_proto(
|
@@ -206,11 +206,9 @@ class CameraInputMixin:
|
|
206
206
|
element_id = compute_and_register_element_id(
|
207
207
|
"camera_input",
|
208
208
|
user_key=key,
|
209
|
+
form_id=current_form_id(self.dg),
|
209
210
|
label=label,
|
210
|
-
key=key,
|
211
211
|
help=help,
|
212
|
-
form_id=current_form_id(self.dg),
|
213
|
-
page=ctx.active_script_hash if ctx else None,
|
214
212
|
)
|
215
213
|
|
216
214
|
camera_input_proto = CameraInputProto()
|
@@ -330,10 +330,10 @@ class ChatMixin:
|
|
330
330
|
element_id = compute_and_register_element_id(
|
331
331
|
"chat_input",
|
332
332
|
user_key=key,
|
333
|
-
|
333
|
+
# chat_input is not allowed to be used in a form.
|
334
|
+
form_id=None,
|
334
335
|
placeholder=placeholder,
|
335
336
|
max_chars=max_chars,
|
336
|
-
page=ctx.active_script_hash if ctx else None,
|
337
337
|
)
|
338
338
|
|
339
339
|
# It doesn't make sense to create a chat input inside a form.
|
@@ -294,12 +294,10 @@ class CheckboxMixin:
|
|
294
294
|
element_id = compute_and_register_element_id(
|
295
295
|
"toggle" if type == CheckboxProto.StyleType.TOGGLE else "checkbox",
|
296
296
|
user_key=key,
|
297
|
+
form_id=current_form_id(self.dg),
|
297
298
|
label=label,
|
298
299
|
value=bool(value),
|
299
|
-
key=key,
|
300
300
|
help=help,
|
301
|
-
form_id=current_form_id(self.dg),
|
302
|
-
page=ctx.active_script_hash if ctx else None,
|
303
301
|
)
|
304
302
|
|
305
303
|
checkbox_proto = CheckboxProto()
|
@@ -189,12 +189,10 @@ class ColorPickerMixin:
|
|
189
189
|
element_id = compute_and_register_element_id(
|
190
190
|
"color_picker",
|
191
191
|
user_key=key,
|
192
|
+
form_id=current_form_id(self.dg),
|
192
193
|
label=label,
|
193
194
|
value=str(value),
|
194
|
-
key=key,
|
195
195
|
help=help,
|
196
|
-
form_id=current_form_id(self.dg),
|
197
|
-
page=ctx.active_script_hash if ctx else None,
|
198
196
|
)
|
199
197
|
|
200
198
|
# set value default
|
@@ -887,6 +887,7 @@ class DataEditorMixin:
|
|
887
887
|
element_id = compute_and_register_element_id(
|
888
888
|
"data_editor",
|
889
889
|
user_key=key,
|
890
|
+
form_id=current_form_id(self.dg),
|
890
891
|
data=arrow_bytes,
|
891
892
|
width=width,
|
892
893
|
height=height,
|
@@ -894,9 +895,6 @@ class DataEditorMixin:
|
|
894
895
|
column_order=column_order,
|
895
896
|
column_config_mapping=str(column_config_mapping),
|
896
897
|
num_rows=num_rows,
|
897
|
-
key=key,
|
898
|
-
form_id=current_form_id(self.dg),
|
899
|
-
page=ctx.active_script_hash if ctx else None,
|
900
898
|
)
|
901
899
|
|
902
900
|
proto = ArrowProto()
|
@@ -408,13 +408,11 @@ class FileUploaderMixin:
|
|
408
408
|
element_id = compute_and_register_element_id(
|
409
409
|
"file_uploader",
|
410
410
|
user_key=key,
|
411
|
+
form_id=current_form_id(self.dg),
|
411
412
|
label=label,
|
412
413
|
type=type,
|
413
414
|
accept_multiple_files=accept_multiple_files,
|
414
|
-
key=key,
|
415
415
|
help=help,
|
416
|
-
form_id=current_form_id(self.dg),
|
417
|
-
page=ctx.active_script_hash if ctx else None,
|
418
416
|
)
|
419
417
|
|
420
418
|
if type:
|
@@ -274,15 +274,13 @@ class MultiSelectMixin:
|
|
274
274
|
element_id = compute_and_register_element_id(
|
275
275
|
widget_name,
|
276
276
|
user_key=key,
|
277
|
+
form_id=form_id,
|
277
278
|
label=label,
|
278
279
|
options=formatted_options,
|
279
280
|
default=default_values,
|
280
|
-
key=key,
|
281
281
|
help=help,
|
282
282
|
max_selections=max_selections,
|
283
283
|
placeholder=placeholder,
|
284
|
-
form_id=form_id,
|
285
|
-
page=ctx.active_script_hash if ctx else None,
|
286
284
|
)
|
287
285
|
|
288
286
|
proto = MultiSelectProto()
|