reflex 0.6.0a4__py3-none-any.whl → 0.6.1__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/_app.js.jinja2 +14 -0
- reflex/.templates/web/utils/state.js +67 -40
- reflex/app.py +9 -5
- reflex/app_mixins/lifespan.py +24 -6
- reflex/base.py +7 -13
- reflex/compiler/utils.py +17 -8
- reflex/components/base/bare.py +3 -1
- reflex/components/base/meta.py +5 -3
- reflex/components/component.py +19 -19
- reflex/components/core/cond.py +4 -4
- reflex/components/datadisplay/__init__.py +0 -1
- reflex/components/datadisplay/__init__.pyi +0 -1
- reflex/components/datadisplay/code.py +93 -106
- reflex/components/datadisplay/code.pyi +710 -53
- reflex/components/datadisplay/logo.py +22 -20
- reflex/components/dynamic.py +157 -0
- reflex/components/el/elements/forms.py +4 -1
- reflex/components/gridjs/datatable.py +2 -1
- reflex/components/markdown/markdown.py +10 -6
- reflex/components/markdown/markdown.pyi +3 -0
- reflex/components/radix/themes/components/progress.py +22 -0
- reflex/components/radix/themes/components/progress.pyi +2 -0
- reflex/components/radix/themes/components/segmented_control.py +3 -0
- reflex/components/radix/themes/components/segmented_control.pyi +2 -0
- reflex/components/radix/themes/layout/stack.py +1 -1
- reflex/components/recharts/cartesian.py +1 -1
- reflex/components/sonner/toast.py +3 -3
- reflex/components/tags/iter_tag.py +5 -1
- reflex/config.py +2 -2
- reflex/constants/base.py +4 -1
- reflex/constants/installer.py +8 -1
- reflex/event.py +61 -20
- reflex/experimental/assets.py +3 -1
- reflex/experimental/client_state.py +5 -1
- reflex/experimental/misc.py +5 -3
- reflex/middleware/hydrate_middleware.py +1 -2
- reflex/page.py +10 -3
- reflex/reflex.py +20 -3
- reflex/state.py +105 -43
- reflex/style.py +12 -2
- reflex/testing.py +8 -4
- reflex/utils/console.py +1 -1
- reflex/utils/exceptions.py +4 -0
- reflex/utils/exec.py +170 -18
- reflex/utils/format.py +6 -44
- reflex/utils/path_ops.py +36 -1
- reflex/utils/prerequisites.py +42 -14
- reflex/utils/serializers.py +7 -46
- reflex/utils/types.py +17 -2
- reflex/vars/base.py +303 -43
- reflex/vars/number.py +3 -0
- reflex/vars/sequence.py +43 -0
- {reflex-0.6.0a4.dist-info → reflex-0.6.1.dist-info}/METADATA +2 -3
- {reflex-0.6.0a4.dist-info → reflex-0.6.1.dist-info}/RECORD +57 -56
- {reflex-0.6.0a4.dist-info → reflex-0.6.1.dist-info}/LICENSE +0 -0
- {reflex-0.6.0a4.dist-info → reflex-0.6.1.dist-info}/WHEEL +0 -0
- {reflex-0.6.0a4.dist-info → reflex-0.6.1.dist-info}/entry_points.txt +0 -0
|
@@ -12,31 +12,33 @@ def logo(**props):
|
|
|
12
12
|
Returns:
|
|
13
13
|
The logo component.
|
|
14
14
|
"""
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<path d="M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z" fill="white"/>
|
|
31
|
-
</svg>"""
|
|
15
|
+
|
|
16
|
+
def logo_path(d):
|
|
17
|
+
return rx.el.svg.path(
|
|
18
|
+
d=d,
|
|
19
|
+
fill=rx.color_mode_cond("#110F1F", "white"),
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
paths = [
|
|
23
|
+
"M0 11.5999V0.399902H8.96V4.8799H6.72V2.6399H2.24V4.8799H6.72V7.1199H2.24V11.5999H0ZM6.72 11.5999V7.1199H8.96V11.5999H6.72Z",
|
|
24
|
+
"M11.2 11.5999V0.399902H17.92V2.6399H13.44V4.8799H17.92V7.1199H13.44V9.3599H17.92V11.5999H11.2Z",
|
|
25
|
+
"M20.16 11.5999V0.399902H26.88V2.6399H22.4V4.8799H26.88V7.1199H22.4V11.5999H20.16Z",
|
|
26
|
+
"M29.12 11.5999V0.399902H31.36V9.3599H35.84V11.5999H29.12Z",
|
|
27
|
+
"M38.08 11.5999V0.399902H44.8V2.6399H40.32V4.8799H44.8V7.1199H40.32V9.3599H44.8V11.5999H38.08Z",
|
|
28
|
+
"M47.04 4.8799V0.399902H49.28V4.8799H47.04ZM53.76 4.8799V0.399902H56V4.8799H53.76ZM49.28 7.1199V4.8799H53.76V7.1199H49.28ZM47.04 11.5999V7.1199H49.28V11.5999H47.04ZM53.76 11.5999V7.1199H56V11.5999H53.76Z",
|
|
29
|
+
]
|
|
32
30
|
|
|
33
31
|
return rx.center(
|
|
34
32
|
rx.link(
|
|
35
33
|
rx.hstack(
|
|
36
34
|
"Built with ",
|
|
37
|
-
rx.
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
rx.el.svg(
|
|
36
|
+
*[logo_path(d) for d in paths],
|
|
37
|
+
width="56",
|
|
38
|
+
height="12",
|
|
39
|
+
viewBox="0 0 56 12",
|
|
40
|
+
fill="none",
|
|
41
|
+
xmlns="http://www.w3.org/2000/svg",
|
|
40
42
|
),
|
|
41
43
|
text_align="center",
|
|
42
44
|
align="center",
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""Components that are dynamically generated on the backend."""
|
|
2
|
+
|
|
3
|
+
from reflex import constants
|
|
4
|
+
from reflex.utils import imports
|
|
5
|
+
from reflex.utils.serializers import serializer
|
|
6
|
+
from reflex.vars import Var, get_unique_variable_name
|
|
7
|
+
from reflex.vars.base import VarData, transform
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_cdn_url(lib: str) -> str:
|
|
11
|
+
"""Get the CDN URL for a library.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
lib: The library to get the CDN URL for.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
The CDN URL for the library.
|
|
18
|
+
"""
|
|
19
|
+
return f"https://cdn.jsdelivr.net/npm/{lib}" + "/+esm"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def load_dynamic_serializer():
|
|
23
|
+
"""Load the serializer for dynamic components."""
|
|
24
|
+
# Causes a circular import, so we import here.
|
|
25
|
+
from reflex.components.component import Component
|
|
26
|
+
|
|
27
|
+
@serializer
|
|
28
|
+
def make_component(component: Component) -> str:
|
|
29
|
+
"""Generate the code for a dynamic component.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
component: The component to generate code for.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
The generated code
|
|
36
|
+
"""
|
|
37
|
+
# Causes a circular import, so we import here.
|
|
38
|
+
from reflex.compiler import templates, utils
|
|
39
|
+
|
|
40
|
+
rendered_components = {}
|
|
41
|
+
# Include dynamic imports in the shared component.
|
|
42
|
+
if dynamic_imports := component._get_all_dynamic_imports():
|
|
43
|
+
rendered_components.update(
|
|
44
|
+
{dynamic_import: None for dynamic_import in dynamic_imports}
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Include custom code in the shared component.
|
|
48
|
+
rendered_components.update(
|
|
49
|
+
{code: None for code in component._get_all_custom_code()},
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
rendered_components[
|
|
53
|
+
templates.STATEFUL_COMPONENT.render(
|
|
54
|
+
tag_name="MySSRComponent",
|
|
55
|
+
memo_trigger_hooks=[],
|
|
56
|
+
component=component,
|
|
57
|
+
)
|
|
58
|
+
] = None
|
|
59
|
+
|
|
60
|
+
libs_in_window = [
|
|
61
|
+
"react",
|
|
62
|
+
"@radix-ui/themes",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
imports = {}
|
|
66
|
+
for lib, names in component._get_all_imports().items():
|
|
67
|
+
if (
|
|
68
|
+
not lib.startswith((".", "/"))
|
|
69
|
+
and not lib.startswith("http")
|
|
70
|
+
and all(
|
|
71
|
+
not lib.startswith(lib_in_window)
|
|
72
|
+
for lib_in_window in libs_in_window
|
|
73
|
+
)
|
|
74
|
+
):
|
|
75
|
+
imports[get_cdn_url(lib)] = names
|
|
76
|
+
else:
|
|
77
|
+
imports[lib] = names
|
|
78
|
+
|
|
79
|
+
module_code_lines = templates.STATEFUL_COMPONENTS.render(
|
|
80
|
+
imports=utils.compile_imports(imports),
|
|
81
|
+
memoized_code="\n".join(rendered_components),
|
|
82
|
+
).splitlines()[1:]
|
|
83
|
+
|
|
84
|
+
# Rewrite imports from `/` to destructure from window
|
|
85
|
+
for ix, line in enumerate(module_code_lines[:]):
|
|
86
|
+
if line.startswith("import "):
|
|
87
|
+
if 'from "/' in line:
|
|
88
|
+
module_code_lines[ix] = (
|
|
89
|
+
line.replace("import ", "const ", 1).replace(
|
|
90
|
+
" from ", " = window['__reflex'][", 1
|
|
91
|
+
)
|
|
92
|
+
+ "]"
|
|
93
|
+
)
|
|
94
|
+
else:
|
|
95
|
+
for lib in libs_in_window:
|
|
96
|
+
if f'from "{lib}"' in line:
|
|
97
|
+
module_code_lines[ix] = (
|
|
98
|
+
line.replace("import ", "const ", 1)
|
|
99
|
+
.replace(
|
|
100
|
+
f' from "{lib}"', f" = window.__reflex['{lib}']", 1
|
|
101
|
+
)
|
|
102
|
+
.replace(" as ", ": ")
|
|
103
|
+
)
|
|
104
|
+
if line.startswith("export function"):
|
|
105
|
+
module_code_lines[ix] = line.replace(
|
|
106
|
+
"export function", "export default function", 1
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
module_code_lines.insert(0, "const React = window.__reflex.react;")
|
|
110
|
+
|
|
111
|
+
return "//__reflex_evaluate\n" + "\n".join(module_code_lines)
|
|
112
|
+
|
|
113
|
+
@transform
|
|
114
|
+
def evaluate_component(js_string: Var[str]) -> Var[Component]:
|
|
115
|
+
"""Evaluate a component.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
js_string: The JavaScript string to evaluate.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
The evaluated JavaScript string.
|
|
122
|
+
"""
|
|
123
|
+
unique_var_name = get_unique_variable_name()
|
|
124
|
+
|
|
125
|
+
return js_string._replace(
|
|
126
|
+
_js_expr=unique_var_name,
|
|
127
|
+
_var_type=Component,
|
|
128
|
+
merge_var_data=VarData.merge(
|
|
129
|
+
VarData(
|
|
130
|
+
imports={
|
|
131
|
+
f"/{constants.Dirs.STATE_PATH}": [
|
|
132
|
+
imports.ImportVar(tag="evalReactComponent"),
|
|
133
|
+
],
|
|
134
|
+
"react": [
|
|
135
|
+
imports.ImportVar(tag="useState"),
|
|
136
|
+
imports.ImportVar(tag="useEffect"),
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
hooks={
|
|
140
|
+
f"const [{unique_var_name}, set_{unique_var_name}] = useState(null);": None,
|
|
141
|
+
"useEffect(() => {"
|
|
142
|
+
"let isMounted = true;"
|
|
143
|
+
f"evalReactComponent({str(js_string)})"
|
|
144
|
+
".then((component) => {"
|
|
145
|
+
"if (isMounted) {"
|
|
146
|
+
f"set_{unique_var_name}(component);"
|
|
147
|
+
"}"
|
|
148
|
+
"});"
|
|
149
|
+
"return () => {"
|
|
150
|
+
"isMounted = false;"
|
|
151
|
+
"};"
|
|
152
|
+
"}"
|
|
153
|
+
f", [{str(js_string)}]);": None,
|
|
154
|
+
},
|
|
155
|
+
),
|
|
156
|
+
),
|
|
157
|
+
)
|
|
@@ -10,7 +10,7 @@ from jinja2 import Environment
|
|
|
10
10
|
from reflex.components.el.element import Element
|
|
11
11
|
from reflex.components.tags.tag import Tag
|
|
12
12
|
from reflex.constants import Dirs, EventTriggers
|
|
13
|
-
from reflex.event import EventChain, EventHandler
|
|
13
|
+
from reflex.event import EventChain, EventHandler, prevent_default
|
|
14
14
|
from reflex.utils.imports import ImportDict
|
|
15
15
|
from reflex.vars import VarData
|
|
16
16
|
from reflex.vars.base import LiteralVar, Var
|
|
@@ -148,6 +148,9 @@ class Form(BaseHTML):
|
|
|
148
148
|
Returns:
|
|
149
149
|
The form component.
|
|
150
150
|
"""
|
|
151
|
+
if "on_submit" not in props:
|
|
152
|
+
props["on_submit"] = prevent_default
|
|
153
|
+
|
|
151
154
|
if "handle_submit_unique_name" in props:
|
|
152
155
|
return super().create(*children, **props)
|
|
153
156
|
|
|
@@ -124,7 +124,8 @@ class DataTable(Gridjs):
|
|
|
124
124
|
if types.is_dataframe(type(self.data)):
|
|
125
125
|
# If given a pandas df break up the data and columns
|
|
126
126
|
data = serialize(self.data)
|
|
127
|
-
|
|
127
|
+
if not isinstance(data, dict):
|
|
128
|
+
raise ValueError("Serialized dataframe should be a dict.")
|
|
128
129
|
self.columns = LiteralVar.create(data["columns"])
|
|
129
130
|
self.data = LiteralVar.create(data["data"])
|
|
130
131
|
|
|
@@ -95,12 +95,16 @@ class Markdown(Component):
|
|
|
95
95
|
*children: The children of the component.
|
|
96
96
|
**props: The properties of the component.
|
|
97
97
|
|
|
98
|
+
Raises:
|
|
99
|
+
ValueError: If the children are not valid.
|
|
100
|
+
|
|
98
101
|
Returns:
|
|
99
102
|
The markdown component.
|
|
100
103
|
"""
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
if len(children) != 1 or not types._isinstance(children[0], Union[str, Var]):
|
|
105
|
+
raise ValueError(
|
|
106
|
+
"Markdown component must have exactly one child containing the markdown source."
|
|
107
|
+
)
|
|
104
108
|
|
|
105
109
|
# Update the base component map with the custom component map.
|
|
106
110
|
component_map = {**get_base_component_map(), **props.pop("component_map", {})}
|
|
@@ -147,7 +151,7 @@ class Markdown(Component):
|
|
|
147
151
|
Returns:
|
|
148
152
|
The imports for the markdown component.
|
|
149
153
|
"""
|
|
150
|
-
from reflex.components.datadisplay.code import CodeBlock
|
|
154
|
+
from reflex.components.datadisplay.code import CodeBlock, Theme
|
|
151
155
|
from reflex.components.radix.themes.typography.code import Code
|
|
152
156
|
|
|
153
157
|
return [
|
|
@@ -173,8 +177,8 @@ class Markdown(Component):
|
|
|
173
177
|
component(_MOCK_ARG)._get_all_imports() # type: ignore
|
|
174
178
|
for component in self.component_map.values()
|
|
175
179
|
],
|
|
176
|
-
CodeBlock.create(theme=
|
|
177
|
-
Code.create()._get_imports(),
|
|
180
|
+
CodeBlock.create(theme=Theme.light)._get_imports(),
|
|
181
|
+
Code.create()._get_imports(),
|
|
178
182
|
]
|
|
179
183
|
|
|
180
184
|
def get_component(self, tag: str, **props) -> Component:
|
|
@@ -4,6 +4,7 @@ from typing import Literal
|
|
|
4
4
|
|
|
5
5
|
from reflex.components.component import Component
|
|
6
6
|
from reflex.components.core.breakpoints import Responsive
|
|
7
|
+
from reflex.style import Style
|
|
7
8
|
from reflex.vars.base import Var
|
|
8
9
|
|
|
9
10
|
from ..base import LiteralAccentColor, RadixThemesComponent
|
|
@@ -38,6 +39,21 @@ class Progress(RadixThemesComponent):
|
|
|
38
39
|
# The duration of the progress bar animation. Once the duration times out, the progress bar will start an indeterminate animation.
|
|
39
40
|
duration: Var[str]
|
|
40
41
|
|
|
42
|
+
# The color of the progress bar fill animation.
|
|
43
|
+
fill_color: Var[str]
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def _color_selector(color: str) -> Style:
|
|
47
|
+
"""Return a style object with the correct color and css selector.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
color: Color of the fill part.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Style: Style object with the correct css selector and color.
|
|
54
|
+
"""
|
|
55
|
+
return Style({".rt-ProgressIndicator": {"background_color": color}})
|
|
56
|
+
|
|
41
57
|
@classmethod
|
|
42
58
|
def create(cls, *children, **props) -> Component:
|
|
43
59
|
"""Create a Progress component.
|
|
@@ -50,6 +66,12 @@ class Progress(RadixThemesComponent):
|
|
|
50
66
|
The Progress Component.
|
|
51
67
|
"""
|
|
52
68
|
props.setdefault("width", "100%")
|
|
69
|
+
if "fill_color" in props:
|
|
70
|
+
color = props.get("fill_color", "")
|
|
71
|
+
style = props.get("style", {})
|
|
72
|
+
style = style | cls._color_selector(color)
|
|
73
|
+
props["style"] = style
|
|
74
|
+
|
|
53
75
|
return super().create(*children, **props)
|
|
54
76
|
|
|
55
77
|
|
|
@@ -107,6 +107,7 @@ class Progress(RadixThemesComponent):
|
|
|
107
107
|
]
|
|
108
108
|
] = None,
|
|
109
109
|
duration: Optional[Union[Var[str], str]] = None,
|
|
110
|
+
fill_color: Optional[Union[Var[str], str]] = None,
|
|
110
111
|
style: Optional[Style] = None,
|
|
111
112
|
key: Optional[Any] = None,
|
|
112
113
|
id: Optional[Any] = None,
|
|
@@ -162,6 +163,7 @@ class Progress(RadixThemesComponent):
|
|
|
162
163
|
high_contrast: Whether to render the progress bar with higher contrast color against background
|
|
163
164
|
radius: Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
|
|
164
165
|
duration: The duration of the progress bar animation. Once the duration times out, the progress bar will start an indeterminate animation.
|
|
166
|
+
fill_color: The color of the progress bar fill animation.
|
|
165
167
|
style: The style of the component.
|
|
166
168
|
key: A unique key for the component.
|
|
167
169
|
id: The id for the component.
|
|
@@ -23,6 +23,7 @@ class SegmentedControlRoot(RadixThemesComponent):
|
|
|
23
23
|
# Variant of button: "classic" | "surface"
|
|
24
24
|
variant: Var[Literal["classic", "surface"]]
|
|
25
25
|
|
|
26
|
+
# The type of the segmented control, either "single" for selecting one option or "multiple" for selecting multiple options.
|
|
26
27
|
type: Var[Literal["single", "multiple"]]
|
|
27
28
|
|
|
28
29
|
# Override theme color for button
|
|
@@ -34,8 +35,10 @@ class SegmentedControlRoot(RadixThemesComponent):
|
|
|
34
35
|
# The default value of the segmented control.
|
|
35
36
|
default_value: Var[Union[str, List[str]]]
|
|
36
37
|
|
|
38
|
+
# The current value of the segmented control.
|
|
37
39
|
value: Var[Union[str, List[str]]]
|
|
38
40
|
|
|
41
|
+
# Handles the `onChange` event for the SegmentedControl component.
|
|
39
42
|
on_change: EventHandler[lambda e0: [e0]]
|
|
40
43
|
|
|
41
44
|
_rename_props = {"onChange": "onValueChange"}
|
|
@@ -161,9 +161,11 @@ class SegmentedControlRoot(RadixThemesComponent):
|
|
|
161
161
|
*children: Child components.
|
|
162
162
|
size: The size of the segmented control: "1" | "2" | "3"
|
|
163
163
|
variant: Variant of button: "classic" | "surface"
|
|
164
|
+
type: The type of the segmented control, either "single" for selecting one option or "multiple" for selecting multiple options.
|
|
164
165
|
color_scheme: Override theme color for button
|
|
165
166
|
radius: The radius of the segmented control: "none" | "small" | "medium" | "large" | "full"
|
|
166
167
|
default_value: The default value of the segmented control.
|
|
168
|
+
value: The current value of the segmented control.
|
|
167
169
|
style: The style of the component.
|
|
168
170
|
key: A unique key for the component.
|
|
169
171
|
id: The id for the component.
|
|
@@ -33,7 +33,7 @@ class Stack(Flex):
|
|
|
33
33
|
"""
|
|
34
34
|
# Apply the default classname
|
|
35
35
|
given_class_name = props.pop("class_name", [])
|
|
36
|
-
if isinstance(given_class_name,
|
|
36
|
+
if not isinstance(given_class_name, list):
|
|
37
37
|
given_class_name = [given_class_name]
|
|
38
38
|
props["class_name"] = ["rx-Stack", *given_class_name]
|
|
39
39
|
|
|
@@ -17,7 +17,7 @@ from reflex.event import (
|
|
|
17
17
|
from reflex.style import Style, resolved_color_mode
|
|
18
18
|
from reflex.utils import format
|
|
19
19
|
from reflex.utils.imports import ImportVar
|
|
20
|
-
from reflex.utils.serializers import
|
|
20
|
+
from reflex.utils.serializers import serializer
|
|
21
21
|
from reflex.vars import VarData
|
|
22
22
|
from reflex.vars.base import LiteralVar, Var
|
|
23
23
|
|
|
@@ -281,8 +281,8 @@ class Toaster(Component):
|
|
|
281
281
|
if message == "" and ("title" not in props or "description" not in props):
|
|
282
282
|
raise ValueError("Toast message or title or description must be provided.")
|
|
283
283
|
if props:
|
|
284
|
-
args =
|
|
285
|
-
toast = f"{toast_command}(`{message}`, {args})"
|
|
284
|
+
args = LiteralVar.create(ToastProps(**props))
|
|
285
|
+
toast = f"{toast_command}(`{message}`, {str(args)})"
|
|
286
286
|
else:
|
|
287
287
|
toast = f"{toast_command}(`{message}`)"
|
|
288
288
|
|
|
@@ -114,6 +114,9 @@ class IterTag(Tag):
|
|
|
114
114
|
def render_component(self) -> Component:
|
|
115
115
|
"""Render the component.
|
|
116
116
|
|
|
117
|
+
Raises:
|
|
118
|
+
ValueError: If the render function takes more than 2 arguments.
|
|
119
|
+
|
|
117
120
|
Returns:
|
|
118
121
|
The rendered component.
|
|
119
122
|
"""
|
|
@@ -132,7 +135,8 @@ class IterTag(Tag):
|
|
|
132
135
|
component = self.render_fn(arg)
|
|
133
136
|
else:
|
|
134
137
|
# If the render function takes the index as an argument.
|
|
135
|
-
|
|
138
|
+
if len(args) != 2:
|
|
139
|
+
raise ValueError("The render function must take 2 arguments.")
|
|
136
140
|
component = self.render_fn(arg, index)
|
|
137
141
|
|
|
138
142
|
# Nested foreach components or cond must be wrapped in fragments.
|
reflex/config.py
CHANGED
|
@@ -158,7 +158,7 @@ class Config(Base):
|
|
|
158
158
|
app_name: str
|
|
159
159
|
|
|
160
160
|
# The log level to use.
|
|
161
|
-
loglevel: constants.LogLevel = constants.LogLevel.
|
|
161
|
+
loglevel: constants.LogLevel = constants.LogLevel.DEFAULT
|
|
162
162
|
|
|
163
163
|
# The port to run the frontend on. NOTE: When running in dev mode, the next available port will be used if this is taken.
|
|
164
164
|
frontend_port: int = constants.DefaultPorts.FRONTEND_PORT
|
|
@@ -194,7 +194,7 @@ class Config(Base):
|
|
|
194
194
|
cors_allowed_origins: List[str] = ["*"]
|
|
195
195
|
|
|
196
196
|
# Tailwind config.
|
|
197
|
-
tailwind: Optional[Dict[str, Any]] = {}
|
|
197
|
+
tailwind: Optional[Dict[str, Any]] = {"plugins": ["@tailwindcss/typography"]}
|
|
198
198
|
|
|
199
199
|
# Timeout when launching the gunicorn server. TODO(rename this to backend_timeout?)
|
|
200
200
|
timeout: int = 120
|
reflex/constants/base.py
CHANGED
|
@@ -117,7 +117,9 @@ class Templates(SimpleNamespace):
|
|
|
117
117
|
REFLEX_BUILD_POLL_URL = REFLEX_BUILD_BACKEND + "/api/init/{reflex_init_token}"
|
|
118
118
|
|
|
119
119
|
# The URL to fetch the generation's reflex code
|
|
120
|
-
REFLEX_BUILD_CODE_URL =
|
|
120
|
+
REFLEX_BUILD_CODE_URL = (
|
|
121
|
+
REFLEX_BUILD_BACKEND + "/api/gen/{generation_hash}/refactored"
|
|
122
|
+
)
|
|
121
123
|
|
|
122
124
|
class Dirs(SimpleNamespace):
|
|
123
125
|
"""Folders used by the template system of Reflex."""
|
|
@@ -171,6 +173,7 @@ class LogLevel(str, Enum):
|
|
|
171
173
|
"""The log levels."""
|
|
172
174
|
|
|
173
175
|
DEBUG = "debug"
|
|
176
|
+
DEFAULT = "default"
|
|
174
177
|
INFO = "info"
|
|
175
178
|
WARNING = "warning"
|
|
176
179
|
ERROR = "error"
|
reflex/constants/installer.py
CHANGED
|
@@ -54,6 +54,9 @@ class Bun(SimpleNamespace):
|
|
|
54
54
|
# Path of the bunfig file
|
|
55
55
|
CONFIG_PATH = "bunfig.toml"
|
|
56
56
|
|
|
57
|
+
# The environment variable to use the system installed bun.
|
|
58
|
+
USE_SYSTEM_VAR = "REFLEX_USE_SYSTEM_BUN"
|
|
59
|
+
|
|
57
60
|
|
|
58
61
|
# FNM config.
|
|
59
62
|
class Fnm(SimpleNamespace):
|
|
@@ -96,6 +99,9 @@ class Node(SimpleNamespace):
|
|
|
96
99
|
# The default path where npm is installed.
|
|
97
100
|
NPM_PATH = os.path.join(BIN_PATH, "npm")
|
|
98
101
|
|
|
102
|
+
# The environment variable to use the system installed node.
|
|
103
|
+
USE_SYSTEM_VAR = "REFLEX_USE_SYSTEM_NODE"
|
|
104
|
+
|
|
99
105
|
|
|
100
106
|
class PackageJson(SimpleNamespace):
|
|
101
107
|
"""Constants used to build the package.json file."""
|
|
@@ -111,10 +117,11 @@ class PackageJson(SimpleNamespace):
|
|
|
111
117
|
PATH = "package.json"
|
|
112
118
|
|
|
113
119
|
DEPENDENCIES = {
|
|
120
|
+
"@babel/standalone": "7.25.3",
|
|
114
121
|
"@emotion/react": "11.11.1",
|
|
115
122
|
"axios": "1.6.0",
|
|
116
123
|
"json5": "2.2.3",
|
|
117
|
-
"next": "14.
|
|
124
|
+
"next": "14.2.13",
|
|
118
125
|
"next-sitemap": "4.1.8",
|
|
119
126
|
"next-themes": "0.2.1",
|
|
120
127
|
"react": "18.2.0",
|