reflex 0.5.10a3__py3-none-any.whl → 0.6.0a1__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/jinja/web/pages/utils.js.jinja2 +4 -4
- reflex/.templates/jinja/web/utils/context.js.jinja2 +1 -1
- reflex/.templates/jinja/web/utils/theme.js.jinja2 +1 -1
- reflex/__init__.py +3 -2
- reflex/__init__.pyi +2 -2
- reflex/app.py +43 -9
- reflex/base.py +3 -2
- reflex/compiler/compiler.py +6 -6
- reflex/compiler/utils.py +5 -3
- reflex/components/base/app_wrap.py +2 -4
- reflex/components/base/app_wrap.pyi +17 -17
- reflex/components/base/bare.py +7 -4
- reflex/components/base/body.pyi +17 -17
- reflex/components/base/document.pyi +81 -81
- reflex/components/base/error_boundary.py +10 -8
- reflex/components/base/error_boundary.pyi +20 -19
- reflex/components/base/fragment.pyi +17 -17
- reflex/components/base/head.pyi +33 -33
- reflex/components/base/link.pyi +34 -33
- reflex/components/base/meta.pyi +65 -65
- reflex/components/base/script.py +2 -1
- reflex/components/base/script.pyi +21 -20
- reflex/components/component.py +116 -145
- reflex/components/core/banner.py +59 -60
- reflex/components/core/banner.pyi +86 -150
- reflex/components/core/client_side_routing.py +2 -1
- reflex/components/core/client_side_routing.pyi +34 -33
- reflex/components/core/clipboard.py +2 -2
- reflex/components/core/clipboard.pyi +19 -18
- reflex/components/core/cond.py +21 -44
- reflex/components/core/debounce.py +6 -8
- reflex/components/core/debounce.pyi +19 -18
- reflex/components/core/foreach.py +5 -14
- reflex/components/core/html.pyi +18 -17
- reflex/components/core/match.py +36 -43
- reflex/components/core/upload.py +32 -25
- reflex/components/core/upload.pyi +84 -73
- reflex/components/datadisplay/code.py +55 -28
- reflex/components/datadisplay/code.pyi +20 -17
- reflex/components/datadisplay/dataeditor.py +17 -11
- reflex/components/datadisplay/dataeditor.pyi +34 -33
- reflex/components/el/__init__.py +0 -1
- reflex/components/el/__init__.pyi +0 -11
- reflex/components/el/element.pyi +17 -17
- reflex/components/el/elements/__init__.py +1 -7
- reflex/components/el/elements/__init__.pyi +1 -15
- reflex/components/el/elements/base.pyi +18 -17
- reflex/components/el/elements/forms.py +24 -31
- reflex/components/el/elements/forms.pyi +237 -236
- reflex/components/el/elements/inline.pyi +450 -449
- reflex/components/el/elements/media.py +0 -21
- reflex/components/el/elements/media.pyi +338 -337
- reflex/components/el/elements/metadata.py +3 -2
- reflex/components/el/elements/metadata.pyi +98 -97
- reflex/components/el/elements/other.pyi +114 -113
- reflex/components/el/elements/scripts.pyi +50 -49
- reflex/components/el/elements/sectioning.pyi +242 -241
- reflex/components/el/elements/tables.pyi +162 -161
- reflex/components/el/elements/typography.pyi +242 -241
- reflex/components/gridjs/datatable.py +13 -14
- reflex/components/gridjs/datatable.pyi +34 -33
- reflex/components/lucide/icon.py +2 -126
- reflex/components/lucide/icon.pyi +34 -142
- reflex/components/markdown/markdown.py +30 -35
- reflex/components/markdown/markdown.pyi +29 -32
- reflex/components/moment/moment.pyi +19 -18
- reflex/components/next/base.pyi +17 -17
- reflex/components/next/image.py +0 -4
- reflex/components/next/image.pyi +20 -19
- reflex/components/next/link.pyi +18 -17
- reflex/components/next/video.pyi +18 -17
- reflex/components/plotly/plotly.py +16 -28
- reflex/components/plotly/plotly.pyi +36 -35
- reflex/components/props.py +21 -10
- reflex/components/radix/__init__.pyi +1 -1
- reflex/components/radix/primitives/__init__.pyi +0 -1
- reflex/components/radix/primitives/accordion.py +7 -8
- reflex/components/radix/primitives/accordion.pyi +117 -116
- reflex/components/radix/primitives/base.pyi +34 -33
- reflex/components/radix/primitives/drawer.pyi +169 -168
- reflex/components/radix/primitives/form.pyi +168 -167
- reflex/components/radix/primitives/progress.pyi +82 -81
- reflex/components/radix/primitives/slider.pyi +84 -83
- reflex/components/radix/themes/base.py +8 -4
- reflex/components/radix/themes/base.pyi +114 -113
- reflex/components/radix/themes/color_mode.py +12 -21
- reflex/components/radix/themes/color_mode.pyi +67 -67
- reflex/components/radix/themes/components/__init__.pyi +1 -0
- reflex/components/radix/themes/components/alert_dialog.pyi +118 -117
- reflex/components/radix/themes/components/aspect_ratio.pyi +18 -17
- reflex/components/radix/themes/components/avatar.pyi +18 -17
- reflex/components/radix/themes/components/badge.pyi +18 -17
- reflex/components/radix/themes/components/button.pyi +18 -17
- reflex/components/radix/themes/components/callout.pyi +82 -81
- reflex/components/radix/themes/components/card.pyi +18 -17
- reflex/components/radix/themes/components/checkbox.py +2 -3
- reflex/components/radix/themes/components/checkbox.pyi +53 -52
- reflex/components/radix/themes/components/checkbox_cards.pyi +34 -33
- reflex/components/radix/themes/components/checkbox_group.pyi +34 -33
- reflex/components/radix/themes/components/context_menu.pyi +140 -139
- reflex/components/radix/themes/components/data_list.py +5 -0
- reflex/components/radix/themes/components/data_list.pyi +71 -65
- reflex/components/radix/themes/components/dialog.pyi +121 -120
- reflex/components/radix/themes/components/dropdown_menu.pyi +142 -141
- reflex/components/radix/themes/components/hover_card.pyi +68 -67
- reflex/components/radix/themes/components/icon_button.py +2 -1
- reflex/components/radix/themes/components/icon_button.pyi +18 -17
- reflex/components/radix/themes/components/inset.pyi +18 -17
- reflex/components/radix/themes/components/popover.pyi +73 -72
- reflex/components/radix/themes/components/progress.pyi +18 -17
- reflex/components/radix/themes/components/radio.pyi +18 -17
- reflex/components/radix/themes/components/radio_cards.pyi +35 -34
- reflex/components/radix/themes/components/radio_group.py +35 -31
- reflex/components/radix/themes/components/radio_group.pyi +73 -66
- reflex/components/radix/themes/components/scroll_area.pyi +18 -17
- reflex/components/radix/themes/components/segmented_control.pyi +35 -34
- reflex/components/radix/themes/components/select.py +2 -1
- reflex/components/radix/themes/components/select.pyi +155 -154
- reflex/components/radix/themes/components/separator.py +2 -3
- reflex/components/radix/themes/components/separator.pyi +18 -17
- reflex/components/radix/themes/components/skeleton.pyi +18 -17
- reflex/components/radix/themes/components/slider.py +2 -1
- reflex/components/radix/themes/components/slider.pyi +20 -19
- reflex/components/radix/themes/components/spinner.pyi +18 -17
- reflex/components/radix/themes/components/switch.pyi +19 -18
- reflex/components/radix/themes/components/table.pyi +114 -113
- reflex/components/radix/themes/components/tabs.pyi +84 -83
- reflex/components/radix/themes/components/text_area.pyi +21 -20
- reflex/components/radix/themes/components/text_field.py +0 -79
- reflex/components/radix/themes/components/text_field.pyi +57 -63
- reflex/components/radix/themes/components/tooltip.pyi +21 -20
- reflex/components/radix/themes/layout/base.pyi +18 -17
- reflex/components/radix/themes/layout/box.pyi +18 -17
- reflex/components/radix/themes/layout/center.pyi +18 -17
- reflex/components/radix/themes/layout/container.py +2 -3
- reflex/components/radix/themes/layout/container.pyi +18 -17
- reflex/components/radix/themes/layout/flex.pyi +18 -17
- reflex/components/radix/themes/layout/grid.pyi +18 -17
- reflex/components/radix/themes/layout/list.py +5 -4
- reflex/components/radix/themes/layout/list.pyi +86 -85
- reflex/components/radix/themes/layout/section.py +2 -3
- reflex/components/radix/themes/layout/section.pyi +18 -17
- reflex/components/radix/themes/layout/spacer.pyi +18 -17
- reflex/components/radix/themes/layout/stack.pyi +50 -49
- reflex/components/radix/themes/typography/blockquote.pyi +18 -17
- reflex/components/radix/themes/typography/code.pyi +18 -17
- reflex/components/radix/themes/typography/heading.pyi +18 -17
- reflex/components/radix/themes/typography/link.pyi +18 -17
- reflex/components/radix/themes/typography/text.pyi +114 -113
- reflex/components/react_player/audio.pyi +34 -33
- reflex/components/react_player/react_player.pyi +34 -33
- reflex/components/react_player/video.pyi +34 -33
- reflex/components/recharts/cartesian.py +23 -19
- reflex/components/recharts/cartesian.pyi +297 -296
- reflex/components/recharts/charts.py +6 -5
- reflex/components/recharts/charts.pyi +179 -178
- reflex/components/recharts/general.py +8 -7
- reflex/components/recharts/general.pyi +82 -81
- reflex/components/recharts/polar.py +14 -13
- reflex/components/recharts/polar.pyi +76 -75
- reflex/components/recharts/recharts.pyi +33 -33
- reflex/components/sonner/toast.py +30 -33
- reflex/components/sonner/toast.pyi +27 -25
- reflex/components/suneditor/editor.py +2 -1
- reflex/components/suneditor/editor.pyi +27 -26
- reflex/components/tags/iter_tag.py +16 -16
- reflex/components/tags/tag.py +8 -10
- reflex/constants/base.py +3 -1
- reflex/constants/event.py +1 -0
- reflex/event.py +89 -79
- reflex/experimental/__init__.py +25 -6
- reflex/experimental/client_state.py +34 -58
- reflex/experimental/hooks.py +13 -18
- reflex/experimental/layout.py +5 -5
- reflex/experimental/layout.pyi +84 -83
- reflex/{experimental/vars → ivars}/__init__.py +0 -1
- reflex/ivars/base.py +2180 -0
- reflex/ivars/function.py +200 -0
- reflex/ivars/number.py +1137 -0
- reflex/ivars/object.py +564 -0
- reflex/ivars/sequence.py +1601 -0
- reflex/model.py +22 -0
- reflex/reflex.py +4 -0
- reflex/state.py +388 -73
- reflex/style.py +52 -34
- reflex/testing.py +8 -3
- reflex/utils/exceptions.py +12 -0
- reflex/utils/exec.py +0 -14
- reflex/utils/format.py +74 -223
- reflex/utils/net.py +43 -0
- reflex/utils/path_ops.py +13 -1
- reflex/utils/prerequisites.py +46 -26
- reflex/utils/pyi_generator.py +5 -4
- reflex/utils/serializers.py +13 -31
- reflex/utils/types.py +44 -9
- reflex/vars.py +127 -2230
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/METADATA +4 -6
- reflex-0.6.0a1.dist-info/RECORD +384 -0
- reflex/.templates/apps/demo/.gitignore +0 -4
- reflex/.templates/apps/demo/assets/favicon.ico +0 -0
- reflex/.templates/apps/demo/assets/github.svg +0 -10
- reflex/.templates/apps/demo/assets/icon.svg +0 -37
- reflex/.templates/apps/demo/assets/logo.svg +0 -68
- reflex/.templates/apps/demo/assets/paneleft.svg +0 -13
- reflex/.templates/apps/demo/code/__init__.py +0 -1
- reflex/.templates/apps/demo/code/demo.py +0 -127
- reflex/.templates/apps/demo/code/pages/__init__.py +0 -7
- reflex/.templates/apps/demo/code/pages/chatapp.py +0 -31
- reflex/.templates/apps/demo/code/pages/datatable.py +0 -360
- reflex/.templates/apps/demo/code/pages/forms.py +0 -257
- reflex/.templates/apps/demo/code/pages/graphing.py +0 -253
- reflex/.templates/apps/demo/code/pages/home.py +0 -56
- reflex/.templates/apps/demo/code/sidebar.py +0 -178
- reflex/.templates/apps/demo/code/state.py +0 -22
- reflex/.templates/apps/demo/code/states/form_state.py +0 -40
- reflex/.templates/apps/demo/code/states/pie_state.py +0 -47
- reflex/.templates/apps/demo/code/styles.py +0 -68
- reflex/.templates/apps/demo/code/webui/__init__.py +0 -0
- reflex/.templates/apps/demo/code/webui/components/__init__.py +0 -4
- reflex/.templates/apps/demo/code/webui/components/chat.py +0 -118
- reflex/.templates/apps/demo/code/webui/components/loading_icon.py +0 -19
- reflex/.templates/apps/demo/code/webui/components/modal.py +0 -56
- reflex/.templates/apps/demo/code/webui/components/navbar.py +0 -70
- reflex/.templates/apps/demo/code/webui/components/sidebar.py +0 -66
- reflex/.templates/apps/demo/code/webui/state.py +0 -146
- reflex/.templates/apps/demo/code/webui/styles.py +0 -88
- reflex/experimental/vars/base.py +0 -583
- reflex/experimental/vars/function.py +0 -290
- reflex/experimental/vars/number.py +0 -1458
- reflex/experimental/vars/object.py +0 -804
- reflex/experimental/vars/sequence.py +0 -1764
- reflex/utils/watch.py +0 -96
- reflex/vars.pyi +0 -218
- reflex-0.5.10a3.dist-info/RECORD +0 -413
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/LICENSE +0 -0
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/WHEEL +0 -0
- {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/entry_points.txt +0 -0
reflex/components/component.py
CHANGED
|
@@ -43,11 +43,18 @@ from reflex.event import (
|
|
|
43
43
|
call_event_handler,
|
|
44
44
|
get_handler_args,
|
|
45
45
|
)
|
|
46
|
+
from reflex.ivars.base import ImmutableVar, LiteralVar
|
|
46
47
|
from reflex.style import Style, format_as_emotion
|
|
47
|
-
from reflex.utils import
|
|
48
|
-
from reflex.utils.imports import
|
|
48
|
+
from reflex.utils import format, imports, types
|
|
49
|
+
from reflex.utils.imports import (
|
|
50
|
+
ImmutableParsedImportDict,
|
|
51
|
+
ImportDict,
|
|
52
|
+
ImportVar,
|
|
53
|
+
ParsedImportDict,
|
|
54
|
+
parse_imports,
|
|
55
|
+
)
|
|
49
56
|
from reflex.utils.serializers import serializer
|
|
50
|
-
from reflex.vars import
|
|
57
|
+
from reflex.vars import Var, VarData
|
|
51
58
|
|
|
52
59
|
|
|
53
60
|
class BaseComponent(Base, ABC):
|
|
@@ -170,7 +177,7 @@ class Component(BaseComponent, ABC):
|
|
|
170
177
|
style: Style = Style()
|
|
171
178
|
|
|
172
179
|
# A mapping from event triggers to event chains.
|
|
173
|
-
event_triggers: Dict[str, Union[EventChain,
|
|
180
|
+
event_triggers: Dict[str, Union[EventChain, ImmutableVar]] = {}
|
|
174
181
|
|
|
175
182
|
# The alias for the tag.
|
|
176
183
|
alias: Optional[str] = None
|
|
@@ -188,7 +195,7 @@ class Component(BaseComponent, ABC):
|
|
|
188
195
|
class_name: Any = None
|
|
189
196
|
|
|
190
197
|
# Special component props.
|
|
191
|
-
special_props: Set[
|
|
198
|
+
special_props: Set[ImmutableVar] = set()
|
|
192
199
|
|
|
193
200
|
# Whether the component should take the focus once the page is loaded
|
|
194
201
|
autofocus: bool = False
|
|
@@ -206,7 +213,7 @@ class Component(BaseComponent, ABC):
|
|
|
206
213
|
_rename_props: Dict[str, str] = {}
|
|
207
214
|
|
|
208
215
|
# custom attribute
|
|
209
|
-
custom_attrs: Dict[str, Union[
|
|
216
|
+
custom_attrs: Dict[str, Union[ImmutableVar, str]] = {}
|
|
210
217
|
|
|
211
218
|
# When to memoize this component and its children.
|
|
212
219
|
_memoization_mode: MemoizationMode = MemoizationMode()
|
|
@@ -242,7 +249,7 @@ class Component(BaseComponent, ABC):
|
|
|
242
249
|
"""
|
|
243
250
|
return {}
|
|
244
251
|
|
|
245
|
-
def add_hooks(self) -> list[str |
|
|
252
|
+
def add_hooks(self) -> list[str | ImmutableVar]:
|
|
246
253
|
"""Add hooks inside the component function.
|
|
247
254
|
|
|
248
255
|
Hooks are pieces of literal Javascript code that is inserted inside the
|
|
@@ -320,9 +327,8 @@ class Component(BaseComponent, ABC):
|
|
|
320
327
|
# Set default values for any props.
|
|
321
328
|
if types._issubclass(field.type_, Var):
|
|
322
329
|
field.required = False
|
|
323
|
-
field.default
|
|
324
|
-
field.default
|
|
325
|
-
)
|
|
330
|
+
if field.default is not None:
|
|
331
|
+
field.default = LiteralVar.create(field.default)
|
|
326
332
|
elif types._issubclass(field.type_, EventHandler):
|
|
327
333
|
field.required = False
|
|
328
334
|
|
|
@@ -351,10 +357,7 @@ class Component(BaseComponent, ABC):
|
|
|
351
357
|
"id": kwargs.get("id"),
|
|
352
358
|
"children": children,
|
|
353
359
|
**{
|
|
354
|
-
prop:
|
|
355
|
-
kwargs[prop],
|
|
356
|
-
_var_is_string=False if isinstance(kwargs[prop], str) else None,
|
|
357
|
-
)
|
|
360
|
+
prop: LiteralVar.create(kwargs[prop])
|
|
358
361
|
for prop in self.get_initial_props()
|
|
359
362
|
if prop in kwargs
|
|
360
363
|
},
|
|
@@ -401,10 +404,10 @@ class Component(BaseComponent, ABC):
|
|
|
401
404
|
passed_types = None
|
|
402
405
|
try:
|
|
403
406
|
# Try to create a var from the value.
|
|
404
|
-
|
|
405
|
-
value
|
|
406
|
-
|
|
407
|
-
|
|
407
|
+
if isinstance(value, ImmutableVar):
|
|
408
|
+
kwargs[key] = value
|
|
409
|
+
else:
|
|
410
|
+
kwargs[key] = LiteralVar.create(value)
|
|
408
411
|
|
|
409
412
|
# Check that the var type is not None.
|
|
410
413
|
if kwargs[key] is None:
|
|
@@ -444,11 +447,12 @@ class Component(BaseComponent, ABC):
|
|
|
444
447
|
not passed_types
|
|
445
448
|
and not types._issubclass(passed_type, expected_type, value)
|
|
446
449
|
):
|
|
447
|
-
value_name =
|
|
450
|
+
value_name = (
|
|
451
|
+
value._var_name if isinstance(value, ImmutableVar) else value
|
|
452
|
+
)
|
|
448
453
|
raise TypeError(
|
|
449
454
|
f"Invalid var passed for prop {type(self).__name__}.{key}, expected type {expected_type}, got value {value_name} of type {passed_types or passed_type}."
|
|
450
455
|
)
|
|
451
|
-
|
|
452
456
|
# Check if the key is an event trigger.
|
|
453
457
|
if key in component_specific_triggers:
|
|
454
458
|
# Temporarily disable full control for event triggers.
|
|
@@ -497,7 +501,7 @@ class Component(BaseComponent, ABC):
|
|
|
497
501
|
value: Union[
|
|
498
502
|
Var, EventHandler, EventSpec, List[Union[EventHandler, EventSpec]], Callable
|
|
499
503
|
],
|
|
500
|
-
) -> Union[EventChain,
|
|
504
|
+
) -> Union[EventChain, ImmutableVar]:
|
|
501
505
|
"""Create an event chain from a variety of input types.
|
|
502
506
|
|
|
503
507
|
Args:
|
|
@@ -511,9 +515,11 @@ class Component(BaseComponent, ABC):
|
|
|
511
515
|
ValueError: If the value is not a valid event chain.
|
|
512
516
|
"""
|
|
513
517
|
# If it's an event chain var, return it.
|
|
514
|
-
if isinstance(value,
|
|
518
|
+
if isinstance(value, ImmutableVar):
|
|
515
519
|
if value._var_type is not EventChain:
|
|
516
|
-
raise ValueError(
|
|
520
|
+
raise ValueError(
|
|
521
|
+
f"Invalid event chain: {repr(value)} of type {type(value)}"
|
|
522
|
+
)
|
|
517
523
|
return value
|
|
518
524
|
elif isinstance(value, EventChain):
|
|
519
525
|
# Trust that the caller knows what they're doing passing an EventChain directly
|
|
@@ -529,19 +535,11 @@ class Component(BaseComponent, ABC):
|
|
|
529
535
|
for v in value:
|
|
530
536
|
if isinstance(v, (EventHandler, EventSpec)):
|
|
531
537
|
# Call the event handler to get the event.
|
|
532
|
-
|
|
533
|
-
event = call_event_handler(v, args_spec)
|
|
534
|
-
except ValueError as err:
|
|
535
|
-
raise ValueError(
|
|
536
|
-
f" {err} defined in the `{type(self).__name__}` component"
|
|
537
|
-
) from err
|
|
538
|
-
|
|
539
|
-
# Add the event to the chain.
|
|
540
|
-
events.append(event)
|
|
538
|
+
events.append(call_event_handler(v, args_spec))
|
|
541
539
|
elif isinstance(v, Callable):
|
|
542
540
|
# Call the lambda to get the event chain.
|
|
543
541
|
result = call_event_fn(v, args_spec)
|
|
544
|
-
if isinstance(result,
|
|
542
|
+
if isinstance(result, ImmutableVar):
|
|
545
543
|
raise ValueError(
|
|
546
544
|
f"Invalid event chain: {v}. Cannot use a Var-returning "
|
|
547
545
|
"lambda inside an EventChain list."
|
|
@@ -553,7 +551,7 @@ class Component(BaseComponent, ABC):
|
|
|
553
551
|
# If the input is a callable, create an event chain.
|
|
554
552
|
elif isinstance(value, Callable):
|
|
555
553
|
result = call_event_fn(value, args_spec)
|
|
556
|
-
if isinstance(result,
|
|
554
|
+
if isinstance(result, ImmutableVar):
|
|
557
555
|
# Recursively call this function if the lambda returned an EventChain Var.
|
|
558
556
|
return self._create_event_chain(args_spec, result)
|
|
559
557
|
events = result
|
|
@@ -571,7 +569,7 @@ class Component(BaseComponent, ABC):
|
|
|
571
569
|
event_actions.update(e.event_actions)
|
|
572
570
|
|
|
573
571
|
# Return the event chain.
|
|
574
|
-
if isinstance(args_spec,
|
|
572
|
+
if isinstance(args_spec, ImmutableVar):
|
|
575
573
|
return EventChain(
|
|
576
574
|
events=events,
|
|
577
575
|
args_spec=None,
|
|
@@ -638,27 +636,6 @@ class Component(BaseComponent, ABC):
|
|
|
638
636
|
|
|
639
637
|
return _compile_component(self)
|
|
640
638
|
|
|
641
|
-
def _apply_theme(self, theme: Optional[Component]):
|
|
642
|
-
"""Apply the theme to this component.
|
|
643
|
-
|
|
644
|
-
Deprecated. Use add_style instead.
|
|
645
|
-
|
|
646
|
-
Args:
|
|
647
|
-
theme: The theme to apply.
|
|
648
|
-
"""
|
|
649
|
-
pass
|
|
650
|
-
|
|
651
|
-
def apply_theme(self, theme: Optional[Component]):
|
|
652
|
-
"""Apply a theme to the component and its children.
|
|
653
|
-
|
|
654
|
-
Args:
|
|
655
|
-
theme: The theme to apply.
|
|
656
|
-
"""
|
|
657
|
-
self._apply_theme(theme)
|
|
658
|
-
for child in self.children:
|
|
659
|
-
if isinstance(child, Component):
|
|
660
|
-
child.apply_theme(theme)
|
|
661
|
-
|
|
662
639
|
def _exclude_props(self) -> list[str]:
|
|
663
640
|
"""Props to exclude when adding the component props to the Tag.
|
|
664
641
|
|
|
@@ -692,9 +669,7 @@ class Component(BaseComponent, ABC):
|
|
|
692
669
|
# Add ref to element if `id` is not None.
|
|
693
670
|
ref = self.get_ref()
|
|
694
671
|
if ref is not None:
|
|
695
|
-
props["ref"] =
|
|
696
|
-
ref, _var_is_local=False, _var_is_string=False
|
|
697
|
-
)
|
|
672
|
+
props["ref"] = ImmutableVar.create(ref)
|
|
698
673
|
else:
|
|
699
674
|
props = props.copy()
|
|
700
675
|
|
|
@@ -768,22 +743,6 @@ class Component(BaseComponent, ABC):
|
|
|
768
743
|
from reflex.components.base.fragment import Fragment
|
|
769
744
|
from reflex.utils.exceptions import ComponentTypeError
|
|
770
745
|
|
|
771
|
-
# Translate deprecated props to new names.
|
|
772
|
-
new_prop_names = [
|
|
773
|
-
prop for prop in cls.get_props() if prop in ["type", "min", "max"]
|
|
774
|
-
]
|
|
775
|
-
for prop in new_prop_names:
|
|
776
|
-
under_prop = f"{prop}_"
|
|
777
|
-
if under_prop in props:
|
|
778
|
-
console.deprecate(
|
|
779
|
-
f"Underscore suffix for prop `{under_prop}`",
|
|
780
|
-
reason=f"for consistency. Use `{prop}` instead.",
|
|
781
|
-
deprecation_version="0.4.0",
|
|
782
|
-
removal_version="0.6.0",
|
|
783
|
-
dedupe=False,
|
|
784
|
-
)
|
|
785
|
-
props[prop] = props.pop(under_prop)
|
|
786
|
-
|
|
787
746
|
# Filter out None props
|
|
788
747
|
props = {key: value for key, value in props.items() if value is not None}
|
|
789
748
|
|
|
@@ -809,7 +768,7 @@ class Component(BaseComponent, ABC):
|
|
|
809
768
|
else (
|
|
810
769
|
Fragment.create(*child)
|
|
811
770
|
if isinstance(child, tuple)
|
|
812
|
-
else Bare.create(contents=
|
|
771
|
+
else Bare.create(contents=LiteralVar.create(child))
|
|
813
772
|
)
|
|
814
773
|
)
|
|
815
774
|
for child in children
|
|
@@ -900,17 +859,6 @@ class Component(BaseComponent, ABC):
|
|
|
900
859
|
new_style.update(component_style)
|
|
901
860
|
style_vars.append(component_style._var_data)
|
|
902
861
|
|
|
903
|
-
# 3. User-defined style from `Component.style`.
|
|
904
|
-
# Apply theme for retro-compatibility with deprecated _apply_theme API
|
|
905
|
-
if type(self)._apply_theme != Component._apply_theme:
|
|
906
|
-
console.deprecate(
|
|
907
|
-
f"{self.__class__.__name__}._apply_theme",
|
|
908
|
-
reason="use add_style instead",
|
|
909
|
-
deprecation_version="0.5.0",
|
|
910
|
-
removal_version="0.6.0",
|
|
911
|
-
)
|
|
912
|
-
self._apply_theme(theme)
|
|
913
|
-
|
|
914
862
|
# 4. style dict and css props passed to the component instance.
|
|
915
863
|
new_style.update(self.style)
|
|
916
864
|
style_vars.append(self.style._var_data)
|
|
@@ -934,9 +882,14 @@ class Component(BaseComponent, ABC):
|
|
|
934
882
|
Returns:
|
|
935
883
|
The dictionary of the component style as value and the style notation as key.
|
|
936
884
|
"""
|
|
937
|
-
if isinstance(self.style,
|
|
885
|
+
if isinstance(self.style, ImmutableVar):
|
|
938
886
|
return {"css": self.style}
|
|
939
|
-
|
|
887
|
+
emotion_style = format_as_emotion(self.style)
|
|
888
|
+
return (
|
|
889
|
+
{"css": LiteralVar.create(emotion_style)}
|
|
890
|
+
if emotion_style is not None
|
|
891
|
+
else {}
|
|
892
|
+
)
|
|
940
893
|
|
|
941
894
|
def render(self) -> Dict:
|
|
942
895
|
"""Render the component.
|
|
@@ -1045,8 +998,8 @@ class Component(BaseComponent, ABC):
|
|
|
1045
998
|
|
|
1046
999
|
@staticmethod
|
|
1047
1000
|
def _get_vars_from_event_triggers(
|
|
1048
|
-
event_triggers: dict[str, EventChain |
|
|
1049
|
-
) -> Iterator[tuple[str, list[
|
|
1001
|
+
event_triggers: dict[str, EventChain | ImmutableVar],
|
|
1002
|
+
) -> Iterator[tuple[str, list[ImmutableVar]]]:
|
|
1050
1003
|
"""Get the Vars associated with each event trigger.
|
|
1051
1004
|
|
|
1052
1005
|
Args:
|
|
@@ -1056,7 +1009,7 @@ class Component(BaseComponent, ABC):
|
|
|
1056
1009
|
tuple of (event_name, event_vars)
|
|
1057
1010
|
"""
|
|
1058
1011
|
for event_trigger, event in event_triggers.items():
|
|
1059
|
-
if isinstance(event,
|
|
1012
|
+
if isinstance(event, ImmutableVar):
|
|
1060
1013
|
yield event_trigger, [event]
|
|
1061
1014
|
elif isinstance(event, EventChain):
|
|
1062
1015
|
event_args = []
|
|
@@ -1065,7 +1018,7 @@ class Component(BaseComponent, ABC):
|
|
|
1065
1018
|
event_args.extend(args)
|
|
1066
1019
|
yield event_trigger, event_args
|
|
1067
1020
|
|
|
1068
|
-
def _get_vars(self, include_children: bool = False) -> list[
|
|
1021
|
+
def _get_vars(self, include_children: bool = False) -> list[ImmutableVar]:
|
|
1069
1022
|
"""Walk all Vars used in this component.
|
|
1070
1023
|
|
|
1071
1024
|
Args:
|
|
@@ -1085,16 +1038,20 @@ class Component(BaseComponent, ABC):
|
|
|
1085
1038
|
# Get Vars associated with component props.
|
|
1086
1039
|
for prop in self.get_props():
|
|
1087
1040
|
prop_var = getattr(self, prop)
|
|
1088
|
-
if isinstance(prop_var,
|
|
1041
|
+
if isinstance(prop_var, ImmutableVar):
|
|
1089
1042
|
vars.append(prop_var)
|
|
1090
1043
|
|
|
1091
1044
|
# Style keeps track of its own VarData instance, so embed in a temp Var that is yielded.
|
|
1092
|
-
if
|
|
1045
|
+
if (
|
|
1046
|
+
isinstance(self.style, dict)
|
|
1047
|
+
and self.style
|
|
1048
|
+
or isinstance(self.style, ImmutableVar)
|
|
1049
|
+
):
|
|
1093
1050
|
vars.append(
|
|
1094
|
-
|
|
1051
|
+
ImmutableVar(
|
|
1095
1052
|
_var_name="style",
|
|
1096
1053
|
_var_type=str,
|
|
1097
|
-
_var_data=self.style._var_data,
|
|
1054
|
+
_var_data=VarData.merge(self.style._var_data),
|
|
1098
1055
|
)
|
|
1099
1056
|
)
|
|
1100
1057
|
|
|
@@ -1109,14 +1066,12 @@ class Component(BaseComponent, ABC):
|
|
|
1109
1066
|
self.autofocus,
|
|
1110
1067
|
*self.custom_attrs.values(),
|
|
1111
1068
|
):
|
|
1112
|
-
if isinstance(comp_prop,
|
|
1069
|
+
if isinstance(comp_prop, ImmutableVar):
|
|
1113
1070
|
vars.append(comp_prop)
|
|
1114
1071
|
elif isinstance(comp_prop, str):
|
|
1115
1072
|
# Collapse VarData encoded in f-strings.
|
|
1116
|
-
var =
|
|
1117
|
-
|
|
1118
|
-
)
|
|
1119
|
-
if var._var_data is not None:
|
|
1073
|
+
var = LiteralVar.create(comp_prop)
|
|
1074
|
+
if var._get_all_var_data() is not None:
|
|
1120
1075
|
vars.append(var)
|
|
1121
1076
|
|
|
1122
1077
|
# Get Vars associated with children.
|
|
@@ -1124,7 +1079,8 @@ class Component(BaseComponent, ABC):
|
|
|
1124
1079
|
for child in self.children:
|
|
1125
1080
|
if not isinstance(child, Component):
|
|
1126
1081
|
continue
|
|
1127
|
-
|
|
1082
|
+
child_vars = child._get_vars(include_children=include_children)
|
|
1083
|
+
vars.extend(child_vars)
|
|
1128
1084
|
|
|
1129
1085
|
return vars
|
|
1130
1086
|
|
|
@@ -1139,7 +1095,7 @@ class Component(BaseComponent, ABC):
|
|
|
1139
1095
|
for event in trigger.events:
|
|
1140
1096
|
if event.handler.state_full_name:
|
|
1141
1097
|
return True
|
|
1142
|
-
elif isinstance(trigger,
|
|
1098
|
+
elif isinstance(trigger, ImmutableVar) and trigger._var_state:
|
|
1143
1099
|
return True
|
|
1144
1100
|
return False
|
|
1145
1101
|
|
|
@@ -1329,13 +1285,13 @@ class Component(BaseComponent, ABC):
|
|
|
1329
1285
|
|
|
1330
1286
|
other_imports = []
|
|
1331
1287
|
user_hooks = self._get_hooks()
|
|
1332
|
-
|
|
1333
|
-
user_hooks
|
|
1334
|
-
and isinstance(user_hooks,
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
other_imports.append(
|
|
1288
|
+
user_hooks_data = (
|
|
1289
|
+
VarData.merge(user_hooks._get_all_var_data())
|
|
1290
|
+
if user_hooks is not None and isinstance(user_hooks, ImmutableVar)
|
|
1291
|
+
else None
|
|
1292
|
+
)
|
|
1293
|
+
if user_hooks_data is not None:
|
|
1294
|
+
other_imports.append(user_hooks_data.imports)
|
|
1339
1295
|
other_imports.extend(
|
|
1340
1296
|
hook_imports for hook_imports in self._get_added_hooks().values()
|
|
1341
1297
|
)
|
|
@@ -1358,9 +1314,16 @@ class Component(BaseComponent, ABC):
|
|
|
1358
1314
|
event_imports = Imports.EVENTS if self.event_triggers else {}
|
|
1359
1315
|
|
|
1360
1316
|
# Collect imports from Vars used directly by this component.
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1317
|
+
var_datas = [var._get_all_var_data() for var in self._get_vars()]
|
|
1318
|
+
var_imports: List[ImmutableParsedImportDict] = list(
|
|
1319
|
+
map(
|
|
1320
|
+
lambda var_data: var_data.imports,
|
|
1321
|
+
filter(
|
|
1322
|
+
None,
|
|
1323
|
+
var_datas,
|
|
1324
|
+
),
|
|
1325
|
+
)
|
|
1326
|
+
)
|
|
1364
1327
|
|
|
1365
1328
|
added_import_dicts: list[ParsedImportDict] = []
|
|
1366
1329
|
for clz in self._iter_parent_classes_with_method("add_imports"):
|
|
@@ -1407,9 +1370,9 @@ class Component(BaseComponent, ABC):
|
|
|
1407
1370
|
on_mount = self.event_triggers.get(EventTriggers.ON_MOUNT, None)
|
|
1408
1371
|
on_unmount = self.event_triggers.get(EventTriggers.ON_UNMOUNT, None)
|
|
1409
1372
|
if on_mount is not None:
|
|
1410
|
-
on_mount =
|
|
1373
|
+
on_mount = str(LiteralVar.create(on_mount)) + "()"
|
|
1411
1374
|
if on_unmount is not None:
|
|
1412
|
-
on_unmount =
|
|
1375
|
+
on_unmount = str(LiteralVar.create(on_unmount)) + "()"
|
|
1413
1376
|
if on_mount is not None or on_unmount is not None:
|
|
1414
1377
|
return f"""
|
|
1415
1378
|
useEffect(() => {{
|
|
@@ -1427,7 +1390,7 @@ class Component(BaseComponent, ABC):
|
|
|
1427
1390
|
"""
|
|
1428
1391
|
ref = self.get_ref()
|
|
1429
1392
|
if ref is not None:
|
|
1430
|
-
return f"const {ref} = useRef(null); {str(
|
|
1393
|
+
return f"const {ref} = useRef(null); {str(ImmutableVar.create_safe(ref).as_ref())} = {ref};"
|
|
1431
1394
|
|
|
1432
1395
|
def _get_vars_hooks(self) -> dict[str, None]:
|
|
1433
1396
|
"""Get the hooks required by vars referenced in this component.
|
|
@@ -1437,8 +1400,13 @@ class Component(BaseComponent, ABC):
|
|
|
1437
1400
|
"""
|
|
1438
1401
|
vars_hooks = {}
|
|
1439
1402
|
for var in self._get_vars():
|
|
1440
|
-
|
|
1441
|
-
|
|
1403
|
+
var_data = var._get_all_var_data()
|
|
1404
|
+
if var_data is not None:
|
|
1405
|
+
vars_hooks.update(
|
|
1406
|
+
var_data.hooks
|
|
1407
|
+
if isinstance(var_data.hooks, dict)
|
|
1408
|
+
else {k: None for k in var_data.hooks}
|
|
1409
|
+
)
|
|
1442
1410
|
return vars_hooks
|
|
1443
1411
|
|
|
1444
1412
|
def _get_events_hooks(self) -> dict[str, None]:
|
|
@@ -1485,13 +1453,14 @@ class Component(BaseComponent, ABC):
|
|
|
1485
1453
|
"""
|
|
1486
1454
|
code = {}
|
|
1487
1455
|
|
|
1488
|
-
def extract_var_hooks(hook:
|
|
1456
|
+
def extract_var_hooks(hook: ImmutableVar):
|
|
1489
1457
|
_imports = {}
|
|
1490
|
-
|
|
1491
|
-
|
|
1458
|
+
var_data = VarData.merge(hook._get_all_var_data())
|
|
1459
|
+
if var_data is not None:
|
|
1460
|
+
for sub_hook in var_data.hooks:
|
|
1492
1461
|
code[sub_hook] = {}
|
|
1493
|
-
if
|
|
1494
|
-
_imports =
|
|
1462
|
+
if var_data.imports:
|
|
1463
|
+
_imports = var_data.imports
|
|
1495
1464
|
if str(hook) in code:
|
|
1496
1465
|
code[str(hook)] = imports.merge_imports(code[str(hook)], _imports)
|
|
1497
1466
|
else:
|
|
@@ -1501,10 +1470,11 @@ class Component(BaseComponent, ABC):
|
|
|
1501
1470
|
# the order of the hooks in the final output)
|
|
1502
1471
|
for clz in reversed(tuple(self._iter_parent_classes_with_method("add_hooks"))):
|
|
1503
1472
|
for hook in clz.add_hooks(self):
|
|
1504
|
-
if isinstance(hook,
|
|
1473
|
+
if isinstance(hook, ImmutableVar):
|
|
1505
1474
|
extract_var_hooks(hook)
|
|
1506
1475
|
else:
|
|
1507
1476
|
code[hook] = {}
|
|
1477
|
+
|
|
1508
1478
|
return code
|
|
1509
1479
|
|
|
1510
1480
|
def _get_hooks(self) -> str | None:
|
|
@@ -1561,7 +1531,7 @@ class Component(BaseComponent, ABC):
|
|
|
1561
1531
|
The ref name.
|
|
1562
1532
|
"""
|
|
1563
1533
|
# do not create a ref if the id is dynamic or unspecified
|
|
1564
|
-
if self.id is None or isinstance(self.id,
|
|
1534
|
+
if self.id is None or isinstance(self.id, ImmutableVar):
|
|
1565
1535
|
return None
|
|
1566
1536
|
return format.format_ref(self.id)
|
|
1567
1537
|
|
|
@@ -1707,7 +1677,7 @@ class CustomComponent(Component):
|
|
|
1707
1677
|
|
|
1708
1678
|
# Handle subclasses of Base.
|
|
1709
1679
|
if isinstance(value, Base):
|
|
1710
|
-
base_value =
|
|
1680
|
+
base_value = LiteralVar.create(value)
|
|
1711
1681
|
|
|
1712
1682
|
# Track hooks and imports associated with Component instances.
|
|
1713
1683
|
if base_value is not None and isinstance(value, Component):
|
|
@@ -1721,7 +1691,7 @@ class CustomComponent(Component):
|
|
|
1721
1691
|
else:
|
|
1722
1692
|
value = base_value
|
|
1723
1693
|
else:
|
|
1724
|
-
value =
|
|
1694
|
+
value = LiteralVar.create(value)
|
|
1725
1695
|
|
|
1726
1696
|
# Set the prop.
|
|
1727
1697
|
self.props[format.to_camel_case(key)] = value
|
|
@@ -1800,23 +1770,23 @@ class CustomComponent(Component):
|
|
|
1800
1770
|
"""
|
|
1801
1771
|
return super()._render(props=self.props)
|
|
1802
1772
|
|
|
1803
|
-
def get_prop_vars(self) -> List[
|
|
1773
|
+
def get_prop_vars(self) -> List[ImmutableVar]:
|
|
1804
1774
|
"""Get the prop vars.
|
|
1805
1775
|
|
|
1806
1776
|
Returns:
|
|
1807
1777
|
The prop vars.
|
|
1808
1778
|
"""
|
|
1809
1779
|
return [
|
|
1810
|
-
|
|
1780
|
+
ImmutableVar(
|
|
1811
1781
|
_var_name=name,
|
|
1812
1782
|
_var_type=(
|
|
1813
1783
|
prop._var_type if types._isinstance(prop, Var) else type(prop)
|
|
1814
1784
|
),
|
|
1815
|
-
)
|
|
1785
|
+
).guess_type()
|
|
1816
1786
|
for name, prop in self.props.items()
|
|
1817
1787
|
]
|
|
1818
1788
|
|
|
1819
|
-
def _get_vars(self, include_children: bool = False) -> list[
|
|
1789
|
+
def _get_vars(self, include_children: bool = False) -> list[ImmutableVar]:
|
|
1820
1790
|
"""Walk all Vars used in this component.
|
|
1821
1791
|
|
|
1822
1792
|
Args:
|
|
@@ -1825,9 +1795,11 @@ class CustomComponent(Component):
|
|
|
1825
1795
|
Returns:
|
|
1826
1796
|
Each var referenced by the component (props, styles, event handlers).
|
|
1827
1797
|
"""
|
|
1828
|
-
return
|
|
1829
|
-
|
|
1830
|
-
|
|
1798
|
+
return (
|
|
1799
|
+
super()._get_vars(include_children=include_children)
|
|
1800
|
+
+ [prop for prop in self.props.values() if isinstance(prop, ImmutableVar)]
|
|
1801
|
+
+ self.get_component(self)._get_vars(include_children=include_children)
|
|
1802
|
+
)
|
|
1831
1803
|
|
|
1832
1804
|
@lru_cache(maxsize=None) # noqa
|
|
1833
1805
|
def get_component(self) -> Component:
|
|
@@ -1981,7 +1953,7 @@ class StatefulComponent(BaseComponent):
|
|
|
1981
1953
|
if not should_memoize:
|
|
1982
1954
|
# Determine if any Vars have associated data.
|
|
1983
1955
|
for prop_var in component._get_vars():
|
|
1984
|
-
if prop_var.
|
|
1956
|
+
if prop_var._get_all_var_data():
|
|
1985
1957
|
should_memoize = True
|
|
1986
1958
|
break
|
|
1987
1959
|
|
|
@@ -1996,7 +1968,7 @@ class StatefulComponent(BaseComponent):
|
|
|
1996
1968
|
should_memoize = True
|
|
1997
1969
|
break
|
|
1998
1970
|
child = cls._child_var(child)
|
|
1999
|
-
if isinstance(child,
|
|
1971
|
+
if isinstance(child, ImmutableVar) and child._get_all_var_data():
|
|
2000
1972
|
should_memoize = True
|
|
2001
1973
|
break
|
|
2002
1974
|
|
|
@@ -2152,7 +2124,7 @@ class StatefulComponent(BaseComponent):
|
|
|
2152
2124
|
def _get_memoized_event_triggers(
|
|
2153
2125
|
cls,
|
|
2154
2126
|
component: Component,
|
|
2155
|
-
) -> dict[str, tuple[
|
|
2127
|
+
) -> dict[str, tuple[ImmutableVar, str]]:
|
|
2156
2128
|
"""Memoize event handler functions with useCallback to avoid unnecessary re-renders.
|
|
2157
2129
|
|
|
2158
2130
|
Args:
|
|
@@ -2176,9 +2148,7 @@ class StatefulComponent(BaseComponent):
|
|
|
2176
2148
|
|
|
2177
2149
|
# Get the actual EventSpec and render it.
|
|
2178
2150
|
event = component.event_triggers[event_trigger]
|
|
2179
|
-
rendered_chain =
|
|
2180
|
-
if isinstance(rendered_chain, str):
|
|
2181
|
-
rendered_chain = rendered_chain.strip("{}")
|
|
2151
|
+
rendered_chain = str(LiteralVar.create(event))
|
|
2182
2152
|
|
|
2183
2153
|
# Hash the rendered EventChain to get a deterministic function name.
|
|
2184
2154
|
chain_hash = md5(str(rendered_chain).encode("utf-8")).hexdigest()
|
|
@@ -2187,12 +2157,13 @@ class StatefulComponent(BaseComponent):
|
|
|
2187
2157
|
# Calculate Var dependencies accessed by the handler for useCallback dep array.
|
|
2188
2158
|
var_deps = ["addEvents", "Event"]
|
|
2189
2159
|
for arg in event_args:
|
|
2190
|
-
|
|
2160
|
+
var_data = arg._get_all_var_data()
|
|
2161
|
+
if var_data is None:
|
|
2191
2162
|
continue
|
|
2192
|
-
for hook in
|
|
2163
|
+
for hook in var_data.hooks:
|
|
2193
2164
|
var_deps.extend(cls._get_hook_deps(hook))
|
|
2194
2165
|
memo_var_data = VarData.merge(
|
|
2195
|
-
*[var.
|
|
2166
|
+
*[var._get_all_var_data() for var in event_args],
|
|
2196
2167
|
VarData(
|
|
2197
2168
|
imports={"react": [ImportVar(tag="useCallback")]},
|
|
2198
2169
|
),
|
|
@@ -2200,7 +2171,7 @@ class StatefulComponent(BaseComponent):
|
|
|
2200
2171
|
|
|
2201
2172
|
# Store the memoized function name and hook code for this event trigger.
|
|
2202
2173
|
trigger_memo[event_trigger] = (
|
|
2203
|
-
|
|
2174
|
+
ImmutableVar.create_safe(memo_name)._replace(
|
|
2204
2175
|
_var_type=EventChain, merge_var_data=memo_var_data
|
|
2205
2176
|
),
|
|
2206
2177
|
f"const {memo_name} = useCallback({rendered_chain}, [{', '.join(var_deps)}])",
|