reflex 0.4.9a2__py3-none-any.whl → 0.5.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- reflex/.templates/apps/blank/code/blank.py +19 -16
- reflex/.templates/apps/demo/code/pages/datatable.py +4 -4
- reflex/.templates/apps/demo/code/pages/forms.py +2 -2
- reflex/.templates/web/utils/helpers/debounce.js +17 -0
- reflex/.templates/web/utils/helpers/throttle.js +22 -0
- reflex/.templates/web/utils/state.js +21 -3
- reflex/__init__.py +6 -1
- reflex/__init__.pyi +4 -1
- reflex/app.py +157 -140
- reflex/app_module_for_backend.py +1 -1
- reflex/base.py +13 -15
- reflex/compiler/compiler.py +10 -1
- reflex/compiler/utils.py +3 -30
- reflex/components/__init__.py +1 -0
- reflex/components/chakra/datadisplay/list.py +1 -3
- reflex/components/chakra/datadisplay/list.pyi +3 -3
- reflex/components/chakra/disclosure/accordion.py +1 -1
- reflex/components/chakra/forms/pininput.pyi +1 -1
- reflex/components/chakra/media/icon.py +2 -2
- reflex/components/component.py +279 -32
- reflex/components/core/__init__.py +2 -2
- reflex/components/core/cond.py +1 -10
- reflex/components/core/debounce.py +5 -2
- reflex/components/core/debounce.pyi +4 -2
- reflex/components/core/foreach.py +1 -16
- reflex/components/core/html.py +6 -0
- reflex/components/core/match.py +2 -17
- reflex/components/core/upload.py +42 -1
- reflex/components/core/upload.pyi +199 -1
- reflex/components/datadisplay/code.py +7 -3
- reflex/components/datadisplay/code.pyi +3 -1
- reflex/components/el/elements/forms.py +1 -1
- reflex/components/el/elements/forms.pyi +1 -1
- reflex/components/lucide/icon.py +5 -13
- reflex/components/lucide/icon.pyi +0 -1
- reflex/components/markdown/markdown.py +5 -23
- reflex/components/markdown/markdown.pyi +1 -4
- reflex/components/radix/primitives/accordion.py +227 -406
- reflex/components/radix/primitives/accordion.pyi +369 -28
- reflex/components/radix/primitives/form.py +33 -29
- reflex/components/radix/primitives/form.pyi +7 -2
- reflex/components/radix/primitives/progress.py +17 -9
- reflex/components/radix/primitives/progress.pyi +2 -0
- reflex/components/radix/primitives/slider.py +30 -18
- reflex/components/radix/primitives/slider.pyi +4 -0
- reflex/components/radix/themes/base.py +8 -1
- reflex/components/radix/themes/base.pyi +79 -1
- reflex/components/radix/themes/color_mode.py +74 -30
- reflex/components/radix/themes/color_mode.pyi +26 -185
- reflex/components/radix/themes/components/__init__.py +17 -0
- reflex/components/radix/themes/components/badge.py +2 -1
- reflex/components/radix/themes/components/badge.pyi +3 -1
- reflex/components/radix/themes/components/button.py +3 -1
- reflex/components/radix/themes/components/button.pyi +4 -1
- reflex/components/radix/themes/components/checkbox_cards.py +48 -0
- reflex/components/radix/themes/components/checkbox_cards.pyi +264 -0
- reflex/components/radix/themes/components/checkbox_group.py +42 -0
- reflex/components/radix/themes/components/checkbox_group.pyi +253 -0
- reflex/components/radix/themes/components/data_list.py +63 -0
- reflex/components/radix/themes/components/data_list.pyi +426 -0
- reflex/components/radix/themes/components/icon_button.py +20 -17
- reflex/components/radix/themes/components/icon_button.pyi +5 -1
- reflex/components/radix/themes/components/progress.py +55 -0
- reflex/components/radix/themes/components/progress.pyi +180 -0
- reflex/components/radix/themes/components/radio.py +31 -0
- reflex/components/radix/themes/components/radio.pyi +169 -0
- reflex/components/radix/themes/components/radio_cards.py +48 -0
- reflex/components/radix/themes/components/radio_cards.pyi +264 -0
- reflex/components/radix/themes/components/radio_group.py +2 -4
- reflex/components/radix/themes/components/segmented_control.py +48 -0
- reflex/components/radix/themes/components/segmented_control.pyi +262 -0
- reflex/components/radix/themes/components/skeleton.py +32 -0
- reflex/components/radix/themes/components/skeleton.pyi +106 -0
- reflex/components/radix/themes/components/spinner.py +26 -0
- reflex/components/radix/themes/components/spinner.pyi +101 -0
- reflex/components/radix/themes/components/tabs.py +26 -1
- reflex/components/radix/themes/components/tabs.pyi +69 -9
- reflex/components/radix/themes/components/text_field.py +101 -71
- reflex/components/radix/themes/components/text_field.pyi +81 -499
- reflex/components/radix/themes/layout/base.py +2 -2
- reflex/components/radix/themes/layout/base.pyi +4 -4
- reflex/components/radix/themes/layout/center.py +8 -3
- reflex/components/radix/themes/layout/center.pyi +2 -1
- reflex/components/radix/themes/layout/container.py +30 -2
- reflex/components/radix/themes/layout/container.pyi +9 -30
- reflex/components/radix/themes/layout/list.py +10 -5
- reflex/components/radix/themes/layout/list.pyi +5 -21
- reflex/components/radix/themes/layout/spacer.py +8 -3
- reflex/components/radix/themes/layout/spacer.pyi +2 -1
- reflex/components/radix/themes/layout/stack.py +7 -1
- reflex/components/radix/themes/layout/stack.pyi +3 -3
- reflex/components/radix/themes/typography/link.py +10 -2
- reflex/components/radix/themes/typography/link.pyi +5 -4
- reflex/components/sonner/__init__.py +3 -0
- reflex/components/sonner/toast.py +267 -0
- reflex/components/sonner/toast.pyi +205 -0
- reflex/components/tags/iter_tag.py +9 -6
- reflex/config.py +30 -54
- reflex/constants/__init__.py +0 -2
- reflex/constants/base.py +0 -5
- reflex/constants/colors.py +2 -0
- reflex/constants/installer.py +5 -1
- reflex/constants/route.py +4 -0
- reflex/custom_components/custom_components.py +22 -1
- reflex/event.py +75 -30
- reflex/experimental/__init__.py +5 -0
- reflex/experimental/layout.py +24 -6
- reflex/model.py +2 -1
- reflex/page.py +7 -4
- reflex/reflex.py +8 -3
- reflex/route.py +39 -0
- reflex/state.py +128 -131
- reflex/style.py +20 -1
- reflex/testing.py +10 -6
- reflex/utils/console.py +3 -1
- reflex/utils/exec.py +20 -7
- reflex/utils/format.py +1 -1
- reflex/utils/imports.py +3 -1
- reflex/utils/prerequisites.py +141 -20
- reflex/utils/processes.py +21 -1
- reflex/utils/pyi_generator.py +95 -5
- reflex/utils/serializers.py +1 -1
- reflex/utils/telemetry.py +26 -4
- reflex/utils/types.py +62 -18
- reflex/vars.py +11 -5
- {reflex-0.4.9a2.dist-info → reflex-0.5.0a1.dist-info}/METADATA +16 -4
- {reflex-0.4.9a2.dist-info → reflex-0.5.0a1.dist-info}/RECORD +130 -108
- {reflex-0.4.9a2.dist-info → reflex-0.5.0a1.dist-info}/WHEEL +1 -1
- reflex/app.pyi +0 -149
- {reflex-0.4.9a2.dist-info → reflex-0.5.0a1.dist-info}/LICENSE +0 -0
- {reflex-0.4.9a2.dist-info → reflex-0.5.0a1.dist-info}/entry_points.txt +0 -0
|
@@ -28,20 +28,24 @@ class ProgressRoot(ProgressComponent):
|
|
|
28
28
|
# Override theme radius for progress bar: "none" | "small" | "medium" | "large" | "full"
|
|
29
29
|
radius: Var[LiteralRadius]
|
|
30
30
|
|
|
31
|
-
def
|
|
31
|
+
def add_style(self) -> Style | None:
|
|
32
|
+
"""Add style to the component.
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
The style of the component.
|
|
36
|
+
"""
|
|
32
37
|
if self.radius is not None:
|
|
33
38
|
self.custom_attrs["data-radius"] = self.radius
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
return Style(
|
|
36
41
|
{
|
|
37
42
|
"position": "relative",
|
|
38
43
|
"overflow": "hidden",
|
|
39
|
-
"background": "
|
|
44
|
+
"background": color("gray", 3, alpha=True),
|
|
40
45
|
"border_radius": "max(var(--radius-2), var(--radius-full))",
|
|
41
46
|
"width": "100%",
|
|
42
47
|
"height": "20px",
|
|
43
|
-
"boxShadow": "inset 0 0 0 1px
|
|
44
|
-
**self.style,
|
|
48
|
+
"boxShadow": f"inset 0 0 0 1px {color('gray', 5, alpha=True)}",
|
|
45
49
|
}
|
|
46
50
|
)
|
|
47
51
|
|
|
@@ -65,22 +69,26 @@ class ProgressIndicator(ProgressComponent):
|
|
|
65
69
|
# The color scheme of the progress indicator.
|
|
66
70
|
color_scheme: Var[LiteralAccentColor]
|
|
67
71
|
|
|
68
|
-
def
|
|
72
|
+
def add_style(self) -> Style | None:
|
|
73
|
+
"""Add style to the component.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
The style of the component.
|
|
77
|
+
"""
|
|
69
78
|
if self.color_scheme is not None:
|
|
70
79
|
self.custom_attrs["data-accent-color"] = self.color_scheme
|
|
71
80
|
|
|
72
|
-
|
|
81
|
+
return Style(
|
|
73
82
|
{
|
|
74
83
|
"background_color": color("accent", 9),
|
|
75
84
|
"width": "100%",
|
|
76
85
|
"height": "100%",
|
|
77
|
-
|
|
86
|
+
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
|
78
87
|
"&[data_state='loading']": {
|
|
79
88
|
"transition": f"transform {DEFAULT_ANIMATION_DURATION}ms linear",
|
|
80
89
|
},
|
|
81
90
|
"transform": f"translateX(calc(-100% + ({self.value} / {self.max} * 100%)))", # type: ignore
|
|
82
91
|
"boxShadow": "inset 0 0 0 1px var(--gray-a5)",
|
|
83
|
-
**self.style,
|
|
84
92
|
}
|
|
85
93
|
)
|
|
86
94
|
|
|
@@ -95,6 +95,7 @@ class ProgressComponent(RadixPrimitiveComponentWithClassName):
|
|
|
95
95
|
...
|
|
96
96
|
|
|
97
97
|
class ProgressRoot(ProgressComponent):
|
|
98
|
+
def add_style(self) -> Style | None: ...
|
|
98
99
|
@overload
|
|
99
100
|
@classmethod
|
|
100
101
|
def create( # type: ignore
|
|
@@ -180,6 +181,7 @@ class ProgressRoot(ProgressComponent):
|
|
|
180
181
|
...
|
|
181
182
|
|
|
182
183
|
class ProgressIndicator(ProgressComponent):
|
|
184
|
+
def add_style(self) -> Style | None: ...
|
|
183
185
|
@overload
|
|
184
186
|
@classmethod
|
|
185
187
|
def create( # type: ignore
|
|
@@ -59,8 +59,13 @@ class SliderRoot(SliderComponent):
|
|
|
59
59
|
"on_value_commit": lambda e0: [e0], # trigger when thumb is released
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
def
|
|
63
|
-
|
|
62
|
+
def add_style(self) -> Style | None:
|
|
63
|
+
"""Add style to the component.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
The style of the component.
|
|
67
|
+
"""
|
|
68
|
+
return Style(
|
|
64
69
|
{
|
|
65
70
|
"position": "relative",
|
|
66
71
|
"display": "flex",
|
|
@@ -74,7 +79,6 @@ class SliderRoot(SliderComponent):
|
|
|
74
79
|
"width": "20px",
|
|
75
80
|
"height": "100px",
|
|
76
81
|
},
|
|
77
|
-
**self.style,
|
|
78
82
|
}
|
|
79
83
|
)
|
|
80
84
|
|
|
@@ -85,18 +89,20 @@ class SliderTrack(SliderComponent):
|
|
|
85
89
|
tag = "Track"
|
|
86
90
|
alias = "RadixSliderTrack"
|
|
87
91
|
|
|
88
|
-
def
|
|
89
|
-
|
|
92
|
+
def add_style(self) -> Style | None:
|
|
93
|
+
"""Add style to the component.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
The style of the component.
|
|
97
|
+
"""
|
|
98
|
+
return Style(
|
|
90
99
|
{
|
|
91
100
|
"position": "relative",
|
|
92
101
|
"flex_grow": "1",
|
|
93
102
|
"background_color": "black",
|
|
94
103
|
"border_radius": "9999px",
|
|
95
104
|
"height": "3px",
|
|
96
|
-
"&[data-orientation='vertical']": {
|
|
97
|
-
"width": "3px",
|
|
98
|
-
},
|
|
99
|
-
**self.style,
|
|
105
|
+
"&[data-orientation='vertical']": {"width": "3px"},
|
|
100
106
|
}
|
|
101
107
|
)
|
|
102
108
|
|
|
@@ -107,16 +113,18 @@ class SliderRange(SliderComponent):
|
|
|
107
113
|
tag = "Range"
|
|
108
114
|
alias = "RadixSliderRange"
|
|
109
115
|
|
|
110
|
-
def
|
|
111
|
-
|
|
116
|
+
def add_style(self) -> Style | None:
|
|
117
|
+
"""Add style to the component.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
The style of the component.
|
|
121
|
+
"""
|
|
122
|
+
return Style(
|
|
112
123
|
{
|
|
113
124
|
"position": "absolute",
|
|
114
125
|
"background_color": "white",
|
|
115
126
|
"height": "100%",
|
|
116
|
-
"&[data-orientation='vertical']": {
|
|
117
|
-
"width": "100%",
|
|
118
|
-
},
|
|
119
|
-
**self.style,
|
|
127
|
+
"&[data-orientation='vertical']": {"width": "100%"},
|
|
120
128
|
}
|
|
121
129
|
)
|
|
122
130
|
|
|
@@ -127,8 +135,13 @@ class SliderThumb(SliderComponent):
|
|
|
127
135
|
tag = "Thumb"
|
|
128
136
|
alias = "RadixSliderThumb"
|
|
129
137
|
|
|
130
|
-
def
|
|
131
|
-
|
|
138
|
+
def add_style(self) -> Style | None:
|
|
139
|
+
"""Add style to the component.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
The style of the component.
|
|
143
|
+
"""
|
|
144
|
+
return Style(
|
|
132
145
|
{
|
|
133
146
|
"display": "block",
|
|
134
147
|
"width": "20px",
|
|
@@ -143,7 +156,6 @@ class SliderThumb(SliderComponent):
|
|
|
143
156
|
"outline": "none",
|
|
144
157
|
"box_shadow": "0 0 0 4px gray",
|
|
145
158
|
},
|
|
146
|
-
**self.style,
|
|
147
159
|
}
|
|
148
160
|
)
|
|
149
161
|
|
|
@@ -96,6 +96,7 @@ class SliderComponent(RadixPrimitiveComponentWithClassName):
|
|
|
96
96
|
|
|
97
97
|
class SliderRoot(SliderComponent):
|
|
98
98
|
def get_event_triggers(self) -> Dict[str, Any]: ...
|
|
99
|
+
def add_style(self) -> Style | None: ...
|
|
99
100
|
@overload
|
|
100
101
|
@classmethod
|
|
101
102
|
def create( # type: ignore
|
|
@@ -196,6 +197,7 @@ class SliderRoot(SliderComponent):
|
|
|
196
197
|
...
|
|
197
198
|
|
|
198
199
|
class SliderTrack(SliderComponent):
|
|
200
|
+
def add_style(self) -> Style | None: ...
|
|
199
201
|
@overload
|
|
200
202
|
@classmethod
|
|
201
203
|
def create( # type: ignore
|
|
@@ -274,6 +276,7 @@ class SliderTrack(SliderComponent):
|
|
|
274
276
|
...
|
|
275
277
|
|
|
276
278
|
class SliderRange(SliderComponent):
|
|
279
|
+
def add_style(self) -> Style | None: ...
|
|
277
280
|
@overload
|
|
278
281
|
@classmethod
|
|
279
282
|
def create( # type: ignore
|
|
@@ -352,6 +355,7 @@ class SliderRange(SliderComponent):
|
|
|
352
355
|
...
|
|
353
356
|
|
|
354
357
|
class SliderThumb(SliderComponent):
|
|
358
|
+
def add_style(self) -> Style | None: ...
|
|
355
359
|
@overload
|
|
356
360
|
@classmethod
|
|
357
361
|
def create( # type: ignore
|
|
@@ -73,10 +73,17 @@ class CommonMarginProps(Component):
|
|
|
73
73
|
ml: Var[LiteralSpacing]
|
|
74
74
|
|
|
75
75
|
|
|
76
|
+
class RadixLoadingProp(Component):
|
|
77
|
+
"""Base class for components that can be in a loading state."""
|
|
78
|
+
|
|
79
|
+
# If set, show an rx.spinner instead of the component children.
|
|
80
|
+
loading: Var[bool]
|
|
81
|
+
|
|
82
|
+
|
|
76
83
|
class RadixThemesComponent(Component):
|
|
77
84
|
"""Base class for all @radix-ui/themes components."""
|
|
78
85
|
|
|
79
|
-
library = "@radix-ui/themes@^
|
|
86
|
+
library = "@radix-ui/themes@^3.0.0"
|
|
80
87
|
|
|
81
88
|
# "Fake" prop color_scheme is used to avoid shadowing CSS prop "color".
|
|
82
89
|
_rename_props: Dict[str, str] = {"colorScheme": "color"}
|
|
@@ -176,6 +176,84 @@ class CommonMarginProps(Component):
|
|
|
176
176
|
"""
|
|
177
177
|
...
|
|
178
178
|
|
|
179
|
+
class RadixLoadingProp(Component):
|
|
180
|
+
@overload
|
|
181
|
+
@classmethod
|
|
182
|
+
def create( # type: ignore
|
|
183
|
+
cls,
|
|
184
|
+
*children,
|
|
185
|
+
loading: Optional[Union[Var[bool], bool]] = None,
|
|
186
|
+
style: Optional[Style] = None,
|
|
187
|
+
key: Optional[Any] = None,
|
|
188
|
+
id: Optional[Any] = None,
|
|
189
|
+
class_name: Optional[Any] = None,
|
|
190
|
+
autofocus: Optional[bool] = None,
|
|
191
|
+
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
|
192
|
+
on_blur: Optional[
|
|
193
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
194
|
+
] = None,
|
|
195
|
+
on_click: Optional[
|
|
196
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
197
|
+
] = None,
|
|
198
|
+
on_context_menu: Optional[
|
|
199
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
200
|
+
] = None,
|
|
201
|
+
on_double_click: Optional[
|
|
202
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
203
|
+
] = None,
|
|
204
|
+
on_focus: Optional[
|
|
205
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
206
|
+
] = None,
|
|
207
|
+
on_mount: Optional[
|
|
208
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
209
|
+
] = None,
|
|
210
|
+
on_mouse_down: Optional[
|
|
211
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
212
|
+
] = None,
|
|
213
|
+
on_mouse_enter: Optional[
|
|
214
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
215
|
+
] = None,
|
|
216
|
+
on_mouse_leave: Optional[
|
|
217
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
218
|
+
] = None,
|
|
219
|
+
on_mouse_move: Optional[
|
|
220
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
221
|
+
] = None,
|
|
222
|
+
on_mouse_out: Optional[
|
|
223
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
224
|
+
] = None,
|
|
225
|
+
on_mouse_over: Optional[
|
|
226
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
227
|
+
] = None,
|
|
228
|
+
on_mouse_up: Optional[
|
|
229
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
230
|
+
] = None,
|
|
231
|
+
on_scroll: Optional[
|
|
232
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
233
|
+
] = None,
|
|
234
|
+
on_unmount: Optional[
|
|
235
|
+
Union[EventHandler, EventSpec, list, function, BaseVar]
|
|
236
|
+
] = None,
|
|
237
|
+
**props
|
|
238
|
+
) -> "RadixLoadingProp":
|
|
239
|
+
"""Create the component.
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
*children: The children of the component.
|
|
243
|
+
loading: If set, show an rx.spinner instead of the component children.
|
|
244
|
+
style: The style of the component.
|
|
245
|
+
key: A unique key for the component.
|
|
246
|
+
id: The id for the component.
|
|
247
|
+
class_name: The class name for the component.
|
|
248
|
+
autofocus: Whether the component should take the focus once the page is loaded
|
|
249
|
+
custom_attrs: custom attribute
|
|
250
|
+
**props: The props of the component.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
The component.
|
|
254
|
+
"""
|
|
255
|
+
...
|
|
256
|
+
|
|
179
257
|
class RadixThemesComponent(Component):
|
|
180
258
|
@overload
|
|
181
259
|
@classmethod
|
|
@@ -331,7 +409,7 @@ class Theme(RadixThemesComponent):
|
|
|
331
409
|
def create( # type: ignore
|
|
332
410
|
cls,
|
|
333
411
|
*children,
|
|
334
|
-
color_mode: Optional[
|
|
412
|
+
color_mode: Optional[Literal["inherit", "light", "dark"]] = None,
|
|
335
413
|
theme_panel: Optional[bool] = False,
|
|
336
414
|
has_background: Optional[Union[Var[bool], bool]] = None,
|
|
337
415
|
appearance: Optional[
|
|
@@ -14,18 +14,20 @@ rx.text(
|
|
|
14
14
|
)
|
|
15
15
|
```
|
|
16
16
|
"""
|
|
17
|
+
|
|
17
18
|
from __future__ import annotations
|
|
18
19
|
|
|
19
20
|
import dataclasses
|
|
21
|
+
from typing import Literal, get_args
|
|
20
22
|
|
|
21
23
|
from reflex.components.component import BaseComponent
|
|
22
|
-
from reflex.components.core.cond import Cond, color_mode_cond
|
|
24
|
+
from reflex.components.core.cond import Cond, color_mode_cond, cond
|
|
23
25
|
from reflex.components.lucide.icon import Icon
|
|
24
|
-
from reflex.style import
|
|
25
|
-
from reflex.
|
|
26
|
+
from reflex.style import color_mode, toggle_color_mode
|
|
27
|
+
from reflex.utils import console
|
|
28
|
+
from reflex.vars import BaseVar, Var
|
|
26
29
|
|
|
27
|
-
from .components.
|
|
28
|
-
from .components.switch import Switch
|
|
30
|
+
from .components.icon_button import IconButton
|
|
29
31
|
|
|
30
32
|
DEFAULT_LIGHT_ICON: Icon = Icon.create(tag="sun")
|
|
31
33
|
DEFAULT_DARK_ICON: Icon = Icon.create(tag="moon")
|
|
@@ -55,44 +57,87 @@ class ColorModeIcon(Cond):
|
|
|
55
57
|
)
|
|
56
58
|
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
"""Switch for toggling light / dark mode via toggle_color_mode."""
|
|
60
|
+
LiteralPosition = Literal["top-left", "top-right", "bottom-left", "bottom-right"]
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
def create(cls, *children, **props):
|
|
63
|
-
"""Create a switch component bound to color_mode.
|
|
62
|
+
position_values = get_args(LiteralPosition)
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
position_map = {
|
|
65
|
+
"position": position_values,
|
|
66
|
+
"left": ["top-left", "bottom-left"],
|
|
67
|
+
"right": ["top-right", "bottom-right"],
|
|
68
|
+
"top": ["top-left", "top-right"],
|
|
69
|
+
"bottom": ["bottom-left", "bottom-right"],
|
|
70
|
+
}
|
|
68
71
|
|
|
69
|
-
Returns:
|
|
70
|
-
The switch component.
|
|
71
|
-
"""
|
|
72
|
-
return Switch.create(
|
|
73
|
-
*children,
|
|
74
|
-
checked=color_mode != LIGHT_COLOR_MODE,
|
|
75
|
-
on_change=toggle_color_mode,
|
|
76
|
-
**props,
|
|
77
|
-
)
|
|
78
72
|
|
|
73
|
+
# needed to inverse contains for find
|
|
74
|
+
def _find(const, var):
|
|
75
|
+
return Var.create_safe(const).contains(var)
|
|
79
76
|
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
|
|
78
|
+
def _set_var_default(props, position, prop, default1, default2=""):
|
|
79
|
+
props.setdefault(
|
|
80
|
+
prop, cond(_find(position_map[prop], position), default1, default2)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _set_static_default(props, position, prop, default):
|
|
85
|
+
if prop in position:
|
|
86
|
+
props.setdefault(prop, default)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class ColorModeIconButton(IconButton):
|
|
90
|
+
"""Icon Button for toggling light / dark mode via toggle_color_mode."""
|
|
82
91
|
|
|
83
92
|
@classmethod
|
|
84
|
-
def create(
|
|
85
|
-
|
|
93
|
+
def create(
|
|
94
|
+
cls,
|
|
95
|
+
*children,
|
|
96
|
+
position: LiteralPosition | None = None,
|
|
97
|
+
**props,
|
|
98
|
+
):
|
|
99
|
+
"""Create a icon button component that calls toggle_color_mode on click.
|
|
86
100
|
|
|
87
101
|
Args:
|
|
88
102
|
*children: The children of the component.
|
|
103
|
+
position: The position of the icon button. Follow document flow if None.
|
|
89
104
|
**props: The props to pass to the component.
|
|
90
105
|
|
|
91
106
|
Returns:
|
|
92
107
|
The button component.
|
|
93
108
|
"""
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
if children:
|
|
110
|
+
console.deprecate(
|
|
111
|
+
feature_name="passing children to color_mode.button",
|
|
112
|
+
reason=", use color_mode_cond and toggle_color_mode instead to build a custom color_mode component",
|
|
113
|
+
deprecation_version="0.5.0",
|
|
114
|
+
removal_version="0.6.0",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# position is used to set nice defaults for positioning the icon button
|
|
118
|
+
if isinstance(position, Var):
|
|
119
|
+
_set_var_default(props, position, "position", "fixed", position)
|
|
120
|
+
_set_var_default(props, position, "bottom", "2rem")
|
|
121
|
+
_set_var_default(props, position, "top", "2rem")
|
|
122
|
+
_set_var_default(props, position, "left", "2rem")
|
|
123
|
+
_set_var_default(props, position, "right", "2rem")
|
|
124
|
+
elif position is not None:
|
|
125
|
+
if position in position_values:
|
|
126
|
+
props.setdefault("position", "fixed")
|
|
127
|
+
_set_static_default(props, position, "bottom", "2rem")
|
|
128
|
+
_set_static_default(props, position, "top", "2rem")
|
|
129
|
+
_set_static_default(props, position, "left", "2rem")
|
|
130
|
+
_set_static_default(props, position, "right", "2rem")
|
|
131
|
+
else:
|
|
132
|
+
props["position"] = position
|
|
133
|
+
|
|
134
|
+
props.setdefault("background", "transparent")
|
|
135
|
+
props.setdefault("color", "inherit")
|
|
136
|
+
props.setdefault("z_index", "20")
|
|
137
|
+
props.setdefault(":hover", {"cursor": "pointer"})
|
|
138
|
+
|
|
139
|
+
return super().create(
|
|
140
|
+
ColorModeIcon.create(),
|
|
96
141
|
on_click=toggle_color_mode,
|
|
97
142
|
**props,
|
|
98
143
|
)
|
|
@@ -102,8 +147,7 @@ class ColorModeNamespace(BaseVar):
|
|
|
102
147
|
"""Namespace for color mode components."""
|
|
103
148
|
|
|
104
149
|
icon = staticmethod(ColorModeIcon.create)
|
|
105
|
-
|
|
106
|
-
button = staticmethod(ColorModeButton.create)
|
|
150
|
+
button = staticmethod(ColorModeIconButton.create)
|
|
107
151
|
|
|
108
152
|
|
|
109
153
|
color_mode_var_and_namespace = ColorModeNamespace(**dataclasses.asdict(color_mode))
|