ex4nicegui 0.6.6__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 (70) 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/libs/gsap/.DS_Store +0 -0
  6. ex4nicegui/libs/gsap/gsap.mjs +6 -0
  7. ex4nicegui/reactive/EChartsComponent/ECharts.js +19 -9
  8. ex4nicegui/reactive/local_file_picker.py +1 -2
  9. ex4nicegui/reactive/officials/aggrid.py +7 -7
  10. ex4nicegui/reactive/officials/base.py +198 -86
  11. ex4nicegui/reactive/officials/button.py +5 -5
  12. ex4nicegui/reactive/officials/checkbox.py +5 -6
  13. ex4nicegui/reactive/officials/circular_progress.py +5 -6
  14. ex4nicegui/reactive/officials/color_picker.py +7 -8
  15. ex4nicegui/reactive/officials/column.py +4 -3
  16. ex4nicegui/reactive/officials/date.py +6 -12
  17. ex4nicegui/reactive/officials/drawer.py +2 -3
  18. ex4nicegui/reactive/officials/echarts.py +32 -15
  19. ex4nicegui/reactive/officials/expansion.py +5 -5
  20. ex4nicegui/reactive/officials/grid.py +1 -1
  21. ex4nicegui/reactive/officials/html.py +1 -3
  22. ex4nicegui/reactive/officials/icon.py +9 -10
  23. ex4nicegui/reactive/officials/image.py +5 -7
  24. ex4nicegui/reactive/officials/input.py +8 -10
  25. ex4nicegui/reactive/officials/knob.py +5 -7
  26. ex4nicegui/reactive/officials/label.py +5 -4
  27. ex4nicegui/reactive/officials/linear_progress.py +9 -10
  28. ex4nicegui/reactive/officials/number.py +23 -8
  29. ex4nicegui/reactive/officials/radio.py +7 -9
  30. ex4nicegui/reactive/officials/row.py +1 -1
  31. ex4nicegui/reactive/officials/select.py +7 -9
  32. ex4nicegui/reactive/officials/slider.py +6 -8
  33. ex4nicegui/reactive/officials/switch.py +5 -7
  34. ex4nicegui/reactive/officials/tab.py +1 -1
  35. ex4nicegui/reactive/officials/tab_panel.py +1 -1
  36. ex4nicegui/reactive/officials/tab_panels.py +15 -3
  37. ex4nicegui/reactive/officials/table.py +12 -10
  38. ex4nicegui/reactive/officials/tabs.py +4 -3
  39. ex4nicegui/reactive/officials/textarea.py +6 -8
  40. ex4nicegui/reactive/officials/upload.py +2 -2
  41. ex4nicegui/reactive/q_pagination.py +5 -4
  42. ex4nicegui/reactive/scopedStyle.js +55 -0
  43. ex4nicegui/reactive/scopedStyle.py +22 -0
  44. ex4nicegui/reactive/services/color_service.py +56 -0
  45. ex4nicegui/reactive/services/pandas_service.py +31 -0
  46. ex4nicegui/reactive/{utils.py → services/reactive_service.py} +9 -67
  47. ex4nicegui/reactive/systems/color_system.py +25 -0
  48. ex4nicegui/reactive/systems/object_system.py +33 -0
  49. ex4nicegui/reactive/systems/reactive_system.py +21 -0
  50. ex4nicegui/reactive/useMouse/UseMouse.py +4 -4
  51. ex4nicegui/reactive/usePagination.py +1 -1
  52. ex4nicegui/reactive/vfor.py +1 -2
  53. ex4nicegui/reactive/vmodel.py +1 -1
  54. ex4nicegui/utils/refComputed.py +147 -0
  55. ex4nicegui/utils/refWrapper.py +57 -0
  56. ex4nicegui/utils/signals.py +51 -192
  57. ex4nicegui/utils/types.py +16 -0
  58. ex4nicegui/version.py +3 -0
  59. {ex4nicegui-0.6.6.dist-info → ex4nicegui-0.6.8.dist-info}/METADATA +1274 -1124
  60. {ex4nicegui-0.6.6.dist-info → ex4nicegui-0.6.8.dist-info}/RECORD +81 -74
  61. {ex4nicegui-0.6.6.dist-info → ex4nicegui-0.6.8.dist-info}/WHEEL +1 -2
  62. ex4nicegui/reactive/EChartsComponent/__init__.py +0 -0
  63. ex4nicegui/reactive/UseDraggable/__init__.py +0 -0
  64. ex4nicegui/reactive/dropZone/__init__.py +0 -0
  65. ex4nicegui/reactive/mermaid/__init__.py +0 -0
  66. ex4nicegui/reactive/officials/__init__.py +0 -1
  67. ex4nicegui/reactive/officials/utils.py +0 -11
  68. ex4nicegui/reactive/useMouse/__init__.py +0 -0
  69. ex4nicegui-0.6.6.dist-info/top_level.txt +0 -1
  70. {ex4nicegui-0.6.6.dist-info → ex4nicegui-0.6.8.dist-info}/LICENSE +0 -0
@@ -1,17 +1,11 @@
1
1
  from datetime import date, datetime
2
- from functools import partial
3
- import types
4
- from weakref import WeakValueDictionary
5
2
  import signe
6
- from signe.core.protocols import ComputedResultProtocol
3
+ from signe.core.scope import Scope
7
4
  from .clientScope import _CLIENT_SCOPE_MANAGER
8
5
  from typing import (
9
6
  Any,
10
7
  Dict,
11
- Protocol,
12
8
  TypeVar,
13
- Generic,
14
- overload,
15
9
  Optional,
16
10
  Callable,
17
11
  cast,
@@ -21,85 +15,51 @@ from typing import (
21
15
  from nicegui import ui
22
16
  from .effect import effect
23
17
  from .scheduler import get_uiScheduler
24
- import warnings
18
+ from .types import (
19
+ _TMaybeRef,
20
+ TGetterOrReadonlyRef,
21
+ Ref,
22
+ TReadonlyRef, # noqa: F401
23
+ TRef, # noqa: F401
24
+ DescReadonlyRef, # noqa: F401
25
+ _TMaybeRef as TMaybeRef, # noqa: F401
26
+ )
27
+ from .refWrapper import RefWrapper, to_ref_wrapper # noqa: F401
28
+ from .refComputed import ref_computed # noqa: F401
25
29
 
26
30
  T = TypeVar("T")
27
31
 
28
32
 
29
- TReadonlyRef = ComputedResultProtocol[T]
30
- ReadonlyRef = TReadonlyRef[T]
31
- DescReadonlyRef = TReadonlyRef[T]
32
-
33
- TGetterOrReadonlyRef = signe.TGetter[T]
34
-
35
-
36
33
  is_reactive = signe.is_reactive
34
+ to_raw = signe.to_raw
37
35
 
38
36
 
39
37
  def reactive(obj: T) -> T:
40
38
  return signe.reactive(obj, get_uiScheduler())
41
39
 
42
40
 
43
- class RefWrapper(Generic[T]):
44
- __slot__ = ("_getter_fn", "_setter_fn", "")
45
-
46
- def __init__(
47
- self,
48
- getter_or_ref: TGetterOrReadonlyRef[T],
49
- setter_or_ref: Optional[Callable[[T], None]] = None,
50
- ):
51
- if signe.is_signal(getter_or_ref):
52
- self._getter_fn = lambda: getter_or_ref.value
53
-
54
- def ref_setter(v):
55
- getter_or_ref.value = v # type: ignore
56
-
57
- self._setter_fn = ref_setter
58
- elif isinstance(getter_or_ref, Callable):
59
- self._getter_fn = getter_or_ref
60
- self._setter_fn = setter_or_ref or (lambda x: None)
61
- else:
62
- self._getter_fn = lambda: getter_or_ref
63
- self._setter_fn = lambda x: None
64
-
65
- self._is_readonly = False
66
-
67
- @property
68
- def value(self) -> T:
69
- return cast(T, self._getter_fn())
70
-
71
- @value.setter
72
- def value(self, new_value: T):
73
- if self._is_readonly:
74
- warnings.warn("readonly ref cannot be assigned.")
75
- return
76
- return self._setter_fn(new_value)
77
-
78
-
79
- def to_ref_wrapper(
80
- getter_or_ref: TGetterOrReadonlyRef[T],
81
- setter_or_ref: Optional[Callable[[T], None]] = None,
82
- ):
83
- return RefWrapper(getter_or_ref, setter_or_ref)
84
-
85
-
86
- _TMaybeRef = signe.TMaybeSignal[T]
87
- TRef = signe.TSignal[T]
88
- Ref = TRef[T]
89
-
90
-
91
- to_raw = signe.to_raw
92
-
93
-
94
41
  def is_setter_ref(obj):
95
42
  return isinstance(obj, (signe.Signal, RefWrapper))
96
43
 
97
44
 
98
- def is_ref(obj):
45
+ def is_ref(obj: Any):
46
+ """Checks if a value is a ref object."""
99
47
  return signe.is_signal(obj) or isinstance(obj, (RefWrapper))
100
48
 
101
49
 
102
50
  def to_value(obj: Union[_TMaybeRef[T], RefWrapper]) -> T:
51
+ """unwraps a ref object and returns its inner value.
52
+
53
+ Args:
54
+ obj (Union[_TMaybeRef[T], RefWrapper]): A getter function, an existing ref, or a non-function value.
55
+
56
+ ## Example
57
+ ```python
58
+ to_value(1) # 1
59
+ to_value(lambda: 1) # 1
60
+ to_value(to_ref(1)) # 1
61
+ ```
62
+ """
103
63
  if is_ref(obj):
104
64
  return obj.value # type: ignore
105
65
  if isinstance(obj, Callable):
@@ -144,7 +104,7 @@ def _ref_comp_with_None(old, new):
144
104
  return False
145
105
 
146
106
 
147
- def ref(value: T, is_deep=False):
107
+ def ref(value: T, is_deep=False) -> Ref[T]:
148
108
  comp = False # Default never equal
149
109
 
150
110
  if _is_comp_values(value):
@@ -170,135 +130,33 @@ def deep_ref(value: T) -> Ref[T]:
170
130
  return to_ref(value, is_deep=True)
171
131
 
172
132
 
173
- class TInstanceCall(Protocol[T]):
174
- def __call__(_, self) -> T:
175
- ...
176
-
177
-
178
- @overload
179
- def ref_computed(
180
- fn: Union[Callable[[], T], TInstanceCall[T]],
181
- *,
182
- desc="",
183
- debug_trigger: Optional[Callable[..., None]] = None,
184
- priority_level: int = 1,
185
- debug_name: Optional[str] = None,
186
- ) -> ReadonlyRef[T]:
187
- """Takes a getter function and returns a readonly reactive ref object for the returned value from the getter. It can also take an object with get and set functions to create a writable ref object.
188
-
189
- @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#ref_computed
190
- @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#ref_computed
191
-
192
-
193
- Args:
194
- fn (Callable[[], T]): _description_
195
- desc (str, optional): _description_. Defaults to "".
196
- debug_trigger (Optional[Callable[..., None]], optional): _description_. Defaults to None.
197
- priority_level (int, optional): _description_. Defaults to 1.
198
- debug_name (Optional[str], optional): _description_. Defaults to None.
199
-
200
- """
201
- ...
202
-
203
-
204
- @overload
205
- def ref_computed(
206
- fn=None,
207
- *,
208
- desc="",
209
- debug_trigger: Optional[Callable[..., None]] = None,
210
- priority_level: int = 1,
211
- debug_name: Optional[str] = None,
212
- ) -> Callable[[Callable[..., T]], ReadonlyRef[T]]:
213
- ...
214
-
215
-
216
- def ref_computed(
217
- fn: Optional[Union[Callable[[], T], TInstanceCall[T]]] = None,
218
- *,
219
- desc="",
220
- debug_trigger: Optional[Callable[..., None]] = None,
221
- priority_level: int = 1,
222
- debug_name: Optional[str] = None,
223
- ) -> Union[ReadonlyRef[T], Callable[[Callable[..., T]], ReadonlyRef[T]]]:
224
- kws = {
225
- "debug_trigger": debug_trigger,
226
- "priority_level": priority_level,
227
- "debug_name": debug_name,
228
- }
229
-
230
- if fn:
231
- if _is_class_define_method(fn):
232
- return cast(
233
- ref_computed_method[T],
234
- ref_computed_method(fn, computed_args=kws), # type: ignore
235
- ) # type: ignore
236
-
237
- getter = signe.Computed(
238
- cast(Callable[[], T], fn),
239
- **kws,
240
- scope=_CLIENT_SCOPE_MANAGER.get_current_scope(),
241
- scheduler=get_uiScheduler(),
242
- )
243
- return cast(DescReadonlyRef[T], getter)
244
-
245
- else:
246
-
247
- def wrap(fn: Callable[[], T]):
248
- return ref_computed(fn, **kws)
249
-
250
- return wrap
251
-
252
-
253
- def _is_class_define_method(fn: Callable):
254
- has_name = hasattr(fn, "__name__")
255
- qualname_prefix = f".<locals>.{fn.__name__}" if has_name else ""
256
-
257
- return (
258
- hasattr(fn, "__qualname__")
259
- and has_name
260
- and "." in fn.__qualname__
261
- and qualname_prefix != fn.__qualname__[-len(qualname_prefix) :]
262
- and (isinstance(fn, types.FunctionType))
263
- )
264
-
265
-
266
- class ref_computed_method(Generic[T]):
267
- __isabstractmethod__: bool
268
-
269
- def __init__(self, fget: Callable[[Any], T], computed_args: Dict) -> None:
270
- self._fget = fget
271
- self._computed_args = computed_args
272
- self._instance_map: WeakValueDictionary[
273
- int, TReadonlyRef[T]
274
- ] = WeakValueDictionary()
275
-
276
- def __get_computed(self, instance):
277
- ins_id = id(instance)
278
- if ins_id not in self._instance_map:
279
- cp = signe.Computed(
280
- partial(self._fget, instance),
281
- **self._computed_args,
282
- scope=_CLIENT_SCOPE_MANAGER.get_current_scope(),
283
- scheduler=get_uiScheduler(),
284
- capture_parent_effect=False,
285
- )
286
- self._instance_map[ins_id] = cp # type: ignore
287
-
288
- return self._instance_map[ins_id]
289
-
290
- def __get__(self, __instance: Any, __owner: Optional[type] = None):
291
- return cast(TRef[T], self.__get_computed(__instance))
133
+ _T_effect_refreshable_refs = Union[
134
+ TGetterOrReadonlyRef,
135
+ RefWrapper,
136
+ Sequence[TGetterOrReadonlyRef],
137
+ _TMaybeRef,
138
+ Sequence[_TMaybeRef],
139
+ ]
292
140
 
293
141
 
294
142
  class effect_refreshable:
295
- def __init__(self, fn: Callable, refs: Union[TRef, Sequence[TRef]] = []) -> None:
143
+ def __init__(self, fn: Callable, refs: _T_effect_refreshable_refs = []) -> None:
296
144
  self._fn = fn
297
- self._refs = refs if isinstance(refs, Sequence) else [refs]
145
+
146
+ if isinstance(refs, Sequence):
147
+ ref_arg = [ref for ref in refs if self._is_valid_ref(ref)]
148
+ else:
149
+ ref_arg = [refs] if self._is_valid_ref(refs) else []
150
+
151
+ self._refs = ref_arg
298
152
  self()
299
153
 
154
+ @classmethod
155
+ def _is_valid_ref(cls, ref):
156
+ return is_ref(ref) or isinstance(ref, Callable)
157
+
300
158
  @staticmethod
301
- def on(refs: Union[TRef, Sequence[TRef]]):
159
+ def on(refs: _T_effect_refreshable_refs):
302
160
  def warp(
303
161
  fn: Callable,
304
162
  ):
@@ -323,7 +181,7 @@ class effect_refreshable:
323
181
  if len(self._refs) == 0:
324
182
  runner = effect(runner)
325
183
  else:
326
- runner = on(self._refs)(runner)
184
+ runner = on(self._refs)(runner) # type: ignore
327
185
 
328
186
  return runner
329
187
 
@@ -334,6 +192,7 @@ def on(
334
192
  priority_level=1,
335
193
  effect_kws: Optional[Dict[str, Any]] = None,
336
194
  deep: bool = True,
195
+ scope: Optional[Scope] = None,
337
196
  ):
338
197
  """Watches one or more reactive data sources and invokes a callback function when the sources change.
339
198
 
@@ -362,7 +221,7 @@ def on(
362
221
  fn,
363
222
  onchanges=onchanges,
364
223
  effect_kws=effect_kws,
365
- scope=_CLIENT_SCOPE_MANAGER.get_current_scope(),
224
+ scope=scope or _CLIENT_SCOPE_MANAGER.get_current_scope(),
366
225
  deep=deep,
367
226
  scheduler=get_uiScheduler(),
368
227
  )
@@ -0,0 +1,16 @@
1
+ import signe
2
+ from signe.core.protocols import ComputedResultProtocol
3
+ from typing import (
4
+ TypeVar,
5
+ )
6
+
7
+ T = TypeVar("T")
8
+
9
+
10
+ TReadonlyRef = ComputedResultProtocol[T]
11
+ ReadonlyRef = TReadonlyRef[T]
12
+ DescReadonlyRef = TReadonlyRef[T]
13
+ TGetterOrReadonlyRef = signe.TGetter[T]
14
+ _TMaybeRef = signe.TMaybeSignal[T]
15
+ TRef = signe.TSignal[T]
16
+ Ref = TRef[T]
ex4nicegui/version.py ADDED
@@ -0,0 +1,3 @@
1
+ import importlib.metadata
2
+
3
+ __version__: str = importlib.metadata.version("ex4nicegui")