reflex 0.5.4a2__py3-none-any.whl → 0.5.5__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/demo/code/demo.py +1 -0
- reflex/.templates/apps/demo/code/pages/__init__.py +1 -0
- reflex/.templates/apps/demo/code/pages/datatable.py +1 -0
- reflex/.templates/apps/demo/code/pages/forms.py +1 -0
- reflex/.templates/apps/demo/code/pages/graphing.py +1 -0
- reflex/.templates/apps/demo/code/pages/home.py +1 -0
- reflex/.templates/apps/demo/code/styles.py +1 -0
- reflex/.templates/apps/demo/code/webui/components/loading_icon.py +1 -8
- reflex/.templates/web/components/reflex/chakra_color_mode_provider.js +27 -12
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +19 -5
- reflex/.templates/web/utils/state.js +73 -7
- reflex/__init__.py +3 -0
- reflex/__init__.pyi +3 -0
- reflex/admin.py +1 -0
- reflex/app.py +8 -6
- reflex/app_module_for_backend.py +2 -1
- reflex/base.py +4 -4
- reflex/compiler/compiler.py +4 -3
- reflex/compiler/templates.py +2 -0
- reflex/compiler/utils.py +58 -35
- reflex/components/__init__.py +1 -0
- reflex/components/base/__init__.py +1 -0
- reflex/components/base/app_wrap.py +1 -0
- reflex/components/base/fragment.py +1 -0
- reflex/components/base/link.py +0 -1
- reflex/components/base/script.py +11 -15
- reflex/components/base/script.pyi +1 -2
- reflex/components/chakra/base.py +15 -13
- reflex/components/chakra/base.pyi +3 -1
- reflex/components/chakra/datadisplay/code.py +1 -0
- reflex/components/chakra/datadisplay/divider.py +1 -0
- reflex/components/chakra/datadisplay/table.py +1 -0
- reflex/components/chakra/datadisplay/table.pyi +3 -0
- reflex/components/chakra/datadisplay/tag.py +1 -0
- reflex/components/chakra/disclosure/transition.py +1 -0
- reflex/components/chakra/feedback/circularprogress.py +1 -0
- reflex/components/chakra/forms/button.py +1 -0
- reflex/components/chakra/forms/checkbox.py +4 -13
- reflex/components/chakra/forms/checkbox.pyi +1 -3
- reflex/components/chakra/forms/colormodeswitch.py +1 -0
- reflex/components/chakra/forms/editable.py +13 -16
- reflex/components/chakra/forms/editable.pyi +1 -3
- reflex/components/chakra/forms/form.py +1 -0
- reflex/components/chakra/forms/input.py +22 -21
- reflex/components/chakra/forms/input.pyi +4 -4
- reflex/components/chakra/forms/multiselect.py +1 -0
- reflex/components/chakra/forms/numberinput.py +3 -12
- reflex/components/chakra/forms/numberinput.pyi +1 -3
- reflex/components/chakra/forms/pininput.py +8 -14
- reflex/components/chakra/forms/pininput.pyi +2 -3
- reflex/components/chakra/forms/radio.py +4 -13
- reflex/components/chakra/forms/radio.pyi +2 -3
- reflex/components/chakra/forms/rangeslider.py +10 -13
- reflex/components/chakra/forms/rangeslider.pyi +2 -3
- reflex/components/chakra/forms/select.py +4 -12
- reflex/components/chakra/forms/select.pyi +2 -3
- reflex/components/chakra/forms/slider.py +10 -13
- reflex/components/chakra/forms/slider.pyi +2 -3
- reflex/components/chakra/forms/switch.py +4 -13
- reflex/components/chakra/forms/switch.pyi +1 -3
- reflex/components/chakra/forms/textarea.py +16 -17
- reflex/components/chakra/forms/textarea.pyi +1 -3
- reflex/components/chakra/media/avatar.py +4 -12
- reflex/components/chakra/media/avatar.pyi +1 -2
- reflex/components/chakra/media/icon.py +1 -0
- reflex/components/chakra/media/image.py +7 -11
- reflex/components/chakra/media/image.pyi +2 -2
- reflex/components/chakra/navigation/link.py +8 -4
- reflex/components/chakra/navigation/link.pyi +2 -1
- reflex/components/chakra/overlay/alertdialog.py +12 -14
- reflex/components/chakra/overlay/alertdialog.pyi +1 -2
- reflex/components/chakra/overlay/drawer.py +12 -14
- reflex/components/chakra/overlay/drawer.pyi +1 -2
- reflex/components/chakra/overlay/menu.py +7 -11
- reflex/components/chakra/overlay/menu.pyi +2 -2
- reflex/components/chakra/overlay/modal.py +13 -13
- reflex/components/chakra/overlay/modal.pyi +2 -2
- reflex/components/chakra/overlay/popover.py +6 -12
- reflex/components/chakra/overlay/popover.pyi +1 -2
- reflex/components/chakra/overlay/tooltip.py +7 -13
- reflex/components/chakra/overlay/tooltip.pyi +1 -2
- reflex/components/chakra/typography/heading.py +0 -1
- reflex/components/chakra/typography/span.py +1 -0
- reflex/components/chakra/typography/text.py +1 -0
- reflex/components/component.py +70 -43
- reflex/components/core/__init__.py +1 -0
- reflex/components/core/banner.py +27 -24
- reflex/components/core/banner.pyi +6 -2
- reflex/components/core/client_side_routing.py +1 -0
- reflex/components/core/cond.py +19 -17
- reflex/components/core/debounce.py +4 -11
- reflex/components/core/debounce.pyi +1 -1
- reflex/components/core/foreach.py +1 -0
- reflex/components/core/html.py +1 -0
- reflex/components/core/match.py +9 -6
- reflex/components/core/upload.py +26 -25
- reflex/components/core/upload.pyi +3 -4
- reflex/components/datadisplay/__init__.py +1 -0
- reflex/components/datadisplay/code.py +27 -23
- reflex/components/datadisplay/code.pyi +4 -2
- reflex/components/datadisplay/dataeditor.py +73 -80
- reflex/components/datadisplay/dataeditor.pyi +52 -4
- reflex/components/datadisplay/logo.py +1 -0
- reflex/components/el/__init__.py +1 -0
- reflex/components/el/__init__.pyi +8 -0
- reflex/components/el/element.py +0 -1
- reflex/components/el/elements/__init__.py +5 -0
- reflex/components/el/elements/__init__.pyi +12 -1
- reflex/components/el/elements/base.py +1 -0
- reflex/components/el/elements/forms.py +44 -61
- reflex/components/el/elements/forms.pyi +4 -6
- reflex/components/el/elements/inline.py +1 -0
- reflex/components/el/elements/media.py +53 -0
- reflex/components/el/elements/media.pyi +428 -0
- reflex/components/el/elements/metadata.py +11 -0
- reflex/components/el/elements/metadata.pyi +80 -0
- reflex/components/el/elements/other.py +1 -0
- reflex/components/el/elements/scripts.py +1 -0
- reflex/components/el/elements/tables.py +1 -0
- reflex/components/el/elements/typography.py +1 -0
- reflex/components/gridjs/datatable.py +9 -6
- reflex/components/gridjs/datatable.pyi +4 -1
- reflex/components/markdown/markdown.py +36 -41
- reflex/components/markdown/markdown.pyi +4 -3
- reflex/components/media/icon.py +1 -0
- reflex/components/moment/moment.py +11 -17
- reflex/components/moment/moment.pyi +4 -3
- reflex/components/next/base.py +1 -0
- reflex/components/next/image.py +6 -11
- reflex/components/next/image.pyi +2 -2
- reflex/components/plotly/plotly.py +1 -0
- reflex/components/props.py +1 -0
- reflex/components/radix/__init__.py +1 -0
- reflex/components/radix/primitives/__init__.py +1 -0
- reflex/components/radix/primitives/accordion.py +7 -15
- reflex/components/radix/primitives/accordion.pyi +7 -4
- reflex/components/radix/primitives/base.py +1 -0
- reflex/components/radix/primitives/drawer.py +17 -27
- reflex/components/radix/primitives/drawer.pyi +2 -4
- reflex/components/radix/primitives/form.py +4 -12
- reflex/components/radix/primitives/form.pyi +2 -3
- reflex/components/radix/primitives/slider.py +6 -11
- reflex/components/radix/primitives/slider.pyi +2 -2
- reflex/components/radix/themes/__init__.py +1 -0
- reflex/components/radix/themes/base.py +3 -3
- reflex/components/radix/themes/base.pyi +3 -2
- reflex/components/radix/themes/color_mode.py +31 -2
- reflex/components/radix/themes/color_mode.pyi +10 -1
- reflex/components/radix/themes/components/__init__.py +1 -0
- reflex/components/radix/themes/components/alert_dialog.py +13 -24
- reflex/components/radix/themes/components/alert_dialog.pyi +2 -4
- reflex/components/radix/themes/components/aspect_ratio.py +1 -0
- reflex/components/radix/themes/components/card.py +1 -0
- reflex/components/radix/themes/components/checkbox.py +6 -22
- reflex/components/radix/themes/components/checkbox.pyi +2 -4
- reflex/components/radix/themes/components/checkbox_group.py +15 -3
- reflex/components/radix/themes/components/checkbox_group.pyi +10 -2
- reflex/components/radix/themes/components/context_menu.py +29 -38
- reflex/components/radix/themes/components/context_menu.pyi +2 -5
- reflex/components/radix/themes/components/dialog.py +18 -26
- reflex/components/radix/themes/components/dialog.pyi +2 -4
- reflex/components/radix/themes/components/dropdown_menu.py +32 -57
- reflex/components/radix/themes/components/dropdown_menu.pyi +2 -7
- reflex/components/radix/themes/components/hover_card.py +5 -12
- reflex/components/radix/themes/components/hover_card.pyi +2 -3
- reflex/components/radix/themes/components/icon_button.py +1 -0
- reflex/components/radix/themes/components/icon_button.pyi +1 -0
- reflex/components/radix/themes/components/inset.py +1 -0
- reflex/components/radix/themes/components/popover.py +22 -27
- reflex/components/radix/themes/components/popover.pyi +2 -4
- reflex/components/radix/themes/components/radio_group.py +25 -17
- reflex/components/radix/themes/components/radio_group.pyi +2 -3
- reflex/components/radix/themes/components/scroll_area.py +1 -0
- reflex/components/radix/themes/components/segmented_control.py +18 -5
- reflex/components/radix/themes/components/segmented_control.pyi +16 -7
- reflex/components/radix/themes/components/select.py +13 -23
- reflex/components/radix/themes/components/select.pyi +1 -4
- reflex/components/radix/themes/components/separator.py +1 -0
- reflex/components/radix/themes/components/slider.py +7 -12
- reflex/components/radix/themes/components/slider.pyi +2 -3
- reflex/components/radix/themes/components/switch.py +5 -12
- reflex/components/radix/themes/components/switch.pyi +2 -3
- reflex/components/radix/themes/components/table.py +1 -0
- reflex/components/radix/themes/components/tabs.py +4 -11
- reflex/components/radix/themes/components/tabs.pyi +2 -2
- reflex/components/radix/themes/components/text_area.py +19 -18
- reflex/components/radix/themes/components/text_area.pyi +2 -3
- reflex/components/radix/themes/components/text_field.py +19 -18
- reflex/components/radix/themes/components/text_field.pyi +3 -3
- reflex/components/radix/themes/components/tooltip.py +10 -13
- reflex/components/radix/themes/components/tooltip.pyi +2 -3
- reflex/components/radix/themes/layout/__init__.py +1 -0
- reflex/components/radix/themes/layout/box.py +1 -0
- reflex/components/radix/themes/layout/container.py +1 -0
- reflex/components/radix/themes/layout/list.py +1 -0
- reflex/components/radix/themes/layout/list.pyi +1 -0
- reflex/components/radix/themes/layout/section.py +1 -0
- reflex/components/radix/themes/typography/__init__.py +1 -0
- reflex/components/radix/themes/typography/base.py +1 -0
- reflex/components/radix/themes/typography/blockquote.py +1 -0
- reflex/components/radix/themes/typography/code.py +1 -0
- reflex/components/radix/themes/typography/heading.py +1 -0
- reflex/components/radix/themes/typography/link.py +8 -3
- reflex/components/radix/themes/typography/link.pyi +2 -1
- reflex/components/react_player/audio.py +1 -0
- reflex/components/react_player/audio.pyi +48 -0
- reflex/components/react_player/react_player.py +49 -0
- reflex/components/react_player/react_player.pyi +49 -0
- reflex/components/react_player/video.py +1 -0
- reflex/components/react_player/video.pyi +48 -0
- reflex/components/recharts/__init__.py +1 -0
- reflex/components/recharts/cartesian.py +264 -74
- reflex/components/recharts/cartesian.pyi +573 -58
- reflex/components/recharts/charts.py +68 -78
- reflex/components/recharts/charts.pyi +373 -156
- reflex/components/recharts/general.py +52 -20
- reflex/components/recharts/general.pyi +52 -6
- reflex/components/recharts/polar.py +30 -18
- reflex/components/recharts/polar.pyi +66 -5
- reflex/components/recharts/recharts.py +5 -3
- reflex/components/recharts/recharts.pyi +2 -1
- reflex/components/sonner/toast.py +2 -2
- reflex/components/sonner/toast.pyi +1 -1
- reflex/components/suneditor/editor.py +39 -26
- reflex/components/suneditor/editor.pyi +4 -4
- reflex/components/tags/iter_tag.py +1 -0
- reflex/constants/__init__.py +3 -2
- reflex/constants/base.py +20 -21
- reflex/constants/compiler.py +3 -1
- reflex/constants/config.py +1 -0
- reflex/constants/event.py +1 -0
- reflex/constants/installer.py +3 -2
- reflex/constants/style.py +2 -8
- reflex/event.py +36 -6
- reflex/experimental/assets.py +1 -0
- reflex/experimental/client_state.py +9 -3
- reflex/experimental/hooks.py +1 -0
- reflex/experimental/misc.py +12 -3
- reflex/middleware/hydrate_middleware.py +1 -0
- reflex/middleware/middleware.py +1 -0
- reflex/state.py +38 -1
- reflex/style.py +67 -20
- reflex/testing.py +6 -2
- reflex/utils/build.py +76 -72
- reflex/utils/compat.py +5 -0
- reflex/utils/exec.py +17 -9
- reflex/utils/export.py +13 -9
- reflex/utils/imports.py +34 -5
- reflex/utils/lazy_loader.py +1 -0
- reflex/utils/path_ops.py +39 -33
- reflex/utils/prerequisites.py +38 -29
- reflex/utils/processes.py +1 -1
- reflex/utils/serializers.py +3 -6
- reflex/utils/watch.py +3 -1
- reflex/vars.py +26 -10
- reflex/vars.pyi +3 -3
- {reflex-0.5.4a2.dist-info → reflex-0.5.5.dist-info}/METADATA +3 -3
- {reflex-0.5.4a2.dist-info → reflex-0.5.5.dist-info}/RECORD +261 -261
- {reflex-0.5.4a2.dist-info → reflex-0.5.5.dist-info}/LICENSE +0 -0
- {reflex-0.5.4a2.dist-info → reflex-0.5.5.dist-info}/WHEEL +0 -0
- {reflex-0.5.4a2.dist-info → reflex-0.5.5.dist-info}/entry_points.txt +0 -0
reflex/components/component.py
CHANGED
|
@@ -44,7 +44,7 @@ from reflex.event import (
|
|
|
44
44
|
)
|
|
45
45
|
from reflex.style import Style, format_as_emotion
|
|
46
46
|
from reflex.utils import console, format, imports, types
|
|
47
|
-
from reflex.utils.imports import ImportVar
|
|
47
|
+
from reflex.utils.imports import ImportDict, ImportVar, ParsedImportDict, parse_imports
|
|
48
48
|
from reflex.utils.serializers import serializer
|
|
49
49
|
from reflex.vars import BaseVar, Var, VarData
|
|
50
50
|
|
|
@@ -95,7 +95,7 @@ class BaseComponent(Base, ABC):
|
|
|
95
95
|
"""
|
|
96
96
|
|
|
97
97
|
@abstractmethod
|
|
98
|
-
def _get_all_imports(self) ->
|
|
98
|
+
def _get_all_imports(self) -> ParsedImportDict:
|
|
99
99
|
"""Get all the libraries and fields that are used by the component.
|
|
100
100
|
|
|
101
101
|
Returns:
|
|
@@ -213,7 +213,7 @@ class Component(BaseComponent, ABC):
|
|
|
213
213
|
# State class associated with this component instance
|
|
214
214
|
State: Optional[Type[reflex.state.State]] = None
|
|
215
215
|
|
|
216
|
-
def add_imports(self) ->
|
|
216
|
+
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
217
217
|
"""Add imports for the component.
|
|
218
218
|
|
|
219
219
|
This method should be implemented by subclasses to add new imports for the component.
|
|
@@ -582,6 +582,7 @@ class Component(BaseComponent, ABC):
|
|
|
582
582
|
|
|
583
583
|
Returns:
|
|
584
584
|
The event triggers.
|
|
585
|
+
|
|
585
586
|
"""
|
|
586
587
|
default_triggers = {
|
|
587
588
|
EventTriggers.ON_FOCUS: lambda: [],
|
|
@@ -600,6 +601,7 @@ class Component(BaseComponent, ABC):
|
|
|
600
601
|
EventTriggers.ON_MOUNT: lambda: [],
|
|
601
602
|
EventTriggers.ON_UNMOUNT: lambda: [],
|
|
602
603
|
}
|
|
604
|
+
|
|
603
605
|
# Look for component specific triggers,
|
|
604
606
|
# e.g. variable declared as EventHandler types.
|
|
605
607
|
for field in self.get_fields().values():
|
|
@@ -1020,10 +1022,10 @@ class Component(BaseComponent, ABC):
|
|
|
1020
1022
|
f"The component `{comp_name}` only allows the components: {valid_child_list} as children. Got `{child_name}` instead."
|
|
1021
1023
|
)
|
|
1022
1024
|
|
|
1023
|
-
if child._valid_parents and
|
|
1024
|
-
*child._valid_parents,
|
|
1025
|
-
|
|
1026
|
-
|
|
1025
|
+
if child._valid_parents and all(
|
|
1026
|
+
clz_name not in [*child._valid_parents, *allowed_components]
|
|
1027
|
+
for clz_name in self._iter_parent_classes_names()
|
|
1028
|
+
):
|
|
1027
1029
|
valid_parent_list = ", ".join(
|
|
1028
1030
|
[f"`{v_parent}`" for v_parent in child._valid_parents]
|
|
1029
1031
|
)
|
|
@@ -1119,20 +1121,45 @@ class Component(BaseComponent, ABC):
|
|
|
1119
1121
|
|
|
1120
1122
|
return vars
|
|
1121
1123
|
|
|
1122
|
-
def
|
|
1123
|
-
"""Check if the
|
|
1124
|
+
def _event_trigger_values_use_state(self) -> bool:
|
|
1125
|
+
"""Check if the values of a component's event trigger use state.
|
|
1124
1126
|
|
|
1125
1127
|
Returns:
|
|
1126
|
-
True if the component
|
|
1128
|
+
True if any of the component's event trigger values uses State.
|
|
1127
1129
|
"""
|
|
1128
|
-
|
|
1130
|
+
for trigger in self.event_triggers.values():
|
|
1131
|
+
if isinstance(trigger, EventChain):
|
|
1132
|
+
for event in trigger.events:
|
|
1133
|
+
if event.handler.state_full_name:
|
|
1134
|
+
return True
|
|
1135
|
+
elif isinstance(trigger, Var) and trigger._var_state:
|
|
1136
|
+
return True
|
|
1137
|
+
return False
|
|
1138
|
+
|
|
1139
|
+
def _has_stateful_event_triggers(self):
|
|
1140
|
+
"""Check if component or children have any event triggers that use state.
|
|
1141
|
+
|
|
1142
|
+
Returns:
|
|
1143
|
+
True if the component or children have any event triggers that uses state.
|
|
1144
|
+
"""
|
|
1145
|
+
if self.event_triggers and self._event_trigger_values_use_state():
|
|
1129
1146
|
return True
|
|
1130
1147
|
else:
|
|
1131
1148
|
for child in self.children:
|
|
1132
|
-
if
|
|
1149
|
+
if (
|
|
1150
|
+
isinstance(child, Component)
|
|
1151
|
+
and child._has_stateful_event_triggers()
|
|
1152
|
+
):
|
|
1133
1153
|
return True
|
|
1134
1154
|
return False
|
|
1135
1155
|
|
|
1156
|
+
@classmethod
|
|
1157
|
+
def _iter_parent_classes_names(cls) -> Iterator[str]:
|
|
1158
|
+
for clz in cls.mro():
|
|
1159
|
+
if clz is Component:
|
|
1160
|
+
break
|
|
1161
|
+
yield clz.__name__
|
|
1162
|
+
|
|
1136
1163
|
@classmethod
|
|
1137
1164
|
def _iter_parent_classes_with_method(cls, method: str) -> Iterator[Type[Component]]:
|
|
1138
1165
|
"""Iterate through parent classes that define a given method.
|
|
@@ -1224,7 +1251,7 @@ class Component(BaseComponent, ABC):
|
|
|
1224
1251
|
# Return the dynamic imports
|
|
1225
1252
|
return dynamic_imports
|
|
1226
1253
|
|
|
1227
|
-
def _get_props_imports(self) -> List[
|
|
1254
|
+
def _get_props_imports(self) -> List[ParsedImportDict]:
|
|
1228
1255
|
"""Get the imports needed for components props.
|
|
1229
1256
|
|
|
1230
1257
|
Returns:
|
|
@@ -1250,7 +1277,7 @@ class Component(BaseComponent, ABC):
|
|
|
1250
1277
|
or format.format_library_name(dep or "") in self.transpile_packages
|
|
1251
1278
|
)
|
|
1252
1279
|
|
|
1253
|
-
def _get_dependencies_imports(self) ->
|
|
1280
|
+
def _get_dependencies_imports(self) -> ParsedImportDict:
|
|
1254
1281
|
"""Get the imports from lib_dependencies for installing.
|
|
1255
1282
|
|
|
1256
1283
|
Returns:
|
|
@@ -1267,7 +1294,7 @@ class Component(BaseComponent, ABC):
|
|
|
1267
1294
|
for dep in self.lib_dependencies
|
|
1268
1295
|
}
|
|
1269
1296
|
|
|
1270
|
-
def _get_hooks_imports(self) ->
|
|
1297
|
+
def _get_hooks_imports(self) -> ParsedImportDict:
|
|
1271
1298
|
"""Get the imports required by certain hooks.
|
|
1272
1299
|
|
|
1273
1300
|
Returns:
|
|
@@ -1308,7 +1335,7 @@ class Component(BaseComponent, ABC):
|
|
|
1308
1335
|
|
|
1309
1336
|
return imports.merge_imports(_imports, *other_imports)
|
|
1310
1337
|
|
|
1311
|
-
def _get_imports(self) ->
|
|
1338
|
+
def _get_imports(self) -> ParsedImportDict:
|
|
1312
1339
|
"""Get all the libraries and fields that are used by the component.
|
|
1313
1340
|
|
|
1314
1341
|
Returns:
|
|
@@ -1328,25 +1355,15 @@ class Component(BaseComponent, ABC):
|
|
|
1328
1355
|
var._var_data.imports for var in self._get_vars() if var._var_data
|
|
1329
1356
|
]
|
|
1330
1357
|
|
|
1331
|
-
|
|
1332
|
-
def _make_list(
|
|
1333
|
-
value: str | ImportVar | list[str | ImportVar],
|
|
1334
|
-
) -> list[str | ImportVar]:
|
|
1335
|
-
if isinstance(value, (str, ImportVar)):
|
|
1336
|
-
return [value]
|
|
1337
|
-
return value
|
|
1338
|
-
|
|
1339
|
-
_added_import_dicts = []
|
|
1358
|
+
added_import_dicts: list[ParsedImportDict] = []
|
|
1340
1359
|
for clz in self._iter_parent_classes_with_method("add_imports"):
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
}
|
|
1349
|
-
)
|
|
1360
|
+
list_of_import_dict = clz.add_imports(self)
|
|
1361
|
+
|
|
1362
|
+
if not isinstance(list_of_import_dict, list):
|
|
1363
|
+
list_of_import_dict = [list_of_import_dict]
|
|
1364
|
+
|
|
1365
|
+
for import_dict in list_of_import_dict:
|
|
1366
|
+
added_import_dicts.append(parse_imports(import_dict))
|
|
1350
1367
|
|
|
1351
1368
|
return imports.merge_imports(
|
|
1352
1369
|
*self._get_props_imports(),
|
|
@@ -1355,10 +1372,10 @@ class Component(BaseComponent, ABC):
|
|
|
1355
1372
|
_imports,
|
|
1356
1373
|
event_imports,
|
|
1357
1374
|
*var_imports,
|
|
1358
|
-
*
|
|
1375
|
+
*added_import_dicts,
|
|
1359
1376
|
)
|
|
1360
1377
|
|
|
1361
|
-
def _get_all_imports(self, collapse: bool = False) ->
|
|
1378
|
+
def _get_all_imports(self, collapse: bool = False) -> ParsedImportDict:
|
|
1362
1379
|
"""Get all the libraries and fields that are used by the component and its children.
|
|
1363
1380
|
|
|
1364
1381
|
Args:
|
|
@@ -1453,7 +1470,7 @@ class Component(BaseComponent, ABC):
|
|
|
1453
1470
|
**self._get_special_hooks(),
|
|
1454
1471
|
}
|
|
1455
1472
|
|
|
1456
|
-
def _get_added_hooks(self) -> dict[str,
|
|
1473
|
+
def _get_added_hooks(self) -> dict[str, ImportDict]:
|
|
1457
1474
|
"""Get the hooks added via `add_hooks` method.
|
|
1458
1475
|
|
|
1459
1476
|
Returns:
|
|
@@ -1842,7 +1859,7 @@ memo = custom_component
|
|
|
1842
1859
|
class NoSSRComponent(Component):
|
|
1843
1860
|
"""A dynamic component that is not rendered on the server."""
|
|
1844
1861
|
|
|
1845
|
-
def _get_imports(self) ->
|
|
1862
|
+
def _get_imports(self) -> ParsedImportDict:
|
|
1846
1863
|
"""Get the imports for the component.
|
|
1847
1864
|
|
|
1848
1865
|
Returns:
|
|
@@ -2104,10 +2121,20 @@ class StatefulComponent(BaseComponent):
|
|
|
2104
2121
|
Returns:
|
|
2105
2122
|
A list of var names created by the hook declaration.
|
|
2106
2123
|
"""
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
return [
|
|
2124
|
+
# Ensure that the hook is a var declaration.
|
|
2125
|
+
var_decl = hook.partition("=")[0].strip()
|
|
2126
|
+
if not any(var_decl.startswith(kw) for kw in ["const ", "let ", "var "]):
|
|
2127
|
+
return []
|
|
2128
|
+
|
|
2129
|
+
# Extract the var name from the declaration.
|
|
2130
|
+
_, _, var_name = var_decl.partition(" ")
|
|
2131
|
+
var_name = var_name.strip()
|
|
2132
|
+
|
|
2133
|
+
# Break up array and object destructuring if used.
|
|
2134
|
+
if var_name.startswith("[") or var_name.startswith("{"):
|
|
2135
|
+
return [
|
|
2136
|
+
v.strip().replace("...", "") for v in var_name.strip("[]{}").split(",")
|
|
2137
|
+
]
|
|
2111
2138
|
return [var_name]
|
|
2112
2139
|
|
|
2113
2140
|
@classmethod
|
|
@@ -2185,7 +2212,7 @@ class StatefulComponent(BaseComponent):
|
|
|
2185
2212
|
"""
|
|
2186
2213
|
return {}
|
|
2187
2214
|
|
|
2188
|
-
def _get_all_imports(self) ->
|
|
2215
|
+
def _get_all_imports(self) -> ParsedImportDict:
|
|
2189
2216
|
"""Get all the libraries and fields that are used by the component.
|
|
2190
2217
|
|
|
2191
2218
|
Returns:
|
reflex/components/core/banner.py
CHANGED
|
@@ -19,7 +19,7 @@ from reflex.components.radix.themes.typography.text import Text
|
|
|
19
19
|
from reflex.components.sonner.toast import Toaster, ToastProps
|
|
20
20
|
from reflex.constants import Dirs, Hooks, Imports
|
|
21
21
|
from reflex.constants.compiler import CompileVars
|
|
22
|
-
from reflex.utils import
|
|
22
|
+
from reflex.utils.imports import ImportDict, ImportVar
|
|
23
23
|
from reflex.utils.serializers import serialize
|
|
24
24
|
from reflex.vars import Var, VarData
|
|
25
25
|
|
|
@@ -65,10 +65,15 @@ has_too_many_connection_errors: Var = Var.create_safe(
|
|
|
65
65
|
class WebsocketTargetURL(Bare):
|
|
66
66
|
"""A component that renders the websocket target URL."""
|
|
67
67
|
|
|
68
|
-
def
|
|
68
|
+
def add_imports(self) -> ImportDict:
|
|
69
|
+
"""Add imports for the websocket target URL component.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The import dict.
|
|
73
|
+
"""
|
|
69
74
|
return {
|
|
70
|
-
f"/{Dirs.STATE_PATH}": [
|
|
71
|
-
"/env.json": [
|
|
75
|
+
f"/{Dirs.STATE_PATH}": [ImportVar(tag="getBackendURL")],
|
|
76
|
+
"/env.json": [ImportVar(tag="env", is_default=True)],
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
@classmethod
|
|
@@ -98,7 +103,7 @@ def default_connection_error() -> list[str | Var | Component]:
|
|
|
98
103
|
class ConnectionToaster(Toaster):
|
|
99
104
|
"""A connection toaster component."""
|
|
100
105
|
|
|
101
|
-
def add_hooks(self) -> list[str]:
|
|
106
|
+
def add_hooks(self) -> list[str | Var]:
|
|
102
107
|
"""Add the hooks for the connection toaster.
|
|
103
108
|
|
|
104
109
|
Returns:
|
|
@@ -116,7 +121,7 @@ class ConnectionToaster(Toaster):
|
|
|
116
121
|
duration=120000,
|
|
117
122
|
id=toast_id,
|
|
118
123
|
)
|
|
119
|
-
hook = Var.
|
|
124
|
+
hook = Var.create_safe(
|
|
120
125
|
f"""
|
|
121
126
|
const toast_props = {serialize(props)};
|
|
122
127
|
const [userDismissed, setUserDismissed] = useState(false);
|
|
@@ -135,22 +140,17 @@ useEffect(() => {{
|
|
|
135
140
|
}}, [{connect_errors}]);""",
|
|
136
141
|
_var_is_string=False,
|
|
137
142
|
)
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
imports: ImportDict = {
|
|
144
|
+
"react": ["useEffect", "useState"],
|
|
145
|
+
**target_url._get_imports(), # type: ignore
|
|
146
|
+
}
|
|
147
|
+
hook._var_data = VarData.merge(
|
|
140
148
|
connect_errors._var_data,
|
|
141
|
-
VarData(
|
|
142
|
-
imports={
|
|
143
|
-
"react": [
|
|
144
|
-
imports.ImportVar(tag="useEffect"),
|
|
145
|
-
imports.ImportVar(tag="useState"),
|
|
146
|
-
],
|
|
147
|
-
**target_url._get_imports(),
|
|
148
|
-
}
|
|
149
|
-
),
|
|
149
|
+
VarData(imports=imports),
|
|
150
150
|
)
|
|
151
151
|
return [
|
|
152
152
|
Hooks.EVENTS,
|
|
153
|
-
hook,
|
|
153
|
+
hook,
|
|
154
154
|
]
|
|
155
155
|
|
|
156
156
|
|
|
@@ -216,10 +216,11 @@ class WifiOffPulse(Icon):
|
|
|
216
216
|
"""A wifi_off icon with an animated opacity pulse."""
|
|
217
217
|
|
|
218
218
|
@classmethod
|
|
219
|
-
def create(cls, **props) ->
|
|
219
|
+
def create(cls, *children, **props) -> Icon:
|
|
220
220
|
"""Create a wifi_off icon with an animated opacity pulse.
|
|
221
221
|
|
|
222
222
|
Args:
|
|
223
|
+
*children: The children of the component.
|
|
223
224
|
**props: The properties of the component.
|
|
224
225
|
|
|
225
226
|
Returns:
|
|
@@ -237,11 +238,13 @@ class WifiOffPulse(Icon):
|
|
|
237
238
|
**props,
|
|
238
239
|
)
|
|
239
240
|
|
|
240
|
-
def
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
241
|
+
def add_imports(self) -> dict[str, str | ImportVar | list[str | ImportVar]]:
|
|
242
|
+
"""Add imports for the WifiOffPulse component.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
The import dict.
|
|
246
|
+
"""
|
|
247
|
+
return {"@emotion/react": [ImportVar(tag="keyframes")]}
|
|
245
248
|
|
|
246
249
|
def _get_custom_code(self) -> str | None:
|
|
247
250
|
return """
|
|
@@ -23,7 +23,7 @@ from reflex.components.radix.themes.typography.text import Text
|
|
|
23
23
|
from reflex.components.sonner.toast import Toaster, ToastProps
|
|
24
24
|
from reflex.constants import Dirs, Hooks, Imports
|
|
25
25
|
from reflex.constants.compiler import CompileVars
|
|
26
|
-
from reflex.utils import
|
|
26
|
+
from reflex.utils.imports import ImportDict, ImportVar
|
|
27
27
|
from reflex.utils.serializers import serialize
|
|
28
28
|
from reflex.vars import Var, VarData
|
|
29
29
|
|
|
@@ -35,6 +35,7 @@ has_connection_errors: Var
|
|
|
35
35
|
has_too_many_connection_errors: Var
|
|
36
36
|
|
|
37
37
|
class WebsocketTargetURL(Bare):
|
|
38
|
+
def add_imports(self) -> ImportDict: ...
|
|
38
39
|
@overload
|
|
39
40
|
@classmethod
|
|
40
41
|
def create( # type: ignore
|
|
@@ -104,7 +105,7 @@ class WebsocketTargetURL(Bare):
|
|
|
104
105
|
def default_connection_error() -> list[str | Var | Component]: ...
|
|
105
106
|
|
|
106
107
|
class ConnectionToaster(Toaster):
|
|
107
|
-
def add_hooks(self) -> list[str]: ...
|
|
108
|
+
def add_hooks(self) -> list[str | Var]: ...
|
|
108
109
|
@overload
|
|
109
110
|
@classmethod
|
|
110
111
|
def create( # type: ignore
|
|
@@ -430,6 +431,7 @@ class WifiOffPulse(Icon):
|
|
|
430
431
|
"""Create a wifi_off icon with an animated opacity pulse.
|
|
431
432
|
|
|
432
433
|
Args:
|
|
434
|
+
*children: The children of the component.
|
|
433
435
|
size: The size of the icon in pixels.
|
|
434
436
|
style: The style of the component.
|
|
435
437
|
key: A unique key for the component.
|
|
@@ -444,6 +446,8 @@ class WifiOffPulse(Icon):
|
|
|
444
446
|
"""
|
|
445
447
|
...
|
|
446
448
|
|
|
449
|
+
def add_imports(self) -> dict[str, str | ImportVar | list[str | ImportVar]]: ...
|
|
450
|
+
|
|
447
451
|
class ConnectionPulser(Div):
|
|
448
452
|
@overload
|
|
449
453
|
@classmethod
|
reflex/components/core/cond.py
CHANGED
|
@@ -9,12 +9,13 @@ from reflex.components.component import BaseComponent, Component, MemoizationLea
|
|
|
9
9
|
from reflex.components.tags import CondTag, Tag
|
|
10
10
|
from reflex.constants import Dirs
|
|
11
11
|
from reflex.constants.colors import Color
|
|
12
|
-
from reflex.style import LIGHT_COLOR_MODE,
|
|
13
|
-
from reflex.utils import format
|
|
14
|
-
from reflex.
|
|
12
|
+
from reflex.style import LIGHT_COLOR_MODE, resolved_color_mode
|
|
13
|
+
from reflex.utils import format
|
|
14
|
+
from reflex.utils.imports import ImportDict, ImportVar
|
|
15
|
+
from reflex.vars import BaseVar, Var, VarData
|
|
15
16
|
|
|
16
|
-
_IS_TRUE_IMPORT = {
|
|
17
|
-
f"/{Dirs.STATE_PATH}": [
|
|
17
|
+
_IS_TRUE_IMPORT: ImportDict = {
|
|
18
|
+
f"/{Dirs.STATE_PATH}": [ImportVar(tag="isTrue")],
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
|
|
@@ -96,27 +97,28 @@ class Cond(MemoizationLeaf):
|
|
|
96
97
|
cond_state=f"isTrue({self.cond._var_full_name})",
|
|
97
98
|
)
|
|
98
99
|
|
|
99
|
-
def
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
def add_imports(self) -> ImportDict:
|
|
101
|
+
"""Add imports for the Cond component.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
The import dict for the component.
|
|
105
|
+
"""
|
|
106
|
+
cond_imports: dict[str, str | ImportVar | list[str | ImportVar]] = getattr(
|
|
107
|
+
self.cond._var_data, "imports", {}
|
|
104
108
|
)
|
|
109
|
+
return {**cond_imports, **_IS_TRUE_IMPORT}
|
|
105
110
|
|
|
106
111
|
|
|
107
112
|
@overload
|
|
108
|
-
def cond(condition: Any, c1: Component, c2: Any) -> Component:
|
|
109
|
-
...
|
|
113
|
+
def cond(condition: Any, c1: Component, c2: Any) -> Component: ...
|
|
110
114
|
|
|
111
115
|
|
|
112
116
|
@overload
|
|
113
|
-
def cond(condition: Any, c1: Component) -> Component:
|
|
114
|
-
...
|
|
117
|
+
def cond(condition: Any, c1: Component) -> Component: ...
|
|
115
118
|
|
|
116
119
|
|
|
117
120
|
@overload
|
|
118
|
-
def cond(condition: Any, c1: Any, c2: Any) ->
|
|
119
|
-
...
|
|
121
|
+
def cond(condition: Any, c1: Any, c2: Any) -> BaseVar: ...
|
|
120
122
|
|
|
121
123
|
|
|
122
124
|
def cond(condition: Any, c1: Any, c2: Any = None):
|
|
@@ -203,7 +205,7 @@ def color_mode_cond(light: Any, dark: Any = None) -> Var | Component:
|
|
|
203
205
|
The conditional component or prop.
|
|
204
206
|
"""
|
|
205
207
|
return cond(
|
|
206
|
-
|
|
208
|
+
resolved_color_mode == Var.create(LIGHT_COLOR_MODE, _var_is_string=True),
|
|
207
209
|
light,
|
|
208
210
|
dark,
|
|
209
211
|
)
|
|
@@ -6,6 +6,7 @@ from typing import Any, Type, Union
|
|
|
6
6
|
|
|
7
7
|
from reflex.components.component import Component
|
|
8
8
|
from reflex.constants import EventTriggers
|
|
9
|
+
from reflex.event import EventHandler
|
|
9
10
|
from reflex.vars import Var, VarData
|
|
10
11
|
|
|
11
12
|
DEFAULT_DEBOUNCE_TIMEOUT = 300
|
|
@@ -43,6 +44,9 @@ class DebounceInput(Component):
|
|
|
43
44
|
# The element to wrap
|
|
44
45
|
element: Var[Type[Component]]
|
|
45
46
|
|
|
47
|
+
# Fired when the input value changes
|
|
48
|
+
on_change: EventHandler[lambda e0: [e0.value]]
|
|
49
|
+
|
|
46
50
|
@classmethod
|
|
47
51
|
def create(cls, *children: Component, **props: Any) -> Component:
|
|
48
52
|
"""Create a DebounceInput component.
|
|
@@ -125,17 +129,6 @@ class DebounceInput(Component):
|
|
|
125
129
|
component._rename_props = child._rename_props
|
|
126
130
|
return component
|
|
127
131
|
|
|
128
|
-
def get_event_triggers(self) -> dict[str, Any]:
|
|
129
|
-
"""Get the event triggers that pass the component's value to the handler.
|
|
130
|
-
|
|
131
|
-
Returns:
|
|
132
|
-
A dict mapping the event trigger to the var that is passed to the handler.
|
|
133
|
-
"""
|
|
134
|
-
return {
|
|
135
|
-
**super().get_event_triggers(),
|
|
136
|
-
EventTriggers.ON_CHANGE: lambda e0: [e0.value],
|
|
137
|
-
}
|
|
138
|
-
|
|
139
132
|
def _render(self):
|
|
140
133
|
return super()._render().remove_props("ref")
|
|
141
134
|
|
|
@@ -10,6 +10,7 @@ from reflex.style import Style
|
|
|
10
10
|
from typing import Any, Type, Union
|
|
11
11
|
from reflex.components.component import Component
|
|
12
12
|
from reflex.constants import EventTriggers
|
|
13
|
+
from reflex.event import EventHandler
|
|
13
14
|
from reflex.vars import Var, VarData
|
|
14
15
|
|
|
15
16
|
DEFAULT_DEBOUNCE_TIMEOUT = 300
|
|
@@ -105,6 +106,5 @@ class DebounceInput(Component):
|
|
|
105
106
|
ValueError: if the child element does not have an on_change handler.
|
|
106
107
|
"""
|
|
107
108
|
...
|
|
108
|
-
def get_event_triggers(self) -> dict[str, Any]: ...
|
|
109
109
|
|
|
110
110
|
debounce_input = DebounceInput.create
|
reflex/components/core/html.py
CHANGED
reflex/components/core/match.py
CHANGED
|
@@ -8,8 +8,9 @@ from reflex.components.component import BaseComponent, Component, MemoizationLea
|
|
|
8
8
|
from reflex.components.core.colors import Color
|
|
9
9
|
from reflex.components.tags import MatchTag, Tag
|
|
10
10
|
from reflex.style import Style
|
|
11
|
-
from reflex.utils import format,
|
|
11
|
+
from reflex.utils import format, types
|
|
12
12
|
from reflex.utils.exceptions import MatchTypeError
|
|
13
|
+
from reflex.utils.imports import ImportDict
|
|
13
14
|
from reflex.vars import BaseVar, Var, VarData
|
|
14
15
|
|
|
15
16
|
|
|
@@ -268,11 +269,13 @@ class Match(MemoizationLeaf):
|
|
|
268
269
|
tag.name = "match"
|
|
269
270
|
return dict(tag)
|
|
270
271
|
|
|
271
|
-
def
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
272
|
+
def add_imports(self) -> ImportDict:
|
|
273
|
+
"""Add imports for the Match component.
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
The import dict.
|
|
277
|
+
"""
|
|
278
|
+
return getattr(self.cond._var_data, "imports", {})
|
|
276
279
|
|
|
277
280
|
|
|
278
281
|
match = Match.create
|