ex4nicegui 0.6.7__py3-none-any.whl → 0.6.8__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.
Files changed (66) hide show
  1. ex4nicegui/__init__.py +10 -6
  2. ex4nicegui/gsap/__init__.py +11 -0
  3. ex4nicegui/helper/__init__.py +4 -0
  4. ex4nicegui/helper/client_instance_locker.py +31 -0
  5. ex4nicegui/reactive/local_file_picker.py +1 -2
  6. ex4nicegui/reactive/officials/aggrid.py +4 -4
  7. ex4nicegui/reactive/officials/base.py +188 -86
  8. ex4nicegui/reactive/officials/button.py +1 -1
  9. ex4nicegui/reactive/officials/checkbox.py +2 -3
  10. ex4nicegui/reactive/officials/circular_progress.py +2 -3
  11. ex4nicegui/reactive/officials/color_picker.py +3 -4
  12. ex4nicegui/reactive/officials/column.py +1 -1
  13. ex4nicegui/reactive/officials/date.py +2 -3
  14. ex4nicegui/reactive/officials/drawer.py +2 -3
  15. ex4nicegui/reactive/officials/echarts.py +2 -3
  16. ex4nicegui/reactive/officials/expansion.py +2 -3
  17. ex4nicegui/reactive/officials/grid.py +1 -1
  18. ex4nicegui/reactive/officials/html.py +1 -3
  19. ex4nicegui/reactive/officials/icon.py +5 -6
  20. ex4nicegui/reactive/officials/image.py +2 -4
  21. ex4nicegui/reactive/officials/input.py +4 -6
  22. ex4nicegui/reactive/officials/knob.py +2 -4
  23. ex4nicegui/reactive/officials/label.py +1 -1
  24. ex4nicegui/reactive/officials/linear_progress.py +5 -6
  25. ex4nicegui/reactive/officials/number.py +3 -6
  26. ex4nicegui/reactive/officials/radio.py +3 -5
  27. ex4nicegui/reactive/officials/row.py +1 -1
  28. ex4nicegui/reactive/officials/select.py +3 -5
  29. ex4nicegui/reactive/officials/slider.py +3 -5
  30. ex4nicegui/reactive/officials/switch.py +2 -4
  31. ex4nicegui/reactive/officials/tab.py +1 -1
  32. ex4nicegui/reactive/officials/tab_panel.py +1 -1
  33. ex4nicegui/reactive/officials/tab_panels.py +1 -1
  34. ex4nicegui/reactive/officials/table.py +7 -6
  35. ex4nicegui/reactive/officials/tabs.py +1 -1
  36. ex4nicegui/reactive/officials/textarea.py +3 -5
  37. ex4nicegui/reactive/officials/upload.py +2 -2
  38. ex4nicegui/reactive/q_pagination.py +2 -2
  39. ex4nicegui/reactive/scopedStyle.js +55 -0
  40. ex4nicegui/reactive/scopedStyle.py +22 -0
  41. ex4nicegui/reactive/services/color_service.py +56 -0
  42. ex4nicegui/reactive/services/pandas_service.py +31 -0
  43. ex4nicegui/reactive/{utils.py → services/reactive_service.py} +9 -67
  44. ex4nicegui/reactive/systems/color_system.py +25 -0
  45. ex4nicegui/reactive/systems/object_system.py +33 -0
  46. ex4nicegui/reactive/systems/reactive_system.py +21 -0
  47. ex4nicegui/reactive/useMouse/UseMouse.py +4 -4
  48. ex4nicegui/reactive/usePagination.py +1 -1
  49. ex4nicegui/reactive/vfor.py +1 -2
  50. ex4nicegui/reactive/vmodel.py +1 -1
  51. ex4nicegui/utils/refComputed.py +147 -0
  52. ex4nicegui/utils/refWrapper.py +57 -0
  53. ex4nicegui/utils/signals.py +51 -192
  54. ex4nicegui/utils/types.py +16 -0
  55. ex4nicegui/version.py +3 -0
  56. {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.8.dist-info}/METADATA +33 -4
  57. {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.8.dist-info}/RECORD +59 -53
  58. ex4nicegui/reactive/EChartsComponent/__init__.py +0 -0
  59. ex4nicegui/reactive/UseDraggable/__init__.py +0 -0
  60. ex4nicegui/reactive/dropZone/__init__.py +0 -0
  61. ex4nicegui/reactive/mermaid/__init__.py +0 -0
  62. ex4nicegui/reactive/officials/__init__.py +0 -1
  63. ex4nicegui/reactive/officials/utils.py +0 -11
  64. ex4nicegui/reactive/useMouse/__init__.py +0 -0
  65. {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.8.dist-info}/LICENSE +0 -0
  66. {ex4nicegui-0.6.7.dist-info → ex4nicegui-0.6.8.dist-info}/WHEEL +0 -0
ex4nicegui/__init__.py CHANGED
@@ -1,6 +1,12 @@
1
1
  from ex4nicegui import reactive as rxui
2
+ from ex4nicegui.utils.refComputed import ref_computed
3
+ from ex4nicegui.utils.types import (
4
+ _TMaybeRef as TMaybeRef,
5
+ Ref,
6
+ ReadonlyRef,
7
+ TGetterOrReadonlyRef,
8
+ )
2
9
  from ex4nicegui.utils.signals import (
3
- ref_computed,
4
10
  effect,
5
11
  effect_refreshable,
6
12
  to_raw,
@@ -10,9 +16,6 @@ from ex4nicegui.utils.signals import (
10
16
  ref,
11
17
  on,
12
18
  event_batch,
13
- _TMaybeRef as TMaybeRef,
14
- Ref,
15
- ReadonlyRef,
16
19
  reactive,
17
20
  deep_ref,
18
21
  is_setter_ref,
@@ -21,6 +24,7 @@ from ex4nicegui.utils.signals import (
21
24
  )
22
25
  from ex4nicegui.utils.asyncComputed import async_computed
23
26
  from ex4nicegui.utils.clientScope import new_scope
27
+ from .version import __version__
24
28
 
25
29
  __all__ = [
26
30
  "async_computed",
@@ -36,6 +40,7 @@ __all__ = [
36
40
  "on",
37
41
  "event_batch",
38
42
  "TMaybeRef",
43
+ "TGetterOrReadonlyRef",
39
44
  "Ref",
40
45
  "ReadonlyRef",
41
46
  "reactive",
@@ -44,6 +49,5 @@ __all__ = [
44
49
  "to_raw",
45
50
  "is_setter_ref",
46
51
  "new_scope",
52
+ "__version__",
47
53
  ]
48
-
49
- __version__ = "0.6.6"
@@ -2,6 +2,17 @@ from .gsap import set_defaults, from_, to, new, run_script
2
2
  from .timeline import Timeline as timeline
3
3
 
4
4
 
5
+ import warnings
6
+
7
+ RED = "\033[91m"
8
+ RESET = "\033[0m"
9
+
10
+ warnings.warn(
11
+ f"{RED}The gsap module is deprecated and will be removed in the next major version.{RESET}",
12
+ DeprecationWarning,
13
+ stacklevel=2,
14
+ )
15
+
5
16
  __all__ = [
6
17
  "set_defaults",
7
18
  "from_",
@@ -0,0 +1,4 @@
1
+ from .client_instance_locker import ClientInstanceLocker
2
+
3
+
4
+ __all__ = ["ClientInstanceLocker"]
@@ -0,0 +1,31 @@
1
+ from typing import Callable, TypeVar, Generic
2
+ from nicegui import ui, Client
3
+ from weakref import WeakKeyDictionary
4
+
5
+
6
+ _T = TypeVar("_T")
7
+
8
+
9
+ class ClientInstanceLocker(Generic[_T]):
10
+ def __init__(self, factory: Callable[[], _T]):
11
+ """Creates a new instance locker that creates a new instance for each client.
12
+
13
+ Args:
14
+ factory (Callable[[], _T]): A factory function that creates a new instance.
15
+ """
16
+ self._client_instances: WeakKeyDictionary[Client, _T] = WeakKeyDictionary()
17
+ self._factory = factory
18
+
19
+ def get_object(self):
20
+ if not ui.context.slot_stack:
21
+ return None
22
+
23
+ client = ui.context.client
24
+ if client not in self._client_instances:
25
+ self._client_instances[client] = self._factory()
26
+
27
+ @client.on_disconnect
28
+ def _():
29
+ del self._client_instances[client]
30
+
31
+ return self._client_instances[client]
@@ -6,7 +6,6 @@ from pathlib import Path
6
6
  from ex4nicegui.utils.signals import (
7
7
  Ref,
8
8
  effect_refreshable,
9
- ReadonlyRef,
10
9
  effect,
11
10
  ref_computed as computed,
12
11
  to_ref,
@@ -17,7 +16,7 @@ SelectMode = Literal["dir", "file"]
17
16
 
18
17
 
19
18
  class LocalFilePickerResult:
20
- def __init__(self, ref: ReadonlyRef[str], open_fn: Callable[..., None]) -> None:
19
+ def __init__(self, ref: Ref[str], open_fn: Callable[..., None]) -> None:
21
20
  self.__open_fn = open_fn
22
21
  self._ref = ref
23
22
 
@@ -9,13 +9,13 @@ from ex4nicegui.utils.signals import (
9
9
  is_ref,
10
10
  ref_computed,
11
11
  to_value,
12
- _TMaybeRef as TMaybeRef,
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.utils import ParameterClassifier, dataframe2col_str
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
- @ui_effect
88
+ @self._ui_effect
89
89
  def _():
90
90
  ele = self.element
91
91
  data = to_value(ref_ui)
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from pathlib import Path
3
4
  from typing import (
4
5
  Any,
5
6
  Callable,
@@ -11,7 +12,7 @@ from typing import (
11
12
  Generic,
12
13
  Union,
13
14
  cast,
14
- Literal,
15
+ overload,
15
16
  )
16
17
 
17
18
  from typing_extensions import Self
@@ -19,21 +20,18 @@ from ex4nicegui.utils.apiEffect import ui_effect
19
20
  import signe
20
21
  from ex4nicegui.utils.signals import (
21
22
  TGetterOrReadonlyRef,
22
- effect,
23
23
  to_value,
24
24
  is_ref,
25
25
  WatchedState,
26
26
  on,
27
27
  )
28
+ from ex4nicegui.utils.clientScope import new_scope
28
29
  from nicegui import Tailwind, ui
29
- from nicegui.elements.mixins.color_elements import (
30
- TextColorElement,
31
- QUASAR_COLORS,
32
- TAILWIND_COLORS,
33
- )
34
30
  from nicegui.elements.mixins.text_element import TextElement
35
31
  from nicegui.elements.mixins.disableable_element import DisableableElement
36
-
32
+ from ex4nicegui.reactive.services.reactive_service import inject_handle_delete
33
+ from ex4nicegui.reactive.scopedStyle import ScopedStyle
34
+ from functools import partial
37
35
 
38
36
  T = TypeVar("T")
39
37
 
@@ -42,21 +40,38 @@ TWidget = TypeVar("TWidget", bound=ui.element)
42
40
 
43
41
  _T_bind_classes_type_dict = Dict[str, TGetterOrReadonlyRef[bool]]
44
42
  _T_bind_classes_type_ref_dict = TGetterOrReadonlyRef[Dict[str, bool]]
45
- _T_bind_classes_type_array = List[TGetterOrReadonlyRef[str]]
43
+ _T_bind_classes_type_single = TGetterOrReadonlyRef[str]
44
+ _T_bind_classes_type_array = List[_T_bind_classes_type_single]
46
45
 
47
46
 
48
47
  _T_bind_classes_type = Union[
49
- _T_bind_classes_type_dict, _T_bind_classes_type_ref_dict, _T_bind_classes_type_array
48
+ _T_bind_classes_type_dict,
49
+ _T_bind_classes_type_ref_dict,
50
+ _T_bind_classes_type_single,
51
+ _T_bind_classes_type_array,
50
52
  ]
51
53
 
52
54
 
53
55
  class BindableUi(Generic[TWidget]):
54
56
  def __init__(self, element: TWidget) -> None:
55
57
  self._element = element
58
+ inject_handle_delete(self.element, self._on_element_delete)
56
59
  self.tailwind = Tailwind(cast(ui.element, self._element))
60
+ self._effect_scope = new_scope()
57
61
 
58
- def _ui_effect(self, fn: Callable):
59
- return ui_effect(fn)
62
+ def _on_element_delete(self):
63
+ self._effect_scope.dispose()
64
+ scope_style = ScopedStyle.get()
65
+ if scope_style:
66
+ scope_style.remove_style(self.element)
67
+
68
+ @property
69
+ def _ui_effect(self):
70
+ return partial(ui_effect, scope=self._effect_scope)
71
+
72
+ @property
73
+ def _ui_signal_on(self):
74
+ return partial(on, scope=self._effect_scope)
60
75
 
61
76
  def props(self, add: Optional[str] = None, *, remove: Optional[str] = None):
62
77
  cast(ui.element, self.element).props(add, remove=remove)
@@ -108,7 +123,7 @@ class BindableUi(Generic[TWidget]):
108
123
 
109
124
  def delete(self) -> None:
110
125
  """Delete the element."""
111
- self.delete()
126
+ self.element.delete()
112
127
 
113
128
  def move(
114
129
  self, target_container: Optional[ui.element] = None, target_index: int = -1
@@ -118,7 +133,7 @@ class BindableUi(Generic[TWidget]):
118
133
  :param target_container: container to move the element to (default: the parent container)
119
134
  :param target_index: index within the target slot (default: append to the end)
120
135
  """
121
- return self.move(target_container, target_index)
136
+ return self.element.move(target_container, target_index)
122
137
 
123
138
  def remove(self, element: Union[ui.element, int]) -> None:
124
139
  """Remove a child element.
@@ -192,6 +207,22 @@ class BindableUi(Generic[TWidget]):
192
207
  def clear(self) -> None:
193
208
  cast(ui.element, self.element).clear()
194
209
 
210
+ @overload
211
+ def bind_classes(self, classes: Dict[str, TGetterOrReadonlyRef[bool]]):
212
+ ...
213
+
214
+ @overload
215
+ def bind_classes(self, classes: TGetterOrReadonlyRef[Dict[str, bool]]):
216
+ ...
217
+
218
+ @overload
219
+ def bind_classes(self, classes: List[TGetterOrReadonlyRef[str]]):
220
+ ...
221
+
222
+ @overload
223
+ def bind_classes(self, classes: TGetterOrReadonlyRef[str]):
224
+ ...
225
+
195
226
  def bind_classes(self, classes: _T_bind_classes_type):
196
227
  """data binding is manipulating an element's class list
197
228
 
@@ -199,7 +230,37 @@ class BindableUi(Generic[TWidget]):
199
230
  @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#%E7%BB%91%E5%AE%9A%E7%B1%BB%E5%90%8D
200
231
 
201
232
  Args:
202
- classes (_T_bind_classes_type):
233
+ classes (_T_bind_classes_type): dict of refs | ref to dict | str ref | list of refs
234
+
235
+ ## usage
236
+
237
+ bind class names with dict,value is bool ref, for example:
238
+
239
+ ```python
240
+ bg_color = to_ref(True)
241
+ has_error = to_ref(False)
242
+
243
+ rxui.label('Hello').bind_classes({'bg-blue':bg_color, 'text-red':has_error})
244
+ ```
245
+
246
+ bind list of class names with ref
247
+
248
+ ```python
249
+ color = to_ref('red')
250
+ bg_color = lambda: f"bg-{color.value}"
251
+
252
+ rxui.label('Hello').bind_classes([bg_color])
253
+ ```
254
+
255
+ bind single class name with ref
256
+
257
+ ```python
258
+ color = to_ref('red')
259
+ bg_color = lambda: f"bg-{color.value}"
260
+
261
+ rxui.label('Hello').bind_classes(bg_color)
262
+ ```
263
+
203
264
  """
204
265
  if isinstance(classes, dict):
205
266
  for name, ref_obj in classes.items():
@@ -213,24 +274,33 @@ class BindableUi(Generic[TWidget]):
213
274
 
214
275
  elif is_ref(classes) or isinstance(classes, Callable):
215
276
  ref_obj = to_value(classes) # type: ignore
216
- assert isinstance(ref_obj, dict)
217
277
 
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)
278
+ if isinstance(ref_obj, dict):
279
+
280
+ @self._ui_effect
281
+ def _():
282
+ for name, value in cast(Dict, to_value(classes)).items(): # type: ignore
283
+ if value:
284
+ self.classes(add=name)
285
+ else:
286
+ self.classes(remove=name)
287
+ else:
288
+ self._bind_single_class(cast(_T_bind_classes_type_single, classes))
289
+
225
290
  elif isinstance(classes, list):
226
291
  for ref_name in classes:
227
- if is_ref(ref_name) or isinstance(ref_name, Callable):
292
+ self._bind_single_class(ref_name)
228
293
 
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
294
+ return self
295
+
296
+ def _bind_single_class(self, class_name: _T_bind_classes_type_single):
297
+ if is_ref(class_name) or isinstance(class_name, Callable):
298
+
299
+ @on(class_name)
300
+ def _(state: WatchedState):
301
+ self.classes(add=state.current, remove=state.previous)
302
+ else:
303
+ self.classes(class_name) # type: ignore
234
304
 
235
305
  return self
236
306
 
@@ -241,7 +311,21 @@ class BindableUi(Generic[TWidget]):
241
311
  @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#bind-style
242
312
 
243
313
  Args:
244
- style (Dict[str, Union[ReadonlyRef[str], Ref[str]]]): _description_
314
+ style (Dict[str, Union[ReadonlyRef[str], Ref[str]]]): dict of style name and ref value
315
+
316
+
317
+ ## usage
318
+ ```python
319
+ bg_color = to_ref("blue")
320
+ text_color = to_ref("red")
321
+
322
+ rxui.label("test").bind_style(
323
+ {
324
+ "background-color": bg_color,
325
+ "color": text_color,
326
+ }
327
+ )
328
+ ```
245
329
  """
246
330
  if isinstance(style, dict):
247
331
  for name, ref_obj in style.items():
@@ -254,26 +338,88 @@ class BindableUi(Generic[TWidget]):
254
338
 
255
339
  return self
256
340
 
341
+ def scoped_style(self, selector: str, style: Union[str, Path]):
342
+ """add scoped style to the element
343
+
344
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#scoped_style
345
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#scoped_style
346
+
347
+ Args:
348
+ selector (str): css selector
349
+ style (Union[str, Path]): path to css file or inline style string
350
+
351
+ ## usage
352
+ ```python
353
+ # all children of the element will have red outline, excluding itself
354
+ with rxui.row().scoped_style("*", "outline: 1px solid red;") as row:
355
+ ui.label("Hello")
356
+ ui.label("World")
357
+
358
+ # all children of the element will have red outline, including the element itself
359
+ with rxui.row().scoped_style(":self *", "outline: 1px solid red;") as row:
360
+ ui.label("Hello")
361
+ ui.label("World")
362
+
363
+ # all children of the element will have red outline when element is hovered
364
+ with rxui.row().scoped_style(":hover *", "outline: 1px solid red;") as row:
365
+ ui.label("Hello")
366
+ ui.label("World")
367
+
368
+ # all children of the element and itself will have red outline when element is hovered
369
+ with rxui.row().scoped_style(":self:hover *", "outline: 1px solid red;") as row:
370
+ ui.label("Hello")
371
+ ui.label("World")
372
+ ```
373
+ """
374
+
375
+ is_css_file = isinstance(style, Path)
376
+
377
+ if is_css_file:
378
+ style = style.read_text(encoding="utf-8")
379
+
380
+ id = f"c{self.element.id}"
381
+ selector_with_self = _utils._parent_id_with_selector(id, selector, is_css_file)
382
+ css = ""
383
+ if is_css_file:
384
+ css = f"{selector_with_self} {style}"
385
+ else:
386
+ css = f"{selector_with_self}{{{style}}}"
387
+
388
+ scope_style = ScopedStyle.get()
389
+ assert scope_style, "can not find scope style"
390
+ scope_style.create_style(self.element, css)
391
+
392
+ return self
393
+
257
394
  def update(self):
258
395
  """Update the element on the client side."""
259
396
  self.element.update()
260
397
 
261
398
 
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)
399
+ class _utils:
400
+ @staticmethod
401
+ def _parent_id_with_selector(
402
+ parent_id: str, selector: str, is_css_file=False
403
+ ) -> str:
404
+ selector_with_self = f"#{parent_id}"
405
+
406
+ selector = selector.strip()
407
+ if (not selector) and (not is_css_file):
408
+ selector = "* "
409
+
410
+ if selector.startswith(":self"):
411
+ selector = selector[5:].lstrip()
412
+ parent_selector = f"#{parent_id}"
413
+ if selector.startswith(":"):
414
+ parent_selector = f"{parent_selector}{selector.split()[0]}"
266
415
 
267
- # @property
268
- # def value(self) -> T:
269
- # return self._ref.value # type: ignore
416
+ selector_with_self = f"{parent_selector},{selector_with_self}"
270
417
 
271
- # def bind_ref(self, ref: TRef[T]):
272
- # @effect
273
- # def _():
274
- # ref.value = self._ref.value # type: ignore
418
+ if not selector.startswith(":"):
419
+ selector_with_self = selector_with_self + " "
275
420
 
276
- # return self
421
+ selector_with_self = selector_with_self + selector
422
+ return selector_with_self
277
423
 
278
424
 
279
425
  _T_DisableableBinder = TypeVar("_T_DisableableBinder", bound=DisableableElement)
@@ -306,47 +452,3 @@ class DisableableMixin(Protocol):
306
452
 
307
453
 
308
454
  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,7 +3,7 @@ from typing import (
3
3
  Callable,
4
4
  Optional,
5
5
  )
6
- from ex4nicegui.reactive.utils import ParameterClassifier
6
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
7
7
  from ex4nicegui.utils.signals import (
8
8
  TGetterOrReadonlyRef,
9
9
  _TMaybeRef as TMaybeRef,
@@ -4,8 +4,7 @@ from typing import (
4
4
  Optional,
5
5
  TypeVar,
6
6
  )
7
- from ex4nicegui.reactive.utils import ParameterClassifier
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
- @ui_effect
53
+ @self._ui_effect
55
54
  def _():
56
55
  self.element.set_value(to_value(ref_ui))
57
56
  self.element.update()
@@ -1,8 +1,7 @@
1
1
  from typing import (
2
2
  Optional,
3
3
  )
4
- from ex4nicegui.reactive.utils import ParameterClassifier
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,
@@ -57,7 +56,7 @@ class CircularProgressBindableUi(
57
56
  return super().bind_prop(prop, ref_ui)
58
57
 
59
58
  def bind_value(self, ref_ui: TGetterOrReadonlyRef[float]):
60
- @ui_effect
59
+ @self._ui_effect
61
60
  def _():
62
61
  self.element.set_value(to_value(ref_ui))
63
62
 
@@ -4,8 +4,7 @@ from typing import (
4
4
  Optional,
5
5
  cast,
6
6
  )
7
- from ex4nicegui.reactive.utils import ParameterClassifier
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
- @ui_effect
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
- @ui_effect
85
+ @self._ui_effect
87
86
  def _():
88
87
  self.element.set_value(to_value(ref_ui))
89
88
 
@@ -1,7 +1,7 @@
1
1
  from typing import (
2
2
  Any,
3
3
  )
4
- from ex4nicegui.reactive.utils import ParameterClassifier
4
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
5
5
  from ex4nicegui.utils.signals import (
6
6
  TGetterOrReadonlyRef,
7
7
  _TMaybeRef as TMaybeRef,
@@ -1,7 +1,6 @@
1
1
  from typing import Any, Callable, List, Optional, TypeVar
2
2
  from typing_extensions import TypedDict
3
- from ex4nicegui.reactive.utils import ParameterClassifier
4
- from ex4nicegui.utils.apiEffect import ui_effect
3
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
5
4
 
6
5
  from ex4nicegui.utils.signals import (
7
6
  TGetterOrReadonlyRef,
@@ -70,7 +69,7 @@ class DateBindableUi(BindableUi[ui.date]):
70
69
  return super().bind_prop(prop, ref_ui)
71
70
 
72
71
  def bind_value(self, ref_ui: TGetterOrReadonlyRef[bool]):
73
- @ui_effect
72
+ @self._ui_effect
74
73
  def _():
75
74
  self.element.set_value(to_value(ref_ui))
76
75
 
@@ -2,8 +2,7 @@ from typing import (
2
2
  Any,
3
3
  )
4
4
  from typing_extensions import Literal
5
- from ex4nicegui.reactive.utils import ParameterClassifier
6
- from ex4nicegui.utils.apiEffect import ui_effect
5
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
7
6
 
8
7
  from ex4nicegui.utils.signals import (
9
8
  is_setter_ref,
@@ -61,7 +60,7 @@ class DrawerBindableUi(BindableUi[Drawer]):
61
60
 
62
61
  super().__init__(element) # type: ignore
63
62
 
64
- @ui_effect
63
+ @self._ui_effect
65
64
  def _():
66
65
  mvalue = "true" if to_value(value) else "false"
67
66
  element.props(f":model-value={mvalue}")
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
  from typing import Any, Callable, Dict, List, Union, cast, Optional, Literal
3
- from ex4nicegui.reactive.utils import ParameterClassifier
3
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
4
4
  from ex4nicegui.utils.signals import (
5
5
  TGetterOrReadonlyRef,
6
6
  is_ref,
@@ -8,7 +8,6 @@ from ex4nicegui.utils.signals import (
8
8
  _TMaybeRef as TMaybeRef,
9
9
  to_value,
10
10
  to_raw,
11
- on,
12
11
  )
13
12
  from .base import BindableUi
14
13
  from ex4nicegui.reactive.EChartsComponent.ECharts import echarts
@@ -141,7 +140,7 @@ class EChartsBindableUi(BindableUi[echarts]):
141
140
  return super().bind_prop(prop, ref_ui)
142
141
 
143
142
  def bind_options(self, ref_ui: TGetterOrReadonlyRef[Dict]):
144
- @on(ref_ui)
143
+ @self._ui_signal_on(ref_ui)
145
144
  def _():
146
145
  ele = self.element
147
146
  ele.update_options(to_raw(to_value(ref_ui)), self.__update_setting)