ex4nicegui 0.6.7__py3-none-any.whl → 0.6.9__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.
- ex4nicegui/__init__.py +12 -6
- ex4nicegui/gsap/__init__.py +11 -0
- ex4nicegui/helper/__init__.py +4 -0
- ex4nicegui/helper/client_instance_locker.py +31 -0
- ex4nicegui/reactive/__init__.py +4 -0
- ex4nicegui/reactive/base.py +426 -0
- ex4nicegui/reactive/deferredTask.py +3 -2
- ex4nicegui/reactive/local_file_picker.py +1 -2
- ex4nicegui/reactive/mixins/backgroundColor.py +41 -0
- ex4nicegui/reactive/mixins/disableable.py +44 -0
- ex4nicegui/reactive/mixins/textColor.py +66 -0
- ex4nicegui/reactive/officials/aggrid.py +4 -4
- ex4nicegui/reactive/officials/base.py +4 -351
- ex4nicegui/reactive/officials/button.py +36 -3
- ex4nicegui/reactive/officials/checkbox.py +2 -3
- ex4nicegui/reactive/officials/chip.py +102 -0
- ex4nicegui/reactive/officials/circular_progress.py +6 -5
- ex4nicegui/reactive/officials/color_picker.py +3 -4
- ex4nicegui/reactive/officials/column.py +1 -1
- ex4nicegui/reactive/officials/date.py +2 -3
- ex4nicegui/reactive/officials/drawer.py +2 -3
- ex4nicegui/reactive/officials/echarts.py +2 -3
- ex4nicegui/reactive/officials/expansion.py +2 -3
- ex4nicegui/reactive/officials/grid.py +4 -3
- ex4nicegui/reactive/officials/html.py +1 -3
- ex4nicegui/reactive/officials/icon.py +5 -9
- ex4nicegui/reactive/officials/image.py +2 -4
- ex4nicegui/reactive/officials/input.py +4 -6
- ex4nicegui/reactive/officials/knob.py +6 -4
- ex4nicegui/reactive/officials/label.py +3 -10
- ex4nicegui/reactive/officials/linear_progress.py +5 -9
- ex4nicegui/reactive/officials/number.py +3 -6
- ex4nicegui/reactive/officials/radio.py +3 -5
- ex4nicegui/reactive/officials/row.py +1 -1
- ex4nicegui/reactive/officials/select.py +3 -5
- ex4nicegui/reactive/officials/slider.py +4 -6
- ex4nicegui/reactive/officials/switch.py +2 -4
- ex4nicegui/reactive/officials/tab.py +1 -1
- ex4nicegui/reactive/officials/tab_panel.py +1 -1
- ex4nicegui/reactive/officials/tab_panels.py +109 -3
- ex4nicegui/reactive/officials/table.py +7 -6
- ex4nicegui/reactive/officials/tabs.py +1 -1
- ex4nicegui/reactive/officials/textarea.py +3 -5
- ex4nicegui/reactive/officials/upload.py +2 -2
- ex4nicegui/reactive/q_pagination.py +2 -2
- ex4nicegui/reactive/scopedStyle.js +55 -0
- ex4nicegui/reactive/scopedStyle.py +25 -0
- ex4nicegui/reactive/services/pandas_service.py +31 -0
- ex4nicegui/reactive/{utils.py → services/reactive_service.py} +9 -67
- ex4nicegui/reactive/systems/color_system.py +157 -0
- ex4nicegui/reactive/systems/object_system.py +33 -0
- ex4nicegui/reactive/systems/reactive_system.py +21 -0
- ex4nicegui/reactive/useMouse/UseMouse.py +4 -4
- ex4nicegui/reactive/usePagination.py +1 -1
- ex4nicegui/reactive/vfor.py +1 -2
- ex4nicegui/reactive/vmodel.py +1 -1
- ex4nicegui/utils/apiEffect.py +5 -1
- ex4nicegui/utils/effect.py +3 -2
- ex4nicegui/utils/refComputed.py +147 -0
- ex4nicegui/utils/refWrapper.py +57 -0
- ex4nicegui/utils/scheduler.py +20 -4
- ex4nicegui/utils/signals.py +51 -192
- ex4nicegui/utils/types.py +16 -0
- ex4nicegui/version.py +3 -0
- {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.9.dist-info}/METADATA +61 -4
- {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.9.dist-info}/RECORD +68 -58
- ex4nicegui/reactive/EChartsComponent/__init__.py +0 -0
- ex4nicegui/reactive/UseDraggable/__init__.py +0 -0
- ex4nicegui/reactive/dropZone/__init__.py +0 -0
- ex4nicegui/reactive/mermaid/__init__.py +0 -0
- ex4nicegui/reactive/officials/__init__.py +0 -1
- ex4nicegui/reactive/officials/utils.py +0 -11
- ex4nicegui/reactive/useMouse/__init__.py +0 -0
- {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.9.dist-info}/LICENSE +0 -0
- {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.9.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
Callable,
|
|
4
|
+
Dict,
|
|
5
|
+
Protocol,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
import signe
|
|
9
|
+
from ex4nicegui.utils.signals import (
|
|
10
|
+
TGetterOrReadonlyRef,
|
|
11
|
+
WatchedState,
|
|
12
|
+
)
|
|
13
|
+
from nicegui import ui
|
|
14
|
+
from ex4nicegui.reactive.systems import color_system
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TextColorableMixin(Protocol):
|
|
18
|
+
_ui_signal_on: Callable[[Callable[[TGetterOrReadonlyRef[str]], Any]], signe.Effect]
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def element(self) -> ui.element:
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
def _bind_text_color(self, ref_ui: TGetterOrReadonlyRef[str]):
|
|
25
|
+
@self._ui_signal_on(ref_ui) # type: ignore
|
|
26
|
+
def _(state: WatchedState):
|
|
27
|
+
if state.previous is not None:
|
|
28
|
+
color_system.remove_text_color(self.element, state.previous)
|
|
29
|
+
|
|
30
|
+
color_system.add_text_color(self.element, state.current)
|
|
31
|
+
|
|
32
|
+
self.element.update()
|
|
33
|
+
|
|
34
|
+
def bind_color(self, ref_ui: TGetterOrReadonlyRef[str]):
|
|
35
|
+
"""bind text color to the element
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
ref_ui (TGetterOrReadonlyRef[str]): a reference to the color value
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
self._bind_text_color(ref_ui)
|
|
42
|
+
return self
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class HtmlTextColorableMixin(Protocol):
|
|
46
|
+
_ui_signal_on: Callable[[Callable[[TGetterOrReadonlyRef[str]], Any]], signe.Effect]
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def element(self) -> ui.element:
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
def bind_style(self, style: Dict[str, TGetterOrReadonlyRef[Any]]):
|
|
53
|
+
...
|
|
54
|
+
|
|
55
|
+
def _bind_text_color(self, ref_ui: TGetterOrReadonlyRef[str]):
|
|
56
|
+
return self.bind_style({"color": ref_ui})
|
|
57
|
+
|
|
58
|
+
def bind_color(self, ref_ui: TGetterOrReadonlyRef[str]):
|
|
59
|
+
"""bind text color to the element
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
ref_ui (TGetterOrReadonlyRef[str]): a reference to the color value
|
|
63
|
+
|
|
64
|
+
"""
|
|
65
|
+
self._bind_text_color(ref_ui)
|
|
66
|
+
return self
|
|
@@ -9,13 +9,13 @@ from ex4nicegui.utils.signals import (
|
|
|
9
9
|
is_ref,
|
|
10
10
|
ref_computed,
|
|
11
11
|
to_value,
|
|
12
|
-
|
|
12
|
+
TMaybeRef,
|
|
13
13
|
TGetterOrReadonlyRef,
|
|
14
14
|
)
|
|
15
|
-
from ex4nicegui.utils.apiEffect import ui_effect
|
|
16
15
|
from nicegui import ui
|
|
17
16
|
from .base import BindableUi
|
|
18
|
-
from ex4nicegui.reactive.
|
|
17
|
+
from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
|
|
18
|
+
from ex4nicegui.reactive.services.pandas_service import dataframe2col_str
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class AggridBindableUi(BindableUi[ui.aggrid]):
|
|
@@ -85,7 +85,7 @@ class AggridBindableUi(BindableUi[ui.aggrid]):
|
|
|
85
85
|
return super().bind_prop(prop, ref_ui)
|
|
86
86
|
|
|
87
87
|
def bind_options(self, ref_ui: TGetterOrReadonlyRef[List[Dict]]):
|
|
88
|
-
@
|
|
88
|
+
@self._ui_effect
|
|
89
89
|
def _():
|
|
90
90
|
ele = self.element
|
|
91
91
|
data = to_value(ref_ui)
|
|
@@ -1,352 +1,5 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Callable,
|
|
6
|
-
Dict,
|
|
7
|
-
List,
|
|
8
|
-
Optional,
|
|
9
|
-
Protocol,
|
|
10
|
-
TypeVar,
|
|
11
|
-
Generic,
|
|
12
|
-
Union,
|
|
13
|
-
cast,
|
|
14
|
-
Literal,
|
|
1
|
+
from ex4nicegui.reactive.base import (
|
|
2
|
+
BindableUi, # noqa: F401
|
|
3
|
+
DisableableMixin, # noqa: F401
|
|
4
|
+
DisableableBindableUi, # noqa: F401
|
|
15
5
|
)
|
|
16
|
-
|
|
17
|
-
from typing_extensions import Self
|
|
18
|
-
from ex4nicegui.utils.apiEffect import ui_effect
|
|
19
|
-
import signe
|
|
20
|
-
from ex4nicegui.utils.signals import (
|
|
21
|
-
TGetterOrReadonlyRef,
|
|
22
|
-
effect,
|
|
23
|
-
to_value,
|
|
24
|
-
is_ref,
|
|
25
|
-
WatchedState,
|
|
26
|
-
on,
|
|
27
|
-
)
|
|
28
|
-
from nicegui import Tailwind, ui
|
|
29
|
-
from nicegui.elements.mixins.color_elements import (
|
|
30
|
-
TextColorElement,
|
|
31
|
-
QUASAR_COLORS,
|
|
32
|
-
TAILWIND_COLORS,
|
|
33
|
-
)
|
|
34
|
-
from nicegui.elements.mixins.text_element import TextElement
|
|
35
|
-
from nicegui.elements.mixins.disableable_element import DisableableElement
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
T = TypeVar("T")
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
TWidget = TypeVar("TWidget", bound=ui.element)
|
|
42
|
-
|
|
43
|
-
_T_bind_classes_type_dict = Dict[str, TGetterOrReadonlyRef[bool]]
|
|
44
|
-
_T_bind_classes_type_ref_dict = TGetterOrReadonlyRef[Dict[str, bool]]
|
|
45
|
-
_T_bind_classes_type_array = List[TGetterOrReadonlyRef[str]]
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
_T_bind_classes_type = Union[
|
|
49
|
-
_T_bind_classes_type_dict, _T_bind_classes_type_ref_dict, _T_bind_classes_type_array
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class BindableUi(Generic[TWidget]):
|
|
54
|
-
def __init__(self, element: TWidget) -> None:
|
|
55
|
-
self._element = element
|
|
56
|
-
self.tailwind = Tailwind(cast(ui.element, self._element))
|
|
57
|
-
|
|
58
|
-
def _ui_effect(self, fn: Callable):
|
|
59
|
-
return ui_effect(fn)
|
|
60
|
-
|
|
61
|
-
def props(self, add: Optional[str] = None, *, remove: Optional[str] = None):
|
|
62
|
-
cast(ui.element, self.element).props(add, remove=remove)
|
|
63
|
-
return self
|
|
64
|
-
|
|
65
|
-
def classes(
|
|
66
|
-
self,
|
|
67
|
-
add: Optional[str] = None,
|
|
68
|
-
*,
|
|
69
|
-
remove: Optional[str] = None,
|
|
70
|
-
replace: Optional[str] = None,
|
|
71
|
-
):
|
|
72
|
-
cast(ui.element, self.element).classes(add, remove=remove, replace=replace)
|
|
73
|
-
return self
|
|
74
|
-
|
|
75
|
-
def style(
|
|
76
|
-
self,
|
|
77
|
-
add: Optional[str] = None,
|
|
78
|
-
*,
|
|
79
|
-
remove: Optional[str] = None,
|
|
80
|
-
replace: Optional[str] = None,
|
|
81
|
-
):
|
|
82
|
-
cast(ui.element, self.element).style(add, remove=remove, replace=replace)
|
|
83
|
-
return self
|
|
84
|
-
|
|
85
|
-
def __enter__(self) -> Self:
|
|
86
|
-
self.element.__enter__()
|
|
87
|
-
return self
|
|
88
|
-
|
|
89
|
-
def __exit__(self, *_):
|
|
90
|
-
self.element.default_slot.__exit__(*_)
|
|
91
|
-
|
|
92
|
-
def tooltip(self, text: str) -> Self:
|
|
93
|
-
cast(ui.element, self.element).tooltip(text)
|
|
94
|
-
return self
|
|
95
|
-
|
|
96
|
-
def add_slot(self, name: str, template: Optional[str] = None):
|
|
97
|
-
"""Add a slot to the element.
|
|
98
|
-
|
|
99
|
-
:param name: name of the slot
|
|
100
|
-
:param template: Vue template of the slot
|
|
101
|
-
:return: the slot
|
|
102
|
-
"""
|
|
103
|
-
return cast(ui.element, self.element).add_slot(name, template)
|
|
104
|
-
|
|
105
|
-
@property
|
|
106
|
-
def element(self):
|
|
107
|
-
return self._element
|
|
108
|
-
|
|
109
|
-
def delete(self) -> None:
|
|
110
|
-
"""Delete the element."""
|
|
111
|
-
self.delete()
|
|
112
|
-
|
|
113
|
-
def move(
|
|
114
|
-
self, target_container: Optional[ui.element] = None, target_index: int = -1
|
|
115
|
-
):
|
|
116
|
-
"""Move the element to another container.
|
|
117
|
-
|
|
118
|
-
:param target_container: container to move the element to (default: the parent container)
|
|
119
|
-
:param target_index: index within the target slot (default: append to the end)
|
|
120
|
-
"""
|
|
121
|
-
return self.move(target_container, target_index)
|
|
122
|
-
|
|
123
|
-
def remove(self, element: Union[ui.element, int]) -> None:
|
|
124
|
-
"""Remove a child element.
|
|
125
|
-
|
|
126
|
-
:param element: either the element instance or its ID
|
|
127
|
-
"""
|
|
128
|
-
return self.element.remove(element)
|
|
129
|
-
|
|
130
|
-
def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef[Any]):
|
|
131
|
-
"""data binding is manipulating an element's property
|
|
132
|
-
|
|
133
|
-
@see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bind_prop
|
|
134
|
-
@中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#bind_prop
|
|
135
|
-
|
|
136
|
-
Args:
|
|
137
|
-
prop (str): property name
|
|
138
|
-
ref_ui (TGetterOrReadonlyRef[Any]): a reference to the value to bind to
|
|
139
|
-
|
|
140
|
-
"""
|
|
141
|
-
if prop == "visible":
|
|
142
|
-
return self.bind_visible(ref_ui)
|
|
143
|
-
|
|
144
|
-
if prop == "text" and isinstance(self.element, TextElement):
|
|
145
|
-
|
|
146
|
-
@self._ui_effect
|
|
147
|
-
def _():
|
|
148
|
-
cast(TextElement, self.element).set_text(to_value(ref_ui))
|
|
149
|
-
self.element.update()
|
|
150
|
-
|
|
151
|
-
@self._ui_effect
|
|
152
|
-
def _():
|
|
153
|
-
element = cast(ui.element, self.element)
|
|
154
|
-
element._props[prop] = to_value(ref_ui)
|
|
155
|
-
element.update()
|
|
156
|
-
|
|
157
|
-
return self
|
|
158
|
-
|
|
159
|
-
def bind_visible(self, ref_ui: TGetterOrReadonlyRef[bool]):
|
|
160
|
-
@self._ui_effect
|
|
161
|
-
def _():
|
|
162
|
-
element = cast(ui.element, self.element)
|
|
163
|
-
element.set_visibility(to_value(ref_ui))
|
|
164
|
-
|
|
165
|
-
return self
|
|
166
|
-
|
|
167
|
-
def bind_not_visible(self, ref_ui: TGetterOrReadonlyRef[bool]):
|
|
168
|
-
return self.bind_visible(lambda: not to_value(ref_ui))
|
|
169
|
-
|
|
170
|
-
def on(
|
|
171
|
-
self,
|
|
172
|
-
type: str,
|
|
173
|
-
handler: Optional[Callable[..., Any]] = None,
|
|
174
|
-
args: Optional[List[str]] = None,
|
|
175
|
-
*,
|
|
176
|
-
throttle: float = 0.0,
|
|
177
|
-
leading_events: bool = True,
|
|
178
|
-
trailing_events: bool = True,
|
|
179
|
-
):
|
|
180
|
-
ele = cast(ui.element, self.element)
|
|
181
|
-
ele.on(
|
|
182
|
-
type,
|
|
183
|
-
handler,
|
|
184
|
-
args,
|
|
185
|
-
throttle=throttle,
|
|
186
|
-
leading_events=leading_events,
|
|
187
|
-
trailing_events=trailing_events,
|
|
188
|
-
)
|
|
189
|
-
|
|
190
|
-
return self
|
|
191
|
-
|
|
192
|
-
def clear(self) -> None:
|
|
193
|
-
cast(ui.element, self.element).clear()
|
|
194
|
-
|
|
195
|
-
def bind_classes(self, classes: _T_bind_classes_type):
|
|
196
|
-
"""data binding is manipulating an element's class list
|
|
197
|
-
|
|
198
|
-
@see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bind-class-names
|
|
199
|
-
@中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#%E7%BB%91%E5%AE%9A%E7%B1%BB%E5%90%8D
|
|
200
|
-
|
|
201
|
-
Args:
|
|
202
|
-
classes (_T_bind_classes_type):
|
|
203
|
-
"""
|
|
204
|
-
if isinstance(classes, dict):
|
|
205
|
-
for name, ref_obj in classes.items():
|
|
206
|
-
|
|
207
|
-
@self._ui_effect
|
|
208
|
-
def _(name=name, ref_obj=ref_obj):
|
|
209
|
-
if to_value(ref_obj):
|
|
210
|
-
self.classes(add=name)
|
|
211
|
-
else:
|
|
212
|
-
self.classes(remove=name)
|
|
213
|
-
|
|
214
|
-
elif is_ref(classes) or isinstance(classes, Callable):
|
|
215
|
-
ref_obj = to_value(classes) # type: ignore
|
|
216
|
-
assert isinstance(ref_obj, dict)
|
|
217
|
-
|
|
218
|
-
@effect
|
|
219
|
-
def _():
|
|
220
|
-
for name, value in cast(Dict, to_value(classes)).items(): # type: ignore
|
|
221
|
-
if value:
|
|
222
|
-
self.classes(add=name)
|
|
223
|
-
else:
|
|
224
|
-
self.classes(remove=name)
|
|
225
|
-
elif isinstance(classes, list):
|
|
226
|
-
for ref_name in classes:
|
|
227
|
-
if is_ref(ref_name) or isinstance(ref_name, Callable):
|
|
228
|
-
|
|
229
|
-
@on(ref_name)
|
|
230
|
-
def _(state: WatchedState):
|
|
231
|
-
self.classes(add=state.current, remove=state.previous)
|
|
232
|
-
else:
|
|
233
|
-
self.classes(ref_name) # type: ignore
|
|
234
|
-
|
|
235
|
-
return self
|
|
236
|
-
|
|
237
|
-
def bind_style(self, style: Dict[str, TGetterOrReadonlyRef[Any]]):
|
|
238
|
-
"""data binding is manipulating an element's style
|
|
239
|
-
|
|
240
|
-
@see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bind-style
|
|
241
|
-
@中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#bind-style
|
|
242
|
-
|
|
243
|
-
Args:
|
|
244
|
-
style (Dict[str, Union[ReadonlyRef[str], Ref[str]]]): _description_
|
|
245
|
-
"""
|
|
246
|
-
if isinstance(style, dict):
|
|
247
|
-
for name, ref_obj in style.items():
|
|
248
|
-
if is_ref(ref_obj) or isinstance(ref_obj, Callable):
|
|
249
|
-
|
|
250
|
-
@self._ui_effect
|
|
251
|
-
def _(name=name, ref_obj=ref_obj):
|
|
252
|
-
self.element._style[name] = str(to_value(ref_obj))
|
|
253
|
-
self.element.update()
|
|
254
|
-
|
|
255
|
-
return self
|
|
256
|
-
|
|
257
|
-
def update(self):
|
|
258
|
-
"""Update the element on the client side."""
|
|
259
|
-
self.element.update()
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
# class SingleValueBindableUi(BindableUi[TWidget], Generic[T, TWidget]):
|
|
263
|
-
# def __init__(self, value: TMaybeRef[T], element: TWidget) -> None:
|
|
264
|
-
# super().__init__(element)
|
|
265
|
-
# self._ref = to_ref(value)
|
|
266
|
-
|
|
267
|
-
# @property
|
|
268
|
-
# def value(self) -> T:
|
|
269
|
-
# return self._ref.value # type: ignore
|
|
270
|
-
|
|
271
|
-
# def bind_ref(self, ref: TRef[T]):
|
|
272
|
-
# @effect
|
|
273
|
-
# def _():
|
|
274
|
-
# ref.value = self._ref.value # type: ignore
|
|
275
|
-
|
|
276
|
-
# return self
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
_T_DisableableBinder = TypeVar("_T_DisableableBinder", bound=DisableableElement)
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
class DisableableMixin(Protocol):
|
|
283
|
-
_ui_effect: Callable[[Callable[..., Any]], signe.Effect[None]]
|
|
284
|
-
|
|
285
|
-
@property
|
|
286
|
-
def element(self) -> DisableableElement:
|
|
287
|
-
...
|
|
288
|
-
|
|
289
|
-
def bind_enabled(self, ref_ui: TGetterOrReadonlyRef[bool]):
|
|
290
|
-
@self._ui_effect
|
|
291
|
-
def _():
|
|
292
|
-
value = to_value(ref_ui)
|
|
293
|
-
self.element.set_enabled(value)
|
|
294
|
-
self.element._handle_enabled_change(value)
|
|
295
|
-
|
|
296
|
-
return self
|
|
297
|
-
|
|
298
|
-
def bind_disable(self, ref_ui: TGetterOrReadonlyRef[bool]):
|
|
299
|
-
@self._ui_effect
|
|
300
|
-
def _():
|
|
301
|
-
value = not to_value(ref_ui)
|
|
302
|
-
self.element.set_enabled(value)
|
|
303
|
-
self.element._handle_enabled_change(value)
|
|
304
|
-
|
|
305
|
-
return self
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
DisableableBindableUi = DisableableMixin
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
_color_sys_type = Literal["QUASAR", "TAILWIND", "STYLE"]
|
|
312
|
-
_color_attr_name = "data-ex4ng-color"
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
def _bind_color(bindable_ui: BindableUi, ref_ui: TGetterOrReadonlyRef):
|
|
316
|
-
@effect
|
|
317
|
-
def _():
|
|
318
|
-
ele = cast(TextColorElement, bindable_ui.element)
|
|
319
|
-
color = to_value(ref_ui)
|
|
320
|
-
|
|
321
|
-
# get exists color
|
|
322
|
-
# e.g 'QUASAR:red'
|
|
323
|
-
pre_color = ele._props.get(_color_attr_name) # type: str | None
|
|
324
|
-
if pre_color:
|
|
325
|
-
color_sys, value = pre_color.split(":") # type: ignore
|
|
326
|
-
color_sys: _color_sys_type
|
|
327
|
-
|
|
328
|
-
if color_sys == "QUASAR":
|
|
329
|
-
del ele._props[ele.TEXT_COLOR_PROP]
|
|
330
|
-
elif color_sys == "TAILWIND":
|
|
331
|
-
ele.classes(remove=value)
|
|
332
|
-
else:
|
|
333
|
-
del ele._style["color"]
|
|
334
|
-
|
|
335
|
-
cur_sys: _color_sys_type = "STYLE"
|
|
336
|
-
cur_color = color
|
|
337
|
-
|
|
338
|
-
if color in QUASAR_COLORS:
|
|
339
|
-
ele._props[ele.TEXT_COLOR_PROP] = color
|
|
340
|
-
cur_sys = "QUASAR"
|
|
341
|
-
elif color in TAILWIND_COLORS:
|
|
342
|
-
cur_color = f"text-{color}"
|
|
343
|
-
ele.classes(replace=cur_color)
|
|
344
|
-
cur_sys = "TAILWIND"
|
|
345
|
-
elif color is not None:
|
|
346
|
-
ele._style["color"] = color
|
|
347
|
-
|
|
348
|
-
ele._props[_color_attr_name] = f"{cur_sys}:{color}"
|
|
349
|
-
|
|
350
|
-
ele.update()
|
|
351
|
-
|
|
352
|
-
return bindable_ui
|
|
@@ -3,17 +3,28 @@ from typing import (
|
|
|
3
3
|
Callable,
|
|
4
4
|
Optional,
|
|
5
5
|
)
|
|
6
|
-
from ex4nicegui.reactive.
|
|
6
|
+
from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
|
|
7
7
|
from ex4nicegui.utils.signals import (
|
|
8
8
|
TGetterOrReadonlyRef,
|
|
9
9
|
_TMaybeRef as TMaybeRef,
|
|
10
10
|
to_value,
|
|
11
11
|
)
|
|
12
12
|
from nicegui import ui
|
|
13
|
-
from .base import
|
|
13
|
+
from .base import (
|
|
14
|
+
BindableUi,
|
|
15
|
+
DisableableMixin,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from ex4nicegui.reactive.mixins.backgroundColor import BackgroundColorableMixin
|
|
19
|
+
from ex4nicegui.reactive.mixins.textColor import TextColorableMixin
|
|
14
20
|
|
|
15
21
|
|
|
16
|
-
class ButtonBindableUi(
|
|
22
|
+
class ButtonBindableUi(
|
|
23
|
+
BindableUi[ui.button],
|
|
24
|
+
DisableableMixin,
|
|
25
|
+
BackgroundColorableMixin,
|
|
26
|
+
TextColorableMixin,
|
|
27
|
+
):
|
|
17
28
|
def __init__(
|
|
18
29
|
self,
|
|
19
30
|
text: TMaybeRef[str] = "",
|
|
@@ -38,9 +49,31 @@ class ButtonBindableUi(BindableUi[ui.button], DisableableMixin):
|
|
|
38
49
|
return self.bind_text(ref_ui)
|
|
39
50
|
if prop == "icon":
|
|
40
51
|
return self.bind_icon(ref_ui)
|
|
52
|
+
if prop == "color":
|
|
53
|
+
return self.bind_color(ref_ui)
|
|
41
54
|
|
|
42
55
|
return super().bind_prop(prop, ref_ui)
|
|
43
56
|
|
|
57
|
+
def bind_color(self, ref_ui: TGetterOrReadonlyRef[str]):
|
|
58
|
+
"""Binds the background color of the button.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
ref_ui (TGetterOrReadonlyRef[str]): Getter or readonly reference to the color.
|
|
62
|
+
|
|
63
|
+
"""
|
|
64
|
+
BackgroundColorableMixin.bind_color(self, ref_ui)
|
|
65
|
+
return self
|
|
66
|
+
|
|
67
|
+
def bind_text_color(self, ref_ui: TGetterOrReadonlyRef[str]):
|
|
68
|
+
"""Binds the text color of the button.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
ref_ui (TGetterOrReadonlyRef[str]): Getter or readonly reference to the color.
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
TextColorableMixin.bind_color(self, ref_ui)
|
|
75
|
+
return self
|
|
76
|
+
|
|
44
77
|
def bind_text(self, ref_ui: TGetterOrReadonlyRef):
|
|
45
78
|
@self._ui_effect
|
|
46
79
|
def _():
|
|
@@ -4,8 +4,7 @@ from typing import (
|
|
|
4
4
|
Optional,
|
|
5
5
|
TypeVar,
|
|
6
6
|
)
|
|
7
|
-
from ex4nicegui.reactive.
|
|
8
|
-
from ex4nicegui.utils.apiEffect import ui_effect
|
|
7
|
+
from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
|
|
9
8
|
from ex4nicegui.utils.signals import (
|
|
10
9
|
TGetterOrReadonlyRef,
|
|
11
10
|
_TMaybeRef as TMaybeRef,
|
|
@@ -51,7 +50,7 @@ class CheckboxBindableUi(BindableUi[ui.checkbox], DisableableMixin):
|
|
|
51
50
|
return super().bind_prop(prop, ref_ui)
|
|
52
51
|
|
|
53
52
|
def bind_value(self, ref_ui: TGetterOrReadonlyRef[bool]):
|
|
54
|
-
@
|
|
53
|
+
@self._ui_effect
|
|
55
54
|
def _():
|
|
56
55
|
self.element.set_value(to_value(ref_ui))
|
|
57
56
|
self.element.update()
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from typing import Any, Callable, Optional
|
|
2
|
+
from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
|
|
3
|
+
from ex4nicegui.utils.signals import (
|
|
4
|
+
TGetterOrReadonlyRef,
|
|
5
|
+
to_value,
|
|
6
|
+
_TMaybeRef as TMaybeRef,
|
|
7
|
+
)
|
|
8
|
+
from nicegui import ui
|
|
9
|
+
from .base import BindableUi
|
|
10
|
+
from ex4nicegui.reactive.mixins.backgroundColor import BackgroundColorableMixin
|
|
11
|
+
from ex4nicegui.reactive.mixins.textColor import TextColorableMixin
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ChipBindableUi(
|
|
15
|
+
BindableUi[ui.chip],
|
|
16
|
+
BackgroundColorableMixin,
|
|
17
|
+
TextColorableMixin,
|
|
18
|
+
):
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
text: TMaybeRef[str] = "",
|
|
22
|
+
*,
|
|
23
|
+
icon: Optional[TMaybeRef[str]] = None,
|
|
24
|
+
color: Optional[TMaybeRef[str]] = "primary",
|
|
25
|
+
text_color: Optional[TMaybeRef[str]] = None,
|
|
26
|
+
on_click: Optional[Callable[..., Any]] = None,
|
|
27
|
+
selectable: TMaybeRef[bool] = False,
|
|
28
|
+
selected: TMaybeRef[bool] = False,
|
|
29
|
+
on_selection_change: Optional[Callable[..., Any]] = None,
|
|
30
|
+
removable: TMaybeRef[bool] = False,
|
|
31
|
+
on_value_change: Optional[Callable[..., Any]] = None,
|
|
32
|
+
) -> None:
|
|
33
|
+
pc = ParameterClassifier(
|
|
34
|
+
locals(),
|
|
35
|
+
maybeRefs=[
|
|
36
|
+
"text",
|
|
37
|
+
"icon",
|
|
38
|
+
"color",
|
|
39
|
+
"text_color",
|
|
40
|
+
"selectable",
|
|
41
|
+
"selected",
|
|
42
|
+
"removable",
|
|
43
|
+
],
|
|
44
|
+
events=["on_click", "on_selection_change", "on_value_change"],
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
element = ui.chip(**pc.get_values_kws())
|
|
48
|
+
super().__init__(element)
|
|
49
|
+
|
|
50
|
+
for key, value in pc.get_bindings().items():
|
|
51
|
+
self.bind_prop(key, value) # type: ignore
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def text(self):
|
|
55
|
+
return self.element.text
|
|
56
|
+
|
|
57
|
+
def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
|
|
58
|
+
if prop == "text":
|
|
59
|
+
return self.bind_text(ref_ui)
|
|
60
|
+
|
|
61
|
+
if prop == "color":
|
|
62
|
+
return self.bind_color(ref_ui)
|
|
63
|
+
if prop == "text-color":
|
|
64
|
+
return self.bind_text_color(ref_ui)
|
|
65
|
+
|
|
66
|
+
return super().bind_prop(prop, ref_ui)
|
|
67
|
+
|
|
68
|
+
def bind_color(self, color: TGetterOrReadonlyRef):
|
|
69
|
+
"""Binds the background color property of the chip to a ui element.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
color (TGetterOrReadonlyRef): background color ui element or getter function
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
BackgroundColorableMixin.bind_color(self, color)
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
def bind_text_color(self, color: TGetterOrReadonlyRef):
|
|
79
|
+
"""Binds the text color property of the chip to a ui element.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
color (TGetterOrReadonlyRef): text color ui element or getter function
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
TextColorableMixin.bind_color(self, color)
|
|
87
|
+
return self
|
|
88
|
+
|
|
89
|
+
def bind_text(self, text: TGetterOrReadonlyRef):
|
|
90
|
+
"""Binds the text property of the chip to a ui element.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
text (TGetterOrReadonlyRef): text ui element or getter function
|
|
94
|
+
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
@self._ui_effect
|
|
98
|
+
def _():
|
|
99
|
+
self.element.set_text(str(to_value(text)))
|
|
100
|
+
self.element.update()
|
|
101
|
+
|
|
102
|
+
return self
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
from typing import (
|
|
2
2
|
Optional,
|
|
3
3
|
)
|
|
4
|
-
from ex4nicegui.reactive.
|
|
5
|
-
from ex4nicegui.utils.apiEffect import ui_effect
|
|
4
|
+
from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
|
|
6
5
|
|
|
7
6
|
from ex4nicegui.utils.signals import (
|
|
8
7
|
TGetterOrReadonlyRef,
|
|
@@ -11,11 +10,11 @@ from ex4nicegui.utils.signals import (
|
|
|
11
10
|
)
|
|
12
11
|
from nicegui import ui
|
|
13
12
|
from .base import BindableUi, DisableableMixin
|
|
13
|
+
from ex4nicegui.reactive.mixins.backgroundColor import BackgroundColorableMixin
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class CircularProgressBindableUi(
|
|
17
|
-
BindableUi[ui.circular_progress],
|
|
18
|
-
DisableableMixin,
|
|
17
|
+
BindableUi[ui.circular_progress], DisableableMixin, BackgroundColorableMixin
|
|
19
18
|
):
|
|
20
19
|
def __init__(
|
|
21
20
|
self,
|
|
@@ -53,11 +52,13 @@ class CircularProgressBindableUi(
|
|
|
53
52
|
def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
|
|
54
53
|
if prop == "value":
|
|
55
54
|
return self.bind_value(ref_ui)
|
|
55
|
+
if prop == "color":
|
|
56
|
+
return self.bind_color(ref_ui)
|
|
56
57
|
|
|
57
58
|
return super().bind_prop(prop, ref_ui)
|
|
58
59
|
|
|
59
60
|
def bind_value(self, ref_ui: TGetterOrReadonlyRef[float]):
|
|
60
|
-
@
|
|
61
|
+
@self._ui_effect
|
|
61
62
|
def _():
|
|
62
63
|
self.element.set_value(to_value(ref_ui))
|
|
63
64
|
|
|
@@ -4,8 +4,7 @@ from typing import (
|
|
|
4
4
|
Optional,
|
|
5
5
|
cast,
|
|
6
6
|
)
|
|
7
|
-
from ex4nicegui.reactive.
|
|
8
|
-
from ex4nicegui.utils.apiEffect import ui_effect
|
|
7
|
+
from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
|
|
9
8
|
|
|
10
9
|
from ex4nicegui.utils.signals import (
|
|
11
10
|
TGetterOrReadonlyRef,
|
|
@@ -76,14 +75,14 @@ class ColorPickerBindableUi(BindableUi[ui.color_picker]):
|
|
|
76
75
|
return super().bind_prop(prop, ref_ui)
|
|
77
76
|
|
|
78
77
|
def bind_color(self, ref_ui: TGetterOrReadonlyRef[str]):
|
|
79
|
-
@
|
|
78
|
+
@self._ui_effect
|
|
80
79
|
def _():
|
|
81
80
|
self.element.set_color(to_value(ref_ui))
|
|
82
81
|
|
|
83
82
|
return self
|
|
84
83
|
|
|
85
84
|
def bind_value(self, ref_ui: TGetterOrReadonlyRef[bool]):
|
|
86
|
-
@
|
|
85
|
+
@self._ui_effect
|
|
87
86
|
def _():
|
|
88
87
|
self.element.set_value(to_value(ref_ui))
|
|
89
88
|
|