reflex 0.6.5a2__py3-none-any.whl → 0.6.6__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/web/utils/state.js +39 -14
- reflex/__init__.py +3 -1
- reflex/__init__.pyi +3 -0
- reflex/app.py +24 -4
- reflex/assets.py +95 -0
- reflex/base.py +2 -2
- reflex/components/base/error_boundary.py +99 -36
- reflex/components/base/error_boundary.pyi +3 -4
- reflex/components/component.py +29 -7
- reflex/components/core/cond.py +8 -0
- reflex/components/core/upload.py +8 -5
- reflex/components/datadisplay/code.py +1 -1
- reflex/components/datadisplay/logo.py +26 -13
- reflex/components/el/__init__.pyi +2 -0
- reflex/components/el/elements/__init__.py +1 -0
- reflex/components/el/elements/__init__.pyi +3 -0
- reflex/components/el/elements/forms.py +1 -0
- reflex/components/el/elements/forms.pyi +1 -0
- reflex/components/moment/moment.py +4 -3
- reflex/components/moment/moment.pyi +12 -2
- reflex/components/plotly/plotly.py +1 -1
- reflex/components/radix/primitives/drawer.py +5 -23
- reflex/components/radix/themes/base.py +3 -0
- reflex/components/radix/themes/components/segmented_control.py +3 -1
- reflex/components/radix/themes/components/segmented_control.pyi +7 -2
- reflex/components/radix/themes/components/text_field.py +3 -0
- reflex/components/radix/themes/components/text_field.pyi +4 -0
- reflex/components/recharts/recharts.py +2 -14
- reflex/components/recharts/recharts.pyi +0 -1
- reflex/components/sonner/toast.py +23 -12
- reflex/components/sonner/toast.pyi +6 -6
- reflex/config.py +60 -9
- reflex/constants/base.py +12 -0
- reflex/constants/installer.py +3 -3
- reflex/constants/style.py +1 -1
- reflex/event.py +22 -5
- reflex/experimental/assets.py +14 -36
- reflex/reflex.py +16 -35
- reflex/state.py +99 -28
- reflex/utils/exceptions.py +4 -0
- reflex/utils/prerequisites.py +174 -40
- reflex/utils/redir.py +13 -4
- reflex/utils/serializers.py +52 -1
- reflex/utils/telemetry.py +2 -1
- reflex/utils/types.py +52 -1
- reflex/vars/base.py +18 -4
- reflex/vars/function.py +283 -37
- {reflex-0.6.5a2.dist-info → reflex-0.6.6.dist-info}/METADATA +3 -2
- {reflex-0.6.5a2.dist-info → reflex-0.6.6.dist-info}/RECORD +52 -51
- {reflex-0.6.5a2.dist-info → reflex-0.6.6.dist-info}/LICENSE +0 -0
- {reflex-0.6.5a2.dist-info → reflex-0.6.6.dist-info}/WHEEL +0 -0
- {reflex-0.6.5a2.dist-info → reflex-0.6.6.dist-info}/entry_points.txt +0 -0
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
"""A Reflex logo component."""
|
|
2
2
|
|
|
3
|
+
from typing import Union
|
|
4
|
+
|
|
3
5
|
import reflex as rx
|
|
4
6
|
|
|
5
7
|
|
|
6
|
-
def
|
|
7
|
-
"""A Reflex logo.
|
|
8
|
+
def svg_logo(color: Union[str, rx.Var[str]] = rx.color_mode_cond("#110F1F", "white")):
|
|
9
|
+
"""A Reflex logo SVG.
|
|
8
10
|
|
|
9
11
|
Args:
|
|
10
|
-
|
|
12
|
+
color: The color of the logo.
|
|
11
13
|
|
|
12
14
|
Returns:
|
|
13
|
-
The logo
|
|
15
|
+
The Reflex logo SVG.
|
|
14
16
|
"""
|
|
15
17
|
|
|
16
18
|
def logo_path(d):
|
|
17
19
|
return rx.el.svg.path(
|
|
18
20
|
d=d,
|
|
19
|
-
fill=rx.color_mode_cond("#110F1F", "white"),
|
|
20
21
|
)
|
|
21
22
|
|
|
22
23
|
paths = [
|
|
@@ -28,18 +29,30 @@ def logo(**props):
|
|
|
28
29
|
"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
30
|
]
|
|
30
31
|
|
|
32
|
+
return rx.el.svg(
|
|
33
|
+
*[logo_path(d) for d in paths],
|
|
34
|
+
width="56",
|
|
35
|
+
height="12",
|
|
36
|
+
viewBox="0 0 56 12",
|
|
37
|
+
fill=color,
|
|
38
|
+
xmlns="http://www.w3.org/2000/svg",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def logo(**props):
|
|
43
|
+
"""A Reflex logo.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
**props: The props to pass to the component.
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
The logo component.
|
|
50
|
+
"""
|
|
31
51
|
return rx.center(
|
|
32
52
|
rx.link(
|
|
33
53
|
rx.hstack(
|
|
34
54
|
"Built with ",
|
|
35
|
-
|
|
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",
|
|
42
|
-
),
|
|
55
|
+
svg_logo(),
|
|
43
56
|
text_align="center",
|
|
44
57
|
align="center",
|
|
45
58
|
padding="1em",
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
from . import elements as elements
|
|
7
7
|
from .elements.forms import Button as Button
|
|
8
|
+
from .elements.forms import Datalist as Datalist
|
|
8
9
|
from .elements.forms import Fieldset as Fieldset
|
|
9
10
|
from .elements.forms import Form as Form
|
|
10
11
|
from .elements.forms import Input as Input
|
|
@@ -18,6 +19,7 @@ from .elements.forms import Progress as Progress
|
|
|
18
19
|
from .elements.forms import Select as Select
|
|
19
20
|
from .elements.forms import Textarea as Textarea
|
|
20
21
|
from .elements.forms import button as button
|
|
22
|
+
from .elements.forms import datalist as datalist
|
|
21
23
|
from .elements.forms import fieldset as fieldset
|
|
22
24
|
from .elements.forms import form as form
|
|
23
25
|
from .elements.forms import input as input
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# ------------------------------------------------------
|
|
5
5
|
|
|
6
6
|
from .forms import Button as Button
|
|
7
|
+
from .forms import Datalist as Datalist
|
|
7
8
|
from .forms import Fieldset as Fieldset
|
|
8
9
|
from .forms import Form as Form
|
|
9
10
|
from .forms import Input as Input
|
|
@@ -17,6 +18,7 @@ from .forms import Progress as Progress
|
|
|
17
18
|
from .forms import Select as Select
|
|
18
19
|
from .forms import Textarea as Textarea
|
|
19
20
|
from .forms import button as button
|
|
21
|
+
from .forms import datalist as datalist
|
|
20
22
|
from .forms import fieldset as fieldset
|
|
21
23
|
from .forms import form as form
|
|
22
24
|
from .forms import input as input
|
|
@@ -226,6 +228,7 @@ from .typography import ul as ul
|
|
|
226
228
|
_MAPPING = {
|
|
227
229
|
"forms": [
|
|
228
230
|
"button",
|
|
231
|
+
"datalist",
|
|
229
232
|
"fieldset",
|
|
230
233
|
"form",
|
|
231
234
|
"input",
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""Moment component for humanized date rendering."""
|
|
2
2
|
|
|
3
3
|
import dataclasses
|
|
4
|
-
from
|
|
4
|
+
from datetime import date, datetime, time, timedelta
|
|
5
|
+
from typing import List, Optional, Union
|
|
5
6
|
|
|
6
7
|
from reflex.components.component import NoSSRComponent
|
|
7
8
|
from reflex.event import EventHandler, passthrough_event_spec
|
|
@@ -19,7 +20,7 @@ class MomentDelta:
|
|
|
19
20
|
weeks: Optional[int] = dataclasses.field(default=None)
|
|
20
21
|
days: Optional[int] = dataclasses.field(default=None)
|
|
21
22
|
hours: Optional[int] = dataclasses.field(default=None)
|
|
22
|
-
|
|
23
|
+
minutes: Optional[int] = dataclasses.field(default=None)
|
|
23
24
|
seconds: Optional[int] = dataclasses.field(default=None)
|
|
24
25
|
milliseconds: Optional[int] = dataclasses.field(default=None)
|
|
25
26
|
|
|
@@ -78,7 +79,7 @@ class Moment(NoSSRComponent):
|
|
|
78
79
|
duration: Var[str]
|
|
79
80
|
|
|
80
81
|
# The date to display (also work if passed as children).
|
|
81
|
-
date: Var[str]
|
|
82
|
+
date: Var[Union[str, datetime, date, time, timedelta]]
|
|
82
83
|
|
|
83
84
|
# Shows the duration (elapsed time) between now and the provided datetime.
|
|
84
85
|
duration_from_now: Var[bool]
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
|
5
5
|
# ------------------------------------------------------
|
|
6
6
|
import dataclasses
|
|
7
|
+
from datetime import date, datetime, time, timedelta
|
|
7
8
|
from typing import Any, Dict, Optional, Union, overload
|
|
8
9
|
|
|
9
10
|
from reflex.components.component import NoSSRComponent
|
|
@@ -20,7 +21,7 @@ class MomentDelta:
|
|
|
20
21
|
weeks: Optional[int]
|
|
21
22
|
days: Optional[int]
|
|
22
23
|
hours: Optional[int]
|
|
23
|
-
|
|
24
|
+
minutes: Optional[int]
|
|
24
25
|
seconds: Optional[int]
|
|
25
26
|
milliseconds: Optional[int]
|
|
26
27
|
|
|
@@ -46,7 +47,16 @@ class Moment(NoSSRComponent):
|
|
|
46
47
|
decimal: Optional[Union[Var[bool], bool]] = None,
|
|
47
48
|
unit: Optional[Union[Var[str], str]] = None,
|
|
48
49
|
duration: Optional[Union[Var[str], str]] = None,
|
|
49
|
-
date: Optional[
|
|
50
|
+
date: Optional[
|
|
51
|
+
Union[
|
|
52
|
+
Var[Union[date, datetime, str, time, timedelta]],
|
|
53
|
+
date,
|
|
54
|
+
datetime,
|
|
55
|
+
str,
|
|
56
|
+
time,
|
|
57
|
+
timedelta,
|
|
58
|
+
]
|
|
59
|
+
] = None,
|
|
50
60
|
duration_from_now: Optional[Union[Var[bool], bool]] = None,
|
|
51
61
|
unix: Optional[Union[Var[bool], bool]] = None,
|
|
52
62
|
local: Optional[Union[Var[bool], bool]] = None,
|
|
@@ -255,7 +255,7 @@ const extractPoints = (points) => {
|
|
|
255
255
|
|
|
256
256
|
def _render(self):
|
|
257
257
|
tag = super()._render()
|
|
258
|
-
figure = self.data.to(dict)
|
|
258
|
+
figure = self.data.to(dict) if self.data is not None else Var.create({})
|
|
259
259
|
merge_dicts = [] # Data will be merged and spread from these dict Vars
|
|
260
260
|
if self.layout is not None:
|
|
261
261
|
# Why is this not a literal dict? Great question... it didn't work
|
|
@@ -11,7 +11,6 @@ from reflex.components.radix.primitives.base import RadixPrimitiveComponent
|
|
|
11
11
|
from reflex.components.radix.themes.base import Theme
|
|
12
12
|
from reflex.components.radix.themes.layout.flex import Flex
|
|
13
13
|
from reflex.event import EventHandler, no_args_event_spec, passthrough_event_spec
|
|
14
|
-
from reflex.utils import console
|
|
15
14
|
from reflex.vars.base import Var
|
|
16
15
|
|
|
17
16
|
|
|
@@ -140,19 +139,19 @@ class DrawerContent(DrawerComponent):
|
|
|
140
139
|
base_style.update(style)
|
|
141
140
|
return {"css": base_style}
|
|
142
141
|
|
|
143
|
-
# Fired when the drawer content is opened.
|
|
142
|
+
# Fired when the drawer content is opened.
|
|
144
143
|
on_open_auto_focus: EventHandler[no_args_event_spec]
|
|
145
144
|
|
|
146
|
-
# Fired when the drawer content is closed.
|
|
145
|
+
# Fired when the drawer content is closed.
|
|
147
146
|
on_close_auto_focus: EventHandler[no_args_event_spec]
|
|
148
147
|
|
|
149
|
-
# Fired when the escape key is pressed.
|
|
148
|
+
# Fired when the escape key is pressed.
|
|
150
149
|
on_escape_key_down: EventHandler[no_args_event_spec]
|
|
151
150
|
|
|
152
|
-
# Fired when the pointer is down outside the drawer content.
|
|
151
|
+
# Fired when the pointer is down outside the drawer content.
|
|
153
152
|
on_pointer_down_outside: EventHandler[no_args_event_spec]
|
|
154
153
|
|
|
155
|
-
# Fired when interacting outside the drawer content.
|
|
154
|
+
# Fired when interacting outside the drawer content.
|
|
156
155
|
on_interact_outside: EventHandler[no_args_event_spec]
|
|
157
156
|
|
|
158
157
|
@classmethod
|
|
@@ -170,23 +169,6 @@ class DrawerContent(DrawerComponent):
|
|
|
170
169
|
Returns:
|
|
171
170
|
The drawer content.
|
|
172
171
|
"""
|
|
173
|
-
deprecated_properties = [
|
|
174
|
-
"on_open_auto_focus",
|
|
175
|
-
"on_close_auto_focus",
|
|
176
|
-
"on_escape_key_down",
|
|
177
|
-
"on_pointer_down_outside",
|
|
178
|
-
"on_interact_outside",
|
|
179
|
-
]
|
|
180
|
-
|
|
181
|
-
for prop in deprecated_properties:
|
|
182
|
-
if prop in props:
|
|
183
|
-
console.deprecate(
|
|
184
|
-
feature_name="drawer content events",
|
|
185
|
-
reason=f"The `{prop}` event is deprecated and will be removed in 0.7.0.",
|
|
186
|
-
deprecation_version="0.6.3",
|
|
187
|
-
removal_version="0.7.0",
|
|
188
|
-
)
|
|
189
|
-
|
|
190
172
|
comp = super().create(*children, **props)
|
|
191
173
|
|
|
192
174
|
return Theme.create(comp)
|
|
@@ -112,6 +112,9 @@ class RadixThemesComponent(Component):
|
|
|
112
112
|
|
|
113
113
|
library = "@radix-ui/themes@^3.0.0"
|
|
114
114
|
|
|
115
|
+
# Temporary pin < 3.1.5 until radix-ui/themes#627 is resolved.
|
|
116
|
+
library = library + " && <3.1.5"
|
|
117
|
+
|
|
115
118
|
# "Fake" prop color_scheme is used to avoid shadowing CSS prop "color".
|
|
116
119
|
_rename_props: Dict[str, str] = {"colorScheme": "color"}
|
|
117
120
|
|
|
@@ -12,7 +12,9 @@ from reflex.vars.base import Var
|
|
|
12
12
|
from ..base import LiteralAccentColor, RadixThemesComponent
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def on_value_change(
|
|
15
|
+
def on_value_change(
|
|
16
|
+
value: Var[Union[str, List[str]]],
|
|
17
|
+
) -> Tuple[Var[Union[str, List[str]]]]:
|
|
16
18
|
"""Handle the on_value_change event.
|
|
17
19
|
|
|
18
20
|
Args:
|
|
@@ -13,7 +13,9 @@ from reflex.vars.base import Var
|
|
|
13
13
|
|
|
14
14
|
from ..base import RadixThemesComponent
|
|
15
15
|
|
|
16
|
-
def on_value_change(
|
|
16
|
+
def on_value_change(
|
|
17
|
+
value: Var[Union[str, List[str]]],
|
|
18
|
+
) -> Tuple[Var[Union[str, List[str]]]]: ...
|
|
17
19
|
|
|
18
20
|
class SegmentedControlRoot(RadixThemesComponent):
|
|
19
21
|
@overload
|
|
@@ -118,7 +120,10 @@ class SegmentedControlRoot(RadixThemesComponent):
|
|
|
118
120
|
custom_attrs: Optional[Dict[str, Union[Var, Any]]] = None,
|
|
119
121
|
on_blur: Optional[EventType[[], BASE_STATE]] = None,
|
|
120
122
|
on_change: Optional[
|
|
121
|
-
Union[
|
|
123
|
+
Union[
|
|
124
|
+
EventType[[], BASE_STATE],
|
|
125
|
+
EventType[[Union[str, List[str]]], BASE_STATE],
|
|
126
|
+
]
|
|
122
127
|
] = None,
|
|
123
128
|
on_click: Optional[EventType[[], BASE_STATE]] = None,
|
|
124
129
|
on_context_menu: Optional[EventType[[], BASE_STATE]] = None,
|
|
@@ -67,6 +67,9 @@ class TextFieldRoot(elements.Div, RadixThemesComponent):
|
|
|
67
67
|
# Value of the input
|
|
68
68
|
value: Var[Union[str, int, float]]
|
|
69
69
|
|
|
70
|
+
# References a datalist for suggested options
|
|
71
|
+
list: Var[Union[str, int, bool]]
|
|
72
|
+
|
|
70
73
|
# Fired when the value of the textarea changes.
|
|
71
74
|
on_change: EventHandler[input_event]
|
|
72
75
|
|
|
@@ -119,6 +119,7 @@ class TextFieldRoot(elements.Div, RadixThemesComponent):
|
|
|
119
119
|
required: Optional[Union[Var[bool], bool]] = None,
|
|
120
120
|
type: Optional[Union[Var[str], str]] = None,
|
|
121
121
|
value: Optional[Union[Var[Union[float, int, str]], float, int, str]] = None,
|
|
122
|
+
list: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
122
123
|
access_key: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
123
124
|
auto_capitalize: Optional[
|
|
124
125
|
Union[Var[Union[bool, int, str]], bool, int, str]
|
|
@@ -206,6 +207,7 @@ class TextFieldRoot(elements.Div, RadixThemesComponent):
|
|
|
206
207
|
required: Indicates that the input is required
|
|
207
208
|
type: Specifies the type of input
|
|
208
209
|
value: Value of the input
|
|
210
|
+
list: References a datalist for suggested options
|
|
209
211
|
on_change: Fired when the value of the textarea changes.
|
|
210
212
|
on_focus: Fired when the textarea is focused.
|
|
211
213
|
on_blur: Fired when the textarea is blurred.
|
|
@@ -454,6 +456,7 @@ class TextField(ComponentNamespace):
|
|
|
454
456
|
required: Optional[Union[Var[bool], bool]] = None,
|
|
455
457
|
type: Optional[Union[Var[str], str]] = None,
|
|
456
458
|
value: Optional[Union[Var[Union[float, int, str]], float, int, str]] = None,
|
|
459
|
+
list: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
457
460
|
access_key: Optional[Union[Var[Union[bool, int, str]], bool, int, str]] = None,
|
|
458
461
|
auto_capitalize: Optional[
|
|
459
462
|
Union[Var[Union[bool, int, str]], bool, int, str]
|
|
@@ -541,6 +544,7 @@ class TextField(ComponentNamespace):
|
|
|
541
544
|
required: Indicates that the input is required
|
|
542
545
|
type: Specifies the type of input
|
|
543
546
|
value: Value of the input
|
|
547
|
+
list: References a datalist for suggested options
|
|
544
548
|
on_change: Fired when the value of the textarea changes.
|
|
545
549
|
on_focus: Fired when the textarea is focused.
|
|
546
550
|
on_blur: Fired when the textarea is blurred.
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from typing import Dict, Literal
|
|
4
4
|
|
|
5
5
|
from reflex.components.component import Component, MemoizationLeaf, NoSSRComponent
|
|
6
|
-
from reflex.utils import console
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
class Recharts(Component):
|
|
@@ -11,19 +10,8 @@ class Recharts(Component):
|
|
|
11
10
|
|
|
12
11
|
library = "recharts@2.13.0"
|
|
13
12
|
|
|
14
|
-
def
|
|
15
|
-
""
|
|
16
|
-
|
|
17
|
-
Returns:
|
|
18
|
-
The rendered tag.
|
|
19
|
-
"""
|
|
20
|
-
tag = super().render()
|
|
21
|
-
if any(p.startswith("css") for p in tag["props"]):
|
|
22
|
-
console.warn(
|
|
23
|
-
f"CSS props do not work for {self.__class__.__name__}. Consult docs to style it with its own prop."
|
|
24
|
-
)
|
|
25
|
-
tag["props"] = [p for p in tag["props"] if not p.startswith("css")]
|
|
26
|
-
return tag
|
|
13
|
+
def _get_style(self) -> Dict:
|
|
14
|
+
return {"wrapperStyle": self.style}
|
|
27
15
|
|
|
28
16
|
|
|
29
17
|
class RechartsCharts(NoSSRComponent, MemoizationLeaf):
|
|
@@ -15,6 +15,8 @@ from reflex.utils.imports import ImportVar
|
|
|
15
15
|
from reflex.utils.serializers import serializer
|
|
16
16
|
from reflex.vars import VarData
|
|
17
17
|
from reflex.vars.base import LiteralVar, Var
|
|
18
|
+
from reflex.vars.function import FunctionVar
|
|
19
|
+
from reflex.vars.object import ObjectVar
|
|
18
20
|
|
|
19
21
|
LiteralPosition = Literal[
|
|
20
22
|
"top-left",
|
|
@@ -232,7 +234,9 @@ class Toaster(Component):
|
|
|
232
234
|
return [hook]
|
|
233
235
|
|
|
234
236
|
@staticmethod
|
|
235
|
-
def send_toast(
|
|
237
|
+
def send_toast(
|
|
238
|
+
message: str | Var = "", level: str | None = None, **props
|
|
239
|
+
) -> EventSpec:
|
|
236
240
|
"""Send a toast message.
|
|
237
241
|
|
|
238
242
|
Args:
|
|
@@ -250,20 +254,27 @@ class Toaster(Component):
|
|
|
250
254
|
raise ValueError(
|
|
251
255
|
"Toaster component must be created before sending a toast. (use `rx.toast.provider()`)"
|
|
252
256
|
)
|
|
253
|
-
|
|
254
|
-
|
|
257
|
+
|
|
258
|
+
toast_command = (
|
|
259
|
+
ObjectVar.__getattr__(toast_ref.to(dict), level) if level else toast_ref
|
|
260
|
+
).to(FunctionVar)
|
|
261
|
+
|
|
262
|
+
if isinstance(message, Var):
|
|
263
|
+
props.setdefault("title", message)
|
|
264
|
+
message = ""
|
|
265
|
+
elif message == "" and "title" not in props and "description" not in props:
|
|
255
266
|
raise ValueError("Toast message or title or description must be provided.")
|
|
267
|
+
|
|
256
268
|
if props:
|
|
257
|
-
args = LiteralVar.create(ToastProps(component_name="rx.toast", **props)) #
|
|
258
|
-
toast =
|
|
269
|
+
args = LiteralVar.create(ToastProps(component_name="rx.toast", **props)) # pyright: ignore [reportCallIssue, reportGeneralTypeIssues]
|
|
270
|
+
toast = toast_command.call(message, args)
|
|
259
271
|
else:
|
|
260
|
-
toast =
|
|
272
|
+
toast = toast_command.call(message)
|
|
261
273
|
|
|
262
|
-
|
|
263
|
-
return run_script(toast_action)
|
|
274
|
+
return run_script(toast)
|
|
264
275
|
|
|
265
276
|
@staticmethod
|
|
266
|
-
def toast_info(message: str = "", **kwargs):
|
|
277
|
+
def toast_info(message: str | Var = "", **kwargs):
|
|
267
278
|
"""Display an info toast message.
|
|
268
279
|
|
|
269
280
|
Args:
|
|
@@ -276,7 +287,7 @@ class Toaster(Component):
|
|
|
276
287
|
return Toaster.send_toast(message, level="info", **kwargs)
|
|
277
288
|
|
|
278
289
|
@staticmethod
|
|
279
|
-
def toast_warning(message: str = "", **kwargs):
|
|
290
|
+
def toast_warning(message: str | Var = "", **kwargs):
|
|
280
291
|
"""Display a warning toast message.
|
|
281
292
|
|
|
282
293
|
Args:
|
|
@@ -289,7 +300,7 @@ class Toaster(Component):
|
|
|
289
300
|
return Toaster.send_toast(message, level="warning", **kwargs)
|
|
290
301
|
|
|
291
302
|
@staticmethod
|
|
292
|
-
def toast_error(message: str = "", **kwargs):
|
|
303
|
+
def toast_error(message: str | Var = "", **kwargs):
|
|
293
304
|
"""Display an error toast message.
|
|
294
305
|
|
|
295
306
|
Args:
|
|
@@ -302,7 +313,7 @@ class Toaster(Component):
|
|
|
302
313
|
return Toaster.send_toast(message, level="error", **kwargs)
|
|
303
314
|
|
|
304
315
|
@staticmethod
|
|
305
|
-
def toast_success(message: str = "", **kwargs):
|
|
316
|
+
def toast_success(message: str | Var = "", **kwargs):
|
|
306
317
|
"""Display a success toast message.
|
|
307
318
|
|
|
308
319
|
Args:
|
|
@@ -59,16 +59,16 @@ class Toaster(Component):
|
|
|
59
59
|
def add_hooks(self) -> list[Var | str]: ...
|
|
60
60
|
@staticmethod
|
|
61
61
|
def send_toast(
|
|
62
|
-
message: str = "", level: str | None = None, **props
|
|
62
|
+
message: str | Var = "", level: str | None = None, **props
|
|
63
63
|
) -> EventSpec: ...
|
|
64
64
|
@staticmethod
|
|
65
|
-
def toast_info(message: str = "", **kwargs): ...
|
|
65
|
+
def toast_info(message: str | Var = "", **kwargs): ...
|
|
66
66
|
@staticmethod
|
|
67
|
-
def toast_warning(message: str = "", **kwargs): ...
|
|
67
|
+
def toast_warning(message: str | Var = "", **kwargs): ...
|
|
68
68
|
@staticmethod
|
|
69
|
-
def toast_error(message: str = "", **kwargs): ...
|
|
69
|
+
def toast_error(message: str | Var = "", **kwargs): ...
|
|
70
70
|
@staticmethod
|
|
71
|
-
def toast_success(message: str = "", **kwargs): ...
|
|
71
|
+
def toast_success(message: str | Var = "", **kwargs): ...
|
|
72
72
|
@staticmethod
|
|
73
73
|
def toast_dismiss(id: Var | str | None = None): ...
|
|
74
74
|
@overload
|
|
@@ -176,7 +176,7 @@ class ToastNamespace(ComponentNamespace):
|
|
|
176
176
|
|
|
177
177
|
@staticmethod
|
|
178
178
|
def __call__(
|
|
179
|
-
message: str = "", level: Optional[str] = None, **props
|
|
179
|
+
message: Union[str, Var] = "", level: Optional[str] = None, **props
|
|
180
180
|
) -> "Optional[EventSpec]":
|
|
181
181
|
"""Send a toast message.
|
|
182
182
|
|
reflex/config.py
CHANGED
|
@@ -8,7 +8,9 @@ import importlib
|
|
|
8
8
|
import inspect
|
|
9
9
|
import os
|
|
10
10
|
import sys
|
|
11
|
+
import threading
|
|
11
12
|
import urllib.parse
|
|
13
|
+
from importlib.util import find_spec
|
|
12
14
|
from pathlib import Path
|
|
13
15
|
from typing import (
|
|
14
16
|
TYPE_CHECKING,
|
|
@@ -452,6 +454,14 @@ class PathExistsFlag:
|
|
|
452
454
|
ExistingPath = Annotated[Path, PathExistsFlag]
|
|
453
455
|
|
|
454
456
|
|
|
457
|
+
class PerformanceMode(enum.Enum):
|
|
458
|
+
"""Performance mode for the app."""
|
|
459
|
+
|
|
460
|
+
WARN = "warn"
|
|
461
|
+
RAISE = "raise"
|
|
462
|
+
OFF = "off"
|
|
463
|
+
|
|
464
|
+
|
|
455
465
|
class EnvironmentVariables:
|
|
456
466
|
"""Environment variables class to instantiate environment variables."""
|
|
457
467
|
|
|
@@ -545,6 +555,15 @@ class EnvironmentVariables:
|
|
|
545
555
|
# Where to save screenshots when tests fail.
|
|
546
556
|
SCREENSHOT_DIR: EnvVar[Optional[Path]] = env_var(None)
|
|
547
557
|
|
|
558
|
+
# Whether to check for outdated package versions.
|
|
559
|
+
REFLEX_CHECK_LATEST_VERSION: EnvVar[bool] = env_var(True)
|
|
560
|
+
|
|
561
|
+
# In which performance mode to run the app.
|
|
562
|
+
REFLEX_PERF_MODE: EnvVar[Optional[PerformanceMode]] = env_var(PerformanceMode.WARN)
|
|
563
|
+
|
|
564
|
+
# The maximum size of the reflex state in kilobytes.
|
|
565
|
+
REFLEX_STATE_SIZE_LIMIT: EnvVar[int] = env_var(1000)
|
|
566
|
+
|
|
548
567
|
|
|
549
568
|
environment = EnvironmentVariables()
|
|
550
569
|
|
|
@@ -798,24 +817,56 @@ class Config(Base):
|
|
|
798
817
|
self._replace_defaults(**kwargs)
|
|
799
818
|
|
|
800
819
|
|
|
801
|
-
def
|
|
820
|
+
def _get_config() -> Config:
|
|
802
821
|
"""Get the app config.
|
|
803
822
|
|
|
804
|
-
Args:
|
|
805
|
-
reload: Re-import the rxconfig module from disk
|
|
806
|
-
|
|
807
823
|
Returns:
|
|
808
824
|
The app config.
|
|
809
825
|
"""
|
|
810
|
-
sys.path.insert(0, os.getcwd())
|
|
811
826
|
# only import the module if it exists. If a module spec exists then
|
|
812
827
|
# the module exists.
|
|
813
|
-
spec =
|
|
828
|
+
spec = find_spec(constants.Config.MODULE)
|
|
814
829
|
if not spec:
|
|
815
830
|
# we need this condition to ensure that a ModuleNotFound error is not thrown when
|
|
816
|
-
# running unit/integration tests
|
|
831
|
+
# running unit/integration tests or during `reflex init`.
|
|
817
832
|
return Config(app_name="")
|
|
818
833
|
rxconfig = importlib.import_module(constants.Config.MODULE)
|
|
819
|
-
if reload:
|
|
820
|
-
importlib.reload(rxconfig)
|
|
821
834
|
return rxconfig.config
|
|
835
|
+
|
|
836
|
+
|
|
837
|
+
# Protect sys.path from concurrent modification
|
|
838
|
+
_config_lock = threading.RLock()
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
def get_config(reload: bool = False) -> Config:
|
|
842
|
+
"""Get the app config.
|
|
843
|
+
|
|
844
|
+
Args:
|
|
845
|
+
reload: Re-import the rxconfig module from disk
|
|
846
|
+
|
|
847
|
+
Returns:
|
|
848
|
+
The app config.
|
|
849
|
+
"""
|
|
850
|
+
cached_rxconfig = sys.modules.get(constants.Config.MODULE, None)
|
|
851
|
+
if cached_rxconfig is not None:
|
|
852
|
+
if reload:
|
|
853
|
+
# Remove any cached module when `reload` is requested.
|
|
854
|
+
del sys.modules[constants.Config.MODULE]
|
|
855
|
+
else:
|
|
856
|
+
return cached_rxconfig.config
|
|
857
|
+
|
|
858
|
+
with _config_lock:
|
|
859
|
+
sys_path = sys.path.copy()
|
|
860
|
+
sys.path.clear()
|
|
861
|
+
sys.path.append(os.getcwd())
|
|
862
|
+
try:
|
|
863
|
+
# Try to import the module with only the current directory in the path.
|
|
864
|
+
return _get_config()
|
|
865
|
+
except Exception:
|
|
866
|
+
# If the module import fails, try to import with the original sys.path.
|
|
867
|
+
sys.path.extend(sys_path)
|
|
868
|
+
return _get_config()
|
|
869
|
+
finally:
|
|
870
|
+
# Restore the original sys.path.
|
|
871
|
+
sys.path.clear()
|
|
872
|
+
sys.path.extend(sys_path)
|
reflex/constants/base.py
CHANGED
|
@@ -97,6 +97,18 @@ class Templates(SimpleNamespace):
|
|
|
97
97
|
# The default template
|
|
98
98
|
DEFAULT = "blank"
|
|
99
99
|
|
|
100
|
+
# The AI template
|
|
101
|
+
AI = "ai"
|
|
102
|
+
|
|
103
|
+
# The option for the user to choose a remote template.
|
|
104
|
+
CHOOSE_TEMPLATES = "choose-templates"
|
|
105
|
+
|
|
106
|
+
# The URL to find reflex templates.
|
|
107
|
+
REFLEX_TEMPLATES_URL = "https://reflex.dev/templates"
|
|
108
|
+
|
|
109
|
+
# Demo url for the default template.
|
|
110
|
+
DEFAULT_TEMPLATE_URL = "https://blank-template.reflex.run"
|
|
111
|
+
|
|
100
112
|
# The reflex.build frontend host
|
|
101
113
|
REFLEX_BUILD_FRONTEND = "https://flexgen.reflex.run"
|
|
102
114
|
|
reflex/constants/installer.py
CHANGED
|
@@ -184,15 +184,15 @@ class PackageJson(SimpleNamespace):
|
|
|
184
184
|
"json5": "2.2.3",
|
|
185
185
|
"next": "14.2.16",
|
|
186
186
|
"next-sitemap": "4.2.3",
|
|
187
|
-
"next-themes": "0.3
|
|
187
|
+
"next-themes": "0.4.3",
|
|
188
188
|
"react": "18.3.1",
|
|
189
189
|
"react-dom": "18.3.1",
|
|
190
190
|
"react-focus-lock": "2.13.2",
|
|
191
191
|
"socket.io-client": "4.8.1",
|
|
192
|
-
"universal-cookie": "7.2.
|
|
192
|
+
"universal-cookie": "7.2.2",
|
|
193
193
|
}
|
|
194
194
|
DEV_DEPENDENCIES = {
|
|
195
195
|
"autoprefixer": "10.4.20",
|
|
196
|
-
"postcss": "8.4.
|
|
196
|
+
"postcss": "8.4.49",
|
|
197
197
|
"postcss-import": "16.1.0",
|
|
198
198
|
}
|
reflex/constants/style.py
CHANGED