reflex 0.7.13a2__py3-none-any.whl → 0.7.14__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.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- reflex/.templates/apps/blank/code/blank.py +0 -2
- reflex/app.py +85 -89
- reflex/app_mixins/lifespan.py +2 -3
- reflex/app_mixins/middleware.py +1 -0
- reflex/app_mixins/mixin.py +0 -1
- reflex/assets.py +7 -4
- reflex/base.py +3 -2
- reflex/compiler/compiler.py +79 -65
- reflex/compiler/utils.py +8 -6
- reflex/components/base/app_wrap.pyi +0 -1
- reflex/components/base/bare.py +22 -12
- reflex/components/base/body.pyi +0 -1
- reflex/components/base/document.pyi +0 -5
- reflex/components/base/error_boundary.pyi +0 -1
- reflex/components/base/fragment.pyi +0 -1
- reflex/components/base/head.pyi +0 -2
- reflex/components/base/link.pyi +0 -2
- reflex/components/base/meta.py +2 -1
- reflex/components/base/meta.pyi +0 -4
- reflex/components/base/script.py +2 -1
- reflex/components/base/script.pyi +0 -1
- reflex/components/base/strict_mode.pyi +0 -1
- reflex/components/component.py +85 -45
- reflex/components/core/auto_scroll.pyi +0 -1
- reflex/components/core/banner.py +1 -1
- reflex/components/core/banner.pyi +0 -6
- reflex/components/core/breakpoints.py +9 -11
- reflex/components/core/client_side_routing.pyi +0 -2
- reflex/components/core/clipboard.pyi +0 -1
- reflex/components/core/colors.py +10 -7
- reflex/components/core/cond.py +4 -2
- reflex/components/core/debounce.py +5 -3
- reflex/components/core/debounce.pyi +0 -1
- reflex/components/core/foreach.py +8 -6
- reflex/components/core/html.py +3 -3
- reflex/components/core/html.pyi +0 -1
- reflex/components/core/match.py +19 -17
- reflex/components/core/sticky.pyi +0 -4
- reflex/components/core/upload.py +1 -1
- reflex/components/core/upload.pyi +0 -5
- reflex/components/datadisplay/code.py +1 -2
- reflex/components/datadisplay/code.pyi +0 -2
- reflex/components/datadisplay/dataeditor.py +7 -10
- reflex/components/datadisplay/dataeditor.pyi +0 -1
- reflex/components/datadisplay/logo.py +3 -4
- reflex/components/datadisplay/shiki_code_block.py +8 -11
- reflex/components/datadisplay/shiki_code_block.pyi +0 -3
- reflex/components/dynamic.py +2 -3
- reflex/components/el/__init__.pyi +2 -0
- reflex/components/el/element.pyi +0 -1
- reflex/components/el/elements/__init__.py +1 -0
- reflex/components/el/elements/__init__.pyi +3 -0
- reflex/components/el/elements/base.pyi +0 -1
- reflex/components/el/elements/forms.py +14 -15
- reflex/components/el/elements/forms.pyi +15 -32
- reflex/components/el/elements/inline.pyi +0 -28
- reflex/components/el/elements/media.py +26 -0
- reflex/components/el/elements/media.pyi +259 -25
- reflex/components/el/elements/metadata.py +0 -1
- reflex/components/el/elements/metadata.pyi +0 -6
- reflex/components/el/elements/other.pyi +0 -7
- reflex/components/el/elements/scripts.pyi +0 -3
- reflex/components/el/elements/sectioning.pyi +0 -15
- reflex/components/el/elements/tables.pyi +0 -10
- reflex/components/el/elements/typography.pyi +0 -15
- reflex/components/gridjs/datatable.py +10 -13
- reflex/components/gridjs/datatable.pyi +0 -2
- reflex/components/lucide/icon.py +10 -9
- reflex/components/lucide/icon.pyi +0 -3
- reflex/components/markdown/markdown.py +6 -8
- reflex/components/markdown/markdown.pyi +0 -1
- reflex/components/moment/moment.pyi +0 -1
- reflex/components/next/base.py +0 -2
- reflex/components/next/base.pyi +0 -3
- reflex/components/next/image.pyi +0 -1
- reflex/components/next/link.pyi +0 -1
- reflex/components/next/video.pyi +0 -1
- reflex/components/plotly/plotly.pyi +0 -9
- reflex/components/props.py +4 -3
- reflex/components/radix/primitives/accordion.pyi +0 -7
- reflex/components/radix/primitives/base.py +1 -3
- reflex/components/radix/primitives/base.pyi +0 -2
- reflex/components/radix/primitives/drawer.pyi +0 -11
- reflex/components/radix/primitives/form.py +4 -8
- reflex/components/radix/primitives/form.pyi +0 -12
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/progress.pyi +0 -5
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/primitives/slider.pyi +0 -5
- reflex/components/radix/themes/base.pyi +0 -8
- reflex/components/radix/themes/color_mode.pyi +0 -3
- reflex/components/radix/themes/components/alert_dialog.py +4 -2
- reflex/components/radix/themes/components/alert_dialog.pyi +4 -9
- reflex/components/radix/themes/components/aspect_ratio.py +1 -2
- reflex/components/radix/themes/components/aspect_ratio.pyi +1 -3
- reflex/components/radix/themes/components/avatar.py +5 -2
- reflex/components/radix/themes/components/avatar.pyi +1 -3
- reflex/components/radix/themes/components/badge.py +5 -2
- reflex/components/radix/themes/components/badge.pyi +1 -3
- reflex/components/radix/themes/components/button.py +2 -3
- reflex/components/radix/themes/components/button.pyi +1 -3
- reflex/components/radix/themes/components/callout.py +1 -2
- reflex/components/radix/themes/components/callout.pyi +1 -7
- reflex/components/radix/themes/components/card.py +1 -2
- reflex/components/radix/themes/components/card.pyi +1 -3
- reflex/components/radix/themes/components/checkbox.py +7 -4
- reflex/components/radix/themes/components/checkbox.pyi +1 -5
- reflex/components/radix/themes/components/checkbox_cards.py +1 -2
- reflex/components/radix/themes/components/checkbox_cards.pyi +1 -4
- reflex/components/radix/themes/components/checkbox_group.py +1 -2
- reflex/components/radix/themes/components/checkbox_group.pyi +1 -4
- reflex/components/radix/themes/components/context_menu.py +1 -1
- reflex/components/radix/themes/components/context_menu.pyi +1 -14
- reflex/components/radix/themes/components/data_list.py +1 -2
- reflex/components/radix/themes/components/data_list.pyi +1 -6
- reflex/components/radix/themes/components/dialog.py +4 -2
- reflex/components/radix/themes/components/dialog.pyi +4 -9
- reflex/components/radix/themes/components/dropdown_menu.py +5 -2
- reflex/components/radix/themes/components/dropdown_menu.pyi +4 -10
- reflex/components/radix/themes/components/hover_card.py +4 -2
- reflex/components/radix/themes/components/hover_card.pyi +4 -6
- reflex/components/radix/themes/components/icon_button.py +7 -8
- reflex/components/radix/themes/components/icon_button.pyi +1 -3
- reflex/components/radix/themes/components/inset.py +1 -2
- reflex/components/radix/themes/components/inset.pyi +1 -3
- reflex/components/radix/themes/components/popover.py +4 -2
- reflex/components/radix/themes/components/popover.pyi +4 -6
- reflex/components/radix/themes/components/progress.py +1 -2
- reflex/components/radix/themes/components/progress.pyi +1 -3
- reflex/components/radix/themes/components/radio.py +1 -2
- reflex/components/radix/themes/components/radio.pyi +1 -3
- reflex/components/radix/themes/components/radio_cards.py +1 -2
- reflex/components/radix/themes/components/radio_cards.pyi +1 -4
- reflex/components/radix/themes/components/radio_group.py +7 -5
- reflex/components/radix/themes/components/radio_group.pyi +1 -6
- reflex/components/radix/themes/components/scroll_area.py +1 -2
- reflex/components/radix/themes/components/scroll_area.pyi +1 -3
- reflex/components/radix/themes/components/segmented_control.py +1 -2
- reflex/components/radix/themes/components/segmented_control.pyi +1 -4
- reflex/components/radix/themes/components/select.py +5 -2
- reflex/components/radix/themes/components/select.pyi +1 -11
- reflex/components/radix/themes/components/separator.py +1 -2
- reflex/components/radix/themes/components/separator.pyi +1 -3
- reflex/components/radix/themes/components/skeleton.py +1 -2
- reflex/components/radix/themes/components/skeleton.pyi +1 -3
- reflex/components/radix/themes/components/slider.py +1 -2
- reflex/components/radix/themes/components/slider.pyi +1 -3
- reflex/components/radix/themes/components/spinner.py +1 -2
- reflex/components/radix/themes/components/spinner.pyi +1 -3
- reflex/components/radix/themes/components/switch.py +1 -2
- reflex/components/radix/themes/components/switch.pyi +1 -3
- reflex/components/radix/themes/components/table.py +1 -2
- reflex/components/radix/themes/components/table.pyi +1 -9
- reflex/components/radix/themes/components/tabs.py +1 -2
- reflex/components/radix/themes/components/tabs.pyi +1 -7
- reflex/components/radix/themes/components/text_area.py +5 -2
- reflex/components/radix/themes/components/text_area.pyi +2 -4
- reflex/components/radix/themes/components/text_field.py +5 -2
- reflex/components/radix/themes/components/text_field.pyi +1 -5
- reflex/components/radix/themes/components/tooltip.py +1 -2
- reflex/components/radix/themes/components/tooltip.pyi +1 -3
- reflex/components/radix/themes/layout/base.py +5 -2
- reflex/components/radix/themes/layout/base.pyi +5 -3
- reflex/components/radix/themes/layout/box.py +1 -2
- reflex/components/radix/themes/layout/box.pyi +1 -3
- reflex/components/radix/themes/layout/center.pyi +0 -1
- reflex/components/radix/themes/layout/container.py +1 -2
- reflex/components/radix/themes/layout/container.pyi +1 -3
- reflex/components/radix/themes/layout/flex.py +6 -2
- reflex/components/radix/themes/layout/flex.pyi +1 -3
- reflex/components/radix/themes/layout/grid.py +6 -2
- reflex/components/radix/themes/layout/grid.pyi +1 -3
- reflex/components/radix/themes/layout/list.py +2 -1
- reflex/components/radix/themes/layout/list.pyi +0 -5
- reflex/components/radix/themes/layout/section.py +1 -2
- reflex/components/radix/themes/layout/section.pyi +1 -3
- reflex/components/radix/themes/layout/spacer.pyi +0 -1
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/radix/themes/layout/stack.pyi +0 -3
- reflex/components/radix/themes/typography/blockquote.py +1 -1
- reflex/components/radix/themes/typography/blockquote.pyi +1 -3
- reflex/components/radix/themes/typography/code.py +5 -1
- reflex/components/radix/themes/typography/code.pyi +1 -3
- reflex/components/radix/themes/typography/heading.py +1 -1
- reflex/components/radix/themes/typography/heading.pyi +1 -3
- reflex/components/radix/themes/typography/link.py +3 -2
- reflex/components/radix/themes/typography/link.pyi +1 -3
- reflex/components/radix/themes/typography/text.py +1 -1
- reflex/components/radix/themes/typography/text.pyi +1 -9
- reflex/components/react_player/audio.py +0 -2
- reflex/components/react_player/audio.pyi +0 -3
- reflex/components/react_player/react_player.pyi +0 -1
- reflex/components/react_player/video.py +0 -2
- reflex/components/react_player/video.pyi +0 -3
- reflex/components/recharts/__init__.py +1 -1
- reflex/components/recharts/__init__.pyi +1 -1
- reflex/components/recharts/cartesian.py +20 -25
- reflex/components/recharts/cartesian.pyi +20 -37
- reflex/components/recharts/charts.py +2 -1
- reflex/components/recharts/charts.pyi +0 -12
- reflex/components/recharts/general.pyi +0 -6
- reflex/components/recharts/polar.py +5 -4
- reflex/components/recharts/polar.pyi +4 -10
- reflex/components/recharts/recharts.py +12 -10
- reflex/components/recharts/recharts.pyi +10 -11
- reflex/components/sonner/toast.py +2 -2
- reflex/components/sonner/toast.pyi +0 -2
- reflex/components/suneditor/editor.py +2 -1
- reflex/components/suneditor/editor.pyi +0 -1
- reflex/components/tags/iter_tag.py +4 -2
- reflex/config.py +41 -615
- reflex/constants/base.py +6 -6
- reflex/constants/compiler.py +8 -6
- reflex/constants/installer.py +25 -16
- reflex/custom_components/custom_components.py +1 -2
- reflex/environment.py +606 -0
- reflex/event.py +58 -60
- reflex/experimental/__init__.py +2 -2
- reflex/experimental/client_state.py +9 -4
- reflex/experimental/layout.pyi +0 -5
- reflex/istate/manager.py +17 -20
- reflex/istate/proxy.py +19 -12
- reflex/model.py +8 -5
- reflex/plugins/base.py +8 -0
- reflex/plugins/tailwind_v3.py +8 -0
- reflex/plugins/tailwind_v4.py +8 -0
- reflex/reflex.py +11 -12
- reflex/route.py +7 -9
- reflex/state.py +67 -71
- reflex/style.py +3 -1
- reflex/testing.py +49 -30
- reflex/utils/build.py +2 -1
- reflex/utils/console.py +70 -17
- reflex/utils/exec.py +113 -39
- reflex/utils/export.py +2 -1
- reflex/utils/format.py +21 -24
- reflex/utils/imports.py +4 -3
- reflex/utils/lazy_loader.py +3 -3
- reflex/utils/misc.py +2 -1
- reflex/utils/net.py +2 -2
- reflex/utils/path_ops.py +4 -2
- reflex/utils/prerequisites.py +69 -39
- reflex/utils/processes.py +5 -7
- reflex/utils/pyi_generator.py +46 -41
- reflex/utils/redir.py +1 -1
- reflex/utils/registry.py +1 -1
- reflex/utils/serializers.py +4 -4
- reflex/utils/telemetry.py +36 -3
- reflex/utils/types.py +16 -13
- reflex/vars/base.py +96 -109
- reflex/vars/datetime.py +2 -1
- reflex/vars/dep_tracking.py +19 -28
- reflex/vars/number.py +6 -7
- reflex/vars/object.py +5 -6
- reflex/vars/sequence.py +11 -11
- {reflex-0.7.13a2.dist-info → reflex-0.7.14.dist-info}/METADATA +1 -1
- reflex-0.7.14.dist-info/RECORD +408 -0
- reflex-0.7.13a2.dist-info/RECORD +0 -407
- {reflex-0.7.13a2.dist-info → reflex-0.7.14.dist-info}/WHEEL +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.13a2.dist-info → reflex-0.7.14.dist-info}/licenses/LICENSE +0 -0
reflex/components/component.py
CHANGED
|
@@ -157,7 +157,8 @@ class ComponentField(Generic[FIELD_TYPE]):
|
|
|
157
157
|
return self.default
|
|
158
158
|
if self.default_factory is not None:
|
|
159
159
|
return self.default_factory()
|
|
160
|
-
|
|
160
|
+
msg = "No default value or factory provided."
|
|
161
|
+
raise ValueError(msg)
|
|
161
162
|
|
|
162
163
|
def __repr__(self) -> str:
|
|
163
164
|
"""Represent the field in a readable format.
|
|
@@ -194,7 +195,8 @@ def field(
|
|
|
194
195
|
ValueError: If both default and default_factory are specified.
|
|
195
196
|
"""
|
|
196
197
|
if default is not MISSING and default_factory is not None:
|
|
197
|
-
|
|
198
|
+
msg = "cannot specify both default and default_factory"
|
|
199
|
+
raise ValueError(msg)
|
|
198
200
|
return ComponentField( # pyright: ignore [reportReturnType]
|
|
199
201
|
default=default,
|
|
200
202
|
default_factory=default_factory,
|
|
@@ -286,10 +288,11 @@ class BaseComponentMeta(ABCMeta):
|
|
|
286
288
|
|
|
287
289
|
namespace["_own_fields"] = own_fields
|
|
288
290
|
namespace["_inherited_fields"] = inherited_fields
|
|
289
|
-
|
|
291
|
+
all_fields = inherited_fields | own_fields
|
|
292
|
+
namespace["_fields"] = all_fields
|
|
290
293
|
namespace["_js_fields"] = {
|
|
291
294
|
key: value
|
|
292
|
-
for key, value in
|
|
295
|
+
for key, value in all_fields.items()
|
|
293
296
|
if value.is_javascript is True
|
|
294
297
|
}
|
|
295
298
|
return super().__new__(cls, name, bases, namespace)
|
|
@@ -769,11 +772,12 @@ class Component(BaseComponent, ABC):
|
|
|
769
772
|
and key not in component_specific_triggers
|
|
770
773
|
and key not in props
|
|
771
774
|
):
|
|
772
|
-
|
|
775
|
+
msg = (
|
|
773
776
|
f"The {(comp_name := type(self).__name__)} does not take in an `{key}` event trigger. If {comp_name}"
|
|
774
777
|
f" is a third party component make sure to add `{key}` to the component's event triggers. "
|
|
775
778
|
f"visit https://reflex.dev/docs/wrapping-react/guide/#event-triggers for more info."
|
|
776
779
|
)
|
|
780
|
+
raise ValueError(msg)
|
|
777
781
|
if key in component_specific_triggers:
|
|
778
782
|
# Event triggers are bound to event chains.
|
|
779
783
|
is_var = False
|
|
@@ -844,7 +848,8 @@ class Component(BaseComponent, ABC):
|
|
|
844
848
|
style = kwargs.get("style", {})
|
|
845
849
|
if isinstance(style, Sequence):
|
|
846
850
|
if any(not isinstance(s, Mapping) for s in style):
|
|
847
|
-
|
|
851
|
+
msg = "Style must be a dictionary or a list of dictionaries."
|
|
852
|
+
raise TypeError(msg)
|
|
848
853
|
# Merge styles, the later ones overriding keys in the earlier ones.
|
|
849
854
|
style = {
|
|
850
855
|
k: v
|
|
@@ -879,14 +884,12 @@ class Component(BaseComponent, ABC):
|
|
|
879
884
|
if not isinstance(c, StringVar) and not issubclass(
|
|
880
885
|
c._var_type, str
|
|
881
886
|
):
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
)
|
|
887
|
+
msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c._js_expr} of type {c._var_type}."
|
|
888
|
+
raise TypeError(msg)
|
|
885
889
|
has_var = True
|
|
886
890
|
else:
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
)
|
|
891
|
+
msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c} of type {type(c)}."
|
|
892
|
+
raise TypeError(msg)
|
|
890
893
|
if has_var:
|
|
891
894
|
kwargs["class_name"] = LiteralArrayVar.create(
|
|
892
895
|
class_name, _var_type=list[str]
|
|
@@ -898,9 +901,8 @@ class Component(BaseComponent, ABC):
|
|
|
898
901
|
and not isinstance(class_name, StringVar)
|
|
899
902
|
and not issubclass(class_name._var_type, str)
|
|
900
903
|
):
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
)
|
|
904
|
+
msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {class_name._js_expr} of type {class_name._var_type}."
|
|
905
|
+
raise TypeError(msg)
|
|
904
906
|
# Construct the component.
|
|
905
907
|
for key, value in kwargs.items():
|
|
906
908
|
setattr(self, key, value)
|
|
@@ -1015,7 +1017,7 @@ class Component(BaseComponent, ABC):
|
|
|
1015
1017
|
Returns:
|
|
1016
1018
|
The unique fields.
|
|
1017
1019
|
"""
|
|
1018
|
-
return set(cls.
|
|
1020
|
+
return set(cls.get_js_fields())
|
|
1019
1021
|
|
|
1020
1022
|
@classmethod
|
|
1021
1023
|
@functools.cache
|
|
@@ -1227,9 +1229,8 @@ class Component(BaseComponent, ABC):
|
|
|
1227
1229
|
"""
|
|
1228
1230
|
# 1. Default style from `_add_style`/`add_style`.
|
|
1229
1231
|
if type(self)._add_style != Component._add_style:
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
)
|
|
1232
|
+
msg = "Do not override _add_style directly. Use add_style instead."
|
|
1233
|
+
raise UserWarning(msg)
|
|
1233
1234
|
new_style = self._add_style()
|
|
1234
1235
|
style_vars = [new_style._var_data]
|
|
1235
1236
|
|
|
@@ -1347,9 +1348,8 @@ class Component(BaseComponent, ABC):
|
|
|
1347
1348
|
validate_child(child.default)
|
|
1348
1349
|
|
|
1349
1350
|
if self._invalid_children and child_name in self._invalid_children:
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
)
|
|
1351
|
+
msg = f"The component `{comp_name}` cannot have `{child_name}` as a child component"
|
|
1352
|
+
raise ValueError(msg)
|
|
1353
1353
|
|
|
1354
1354
|
if self._valid_children and child_name not in [
|
|
1355
1355
|
*self._valid_children,
|
|
@@ -1358,9 +1358,8 @@ class Component(BaseComponent, ABC):
|
|
|
1358
1358
|
valid_child_list = ", ".join(
|
|
1359
1359
|
[f"`{v_child}`" for v_child in self._valid_children]
|
|
1360
1360
|
)
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
)
|
|
1361
|
+
msg = f"The component `{comp_name}` only allows the components: {valid_child_list} as children. Got `{child_name}` instead."
|
|
1362
|
+
raise ValueError(msg)
|
|
1364
1363
|
|
|
1365
1364
|
if child._valid_parents and all(
|
|
1366
1365
|
clz_name not in [*child._valid_parents, *allowed_components]
|
|
@@ -1369,9 +1368,8 @@ class Component(BaseComponent, ABC):
|
|
|
1369
1368
|
valid_parent_list = ", ".join(
|
|
1370
1369
|
[f"`{v_parent}`" for v_parent in child._valid_parents]
|
|
1371
1370
|
)
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
)
|
|
1371
|
+
msg = f"The component `{child_name}` can only be a child of the components: {valid_parent_list}. Got `{comp_name}` instead."
|
|
1372
|
+
raise ValueError(msg)
|
|
1375
1373
|
|
|
1376
1374
|
for child in children:
|
|
1377
1375
|
validate_child(child)
|
|
@@ -1502,13 +1500,9 @@ class Component(BaseComponent, ABC):
|
|
|
1502
1500
|
"""
|
|
1503
1501
|
if self.event_triggers and self._event_trigger_values_use_state():
|
|
1504
1502
|
return True
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
isinstance(child, Component)
|
|
1509
|
-
and child._has_stateful_event_triggers()
|
|
1510
|
-
):
|
|
1511
|
-
return True
|
|
1503
|
+
for child in self.children:
|
|
1504
|
+
if isinstance(child, Component) and child._has_stateful_event_triggers():
|
|
1505
|
+
return True
|
|
1512
1506
|
return False
|
|
1513
1507
|
|
|
1514
1508
|
@classmethod
|
|
@@ -1767,6 +1761,7 @@ class Component(BaseComponent, ABC):
|
|
|
1767
1761
|
{on_unmount or ""}
|
|
1768
1762
|
}}
|
|
1769
1763
|
}}, []);"""
|
|
1764
|
+
return None
|
|
1770
1765
|
|
|
1771
1766
|
def _get_ref_hook(self) -> Var | None:
|
|
1772
1767
|
"""Generate the ref hook for the component.
|
|
@@ -1780,6 +1775,7 @@ class Component(BaseComponent, ABC):
|
|
|
1780
1775
|
f"const {ref} = useRef(null); {Var(_js_expr=ref)._as_ref()!s} = {ref};",
|
|
1781
1776
|
_var_data=VarData(position=Hooks.HookPosition.INTERNAL),
|
|
1782
1777
|
)
|
|
1778
|
+
return None
|
|
1783
1779
|
|
|
1784
1780
|
def _get_vars_hooks(self) -> dict[str, VarData | None]:
|
|
1785
1781
|
"""Get the hooks required by vars referenced in this component.
|
|
@@ -1980,24 +1976,38 @@ class Component(BaseComponent, ABC):
|
|
|
1980
1976
|
"""
|
|
1981
1977
|
return {}
|
|
1982
1978
|
|
|
1983
|
-
def _get_all_app_wrap_components(
|
|
1979
|
+
def _get_all_app_wrap_components(
|
|
1980
|
+
self, *, ignore_ids: set[int] | None = None
|
|
1981
|
+
) -> dict[tuple[int, str], Component]:
|
|
1984
1982
|
"""Get the app wrap components for the component and its children.
|
|
1985
1983
|
|
|
1984
|
+
Args:
|
|
1985
|
+
ignore_ids: A set of component IDs to ignore. Used to avoid duplicates.
|
|
1986
|
+
|
|
1986
1987
|
Returns:
|
|
1987
1988
|
The app wrap components.
|
|
1988
1989
|
"""
|
|
1990
|
+
ignore_ids = ignore_ids or set()
|
|
1989
1991
|
# Store the components in a set to avoid duplicates.
|
|
1990
1992
|
components = self._get_app_wrap_components()
|
|
1991
1993
|
|
|
1992
1994
|
for component in tuple(components.values()):
|
|
1993
|
-
|
|
1995
|
+
component_id = id(component)
|
|
1996
|
+
if component_id in ignore_ids:
|
|
1997
|
+
continue
|
|
1998
|
+
ignore_ids.add(component_id)
|
|
1999
|
+
components.update(
|
|
2000
|
+
component._get_all_app_wrap_components(ignore_ids=ignore_ids)
|
|
2001
|
+
)
|
|
1994
2002
|
|
|
1995
2003
|
# Add the app wrap components for the children.
|
|
1996
2004
|
for child in self.children:
|
|
2005
|
+
child_id = id(child)
|
|
1997
2006
|
# Skip BaseComponent and StatefulComponent children.
|
|
1998
|
-
if not isinstance(child, Component):
|
|
2007
|
+
if not isinstance(child, Component) or child_id in ignore_ids:
|
|
1999
2008
|
continue
|
|
2000
|
-
|
|
2009
|
+
ignore_ids.add(child_id)
|
|
2010
|
+
components.update(child._get_all_app_wrap_components(ignore_ids=ignore_ids))
|
|
2001
2011
|
|
|
2002
2012
|
# Return the components.
|
|
2003
2013
|
return components
|
|
@@ -2198,7 +2208,35 @@ class CustomComponent(Component):
|
|
|
2198
2208
|
Returns:
|
|
2199
2209
|
The code to render the component.
|
|
2200
2210
|
"""
|
|
2201
|
-
|
|
2211
|
+
component = self.component_fn(*self.get_prop_vars())
|
|
2212
|
+
|
|
2213
|
+
try:
|
|
2214
|
+
from reflex.utils.prerequisites import get_and_validate_app
|
|
2215
|
+
|
|
2216
|
+
style = get_and_validate_app().app.style
|
|
2217
|
+
except Exception:
|
|
2218
|
+
style = {}
|
|
2219
|
+
|
|
2220
|
+
component._add_style_recursive(style)
|
|
2221
|
+
return component
|
|
2222
|
+
|
|
2223
|
+
def _get_all_app_wrap_components(
|
|
2224
|
+
self, *, ignore_ids: set[int] | None = None
|
|
2225
|
+
) -> dict[tuple[int, str], Component]:
|
|
2226
|
+
"""Get the app wrap components for the custom component.
|
|
2227
|
+
|
|
2228
|
+
Args:
|
|
2229
|
+
ignore_ids: A set of IDs to ignore to avoid infinite recursion.
|
|
2230
|
+
|
|
2231
|
+
Returns:
|
|
2232
|
+
The app wrap components.
|
|
2233
|
+
"""
|
|
2234
|
+
ignore_ids = ignore_ids or set()
|
|
2235
|
+
component = self.get_component()
|
|
2236
|
+
if id(component) in ignore_ids:
|
|
2237
|
+
return {}
|
|
2238
|
+
ignore_ids.add(id(component))
|
|
2239
|
+
return self.get_component()._get_all_app_wrap_components(ignore_ids=ignore_ids)
|
|
2202
2240
|
|
|
2203
2241
|
|
|
2204
2242
|
CUSTOM_COMPONENTS: dict[str, CustomComponent] = {}
|
|
@@ -2222,7 +2260,7 @@ def _register_custom_component(
|
|
|
2222
2260
|
_var_type=unwrap_var_annotation(annotation),
|
|
2223
2261
|
).guess_type()
|
|
2224
2262
|
if not types.safe_issubclass(annotation, EventHandler)
|
|
2225
|
-
else EventSpec(handler=EventHandler(fn=
|
|
2263
|
+
else EventSpec(handler=EventHandler(fn=no_args_event_spec))
|
|
2226
2264
|
)
|
|
2227
2265
|
for prop, annotation in typing.get_type_hints(component_fn).items()
|
|
2228
2266
|
if prop != "return"
|
|
@@ -2233,7 +2271,8 @@ def _register_custom_component(
|
|
|
2233
2271
|
**dummy_props,
|
|
2234
2272
|
)
|
|
2235
2273
|
if dummy_component.tag is None:
|
|
2236
|
-
|
|
2274
|
+
msg = f"Could not determine the tag name for {component_fn!r}"
|
|
2275
|
+
raise TypeError(msg)
|
|
2237
2276
|
CUSTOM_COMPONENTS[dummy_component.tag] = dummy_component
|
|
2238
2277
|
|
|
2239
2278
|
|
|
@@ -2312,7 +2351,8 @@ class NoSSRComponent(Component):
|
|
|
2312
2351
|
# extract the correct import name from library name
|
|
2313
2352
|
base_import_name = self._get_import_name()
|
|
2314
2353
|
if base_import_name is None:
|
|
2315
|
-
|
|
2354
|
+
msg = "Undefined library for NoSSRComponent"
|
|
2355
|
+
raise ValueError(msg)
|
|
2316
2356
|
import_name = format.format_library_name(base_import_name)
|
|
2317
2357
|
|
|
2318
2358
|
library_import = f"const {self.alias if self.alias else self.tag} = dynamic(() => import('{import_name}')"
|
|
@@ -2320,7 +2360,7 @@ class NoSSRComponent(Component):
|
|
|
2320
2360
|
# https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#with-named-exports
|
|
2321
2361
|
f".then((mod) => mod.{self.tag})" if not self.is_default else ""
|
|
2322
2362
|
)
|
|
2323
|
-
return
|
|
2363
|
+
return library_import + mod_import + opts_fragment
|
|
2324
2364
|
|
|
2325
2365
|
|
|
2326
2366
|
class StatefulComponent(BaseComponent):
|
|
@@ -2540,7 +2580,7 @@ class StatefulComponent(BaseComponent):
|
|
|
2540
2580
|
var_name = var_name.strip()
|
|
2541
2581
|
|
|
2542
2582
|
# Break up array and object destructuring if used.
|
|
2543
|
-
if var_name.startswith("["
|
|
2583
|
+
if var_name.startswith(("[", "{")):
|
|
2544
2584
|
return [
|
|
2545
2585
|
v.strip().replace("...", "") for v in var_name.strip("[]{}").split(",")
|
|
2546
2586
|
]
|
reflex/components/core/banner.py
CHANGED
|
@@ -16,9 +16,9 @@ from reflex.components.radix.themes.components.dialog import (
|
|
|
16
16
|
from reflex.components.radix.themes.layout.flex import Flex
|
|
17
17
|
from reflex.components.radix.themes.typography.text import Text
|
|
18
18
|
from reflex.components.sonner.toast import ToastProps, toast_ref
|
|
19
|
-
from reflex.config import environment
|
|
20
19
|
from reflex.constants import Dirs, Hooks, Imports
|
|
21
20
|
from reflex.constants.compiler import CompileVars
|
|
21
|
+
from reflex.environment import environment
|
|
22
22
|
from reflex.utils.imports import ImportVar
|
|
23
23
|
from reflex.vars import VarData
|
|
24
24
|
from reflex.vars.base import LiteralVar, Var
|
|
@@ -93,7 +93,6 @@ class ConnectionToaster(Fragment):
|
|
|
93
93
|
Returns:
|
|
94
94
|
The connection toaster component.
|
|
95
95
|
"""
|
|
96
|
-
...
|
|
97
96
|
|
|
98
97
|
class ConnectionBanner(Component):
|
|
99
98
|
@overload
|
|
@@ -137,7 +136,6 @@ class ConnectionBanner(Component):
|
|
|
137
136
|
Returns:
|
|
138
137
|
The connection banner component.
|
|
139
138
|
"""
|
|
140
|
-
...
|
|
141
139
|
|
|
142
140
|
class ConnectionModal(Component):
|
|
143
141
|
@overload
|
|
@@ -181,7 +179,6 @@ class ConnectionModal(Component):
|
|
|
181
179
|
Returns:
|
|
182
180
|
The connection banner component.
|
|
183
181
|
"""
|
|
184
|
-
...
|
|
185
182
|
|
|
186
183
|
class WifiOffPulse(Icon):
|
|
187
184
|
@overload
|
|
@@ -235,7 +232,6 @@ class WifiOffPulse(Icon):
|
|
|
235
232
|
Returns:
|
|
236
233
|
The icon component with default props applied.
|
|
237
234
|
"""
|
|
238
|
-
...
|
|
239
235
|
|
|
240
236
|
def add_imports(self) -> dict[str, str | ImportVar | list[str | ImportVar]]: ...
|
|
241
237
|
|
|
@@ -482,7 +478,6 @@ class ConnectionPulser(Div):
|
|
|
482
478
|
Returns:
|
|
483
479
|
The connection pulser component.
|
|
484
480
|
"""
|
|
485
|
-
...
|
|
486
481
|
|
|
487
482
|
class BackendDisabled(Div):
|
|
488
483
|
@overload
|
|
@@ -727,7 +722,6 @@ class BackendDisabled(Div):
|
|
|
727
722
|
Returns:
|
|
728
723
|
The backend disabled component.
|
|
729
724
|
"""
|
|
730
|
-
...
|
|
731
725
|
|
|
732
726
|
connection_banner = ConnectionBanner.create
|
|
733
727
|
connection_modal = ConnectionModal.create
|
|
@@ -75,19 +75,17 @@ class Breakpoints(dict[K, V]):
|
|
|
75
75
|
|
|
76
76
|
if custom is not None:
|
|
77
77
|
if any(threshold is not None for threshold in thresholds):
|
|
78
|
-
|
|
78
|
+
msg = "Named props cannot be used with custom thresholds"
|
|
79
|
+
raise ValueError(msg)
|
|
79
80
|
|
|
80
81
|
return Breakpoints(custom)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if v is not None
|
|
89
|
-
}
|
|
90
|
-
)
|
|
82
|
+
return Breakpoints(
|
|
83
|
+
{
|
|
84
|
+
k: v
|
|
85
|
+
for k, v in zip(["initial", *breakpoint_names], thresholds, strict=True)
|
|
86
|
+
if v is not None
|
|
87
|
+
}
|
|
88
|
+
)
|
|
91
89
|
|
|
92
90
|
|
|
93
91
|
breakpoints = Breakpoints.create
|
|
@@ -65,7 +65,6 @@ class ClientSideRouting(Component):
|
|
|
65
65
|
Returns:
|
|
66
66
|
The component.
|
|
67
67
|
"""
|
|
68
|
-
...
|
|
69
68
|
|
|
70
69
|
def wait_for_client_redirect(component: Component) -> Component: ...
|
|
71
70
|
|
|
@@ -120,4 +119,3 @@ class Default404Page(Component):
|
|
|
120
119
|
Returns:
|
|
121
120
|
The component.
|
|
122
121
|
"""
|
|
123
|
-
...
|
reflex/components/core/colors.py
CHANGED
|
@@ -32,19 +32,22 @@ def color(
|
|
|
32
32
|
"""
|
|
33
33
|
if isinstance(color, str):
|
|
34
34
|
if color not in COLORS and REFLEX_VAR_OPENING_TAG not in color:
|
|
35
|
-
|
|
35
|
+
msg = f"Color must be one of {COLORS}, received {color}"
|
|
36
|
+
raise ValueError(msg)
|
|
36
37
|
elif not isinstance(color, Var):
|
|
37
|
-
|
|
38
|
+
msg = "Color must be a string or a Var"
|
|
39
|
+
raise ValueError(msg)
|
|
38
40
|
|
|
39
41
|
if isinstance(shade, int):
|
|
40
42
|
if shade < MIN_SHADE_VALUE or shade > MAX_SHADE_VALUE:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
43
|
+
msg = f"Shade must be between {MIN_SHADE_VALUE} and {MAX_SHADE_VALUE}"
|
|
44
|
+
raise ValueError(msg)
|
|
44
45
|
elif not isinstance(shade, Var):
|
|
45
|
-
|
|
46
|
+
msg = "Shade must be an integer or a Var"
|
|
47
|
+
raise ValueError(msg)
|
|
46
48
|
|
|
47
49
|
if not isinstance(alpha, (bool, Var)):
|
|
48
|
-
|
|
50
|
+
msg = "Alpha must be a boolean or a Var"
|
|
51
|
+
raise ValueError(msg)
|
|
49
52
|
|
|
50
53
|
return Color(color, shade, alpha)
|
reflex/components/core/cond.py
CHANGED
|
@@ -132,7 +132,8 @@ def cond(condition: Any, c1: Any, c2: Any = types.Unset(), /) -> Component | Var
|
|
|
132
132
|
# Convert the condition to a Var.
|
|
133
133
|
cond_var = LiteralVar.create(condition)
|
|
134
134
|
if cond_var is None:
|
|
135
|
-
|
|
135
|
+
msg = "The condition must be set."
|
|
136
|
+
raise ValueError(msg)
|
|
136
137
|
|
|
137
138
|
# If the first component is a component, create a Cond component.
|
|
138
139
|
if isinstance(c1, BaseComponent):
|
|
@@ -145,7 +146,8 @@ def cond(condition: Any, c1: Any, c2: Any = types.Unset(), /) -> Component | Var
|
|
|
145
146
|
if isinstance(c2, BaseComponent):
|
|
146
147
|
return Cond.create(cond_var.bool(), Fragment.create(c1), c2)
|
|
147
148
|
if isinstance(c2, types.Unset):
|
|
148
|
-
|
|
149
|
+
msg = "For conditional vars, the second argument must be set."
|
|
150
|
+
raise ValueError(msg)
|
|
149
151
|
|
|
150
152
|
# convert the truth and false cond parts into vars so the _var_data can be obtained.
|
|
151
153
|
c1_var = Var.create(c1)
|
|
@@ -70,14 +70,16 @@ class DebounceInput(Component):
|
|
|
70
70
|
ValueError: if the child element does not have an on_change handler.
|
|
71
71
|
"""
|
|
72
72
|
if len(children) != 1:
|
|
73
|
-
|
|
73
|
+
msg = (
|
|
74
74
|
"Provide a single child for DebounceInput, such as rx.input() or "
|
|
75
|
-
"rx.text_area()"
|
|
75
|
+
"rx.text_area()"
|
|
76
76
|
)
|
|
77
|
+
raise RuntimeError(msg)
|
|
77
78
|
|
|
78
79
|
child = children[0]
|
|
79
80
|
if "on_change" not in child.event_triggers:
|
|
80
|
-
|
|
81
|
+
msg = "DebounceInput child requires an on_change handler"
|
|
82
|
+
raise ValueError(msg)
|
|
81
83
|
|
|
82
84
|
# Carry known props and event_triggers from the child.
|
|
83
85
|
props_from_child = {
|
|
@@ -69,19 +69,19 @@ class Foreach(Component):
|
|
|
69
69
|
)
|
|
70
70
|
|
|
71
71
|
if iterable._var_type == Any:
|
|
72
|
-
|
|
72
|
+
msg = (
|
|
73
73
|
f"Could not foreach over var `{iterable!s}` of type Any. "
|
|
74
74
|
"(If you are trying to foreach over a state var, add a type annotation to the var). "
|
|
75
75
|
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
|
|
76
76
|
)
|
|
77
|
+
raise ForeachVarError(msg)
|
|
77
78
|
|
|
78
79
|
if (
|
|
79
80
|
hasattr(render_fn, "__qualname__")
|
|
80
81
|
and render_fn.__qualname__ == ComponentState.create.__qualname__
|
|
81
82
|
):
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
)
|
|
83
|
+
msg = "Using a ComponentState as `render_fn` inside `rx.foreach` is not supported yet."
|
|
84
|
+
raise TypeError(msg)
|
|
85
85
|
|
|
86
86
|
if isinstance(iterable, ObjectVar):
|
|
87
87
|
iterable = iterable.entries()
|
|
@@ -90,10 +90,11 @@ class Foreach(Component):
|
|
|
90
90
|
iterable = iterable.split()
|
|
91
91
|
|
|
92
92
|
if not isinstance(iterable, ArrayVar):
|
|
93
|
-
|
|
93
|
+
msg = (
|
|
94
94
|
f"Could not foreach over var `{iterable!s}` of type {iterable._var_type}. "
|
|
95
95
|
"See https://reflex.dev/docs/library/dynamic-rendering/foreach/"
|
|
96
96
|
)
|
|
97
|
+
raise ForeachVarError(msg)
|
|
97
98
|
|
|
98
99
|
if types.is_optional(iterable._var_type):
|
|
99
100
|
iterable = cond(iterable, iterable, [])
|
|
@@ -122,11 +123,12 @@ class Foreach(Component):
|
|
|
122
123
|
|
|
123
124
|
# Validate the render function signature.
|
|
124
125
|
if len(params) == 0 or len(params) > 2:
|
|
125
|
-
|
|
126
|
+
msg = (
|
|
126
127
|
"Expected 1 or 2 parameters in foreach render function, got "
|
|
127
128
|
f"{[p.name for p in params]}. See "
|
|
128
129
|
"https://reflex.dev/docs/library/dynamic-rendering/foreach/"
|
|
129
130
|
)
|
|
131
|
+
raise ForeachRenderError(msg)
|
|
130
132
|
|
|
131
133
|
if len(params) >= 1:
|
|
132
134
|
# Determine the arg var name based on the params accepted by render_fn.
|
reflex/components/core/html.py
CHANGED
|
@@ -30,9 +30,9 @@ class Html(Div):
|
|
|
30
30
|
"""
|
|
31
31
|
# If children are not provided, throw an error.
|
|
32
32
|
if len(children) != 1:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
msg = "Must provide children to the html component."
|
|
34
|
+
raise ValueError(msg)
|
|
35
|
+
props["dangerouslySetInnerHTML"] = {"__html": children[0]}
|
|
36
36
|
|
|
37
37
|
# Apply the default classname
|
|
38
38
|
given_class_name = props.pop("class_name", [])
|