reflex 0.7.1a4__py3-none-any.whl → 0.7.2a1__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/utils/context.js.jinja2 +8 -8
- reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +3 -3
- reflex/admin.py +1 -2
- reflex/app.py +46 -49
- reflex/app_mixins/lifespan.py +2 -2
- reflex/app_mixins/middleware.py +1 -2
- reflex/assets.py +1 -2
- reflex/base.py +2 -2
- reflex/compiler/compiler.py +51 -16
- reflex/compiler/utils.py +4 -13
- reflex/components/base/app_wrap.pyi +7 -7
- reflex/components/base/bare.py +3 -3
- reflex/components/base/body.pyi +7 -7
- reflex/components/base/document.py +1 -3
- reflex/components/base/document.pyi +32 -32
- reflex/components/base/error_boundary.py +2 -4
- reflex/components/base/error_boundary.pyi +11 -13
- reflex/components/base/fragment.pyi +7 -7
- reflex/components/base/head.pyi +13 -13
- reflex/components/base/link.pyi +22 -22
- reflex/components/base/meta.py +5 -7
- reflex/components/base/meta.pyi +40 -40
- reflex/components/base/script.pyi +11 -14
- reflex/components/base/strict_mode.pyi +7 -7
- reflex/components/component.py +188 -113
- reflex/components/core/auto_scroll.py +8 -1
- reflex/components/core/auto_scroll.pyi +183 -210
- reflex/components/core/banner.py +2 -4
- reflex/components/core/banner.pyi +390 -444
- reflex/components/core/breakpoints.py +5 -5
- reflex/components/core/client_side_routing.pyi +14 -14
- reflex/components/core/clipboard.py +4 -4
- reflex/components/core/clipboard.pyi +12 -14
- reflex/components/core/cond.py +17 -25
- reflex/components/core/debounce.py +3 -3
- reflex/components/core/debounce.pyi +14 -14
- reflex/components/core/foreach.py +7 -2
- reflex/components/core/html.py +1 -3
- reflex/components/core/html.pyi +184 -213
- reflex/components/core/match.py +15 -19
- reflex/components/core/sticky.pyi +930 -1078
- reflex/components/core/upload.py +4 -4
- reflex/components/core/upload.pyi +62 -62
- reflex/components/datadisplay/code.py +6 -6
- reflex/components/datadisplay/code.pyi +1159 -1165
- reflex/components/datadisplay/dataeditor.py +49 -49
- reflex/components/datadisplay/dataeditor.pyi +95 -123
- reflex/components/datadisplay/logo.py +1 -3
- reflex/components/datadisplay/shiki_code_block.py +8 -10
- reflex/components/datadisplay/shiki_code_block.pyi +1678 -1720
- reflex/components/el/element.pyi +7 -7
- reflex/components/el/elements/base.pyi +183 -210
- reflex/components/el/elements/forms.py +23 -23
- reflex/components/el/elements/forms.pyi +2571 -2933
- reflex/components/el/elements/inline.py +4 -4
- reflex/components/el/elements/inline.pyi +5191 -5953
- reflex/components/el/elements/media.py +47 -47
- reflex/components/el/elements/media.pyi +4802 -5500
- reflex/components/el/elements/metadata.py +1 -3
- reflex/components/el/elements/metadata.pyi +782 -896
- reflex/components/el/elements/other.pyi +1278 -1467
- reflex/components/el/elements/scripts.pyi +580 -667
- reflex/components/el/elements/sectioning.pyi +2761 -3166
- reflex/components/el/elements/tables.pyi +1840 -2119
- reflex/components/el/elements/typography.pyi +2772 -3179
- reflex/components/gridjs/datatable.py +7 -7
- reflex/components/gridjs/datatable.pyi +19 -19
- reflex/components/lucide/icon.pyi +21 -21
- reflex/components/markdown/markdown.py +2 -2
- reflex/components/markdown/markdown.pyi +9 -9
- reflex/components/moment/moment.py +11 -12
- reflex/components/moment/moment.pyi +44 -47
- reflex/components/next/base.pyi +7 -7
- reflex/components/next/image.py +3 -3
- reflex/components/next/image.pyi +19 -21
- reflex/components/next/link.pyi +9 -9
- reflex/components/next/video.py +1 -3
- reflex/components/next/video.pyi +9 -9
- reflex/components/plotly/plotly.py +22 -45
- reflex/components/plotly/plotly.pyi +164 -164
- reflex/components/radix/primitives/accordion.py +14 -14
- reflex/components/radix/primitives/accordion.pyi +439 -487
- reflex/components/radix/primitives/base.py +1 -3
- reflex/components/radix/primitives/base.pyi +15 -15
- reflex/components/radix/primitives/drawer.py +3 -3
- reflex/components/radix/primitives/drawer.pyi +110 -116
- reflex/components/radix/primitives/form.py +1 -1
- reflex/components/radix/primitives/form.pyi +668 -752
- reflex/components/radix/primitives/progress.py +6 -6
- reflex/components/radix/primitives/progress.pyi +225 -243
- reflex/components/radix/primitives/slider.py +6 -6
- reflex/components/radix/primitives/slider.pyi +52 -55
- reflex/components/radix/themes/base.py +3 -6
- reflex/components/radix/themes/base.pyi +197 -303
- reflex/components/radix/themes/color_mode.py +5 -5
- reflex/components/radix/themes/color_mode.pyi +366 -436
- reflex/components/radix/themes/components/alert_dialog.pyi +229 -262
- reflex/components/radix/themes/components/aspect_ratio.py +1 -3
- reflex/components/radix/themes/components/aspect_ratio.pyi +8 -8
- reflex/components/radix/themes/components/avatar.pyi +79 -94
- reflex/components/radix/themes/components/badge.pyi +252 -295
- reflex/components/radix/themes/components/button.pyi +269 -314
- reflex/components/radix/themes/components/callout.py +2 -2
- reflex/components/radix/themes/components/callout.pyi +1116 -1290
- reflex/components/radix/themes/components/card.pyi +194 -229
- reflex/components/radix/themes/components/checkbox.pyi +243 -278
- reflex/components/radix/themes/components/checkbox_cards.py +3 -7
- reflex/components/radix/themes/components/checkbox_cards.pyi +101 -135
- reflex/components/radix/themes/components/checkbox_group.py +2 -2
- reflex/components/radix/themes/components/checkbox_group.pyi +83 -96
- reflex/components/radix/themes/components/context_menu.py +18 -15
- reflex/components/radix/themes/components/context_menu.pyi +408 -458
- reflex/components/radix/themes/components/data_list.pyi +122 -147
- reflex/components/radix/themes/components/dialog.pyi +231 -264
- reflex/components/radix/themes/components/dropdown_menu.py +16 -13
- reflex/components/radix/themes/components/dropdown_menu.pyi +223 -246
- reflex/components/radix/themes/components/hover_card.py +2 -2
- reflex/components/radix/themes/components/hover_card.pyi +237 -282
- reflex/components/radix/themes/components/icon_button.pyi +269 -314
- reflex/components/radix/themes/components/inset.py +8 -8
- reflex/components/radix/themes/components/inset.pyi +232 -292
- reflex/components/radix/themes/components/popover.py +2 -2
- reflex/components/radix/themes/components/popover.pyi +229 -271
- reflex/components/radix/themes/components/progress.pyi +80 -96
- reflex/components/radix/themes/components/radio.pyi +73 -86
- reflex/components/radix/themes/components/radio_cards.py +4 -8
- reflex/components/radix/themes/components/radio_cards.pyi +117 -154
- reflex/components/radix/themes/components/radio_group.py +3 -3
- reflex/components/radix/themes/components/radio_group.pyi +250 -291
- reflex/components/radix/themes/components/scroll_area.pyi +14 -20
- reflex/components/radix/themes/components/segmented_control.py +6 -6
- reflex/components/radix/themes/components/segmented_control.pyi +89 -108
- reflex/components/radix/themes/components/select.py +7 -7
- reflex/components/radix/themes/components/select.pyi +376 -444
- reflex/components/radix/themes/components/separator.pyi +79 -93
- reflex/components/radix/themes/components/skeleton.pyi +32 -26
- reflex/components/radix/themes/components/slider.py +8 -8
- reflex/components/radix/themes/components/slider.pyi +99 -122
- reflex/components/radix/themes/components/spinner.pyi +12 -19
- reflex/components/radix/themes/components/switch.pyi +84 -99
- reflex/components/radix/themes/components/table.py +9 -9
- reflex/components/radix/themes/components/table.pyi +1440 -1794
- reflex/components/radix/themes/components/tabs.py +4 -4
- reflex/components/radix/themes/components/tabs.pyi +120 -132
- reflex/components/radix/themes/components/text_area.pyi +281 -331
- reflex/components/radix/themes/components/text_field.py +2 -2
- reflex/components/radix/themes/components/text_field.pyi +639 -734
- reflex/components/radix/themes/components/tooltip.py +6 -6
- reflex/components/radix/themes/components/tooltip.pyi +34 -43
- reflex/components/radix/themes/layout/base.pyi +85 -182
- reflex/components/radix/themes/layout/box.pyi +183 -210
- reflex/components/radix/themes/layout/center.pyi +225 -286
- reflex/components/radix/themes/layout/container.pyi +191 -224
- reflex/components/radix/themes/layout/flex.py +2 -2
- reflex/components/radix/themes/layout/flex.pyi +225 -286
- reflex/components/radix/themes/layout/grid.py +2 -2
- reflex/components/radix/themes/layout/grid.pyi +245 -315
- reflex/components/radix/themes/layout/list.py +2 -2
- reflex/components/radix/themes/layout/list.pyi +712 -815
- reflex/components/radix/themes/layout/section.pyi +187 -221
- reflex/components/radix/themes/layout/spacer.pyi +225 -286
- reflex/components/radix/themes/layout/stack.pyi +625 -768
- reflex/components/radix/themes/typography/blockquote.pyi +257 -299
- reflex/components/radix/themes/typography/code.pyi +259 -304
- reflex/components/radix/themes/typography/heading.pyi +272 -324
- reflex/components/radix/themes/typography/link.pyi +302 -358
- reflex/components/radix/themes/typography/text.pyi +1669 -1945
- reflex/components/react_player/audio.pyi +20 -22
- reflex/components/react_player/react_player.pyi +19 -19
- reflex/components/react_player/video.pyi +20 -22
- reflex/components/recharts/cartesian.py +100 -97
- reflex/components/recharts/cartesian.pyi +891 -1007
- reflex/components/recharts/charts.py +42 -42
- reflex/components/recharts/charts.pyi +212 -249
- reflex/components/recharts/general.py +22 -21
- reflex/components/recharts/general.pyi +198 -223
- reflex/components/recharts/polar.py +42 -45
- reflex/components/recharts/polar.pyi +254 -288
- reflex/components/recharts/recharts.pyi +13 -13
- reflex/components/sonner/toast.py +20 -20
- reflex/components/sonner/toast.pyi +58 -61
- reflex/components/suneditor/editor.py +9 -9
- reflex/components/suneditor/editor.pyi +78 -83
- reflex/components/tags/cond_tag.py +2 -2
- reflex/components/tags/iter_tag.py +10 -14
- reflex/components/tags/match_tag.py +2 -2
- reflex/components/tags/tag.py +10 -10
- reflex/config.py +36 -35
- reflex/constants/__init__.py +56 -53
- reflex/custom_components/custom_components.py +6 -7
- reflex/event.py +38 -42
- reflex/experimental/client_state.py +2 -4
- reflex/experimental/layout.py +2 -2
- reflex/experimental/layout.pyi +579 -663
- reflex/istate/data.py +4 -5
- reflex/middleware/hydrate_middleware.py +2 -2
- reflex/middleware/middleware.py +2 -2
- reflex/model.py +3 -5
- reflex/page.py +2 -2
- reflex/reflex.py +9 -10
- reflex/state.py +77 -49
- reflex/style.py +9 -3
- reflex/testing.py +21 -24
- reflex/utils/console.py +1 -1
- reflex/utils/decorator.py +26 -1
- reflex/utils/exec.py +6 -11
- reflex/utils/export.py +2 -3
- reflex/utils/format.py +4 -4
- reflex/utils/imports.py +12 -12
- reflex/utils/prerequisites.py +35 -84
- reflex/utils/processes.py +5 -5
- reflex/utils/pyi_generator.py +33 -22
- reflex/utils/serializers.py +60 -15
- reflex/utils/types.py +237 -56
- reflex/vars/base.py +122 -72
- reflex/vars/datetime.py +2 -2
- reflex/vars/function.py +52 -55
- reflex/vars/number.py +59 -5
- reflex/vars/object.py +57 -26
- reflex/vars/sequence.py +983 -958
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/METADATA +3 -6
- reflex-0.7.2a1.dist-info/RECORD +405 -0
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/WHEEL +1 -1
- reflex-0.7.1a4.dist-info/RECORD +0 -405
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/LICENSE +0 -0
- {reflex-0.7.1a4.dist-info → reflex-0.7.2a1.dist-info}/entry_points.txt +0 -0
reflex/components/component.py
CHANGED
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import copy
|
|
6
6
|
import dataclasses
|
|
7
|
+
import functools
|
|
7
8
|
import inspect
|
|
8
9
|
import typing
|
|
9
10
|
from abc import ABC, abstractmethod
|
|
@@ -14,19 +15,19 @@ from typing import (
|
|
|
14
15
|
Any,
|
|
15
16
|
Callable,
|
|
16
17
|
ClassVar,
|
|
17
|
-
Dict,
|
|
18
18
|
Iterator,
|
|
19
19
|
List,
|
|
20
|
-
Optional,
|
|
21
20
|
Sequence,
|
|
22
21
|
Set,
|
|
23
22
|
Type,
|
|
23
|
+
TypeVar,
|
|
24
24
|
Union,
|
|
25
25
|
get_args,
|
|
26
26
|
get_origin,
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
import pydantic.v1
|
|
30
|
+
import pydantic.v1.fields
|
|
30
31
|
|
|
31
32
|
import reflex.state
|
|
32
33
|
from reflex.base import Base
|
|
@@ -54,7 +55,7 @@ from reflex.event import (
|
|
|
54
55
|
no_args_event_spec,
|
|
55
56
|
)
|
|
56
57
|
from reflex.style import Style, format_as_emotion
|
|
57
|
-
from reflex.utils import format, imports, types
|
|
58
|
+
from reflex.utils import console, format, imports, types
|
|
58
59
|
from reflex.utils.imports import ImportDict, ImportVar, ParsedImportDict, parse_imports
|
|
59
60
|
from reflex.vars import VarData
|
|
60
61
|
from reflex.vars.base import (
|
|
@@ -76,19 +77,19 @@ class BaseComponent(Base, ABC):
|
|
|
76
77
|
"""
|
|
77
78
|
|
|
78
79
|
# The children nested within the component.
|
|
79
|
-
children:
|
|
80
|
+
children: list[BaseComponent] = pydantic.v1.Field(default_factory=list)
|
|
80
81
|
|
|
81
82
|
# The library that the component is based on.
|
|
82
|
-
library:
|
|
83
|
+
library: str | None = pydantic.v1.Field(default_factory=lambda: None)
|
|
83
84
|
|
|
84
85
|
# List here the non-react dependency needed by `library`
|
|
85
|
-
lib_dependencies:
|
|
86
|
+
lib_dependencies: list[str] = pydantic.v1.Field(default_factory=list)
|
|
86
87
|
|
|
87
88
|
# List here the dependencies that need to be transpiled by Next.js
|
|
88
|
-
transpile_packages:
|
|
89
|
+
transpile_packages: list[str] = pydantic.v1.Field(default_factory=list)
|
|
89
90
|
|
|
90
91
|
# The tag to use when rendering the component.
|
|
91
|
-
tag:
|
|
92
|
+
tag: str | None = pydantic.v1.Field(default_factory=lambda: None)
|
|
92
93
|
|
|
93
94
|
@abstractmethod
|
|
94
95
|
def render(self) -> dict:
|
|
@@ -175,13 +176,23 @@ def evaluate_style_namespaces(style: ComponentStyle) -> dict:
|
|
|
175
176
|
|
|
176
177
|
|
|
177
178
|
# Map from component to styling.
|
|
178
|
-
ComponentStyle =
|
|
179
|
-
|
|
180
|
-
]
|
|
181
|
-
ComponentChild = Union[types.PrimitiveType, Var, BaseComponent]
|
|
179
|
+
ComponentStyle = dict[str | Type[BaseComponent] | Callable | ComponentNamespace, Any]
|
|
180
|
+
ComponentChild = types.PrimitiveType | Var | BaseComponent
|
|
182
181
|
ComponentChildTypes = (*types.PrimitiveTypes, Var, BaseComponent)
|
|
183
182
|
|
|
184
183
|
|
|
184
|
+
def _satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
|
|
185
|
+
return types._isinstance(
|
|
186
|
+
obj,
|
|
187
|
+
type_hint,
|
|
188
|
+
nested=1,
|
|
189
|
+
treat_var_as_type=True,
|
|
190
|
+
treat_mutable_obj_as_immutable=(
|
|
191
|
+
isinstance(obj, Var) and not isinstance(obj, LiteralVar)
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
|
|
185
196
|
def satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
|
|
186
197
|
"""Check if an object satisfies a type hint.
|
|
187
198
|
|
|
@@ -192,7 +203,23 @@ def satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
|
|
|
192
203
|
Returns:
|
|
193
204
|
Whether the object satisfies the type hint.
|
|
194
205
|
"""
|
|
195
|
-
|
|
206
|
+
if _satisfies_type_hint(obj, type_hint):
|
|
207
|
+
return True
|
|
208
|
+
if _satisfies_type_hint(obj, type_hint | None):
|
|
209
|
+
obj = (
|
|
210
|
+
obj
|
|
211
|
+
if not isinstance(obj, Var)
|
|
212
|
+
else (obj._var_value if isinstance(obj, LiteralVar) else obj)
|
|
213
|
+
)
|
|
214
|
+
console.deprecate(
|
|
215
|
+
"implicit-none-for-component-fields",
|
|
216
|
+
reason="Passing Vars with possible None values to component fields not explicitly marked as Optional is deprecated. "
|
|
217
|
+
+ f"Passed {obj!s} of type {type(obj) if not isinstance(obj, Var) else obj._var_type} to {type_hint}.",
|
|
218
|
+
deprecation_version="0.7.2",
|
|
219
|
+
removal_version="0.8.0",
|
|
220
|
+
)
|
|
221
|
+
return True
|
|
222
|
+
return False
|
|
196
223
|
|
|
197
224
|
|
|
198
225
|
def _components_from(
|
|
@@ -214,56 +241,81 @@ def _components_from(
|
|
|
214
241
|
return ()
|
|
215
242
|
|
|
216
243
|
|
|
244
|
+
DEFAULT_TRIGGERS: dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]] = {
|
|
245
|
+
EventTriggers.ON_FOCUS: no_args_event_spec,
|
|
246
|
+
EventTriggers.ON_BLUR: no_args_event_spec,
|
|
247
|
+
EventTriggers.ON_CLICK: no_args_event_spec,
|
|
248
|
+
EventTriggers.ON_CONTEXT_MENU: no_args_event_spec,
|
|
249
|
+
EventTriggers.ON_DOUBLE_CLICK: no_args_event_spec,
|
|
250
|
+
EventTriggers.ON_MOUSE_DOWN: no_args_event_spec,
|
|
251
|
+
EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
|
|
252
|
+
EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
|
|
253
|
+
EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
|
|
254
|
+
EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
|
|
255
|
+
EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
|
|
256
|
+
EventTriggers.ON_MOUSE_UP: no_args_event_spec,
|
|
257
|
+
EventTriggers.ON_SCROLL: no_args_event_spec,
|
|
258
|
+
EventTriggers.ON_MOUNT: no_args_event_spec,
|
|
259
|
+
EventTriggers.ON_UNMOUNT: no_args_event_spec,
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
T = TypeVar("T", bound="Component")
|
|
263
|
+
|
|
264
|
+
|
|
217
265
|
class Component(BaseComponent, ABC):
|
|
218
266
|
"""A component with style, event trigger and other props."""
|
|
219
267
|
|
|
220
268
|
# The style of the component.
|
|
221
|
-
style: Style = Style
|
|
269
|
+
style: Style = pydantic.v1.Field(default_factory=Style)
|
|
222
270
|
|
|
223
271
|
# A mapping from event triggers to event chains.
|
|
224
|
-
event_triggers:
|
|
272
|
+
event_triggers: dict[str, EventChain | Var] = pydantic.v1.Field(
|
|
273
|
+
default_factory=dict
|
|
274
|
+
)
|
|
225
275
|
|
|
226
276
|
# The alias for the tag.
|
|
227
|
-
alias:
|
|
277
|
+
alias: str | None = pydantic.v1.Field(default_factory=lambda: None)
|
|
228
278
|
|
|
229
279
|
# Whether the import is default or named.
|
|
230
|
-
is_default:
|
|
280
|
+
is_default: bool | None = pydantic.v1.Field(default_factory=lambda: False)
|
|
231
281
|
|
|
232
282
|
# A unique key for the component.
|
|
233
|
-
key: Any = None
|
|
283
|
+
key: Any = pydantic.v1.Field(default_factory=lambda: None)
|
|
234
284
|
|
|
235
285
|
# The id for the component.
|
|
236
|
-
id: Any = None
|
|
286
|
+
id: Any = pydantic.v1.Field(default_factory=lambda: None)
|
|
237
287
|
|
|
238
288
|
# The class name for the component.
|
|
239
|
-
class_name: Any = None
|
|
289
|
+
class_name: Any = pydantic.v1.Field(default_factory=lambda: None)
|
|
240
290
|
|
|
241
291
|
# Special component props.
|
|
242
|
-
special_props:
|
|
292
|
+
special_props: list[Var] = pydantic.v1.Field(default_factory=list)
|
|
243
293
|
|
|
244
294
|
# Whether the component should take the focus once the page is loaded
|
|
245
|
-
autofocus: bool = False
|
|
295
|
+
autofocus: bool = pydantic.v1.Field(default_factory=lambda: False)
|
|
246
296
|
|
|
247
297
|
# components that cannot be children
|
|
248
|
-
_invalid_children:
|
|
298
|
+
_invalid_children: ClassVar[list[str]] = []
|
|
249
299
|
|
|
250
300
|
# only components that are allowed as children
|
|
251
|
-
_valid_children:
|
|
301
|
+
_valid_children: ClassVar[list[str]] = []
|
|
252
302
|
|
|
253
303
|
# only components that are allowed as parent
|
|
254
|
-
_valid_parents:
|
|
304
|
+
_valid_parents: ClassVar[list[str]] = []
|
|
255
305
|
|
|
256
306
|
# props to change the name of
|
|
257
|
-
_rename_props:
|
|
307
|
+
_rename_props: ClassVar[dict[str, str]] = {}
|
|
258
308
|
|
|
259
309
|
# custom attribute
|
|
260
|
-
custom_attrs:
|
|
310
|
+
custom_attrs: dict[str, Var | Any] = pydantic.v1.Field(default_factory=dict)
|
|
261
311
|
|
|
262
312
|
# When to memoize this component and its children.
|
|
263
313
|
_memoization_mode: MemoizationMode = MemoizationMode()
|
|
264
314
|
|
|
265
315
|
# State class associated with this component instance
|
|
266
|
-
State:
|
|
316
|
+
State: Type[reflex.state.State] | None = pydantic.v1.Field(
|
|
317
|
+
default_factory=lambda: None
|
|
318
|
+
)
|
|
267
319
|
|
|
268
320
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
269
321
|
"""Add imports for the component.
|
|
@@ -369,11 +421,13 @@ class Component(BaseComponent, ABC):
|
|
|
369
421
|
continue
|
|
370
422
|
|
|
371
423
|
# Set default values for any props.
|
|
372
|
-
if
|
|
424
|
+
if field.type_ is Var:
|
|
373
425
|
field.required = False
|
|
374
426
|
if field.default is not None:
|
|
375
|
-
field.
|
|
376
|
-
|
|
427
|
+
field.default_factory = functools.partial(
|
|
428
|
+
LiteralVar.create, field.default
|
|
429
|
+
)
|
|
430
|
+
elif field.type_ is EventHandler:
|
|
377
431
|
field.required = False
|
|
378
432
|
|
|
379
433
|
# Ensure renamed props from parent classes are applied to the subclass.
|
|
@@ -384,7 +438,24 @@ class Component(BaseComponent, ABC):
|
|
|
384
438
|
inherited_rename_props.update(parent._rename_props)
|
|
385
439
|
cls._rename_props = inherited_rename_props
|
|
386
440
|
|
|
387
|
-
def __init__(self,
|
|
441
|
+
def __init__(self, **kwargs):
|
|
442
|
+
"""Initialize the custom component.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
**kwargs: The kwargs to pass to the component.
|
|
446
|
+
"""
|
|
447
|
+
console.deprecate(
|
|
448
|
+
"component-direct-instantiation",
|
|
449
|
+
reason="Use the `create` method instead.",
|
|
450
|
+
deprecation_version="0.7.2",
|
|
451
|
+
removal_version="0.8.0",
|
|
452
|
+
)
|
|
453
|
+
super().__init__(
|
|
454
|
+
children=kwargs.get("children", []),
|
|
455
|
+
)
|
|
456
|
+
self._post_init(**kwargs)
|
|
457
|
+
|
|
458
|
+
def _post_init(self, *args, **kwargs):
|
|
388
459
|
"""Initialize the component.
|
|
389
460
|
|
|
390
461
|
Args:
|
|
@@ -397,16 +468,6 @@ class Component(BaseComponent, ABC):
|
|
|
397
468
|
"""
|
|
398
469
|
# Set the id and children initially.
|
|
399
470
|
children = kwargs.get("children", [])
|
|
400
|
-
initial_kwargs = {
|
|
401
|
-
"id": kwargs.get("id"),
|
|
402
|
-
"children": children,
|
|
403
|
-
**{
|
|
404
|
-
prop: LiteralVar.create(kwargs[prop])
|
|
405
|
-
for prop in self.get_initial_props()
|
|
406
|
-
if prop in kwargs
|
|
407
|
-
},
|
|
408
|
-
}
|
|
409
|
-
super().__init__(**initial_kwargs)
|
|
410
471
|
|
|
411
472
|
self._validate_component_children(children)
|
|
412
473
|
|
|
@@ -434,11 +495,10 @@ class Component(BaseComponent, ABC):
|
|
|
434
495
|
)
|
|
435
496
|
if key in component_specific_triggers:
|
|
436
497
|
# Event triggers are bound to event chains.
|
|
437
|
-
|
|
498
|
+
is_var = False
|
|
438
499
|
elif key in props:
|
|
439
500
|
# Set the field type.
|
|
440
|
-
|
|
441
|
-
|
|
501
|
+
is_var = field.type_ is Var if (field := fields.get(key)) else False
|
|
442
502
|
else:
|
|
443
503
|
continue
|
|
444
504
|
|
|
@@ -453,13 +513,14 @@ class Component(BaseComponent, ABC):
|
|
|
453
513
|
return key
|
|
454
514
|
|
|
455
515
|
# Check whether the key is a component prop.
|
|
456
|
-
if
|
|
457
|
-
# Used to store the passed types if var type is a union.
|
|
458
|
-
passed_types = None
|
|
516
|
+
if is_var:
|
|
459
517
|
try:
|
|
460
518
|
kwargs[key] = determine_key(value)
|
|
461
519
|
|
|
462
|
-
expected_type =
|
|
520
|
+
expected_type = types.get_args(
|
|
521
|
+
types.get_field_type(type(self), key)
|
|
522
|
+
)[0]
|
|
523
|
+
|
|
463
524
|
# validate literal fields.
|
|
464
525
|
types.validate_literal(
|
|
465
526
|
key, value, expected_type, type(self).__name__
|
|
@@ -474,22 +535,9 @@ class Component(BaseComponent, ABC):
|
|
|
474
535
|
except TypeError:
|
|
475
536
|
# If it is not a valid var, check the base types.
|
|
476
537
|
passed_type = type(value)
|
|
477
|
-
expected_type =
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
passed_types = (
|
|
481
|
-
arg for arg in passed_type.__args__ if arg is not type(None)
|
|
482
|
-
)
|
|
483
|
-
if (
|
|
484
|
-
# If the passed var is a union, check if all possible types are valid.
|
|
485
|
-
passed_types
|
|
486
|
-
and not all(
|
|
487
|
-
types._issubclass(pt, expected_type) for pt in passed_types
|
|
488
|
-
)
|
|
489
|
-
) or (
|
|
490
|
-
# Else just check if the passed var type is valid.
|
|
491
|
-
not passed_types and not satisfies_type_hint(value, expected_type)
|
|
492
|
-
):
|
|
538
|
+
expected_type = types.get_field_type(type(self), key)
|
|
539
|
+
|
|
540
|
+
if not satisfies_type_hint(value, expected_type):
|
|
493
541
|
value_name = value._js_expr if isinstance(value, Var) else value
|
|
494
542
|
|
|
495
543
|
additional_info = (
|
|
@@ -537,9 +585,15 @@ class Component(BaseComponent, ABC):
|
|
|
537
585
|
"&": style,
|
|
538
586
|
}
|
|
539
587
|
|
|
588
|
+
fields_style = self.get_fields()["style"]
|
|
589
|
+
|
|
540
590
|
kwargs["style"] = Style(
|
|
541
591
|
{
|
|
542
|
-
**
|
|
592
|
+
**(
|
|
593
|
+
fields_style.default_factory()
|
|
594
|
+
if fields_style.default_factory
|
|
595
|
+
else fields_style.default
|
|
596
|
+
),
|
|
543
597
|
**style,
|
|
544
598
|
**{attr: value for attr, value in kwargs.items() if attr not in fields},
|
|
545
599
|
}
|
|
@@ -550,50 +604,34 @@ class Component(BaseComponent, ABC):
|
|
|
550
604
|
if isinstance(class_name, (List, tuple)):
|
|
551
605
|
if any(isinstance(c, Var) for c in class_name):
|
|
552
606
|
kwargs["class_name"] = LiteralArrayVar.create(
|
|
553
|
-
class_name, _var_type=
|
|
607
|
+
class_name, _var_type=list[str]
|
|
554
608
|
).join(" ")
|
|
555
609
|
else:
|
|
556
610
|
kwargs["class_name"] = " ".join(class_name)
|
|
557
611
|
|
|
558
612
|
# Construct the component.
|
|
559
|
-
|
|
613
|
+
for key, value in kwargs.items():
|
|
614
|
+
setattr(self, key, value)
|
|
560
615
|
|
|
561
616
|
def get_event_triggers(
|
|
562
617
|
self,
|
|
563
|
-
) ->
|
|
618
|
+
) -> dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]]:
|
|
564
619
|
"""Get the event triggers for the component.
|
|
565
620
|
|
|
566
621
|
Returns:
|
|
567
622
|
The event triggers.
|
|
568
623
|
"""
|
|
569
|
-
|
|
570
|
-
EventTriggers.ON_FOCUS: no_args_event_spec,
|
|
571
|
-
EventTriggers.ON_BLUR: no_args_event_spec,
|
|
572
|
-
EventTriggers.ON_CLICK: no_args_event_spec,
|
|
573
|
-
EventTriggers.ON_CONTEXT_MENU: no_args_event_spec,
|
|
574
|
-
EventTriggers.ON_DOUBLE_CLICK: no_args_event_spec,
|
|
575
|
-
EventTriggers.ON_MOUSE_DOWN: no_args_event_spec,
|
|
576
|
-
EventTriggers.ON_MOUSE_ENTER: no_args_event_spec,
|
|
577
|
-
EventTriggers.ON_MOUSE_LEAVE: no_args_event_spec,
|
|
578
|
-
EventTriggers.ON_MOUSE_MOVE: no_args_event_spec,
|
|
579
|
-
EventTriggers.ON_MOUSE_OUT: no_args_event_spec,
|
|
580
|
-
EventTriggers.ON_MOUSE_OVER: no_args_event_spec,
|
|
581
|
-
EventTriggers.ON_MOUSE_UP: no_args_event_spec,
|
|
582
|
-
EventTriggers.ON_SCROLL: no_args_event_spec,
|
|
583
|
-
EventTriggers.ON_MOUNT: no_args_event_spec,
|
|
584
|
-
EventTriggers.ON_UNMOUNT: no_args_event_spec,
|
|
585
|
-
}
|
|
586
|
-
|
|
624
|
+
triggers = DEFAULT_TRIGGERS.copy()
|
|
587
625
|
# Look for component specific triggers,
|
|
588
626
|
# e.g. variable declared as EventHandler types.
|
|
589
627
|
for field in self.get_fields().values():
|
|
590
|
-
if
|
|
628
|
+
if field.type_ is EventHandler:
|
|
591
629
|
args_spec = None
|
|
592
630
|
annotation = field.annotation
|
|
593
631
|
if (metadata := getattr(annotation, "__metadata__", None)) is not None:
|
|
594
632
|
args_spec = metadata[0]
|
|
595
|
-
|
|
596
|
-
return
|
|
633
|
+
triggers[field.name] = args_spec or (no_args_event_spec)
|
|
634
|
+
return triggers
|
|
597
635
|
|
|
598
636
|
def __repr__(self) -> str:
|
|
599
637
|
"""Represent the component in React.
|
|
@@ -670,7 +708,7 @@ class Component(BaseComponent, ABC):
|
|
|
670
708
|
|
|
671
709
|
@classmethod
|
|
672
710
|
@lru_cache(maxsize=None)
|
|
673
|
-
def get_props(cls) ->
|
|
711
|
+
def get_props(cls) -> set[str]:
|
|
674
712
|
"""Get the unique fields for the component.
|
|
675
713
|
|
|
676
714
|
Returns:
|
|
@@ -680,7 +718,7 @@ class Component(BaseComponent, ABC):
|
|
|
680
718
|
|
|
681
719
|
@classmethod
|
|
682
720
|
@lru_cache(maxsize=None)
|
|
683
|
-
def get_initial_props(cls) ->
|
|
721
|
+
def get_initial_props(cls) -> set[str]:
|
|
684
722
|
"""Get the initial props to set for the component.
|
|
685
723
|
|
|
686
724
|
Returns:
|
|
@@ -707,9 +745,11 @@ class Component(BaseComponent, ABC):
|
|
|
707
745
|
"""
|
|
708
746
|
return {
|
|
709
747
|
name
|
|
710
|
-
for name
|
|
748
|
+
for name in cls.get_fields()
|
|
711
749
|
if name in cls.get_props()
|
|
712
|
-
and types._issubclass(
|
|
750
|
+
and types._issubclass(
|
|
751
|
+
types.value_inside_optional(types.get_field_type(cls, name)), Component
|
|
752
|
+
)
|
|
713
753
|
}
|
|
714
754
|
|
|
715
755
|
def _get_components_in_props(self) -> Sequence[BaseComponent]:
|
|
@@ -733,7 +773,7 @@ class Component(BaseComponent, ABC):
|
|
|
733
773
|
]
|
|
734
774
|
|
|
735
775
|
@classmethod
|
|
736
|
-
def create(cls, *children, **props) ->
|
|
776
|
+
def create(cls: Type[T], *children, **props) -> T:
|
|
737
777
|
"""Create the component.
|
|
738
778
|
|
|
739
779
|
Args:
|
|
@@ -765,7 +805,7 @@ class Component(BaseComponent, ABC):
|
|
|
765
805
|
# Validate all the children.
|
|
766
806
|
validate_children(children)
|
|
767
807
|
|
|
768
|
-
|
|
808
|
+
children_normalized = [
|
|
769
809
|
(
|
|
770
810
|
child
|
|
771
811
|
if isinstance(child, Component)
|
|
@@ -778,7 +818,40 @@ class Component(BaseComponent, ABC):
|
|
|
778
818
|
for child in children
|
|
779
819
|
]
|
|
780
820
|
|
|
781
|
-
return cls(
|
|
821
|
+
return cls._create(children_normalized, **props)
|
|
822
|
+
|
|
823
|
+
@classmethod
|
|
824
|
+
def _create(cls: Type[T], children: Sequence[BaseComponent], **props: Any) -> T:
|
|
825
|
+
"""Create the component.
|
|
826
|
+
|
|
827
|
+
Args:
|
|
828
|
+
children: The children of the component.
|
|
829
|
+
**props: The props of the component.
|
|
830
|
+
|
|
831
|
+
Returns:
|
|
832
|
+
The component.
|
|
833
|
+
"""
|
|
834
|
+
comp = cls.construct(id=props.get("id"), children=list(children))
|
|
835
|
+
comp._post_init(children=list(children), **props)
|
|
836
|
+
return comp
|
|
837
|
+
|
|
838
|
+
@classmethod
|
|
839
|
+
def _unsafe_create(
|
|
840
|
+
cls: Type[T], children: Sequence[BaseComponent], **props: Any
|
|
841
|
+
) -> T:
|
|
842
|
+
"""Create the component without running post_init.
|
|
843
|
+
|
|
844
|
+
Args:
|
|
845
|
+
children: The children of the component.
|
|
846
|
+
**props: The props of the component.
|
|
847
|
+
|
|
848
|
+
Returns:
|
|
849
|
+
The component.
|
|
850
|
+
"""
|
|
851
|
+
comp = cls.construct(id=props.get("id"), children=list(children))
|
|
852
|
+
for prop, value in props.items():
|
|
853
|
+
setattr(comp, prop, value)
|
|
854
|
+
return comp
|
|
782
855
|
|
|
783
856
|
def add_style(self) -> dict[str, Any] | None:
|
|
784
857
|
"""Add style to the component.
|
|
@@ -829,7 +902,7 @@ class Component(BaseComponent, ABC):
|
|
|
829
902
|
return component_style
|
|
830
903
|
|
|
831
904
|
def _add_style_recursive(
|
|
832
|
-
self, style: ComponentStyle, theme:
|
|
905
|
+
self, style: ComponentStyle, theme: Component | None = None
|
|
833
906
|
) -> Component:
|
|
834
907
|
"""Add additional style to the component and its children.
|
|
835
908
|
|
|
@@ -928,7 +1001,7 @@ class Component(BaseComponent, ABC):
|
|
|
928
1001
|
if prop.startswith(old_prop):
|
|
929
1002
|
rendered_dict["props"][ix] = prop.replace(old_prop, new_prop, 1)
|
|
930
1003
|
|
|
931
|
-
def _validate_component_children(self, children:
|
|
1004
|
+
def _validate_component_children(self, children: list[Component]):
|
|
932
1005
|
"""Validate the children components.
|
|
933
1006
|
|
|
934
1007
|
Args:
|
|
@@ -962,8 +1035,8 @@ class Component(BaseComponent, ABC):
|
|
|
962
1035
|
validate_child(c)
|
|
963
1036
|
|
|
964
1037
|
if isinstance(child, Cond):
|
|
965
|
-
validate_child(child.
|
|
966
|
-
validate_child(child.
|
|
1038
|
+
validate_child(child.children[0])
|
|
1039
|
+
validate_child(child.children[1])
|
|
967
1040
|
|
|
968
1041
|
if isinstance(child, Match):
|
|
969
1042
|
for cases in child.match_cases:
|
|
@@ -1038,7 +1111,7 @@ class Component(BaseComponent, ABC):
|
|
|
1038
1111
|
Each var referenced by the component (props, styles, event handlers).
|
|
1039
1112
|
"""
|
|
1040
1113
|
ignore_ids = ignore_ids or set()
|
|
1041
|
-
vars:
|
|
1114
|
+
vars: list[Var] | None = getattr(self, "__vars", None)
|
|
1042
1115
|
if vars is not None:
|
|
1043
1116
|
yield from vars
|
|
1044
1117
|
vars = self.__vars = []
|
|
@@ -1211,7 +1284,7 @@ class Component(BaseComponent, ABC):
|
|
|
1211
1284
|
"""
|
|
1212
1285
|
return None
|
|
1213
1286
|
|
|
1214
|
-
def _get_all_dynamic_imports(self) ->
|
|
1287
|
+
def _get_all_dynamic_imports(self) -> set[str]:
|
|
1215
1288
|
"""Get dynamic imports for the component and its children.
|
|
1216
1289
|
|
|
1217
1290
|
Returns:
|
|
@@ -1578,7 +1651,7 @@ class Component(BaseComponent, ABC):
|
|
|
1578
1651
|
|
|
1579
1652
|
def _get_all_custom_components(
|
|
1580
1653
|
self, seen: set[str] | None = None
|
|
1581
|
-
) ->
|
|
1654
|
+
) -> set[CustomComponent]:
|
|
1582
1655
|
"""Get all the custom components used by the component.
|
|
1583
1656
|
|
|
1584
1657
|
Args:
|
|
@@ -1661,9 +1734,9 @@ class CustomComponent(Component):
|
|
|
1661
1734
|
component_fn: Callable[..., Component] = Component.create
|
|
1662
1735
|
|
|
1663
1736
|
# The props of the component.
|
|
1664
|
-
props:
|
|
1737
|
+
props: dict[str, Any] = {}
|
|
1665
1738
|
|
|
1666
|
-
def
|
|
1739
|
+
def _post_init(self, **kwargs):
|
|
1667
1740
|
"""Initialize the custom component.
|
|
1668
1741
|
|
|
1669
1742
|
Args:
|
|
@@ -1706,7 +1779,7 @@ class CustomComponent(Component):
|
|
|
1706
1779
|
)
|
|
1707
1780
|
)
|
|
1708
1781
|
|
|
1709
|
-
super().
|
|
1782
|
+
super()._post_init(
|
|
1710
1783
|
event_triggers={
|
|
1711
1784
|
key: EventChain.create(
|
|
1712
1785
|
value=props[key],
|
|
@@ -1740,7 +1813,7 @@ class CustomComponent(Component):
|
|
|
1740
1813
|
type_ = props_types[key]
|
|
1741
1814
|
|
|
1742
1815
|
# Handle event chains.
|
|
1743
|
-
if
|
|
1816
|
+
if type_ is EventHandler:
|
|
1744
1817
|
inspect.getfullargspec(component_fn).annotations[key]
|
|
1745
1818
|
self.props[camel_cased_key] = EventChain.create(
|
|
1746
1819
|
value=value, args_spec=get_args_spec(key), key=key
|
|
@@ -1780,7 +1853,7 @@ class CustomComponent(Component):
|
|
|
1780
1853
|
return hash(self.tag)
|
|
1781
1854
|
|
|
1782
1855
|
@classmethod
|
|
1783
|
-
def get_props(cls) ->
|
|
1856
|
+
def get_props(cls) -> set[str]:
|
|
1784
1857
|
"""Get the props for the component.
|
|
1785
1858
|
|
|
1786
1859
|
Returns:
|
|
@@ -1790,7 +1863,7 @@ class CustomComponent(Component):
|
|
|
1790
1863
|
|
|
1791
1864
|
def _get_all_custom_components(
|
|
1792
1865
|
self, seen: set[str] | None = None
|
|
1793
|
-
) ->
|
|
1866
|
+
) -> set[CustomComponent]:
|
|
1794
1867
|
"""Get all the custom components used by the component.
|
|
1795
1868
|
|
|
1796
1869
|
Args:
|
|
@@ -1867,7 +1940,9 @@ def custom_component(
|
|
|
1867
1940
|
def wrapper(*children, **props) -> CustomComponent:
|
|
1868
1941
|
# Remove the children from the props.
|
|
1869
1942
|
props.pop("children", None)
|
|
1870
|
-
return CustomComponent(
|
|
1943
|
+
return CustomComponent._create(
|
|
1944
|
+
children=list(children), component_fn=component_fn, **props
|
|
1945
|
+
)
|
|
1871
1946
|
|
|
1872
1947
|
return wrapper
|
|
1873
1948
|
|
|
@@ -1942,7 +2017,7 @@ class StatefulComponent(BaseComponent):
|
|
|
1942
2017
|
"""
|
|
1943
2018
|
|
|
1944
2019
|
# A lookup table to caching memoized component instances.
|
|
1945
|
-
tag_to_stateful_component: ClassVar[
|
|
2020
|
+
tag_to_stateful_component: ClassVar[dict[str, StatefulComponent]] = {}
|
|
1946
2021
|
|
|
1947
2022
|
# Reference to the original component that was memoized into this component.
|
|
1948
2023
|
component: Component
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import dataclasses
|
|
6
|
+
|
|
5
7
|
from reflex.components.el.elements.typography import Div
|
|
6
8
|
from reflex.constants.compiler import MemoizationDisposition, MemoizationMode
|
|
7
9
|
from reflex.utils.imports import ImportDict
|
|
@@ -28,7 +30,12 @@ class AutoScroll(Div):
|
|
|
28
30
|
"""
|
|
29
31
|
props.setdefault("overflow", "auto")
|
|
30
32
|
props.setdefault("id", get_unique_variable_name())
|
|
31
|
-
|
|
33
|
+
component = super().create(*children, **props)
|
|
34
|
+
if "key" in props:
|
|
35
|
+
component._memoization_mode = dataclasses.replace(
|
|
36
|
+
component._memoization_mode, recursive=True
|
|
37
|
+
)
|
|
38
|
+
return component
|
|
32
39
|
|
|
33
40
|
def add_imports(self) -> ImportDict | list[ImportDict]:
|
|
34
41
|
"""Add imports required for the component.
|