reflex 0.7.13a1__py3-none-any.whl → 0.7.14a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- reflex/.templates/apps/blank/code/blank.py +0 -2
- reflex/app.py +79 -72
- reflex/app_mixins/lifespan.py +2 -3
- reflex/app_mixins/middleware.py +1 -0
- reflex/app_mixins/mixin.py +0 -1
- reflex/assets.py +6 -3
- reflex/base.py +3 -2
- reflex/compiler/compiler.py +77 -64
- reflex/compiler/utils.py +8 -6
- reflex/components/base/app_wrap.pyi +0 -1
- reflex/components/base/bare.py +5 -7
- reflex/components/base/body.pyi +0 -1
- reflex/components/base/document.pyi +0 -5
- reflex/components/base/error_boundary.pyi +0 -1
- reflex/components/base/fragment.pyi +0 -1
- reflex/components/base/head.pyi +0 -2
- reflex/components/base/link.pyi +0 -2
- reflex/components/base/meta.py +2 -1
- reflex/components/base/meta.pyi +0 -4
- reflex/components/base/script.py +2 -1
- reflex/components/base/script.pyi +0 -1
- reflex/components/base/strict_mode.pyi +0 -1
- reflex/components/component.py +38 -40
- reflex/components/core/auto_scroll.pyi +0 -1
- reflex/components/core/banner.pyi +0 -6
- reflex/components/core/breakpoints.py +9 -11
- reflex/components/core/client_side_routing.pyi +0 -2
- reflex/components/core/clipboard.pyi +0 -1
- reflex/components/core/colors.py +10 -7
- reflex/components/core/cond.py +4 -2
- reflex/components/core/debounce.py +5 -3
- reflex/components/core/debounce.pyi +0 -1
- reflex/components/core/foreach.py +8 -6
- reflex/components/core/html.py +3 -3
- reflex/components/core/html.pyi +0 -1
- reflex/components/core/match.py +19 -17
- reflex/components/core/sticky.pyi +0 -4
- reflex/components/core/upload.pyi +0 -5
- reflex/components/datadisplay/code.py +1 -2
- reflex/components/datadisplay/code.pyi +0 -2
- reflex/components/datadisplay/dataeditor.py +7 -10
- reflex/components/datadisplay/dataeditor.pyi +0 -1
- reflex/components/datadisplay/logo.py +3 -4
- reflex/components/datadisplay/shiki_code_block.py +8 -11
- reflex/components/datadisplay/shiki_code_block.pyi +0 -3
- reflex/components/dynamic.py +2 -3
- reflex/components/el/__init__.pyi +2 -0
- reflex/components/el/element.pyi +0 -1
- reflex/components/el/elements/__init__.py +1 -0
- reflex/components/el/elements/__init__.pyi +3 -0
- reflex/components/el/elements/base.pyi +0 -1
- reflex/components/el/elements/forms.py +3 -4
- reflex/components/el/elements/forms.pyi +1 -18
- reflex/components/el/elements/inline.pyi +0 -28
- reflex/components/el/elements/media.py +26 -0
- reflex/components/el/elements/media.pyi +259 -25
- reflex/components/el/elements/metadata.py +0 -1
- reflex/components/el/elements/metadata.pyi +0 -6
- reflex/components/el/elements/other.pyi +0 -7
- reflex/components/el/elements/scripts.pyi +0 -3
- reflex/components/el/elements/sectioning.pyi +0 -15
- reflex/components/el/elements/tables.pyi +0 -10
- reflex/components/el/elements/typography.pyi +0 -15
- reflex/components/gridjs/datatable.py +10 -13
- reflex/components/gridjs/datatable.pyi +0 -2
- reflex/components/lucide/icon.py +10 -9
- reflex/components/lucide/icon.pyi +0 -3
- reflex/components/markdown/markdown.py +6 -8
- reflex/components/markdown/markdown.pyi +0 -1
- reflex/components/moment/moment.pyi +0 -1
- reflex/components/next/base.py +0 -2
- reflex/components/next/base.pyi +0 -3
- reflex/components/next/image.pyi +0 -1
- reflex/components/next/link.pyi +0 -1
- reflex/components/next/video.pyi +0 -1
- reflex/components/plotly/plotly.pyi +0 -9
- reflex/components/props.py +4 -3
- reflex/components/radix/primitives/accordion.py +1 -1
- reflex/components/radix/primitives/accordion.pyi +0 -7
- reflex/components/radix/primitives/base.py +1 -3
- reflex/components/radix/primitives/base.pyi +0 -2
- reflex/components/radix/primitives/drawer.py +1 -1
- reflex/components/radix/primitives/drawer.pyi +0 -11
- reflex/components/radix/primitives/form.py +5 -9
- reflex/components/radix/primitives/form.pyi +0 -12
- reflex/components/radix/primitives/progress.py +1 -1
- reflex/components/radix/primitives/progress.pyi +0 -5
- reflex/components/radix/primitives/slider.py +1 -1
- reflex/components/radix/primitives/slider.pyi +0 -5
- reflex/components/radix/themes/base.pyi +0 -8
- reflex/components/radix/themes/color_mode.pyi +0 -3
- reflex/components/radix/themes/components/alert_dialog.py +4 -2
- reflex/components/radix/themes/components/alert_dialog.pyi +4 -9
- reflex/components/radix/themes/components/aspect_ratio.py +1 -2
- reflex/components/radix/themes/components/aspect_ratio.pyi +1 -3
- reflex/components/radix/themes/components/avatar.py +5 -2
- reflex/components/radix/themes/components/avatar.pyi +1 -3
- reflex/components/radix/themes/components/badge.py +5 -2
- reflex/components/radix/themes/components/badge.pyi +1 -3
- reflex/components/radix/themes/components/button.py +2 -3
- reflex/components/radix/themes/components/button.pyi +1 -3
- reflex/components/radix/themes/components/callout.py +1 -2
- reflex/components/radix/themes/components/callout.pyi +1 -7
- reflex/components/radix/themes/components/card.py +1 -2
- reflex/components/radix/themes/components/card.pyi +1 -3
- reflex/components/radix/themes/components/checkbox.py +7 -4
- reflex/components/radix/themes/components/checkbox.pyi +1 -5
- reflex/components/radix/themes/components/checkbox_cards.py +1 -2
- reflex/components/radix/themes/components/checkbox_cards.pyi +1 -4
- reflex/components/radix/themes/components/checkbox_group.py +1 -2
- reflex/components/radix/themes/components/checkbox_group.pyi +1 -4
- reflex/components/radix/themes/components/context_menu.py +1 -1
- reflex/components/radix/themes/components/context_menu.pyi +1 -14
- reflex/components/radix/themes/components/data_list.py +1 -2
- reflex/components/radix/themes/components/data_list.pyi +1 -6
- reflex/components/radix/themes/components/dialog.py +4 -2
- reflex/components/radix/themes/components/dialog.pyi +4 -9
- reflex/components/radix/themes/components/dropdown_menu.py +5 -2
- reflex/components/radix/themes/components/dropdown_menu.pyi +4 -10
- reflex/components/radix/themes/components/hover_card.py +4 -2
- reflex/components/radix/themes/components/hover_card.pyi +4 -6
- reflex/components/radix/themes/components/icon_button.py +7 -8
- reflex/components/radix/themes/components/icon_button.pyi +1 -3
- reflex/components/radix/themes/components/inset.py +1 -2
- reflex/components/radix/themes/components/inset.pyi +1 -3
- reflex/components/radix/themes/components/popover.py +4 -2
- reflex/components/radix/themes/components/popover.pyi +4 -6
- reflex/components/radix/themes/components/progress.py +1 -2
- reflex/components/radix/themes/components/progress.pyi +1 -3
- reflex/components/radix/themes/components/radio.py +1 -2
- reflex/components/radix/themes/components/radio.pyi +1 -3
- reflex/components/radix/themes/components/radio_cards.py +1 -2
- reflex/components/radix/themes/components/radio_cards.pyi +1 -4
- reflex/components/radix/themes/components/radio_group.py +7 -5
- reflex/components/radix/themes/components/radio_group.pyi +1 -6
- reflex/components/radix/themes/components/scroll_area.py +1 -2
- reflex/components/radix/themes/components/scroll_area.pyi +1 -3
- reflex/components/radix/themes/components/segmented_control.py +1 -2
- reflex/components/radix/themes/components/segmented_control.pyi +1 -4
- reflex/components/radix/themes/components/select.py +5 -2
- reflex/components/radix/themes/components/select.pyi +1 -11
- reflex/components/radix/themes/components/separator.py +1 -2
- reflex/components/radix/themes/components/separator.pyi +1 -3
- reflex/components/radix/themes/components/skeleton.py +1 -2
- reflex/components/radix/themes/components/skeleton.pyi +1 -3
- reflex/components/radix/themes/components/slider.py +1 -2
- reflex/components/radix/themes/components/slider.pyi +1 -3
- reflex/components/radix/themes/components/spinner.py +1 -2
- reflex/components/radix/themes/components/spinner.pyi +1 -3
- reflex/components/radix/themes/components/switch.py +1 -2
- reflex/components/radix/themes/components/switch.pyi +1 -3
- reflex/components/radix/themes/components/table.py +1 -2
- reflex/components/radix/themes/components/table.pyi +1 -9
- reflex/components/radix/themes/components/tabs.py +1 -2
- reflex/components/radix/themes/components/tabs.pyi +1 -7
- reflex/components/radix/themes/components/text_area.py +5 -2
- reflex/components/radix/themes/components/text_area.pyi +1 -3
- reflex/components/radix/themes/components/text_field.py +5 -2
- reflex/components/radix/themes/components/text_field.pyi +1 -5
- reflex/components/radix/themes/components/tooltip.py +1 -2
- reflex/components/radix/themes/components/tooltip.pyi +1 -3
- reflex/components/radix/themes/layout/base.py +5 -2
- reflex/components/radix/themes/layout/base.pyi +5 -3
- reflex/components/radix/themes/layout/box.py +1 -2
- reflex/components/radix/themes/layout/box.pyi +1 -3
- reflex/components/radix/themes/layout/center.pyi +0 -1
- reflex/components/radix/themes/layout/container.py +1 -2
- reflex/components/radix/themes/layout/container.pyi +1 -3
- reflex/components/radix/themes/layout/flex.py +6 -2
- reflex/components/radix/themes/layout/flex.pyi +1 -3
- reflex/components/radix/themes/layout/grid.py +6 -2
- reflex/components/radix/themes/layout/grid.pyi +1 -3
- reflex/components/radix/themes/layout/list.py +2 -1
- reflex/components/radix/themes/layout/list.pyi +0 -5
- reflex/components/radix/themes/layout/section.py +1 -2
- reflex/components/radix/themes/layout/section.pyi +1 -3
- reflex/components/radix/themes/layout/spacer.pyi +0 -1
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/radix/themes/layout/stack.pyi +0 -3
- reflex/components/radix/themes/typography/blockquote.py +1 -1
- reflex/components/radix/themes/typography/blockquote.pyi +1 -3
- reflex/components/radix/themes/typography/code.py +5 -1
- reflex/components/radix/themes/typography/code.pyi +1 -3
- reflex/components/radix/themes/typography/heading.py +1 -1
- reflex/components/radix/themes/typography/heading.pyi +1 -3
- reflex/components/radix/themes/typography/link.py +3 -2
- reflex/components/radix/themes/typography/link.pyi +1 -3
- reflex/components/radix/themes/typography/text.py +1 -1
- reflex/components/radix/themes/typography/text.pyi +1 -9
- reflex/components/react_player/audio.py +0 -2
- reflex/components/react_player/audio.pyi +0 -3
- reflex/components/react_player/react_player.pyi +0 -1
- reflex/components/react_player/video.py +0 -2
- reflex/components/react_player/video.pyi +0 -3
- reflex/components/recharts/__init__.py +1 -1
- reflex/components/recharts/__init__.pyi +1 -1
- reflex/components/recharts/cartesian.py +20 -25
- reflex/components/recharts/cartesian.pyi +20 -37
- reflex/components/recharts/charts.py +2 -1
- reflex/components/recharts/charts.pyi +0 -12
- reflex/components/recharts/general.pyi +0 -6
- reflex/components/recharts/polar.py +5 -4
- reflex/components/recharts/polar.pyi +4 -10
- reflex/components/recharts/recharts.py +12 -10
- reflex/components/recharts/recharts.pyi +10 -11
- reflex/components/sonner/toast.py +2 -2
- reflex/components/sonner/toast.pyi +0 -2
- reflex/components/suneditor/editor.py +2 -1
- reflex/components/suneditor/editor.pyi +0 -1
- reflex/components/tags/iter_tag.py +4 -2
- reflex/config.py +47 -35
- reflex/constants/base.py +3 -3
- reflex/constants/compiler.py +8 -6
- reflex/constants/installer.py +24 -15
- reflex/custom_components/custom_components.py +1 -2
- reflex/event.py +58 -60
- reflex/experimental/__init__.py +2 -2
- reflex/experimental/client_state.py +9 -4
- reflex/experimental/layout.pyi +0 -5
- reflex/istate/manager.py +15 -19
- reflex/istate/proxy.py +19 -12
- reflex/model.py +6 -4
- reflex/plugins/base.py +8 -0
- reflex/plugins/tailwind_v3.py +8 -0
- reflex/plugins/tailwind_v4.py +9 -0
- reflex/reflex.py +9 -11
- reflex/route.py +7 -9
- reflex/state.py +66 -70
- reflex/style.py +3 -1
- reflex/testing.py +46 -29
- reflex/utils/build.py +2 -1
- reflex/utils/console.py +9 -17
- reflex/utils/exec.py +9 -11
- reflex/utils/format.py +21 -24
- reflex/utils/imports.py +4 -3
- reflex/utils/lazy_loader.py +3 -3
- reflex/utils/misc.py +2 -1
- reflex/utils/net.py +2 -2
- reflex/utils/path_ops.py +2 -1
- reflex/utils/prerequisites.py +67 -38
- reflex/utils/processes.py +4 -6
- reflex/utils/pyi_generator.py +46 -41
- reflex/utils/redir.py +1 -1
- reflex/utils/serializers.py +4 -4
- reflex/utils/telemetry.py +42 -4
- reflex/utils/types.py +16 -13
- reflex/vars/base.py +96 -109
- reflex/vars/datetime.py +2 -1
- reflex/vars/dep_tracking.py +19 -28
- reflex/vars/number.py +6 -7
- reflex/vars/object.py +5 -6
- reflex/vars/sequence.py +11 -11
- {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/METADATA +1 -1
- reflex-0.7.14a1.dist-info/RECORD +407 -0
- reflex-0.7.13a1.dist-info/RECORD +0 -407
- {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/WHEEL +0 -0
- {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/entry_points.txt +0 -0
- {reflex-0.7.13a1.dist-info → reflex-0.7.14a1.dist-info}/licenses/LICENSE +0 -0
reflex/compiler/compiler.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import sys
|
|
5
6
|
from collections.abc import Iterable, Sequence
|
|
6
7
|
from datetime import datetime
|
|
7
8
|
from inspect import getmodule
|
|
@@ -200,15 +201,14 @@ def _validate_stylesheet(stylesheet_full_path: Path, assets_app_path: Path) -> N
|
|
|
200
201
|
"""
|
|
201
202
|
suffix = stylesheet_full_path.suffix[1:] if stylesheet_full_path.suffix else ""
|
|
202
203
|
if suffix not in constants.Reflex.STYLESHEETS_SUPPORTED:
|
|
203
|
-
|
|
204
|
+
msg = f"Stylesheet file {stylesheet_full_path} is not supported."
|
|
205
|
+
raise ValueError(msg)
|
|
204
206
|
if not stylesheet_full_path.absolute().is_relative_to(assets_app_path.absolute()):
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
)
|
|
207
|
+
msg = f"Cannot include stylesheets from outside the assets directory: {stylesheet_full_path}"
|
|
208
|
+
raise FileNotFoundError(msg)
|
|
208
209
|
if not stylesheet_full_path.name:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
)
|
|
210
|
+
msg = f"Stylesheet file name cannot be empty: {stylesheet_full_path}"
|
|
211
|
+
raise ValueError(msg)
|
|
212
212
|
if (
|
|
213
213
|
len(
|
|
214
214
|
stylesheet_full_path.absolute()
|
|
@@ -218,9 +218,8 @@ def _validate_stylesheet(stylesheet_full_path: Path, assets_app_path: Path) -> N
|
|
|
218
218
|
== 1
|
|
219
219
|
and stylesheet_full_path.stem == PageNames.STYLESHEET_ROOT
|
|
220
220
|
):
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
)
|
|
221
|
+
msg = f"Stylesheet file name cannot be '{PageNames.STYLESHEET_ROOT}': {stylesheet_full_path}"
|
|
222
|
+
raise ValueError(msg)
|
|
224
223
|
|
|
225
224
|
|
|
226
225
|
RADIX_THEMES_STYLESHEET = "@radix-ui/themes/styles.css"
|
|
@@ -257,9 +256,8 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
|
|
|
257
256
|
stylesheet_full_path = assets_app_path / stylesheet.strip("/")
|
|
258
257
|
|
|
259
258
|
if not stylesheet_full_path.exists():
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
)
|
|
259
|
+
msg = f"The stylesheet file {stylesheet_full_path} does not exist."
|
|
260
|
+
raise FileNotFoundError(msg)
|
|
263
261
|
|
|
264
262
|
if stylesheet_full_path.is_dir():
|
|
265
263
|
all_files = (
|
|
@@ -685,12 +683,12 @@ def into_component(component: Component | ComponentCallable) -> Component:
|
|
|
685
683
|
"""
|
|
686
684
|
if (converted := _into_component_once(component)) is not None:
|
|
687
685
|
return converted
|
|
686
|
+
if not callable(component):
|
|
687
|
+
msg = f"Expected a Component or callable, got {component!r} of type {type(component)}"
|
|
688
|
+
raise TypeError(msg)
|
|
689
|
+
|
|
688
690
|
try:
|
|
689
|
-
|
|
690
|
-
callable(component)
|
|
691
|
-
and (converted := _into_component_once(component())) is not None
|
|
692
|
-
):
|
|
693
|
-
return converted
|
|
691
|
+
component_called = component()
|
|
694
692
|
except KeyError as e:
|
|
695
693
|
if isinstance(e, ReflexError):
|
|
696
694
|
raise
|
|
@@ -714,9 +712,10 @@ def into_component(component: Component | ComponentCallable) -> Component:
|
|
|
714
712
|
"Cannot pass a Var to a built-in function. Consider using .length() for accessing the length of an iterable Var."
|
|
715
713
|
).with_traceback(e.__traceback__) from None
|
|
716
714
|
if message.endswith(
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
715
|
+
(
|
|
716
|
+
"indices must be integers or slices, not NumberCastedVar",
|
|
717
|
+
"indices must be integers or slices, not BooleanCastedVar",
|
|
718
|
+
)
|
|
720
719
|
):
|
|
721
720
|
raise TypeError(
|
|
722
721
|
"Cannot index into a primitive sequence with a Var. Consider calling rx.Var.create() on the sequence."
|
|
@@ -727,7 +726,11 @@ def into_component(component: Component | ComponentCallable) -> Component:
|
|
|
727
726
|
).with_traceback(e.__traceback__) from None
|
|
728
727
|
raise
|
|
729
728
|
|
|
730
|
-
|
|
729
|
+
if (converted := _into_component_once(component_called)) is not None:
|
|
730
|
+
return converted
|
|
731
|
+
|
|
732
|
+
msg = f"Expected a Component, got {component_called!r} of type {type(component_called)}"
|
|
733
|
+
raise TypeError(msg)
|
|
731
734
|
|
|
732
735
|
|
|
733
736
|
def compile_unevaluated_page(
|
|
@@ -748,52 +751,61 @@ def compile_unevaluated_page(
|
|
|
748
751
|
|
|
749
752
|
Returns:
|
|
750
753
|
The compiled component and whether state should be enabled.
|
|
754
|
+
|
|
755
|
+
Raises:
|
|
756
|
+
Exception: If an error occurs while evaluating the page.
|
|
751
757
|
"""
|
|
752
|
-
|
|
753
|
-
|
|
758
|
+
try:
|
|
759
|
+
# Generate the component if it is a callable.
|
|
760
|
+
component = into_component(page.component)
|
|
754
761
|
|
|
755
|
-
|
|
762
|
+
component._add_style_recursive(style or {}, theme)
|
|
756
763
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
enable_state = True
|
|
762
|
-
else:
|
|
763
|
-
for var in component._get_vars(include_children=True):
|
|
764
|
-
var_data = var._get_all_var_data()
|
|
765
|
-
if not var_data:
|
|
766
|
-
continue
|
|
767
|
-
if not var_data.state:
|
|
768
|
-
continue
|
|
764
|
+
enable_state = False
|
|
765
|
+
# Ensure state is enabled if this page uses state.
|
|
766
|
+
if state is None:
|
|
767
|
+
if page.on_load or component._has_stateful_event_triggers():
|
|
769
768
|
enable_state = True
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
769
|
+
else:
|
|
770
|
+
for var in component._get_vars(include_children=True):
|
|
771
|
+
var_data = var._get_all_var_data()
|
|
772
|
+
if not var_data:
|
|
773
|
+
continue
|
|
774
|
+
if not var_data.state:
|
|
775
|
+
continue
|
|
776
|
+
enable_state = True
|
|
777
|
+
break
|
|
778
|
+
|
|
779
|
+
from reflex.app import OverlayFragment
|
|
780
|
+
from reflex.utils.format import make_default_page_title
|
|
781
|
+
|
|
782
|
+
component = OverlayFragment.create(component)
|
|
783
|
+
|
|
784
|
+
meta_args = {
|
|
785
|
+
"title": (
|
|
786
|
+
page.title
|
|
787
|
+
if page.title is not None
|
|
788
|
+
else make_default_page_title(get_config().app_name, route)
|
|
789
|
+
),
|
|
790
|
+
"image": page.image,
|
|
791
|
+
"meta": page.meta,
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
if page.description is not None:
|
|
795
|
+
meta_args["description"] = page.description
|
|
796
|
+
|
|
797
|
+
# Add meta information to the component.
|
|
798
|
+
utils.add_meta(
|
|
799
|
+
component,
|
|
800
|
+
**meta_args,
|
|
801
|
+
)
|
|
795
802
|
|
|
796
|
-
|
|
803
|
+
except Exception as e:
|
|
804
|
+
if sys.version_info >= (3, 11):
|
|
805
|
+
e.add_note(f"Happened while evaluating page {route!r}")
|
|
806
|
+
raise
|
|
807
|
+
else:
|
|
808
|
+
return component, enable_state
|
|
797
809
|
|
|
798
810
|
|
|
799
811
|
class ExecutorSafeFunctions:
|
|
@@ -873,5 +885,6 @@ class ExecutorSafeFunctions:
|
|
|
873
885
|
ValueError: If the style is not set.
|
|
874
886
|
"""
|
|
875
887
|
if style is None:
|
|
876
|
-
|
|
888
|
+
msg = "STYLE should be set"
|
|
889
|
+
raise ValueError(msg)
|
|
877
890
|
return compile_theme(style)
|
reflex/compiler/utils.py
CHANGED
|
@@ -60,7 +60,8 @@ def compile_import_statement(fields: list[ImportVar]) -> tuple[str, list[str]]:
|
|
|
60
60
|
# Check for default imports.
|
|
61
61
|
defaults = {field for field in fields_set if field.is_default}
|
|
62
62
|
if len(defaults) >= 2:
|
|
63
|
-
|
|
63
|
+
msg = "Only one default import is allowed."
|
|
64
|
+
raise ValueError(msg)
|
|
64
65
|
|
|
65
66
|
# Get the default import, and the specific imports.
|
|
66
67
|
default = next(iter({field.name for field in defaults}), "")
|
|
@@ -91,9 +92,8 @@ def validate_imports(import_dict: ParsedImportDict):
|
|
|
91
92
|
):
|
|
92
93
|
used_tags[import_name] = lib if lib[0] == "$" else already_imported
|
|
93
94
|
continue
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
95
|
+
msg = f"Can not compile, the tag {import_name} is used multiple time from {lib} and {used_tags[import_name]}"
|
|
96
|
+
raise ValueError(msg)
|
|
97
97
|
if import_name is not None:
|
|
98
98
|
used_tags[import_name] = lib
|
|
99
99
|
|
|
@@ -130,9 +130,11 @@ def compile_imports(import_dict: ParsedImportDict) -> list[dict]:
|
|
|
130
130
|
for path, (default, rest) in compiled.items():
|
|
131
131
|
if not lib:
|
|
132
132
|
if default:
|
|
133
|
-
|
|
133
|
+
msg = "No default field allowed for empty library."
|
|
134
|
+
raise ValueError(msg)
|
|
134
135
|
if rest is None or len(rest) == 0:
|
|
135
|
-
|
|
136
|
+
msg = "No fields to import."
|
|
137
|
+
raise ValueError(msg)
|
|
136
138
|
import_dicts.extend(get_import_dict(module) for module in sorted(rest))
|
|
137
139
|
continue
|
|
138
140
|
|
reflex/components/base/bare.py
CHANGED
|
@@ -43,9 +43,8 @@ def validate_str(value: str):
|
|
|
43
43
|
f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
|
|
44
44
|
)
|
|
45
45
|
elif perf_mode == PerformanceMode.RAISE:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)
|
|
46
|
+
msg = f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
|
|
47
|
+
raise ValueError(msg)
|
|
49
48
|
|
|
50
49
|
|
|
51
50
|
def _components_from_var(var: Var) -> Sequence[BaseComponent]:
|
|
@@ -72,10 +71,9 @@ class Bare(Component):
|
|
|
72
71
|
if isinstance(contents, LiteralStringVar):
|
|
73
72
|
validate_str(contents._var_value)
|
|
74
73
|
return cls._unsafe_create(children=[], contents=contents)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
contents = Var.create(contents if contents is not None else "")
|
|
74
|
+
if isinstance(contents, str):
|
|
75
|
+
validate_str(contents)
|
|
76
|
+
contents = Var.create(contents if contents is not None else "")
|
|
79
77
|
|
|
80
78
|
return cls._unsafe_create(children=[], contents=contents)
|
|
81
79
|
|
reflex/components/base/body.pyi
CHANGED
|
@@ -61,7 +61,6 @@ class NextDocumentLib(Component):
|
|
|
61
61
|
Returns:
|
|
62
62
|
The component.
|
|
63
63
|
"""
|
|
64
|
-
...
|
|
65
64
|
|
|
66
65
|
class Html(NextDocumentLib):
|
|
67
66
|
@overload
|
|
@@ -114,7 +113,6 @@ class Html(NextDocumentLib):
|
|
|
114
113
|
Returns:
|
|
115
114
|
The component.
|
|
116
115
|
"""
|
|
117
|
-
...
|
|
118
116
|
|
|
119
117
|
class DocumentHead(NextDocumentLib):
|
|
120
118
|
@overload
|
|
@@ -166,7 +164,6 @@ class DocumentHead(NextDocumentLib):
|
|
|
166
164
|
Returns:
|
|
167
165
|
The component.
|
|
168
166
|
"""
|
|
169
|
-
...
|
|
170
167
|
|
|
171
168
|
class Main(NextDocumentLib):
|
|
172
169
|
@overload
|
|
@@ -218,7 +215,6 @@ class Main(NextDocumentLib):
|
|
|
218
215
|
Returns:
|
|
219
216
|
The component.
|
|
220
217
|
"""
|
|
221
|
-
...
|
|
222
218
|
|
|
223
219
|
class NextScript(NextDocumentLib):
|
|
224
220
|
@overload
|
|
@@ -270,4 +266,3 @@ class NextScript(NextDocumentLib):
|
|
|
270
266
|
Returns:
|
|
271
267
|
The component.
|
|
272
268
|
"""
|
|
273
|
-
...
|
reflex/components/base/head.pyi
CHANGED
|
@@ -61,7 +61,6 @@ class NextHeadLib(Component):
|
|
|
61
61
|
Returns:
|
|
62
62
|
The component.
|
|
63
63
|
"""
|
|
64
|
-
...
|
|
65
64
|
|
|
66
65
|
class Head(NextHeadLib, MemoizationLeaf):
|
|
67
66
|
@overload
|
|
@@ -113,6 +112,5 @@ class Head(NextHeadLib, MemoizationLeaf):
|
|
|
113
112
|
Returns:
|
|
114
113
|
The memoization leaf
|
|
115
114
|
"""
|
|
116
|
-
...
|
|
117
115
|
|
|
118
116
|
head = Head.create
|
reflex/components/base/link.pyi
CHANGED
reflex/components/base/meta.py
CHANGED
|
@@ -20,7 +20,8 @@ class Title(elements.Title):
|
|
|
20
20
|
"""
|
|
21
21
|
# Make sure the title is a single string.
|
|
22
22
|
if len(self.children) != 1 or not isinstance(self.children[0], Bare):
|
|
23
|
-
|
|
23
|
+
msg = "Title must be a single string."
|
|
24
|
+
raise ValueError(msg)
|
|
24
25
|
return super().render()
|
|
25
26
|
|
|
26
27
|
|
reflex/components/base/meta.pyi
CHANGED
|
@@ -62,7 +62,6 @@ class Title(elements.Title):
|
|
|
62
62
|
Returns:
|
|
63
63
|
The component.
|
|
64
64
|
"""
|
|
65
|
-
...
|
|
66
65
|
|
|
67
66
|
class Meta(elements.Meta):
|
|
68
67
|
@overload
|
|
@@ -318,7 +317,6 @@ class Meta(elements.Meta):
|
|
|
318
317
|
Returns:
|
|
319
318
|
The component.
|
|
320
319
|
"""
|
|
321
|
-
...
|
|
322
320
|
|
|
323
321
|
class Description(elements.Meta):
|
|
324
322
|
@overload
|
|
@@ -572,7 +570,6 @@ class Description(elements.Meta):
|
|
|
572
570
|
Returns:
|
|
573
571
|
The component.
|
|
574
572
|
"""
|
|
575
|
-
...
|
|
576
573
|
|
|
577
574
|
class Image(elements.Meta):
|
|
578
575
|
@overload
|
|
@@ -828,4 +825,3 @@ class Image(elements.Meta):
|
|
|
828
825
|
Returns:
|
|
829
826
|
The component.
|
|
830
827
|
"""
|
|
831
|
-
...
|
reflex/components/base/script.py
CHANGED
|
@@ -68,7 +68,8 @@ class Script(Component):
|
|
|
68
68
|
ValueError: when neither children nor `src` are specified.
|
|
69
69
|
"""
|
|
70
70
|
if not children and not props.get("src"):
|
|
71
|
-
|
|
71
|
+
msg = "Must provide inline script or `src` prop."
|
|
72
|
+
raise ValueError(msg)
|
|
72
73
|
return super().create(*children, **props)
|
|
73
74
|
|
|
74
75
|
|
reflex/components/component.py
CHANGED
|
@@ -157,7 +157,8 @@ class ComponentField(Generic[FIELD_TYPE]):
|
|
|
157
157
|
return self.default
|
|
158
158
|
if self.default_factory is not None:
|
|
159
159
|
return self.default_factory()
|
|
160
|
-
|
|
160
|
+
msg = "No default value or factory provided."
|
|
161
|
+
raise ValueError(msg)
|
|
161
162
|
|
|
162
163
|
def __repr__(self) -> str:
|
|
163
164
|
"""Represent the field in a readable format.
|
|
@@ -194,7 +195,8 @@ def field(
|
|
|
194
195
|
ValueError: If both default and default_factory are specified.
|
|
195
196
|
"""
|
|
196
197
|
if default is not MISSING and default_factory is not None:
|
|
197
|
-
|
|
198
|
+
msg = "cannot specify both default and default_factory"
|
|
199
|
+
raise ValueError(msg)
|
|
198
200
|
return ComponentField( # pyright: ignore [reportReturnType]
|
|
199
201
|
default=default,
|
|
200
202
|
default_factory=default_factory,
|
|
@@ -286,10 +288,11 @@ class BaseComponentMeta(ABCMeta):
|
|
|
286
288
|
|
|
287
289
|
namespace["_own_fields"] = own_fields
|
|
288
290
|
namespace["_inherited_fields"] = inherited_fields
|
|
289
|
-
|
|
291
|
+
all_fields = inherited_fields | own_fields
|
|
292
|
+
namespace["_fields"] = all_fields
|
|
290
293
|
namespace["_js_fields"] = {
|
|
291
294
|
key: value
|
|
292
|
-
for key, value in
|
|
295
|
+
for key, value in all_fields.items()
|
|
293
296
|
if value.is_javascript is True
|
|
294
297
|
}
|
|
295
298
|
return super().__new__(cls, name, bases, namespace)
|
|
@@ -769,11 +772,12 @@ class Component(BaseComponent, ABC):
|
|
|
769
772
|
and key not in component_specific_triggers
|
|
770
773
|
and key not in props
|
|
771
774
|
):
|
|
772
|
-
|
|
775
|
+
msg = (
|
|
773
776
|
f"The {(comp_name := type(self).__name__)} does not take in an `{key}` event trigger. If {comp_name}"
|
|
774
777
|
f" is a third party component make sure to add `{key}` to the component's event triggers. "
|
|
775
778
|
f"visit https://reflex.dev/docs/wrapping-react/guide/#event-triggers for more info."
|
|
776
779
|
)
|
|
780
|
+
raise ValueError(msg)
|
|
777
781
|
if key in component_specific_triggers:
|
|
778
782
|
# Event triggers are bound to event chains.
|
|
779
783
|
is_var = False
|
|
@@ -844,7 +848,8 @@ class Component(BaseComponent, ABC):
|
|
|
844
848
|
style = kwargs.get("style", {})
|
|
845
849
|
if isinstance(style, Sequence):
|
|
846
850
|
if any(not isinstance(s, Mapping) for s in style):
|
|
847
|
-
|
|
851
|
+
msg = "Style must be a dictionary or a list of dictionaries."
|
|
852
|
+
raise TypeError(msg)
|
|
848
853
|
# Merge styles, the later ones overriding keys in the earlier ones.
|
|
849
854
|
style = {
|
|
850
855
|
k: v
|
|
@@ -879,14 +884,12 @@ class Component(BaseComponent, ABC):
|
|
|
879
884
|
if not isinstance(c, StringVar) and not issubclass(
|
|
880
885
|
c._var_type, str
|
|
881
886
|
):
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
)
|
|
887
|
+
msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c._js_expr} of type {c._var_type}."
|
|
888
|
+
raise TypeError(msg)
|
|
885
889
|
has_var = True
|
|
886
890
|
else:
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
)
|
|
891
|
+
msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {c} of type {type(c)}."
|
|
892
|
+
raise TypeError(msg)
|
|
890
893
|
if has_var:
|
|
891
894
|
kwargs["class_name"] = LiteralArrayVar.create(
|
|
892
895
|
class_name, _var_type=list[str]
|
|
@@ -898,9 +901,8 @@ class Component(BaseComponent, ABC):
|
|
|
898
901
|
and not isinstance(class_name, StringVar)
|
|
899
902
|
and not issubclass(class_name._var_type, str)
|
|
900
903
|
):
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
)
|
|
904
|
+
msg = f"Invalid class_name passed for prop {type(self).__name__}.class_name, expected type str, got value {class_name._js_expr} of type {class_name._var_type}."
|
|
905
|
+
raise TypeError(msg)
|
|
904
906
|
# Construct the component.
|
|
905
907
|
for key, value in kwargs.items():
|
|
906
908
|
setattr(self, key, value)
|
|
@@ -1015,7 +1017,7 @@ class Component(BaseComponent, ABC):
|
|
|
1015
1017
|
Returns:
|
|
1016
1018
|
The unique fields.
|
|
1017
1019
|
"""
|
|
1018
|
-
return set(cls.
|
|
1020
|
+
return set(cls.get_js_fields())
|
|
1019
1021
|
|
|
1020
1022
|
@classmethod
|
|
1021
1023
|
@functools.cache
|
|
@@ -1227,9 +1229,8 @@ class Component(BaseComponent, ABC):
|
|
|
1227
1229
|
"""
|
|
1228
1230
|
# 1. Default style from `_add_style`/`add_style`.
|
|
1229
1231
|
if type(self)._add_style != Component._add_style:
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
)
|
|
1232
|
+
msg = "Do not override _add_style directly. Use add_style instead."
|
|
1233
|
+
raise UserWarning(msg)
|
|
1233
1234
|
new_style = self._add_style()
|
|
1234
1235
|
style_vars = [new_style._var_data]
|
|
1235
1236
|
|
|
@@ -1347,9 +1348,8 @@ class Component(BaseComponent, ABC):
|
|
|
1347
1348
|
validate_child(child.default)
|
|
1348
1349
|
|
|
1349
1350
|
if self._invalid_children and child_name in self._invalid_children:
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
)
|
|
1351
|
+
msg = f"The component `{comp_name}` cannot have `{child_name}` as a child component"
|
|
1352
|
+
raise ValueError(msg)
|
|
1353
1353
|
|
|
1354
1354
|
if self._valid_children and child_name not in [
|
|
1355
1355
|
*self._valid_children,
|
|
@@ -1358,9 +1358,8 @@ class Component(BaseComponent, ABC):
|
|
|
1358
1358
|
valid_child_list = ", ".join(
|
|
1359
1359
|
[f"`{v_child}`" for v_child in self._valid_children]
|
|
1360
1360
|
)
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
)
|
|
1361
|
+
msg = f"The component `{comp_name}` only allows the components: {valid_child_list} as children. Got `{child_name}` instead."
|
|
1362
|
+
raise ValueError(msg)
|
|
1364
1363
|
|
|
1365
1364
|
if child._valid_parents and all(
|
|
1366
1365
|
clz_name not in [*child._valid_parents, *allowed_components]
|
|
@@ -1369,9 +1368,8 @@ class Component(BaseComponent, ABC):
|
|
|
1369
1368
|
valid_parent_list = ", ".join(
|
|
1370
1369
|
[f"`{v_parent}`" for v_parent in child._valid_parents]
|
|
1371
1370
|
)
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
)
|
|
1371
|
+
msg = f"The component `{child_name}` can only be a child of the components: {valid_parent_list}. Got `{comp_name}` instead."
|
|
1372
|
+
raise ValueError(msg)
|
|
1375
1373
|
|
|
1376
1374
|
for child in children:
|
|
1377
1375
|
validate_child(child)
|
|
@@ -1502,13 +1500,9 @@ class Component(BaseComponent, ABC):
|
|
|
1502
1500
|
"""
|
|
1503
1501
|
if self.event_triggers and self._event_trigger_values_use_state():
|
|
1504
1502
|
return True
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
isinstance(child, Component)
|
|
1509
|
-
and child._has_stateful_event_triggers()
|
|
1510
|
-
):
|
|
1511
|
-
return True
|
|
1503
|
+
for child in self.children:
|
|
1504
|
+
if isinstance(child, Component) and child._has_stateful_event_triggers():
|
|
1505
|
+
return True
|
|
1512
1506
|
return False
|
|
1513
1507
|
|
|
1514
1508
|
@classmethod
|
|
@@ -1767,6 +1761,7 @@ class Component(BaseComponent, ABC):
|
|
|
1767
1761
|
{on_unmount or ""}
|
|
1768
1762
|
}}
|
|
1769
1763
|
}}, []);"""
|
|
1764
|
+
return None
|
|
1770
1765
|
|
|
1771
1766
|
def _get_ref_hook(self) -> Var | None:
|
|
1772
1767
|
"""Generate the ref hook for the component.
|
|
@@ -1780,6 +1775,7 @@ class Component(BaseComponent, ABC):
|
|
|
1780
1775
|
f"const {ref} = useRef(null); {Var(_js_expr=ref)._as_ref()!s} = {ref};",
|
|
1781
1776
|
_var_data=VarData(position=Hooks.HookPosition.INTERNAL),
|
|
1782
1777
|
)
|
|
1778
|
+
return None
|
|
1783
1779
|
|
|
1784
1780
|
def _get_vars_hooks(self) -> dict[str, VarData | None]:
|
|
1785
1781
|
"""Get the hooks required by vars referenced in this component.
|
|
@@ -2222,7 +2218,7 @@ def _register_custom_component(
|
|
|
2222
2218
|
_var_type=unwrap_var_annotation(annotation),
|
|
2223
2219
|
).guess_type()
|
|
2224
2220
|
if not types.safe_issubclass(annotation, EventHandler)
|
|
2225
|
-
else EventSpec(handler=EventHandler(fn=
|
|
2221
|
+
else EventSpec(handler=EventHandler(fn=no_args_event_spec))
|
|
2226
2222
|
)
|
|
2227
2223
|
for prop, annotation in typing.get_type_hints(component_fn).items()
|
|
2228
2224
|
if prop != "return"
|
|
@@ -2233,7 +2229,8 @@ def _register_custom_component(
|
|
|
2233
2229
|
**dummy_props,
|
|
2234
2230
|
)
|
|
2235
2231
|
if dummy_component.tag is None:
|
|
2236
|
-
|
|
2232
|
+
msg = f"Could not determine the tag name for {component_fn!r}"
|
|
2233
|
+
raise TypeError(msg)
|
|
2237
2234
|
CUSTOM_COMPONENTS[dummy_component.tag] = dummy_component
|
|
2238
2235
|
|
|
2239
2236
|
|
|
@@ -2312,7 +2309,8 @@ class NoSSRComponent(Component):
|
|
|
2312
2309
|
# extract the correct import name from library name
|
|
2313
2310
|
base_import_name = self._get_import_name()
|
|
2314
2311
|
if base_import_name is None:
|
|
2315
|
-
|
|
2312
|
+
msg = "Undefined library for NoSSRComponent"
|
|
2313
|
+
raise ValueError(msg)
|
|
2316
2314
|
import_name = format.format_library_name(base_import_name)
|
|
2317
2315
|
|
|
2318
2316
|
library_import = f"const {self.alias if self.alias else self.tag} = dynamic(() => import('{import_name}')"
|
|
@@ -2320,7 +2318,7 @@ class NoSSRComponent(Component):
|
|
|
2320
2318
|
# https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#with-named-exports
|
|
2321
2319
|
f".then((mod) => mod.{self.tag})" if not self.is_default else ""
|
|
2322
2320
|
)
|
|
2323
|
-
return
|
|
2321
|
+
return library_import + mod_import + opts_fragment
|
|
2324
2322
|
|
|
2325
2323
|
|
|
2326
2324
|
class StatefulComponent(BaseComponent):
|
|
@@ -2540,7 +2538,7 @@ class StatefulComponent(BaseComponent):
|
|
|
2540
2538
|
var_name = var_name.strip()
|
|
2541
2539
|
|
|
2542
2540
|
# Break up array and object destructuring if used.
|
|
2543
|
-
if var_name.startswith("["
|
|
2541
|
+
if var_name.startswith(("[", "{")):
|
|
2544
2542
|
return [
|
|
2545
2543
|
v.strip().replace("...", "") for v in var_name.strip("[]{}").split(",")
|
|
2546
2544
|
]
|