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
@@ -5,36 +5,16 @@ from typing import (
5
5
  Iterable,
6
6
  List,
7
7
  Optional,
8
- Protocol,
9
8
  Tuple,
10
9
  cast,
11
- runtime_checkable,
12
- Union,
13
10
  )
14
-
15
- from ex4nicegui.utils.signals import is_ref, to_value, is_setter_ref
11
+ from nicegui import ui
12
+ from ex4nicegui.utils.signals import is_ref, is_setter_ref
16
13
  from nicegui.events import handle_event
17
-
18
- try:
19
- import pandas as pd
20
- except ImportError:
21
- pass
22
-
23
-
24
- @runtime_checkable
25
- class GetItemProtocol(Protocol):
26
- def __getitem__(self, key):
27
- ...
28
-
29
-
30
- @runtime_checkable
31
- class SetItemProtocol(Protocol):
32
- def __setitem__(self, key, value):
33
- ...
34
-
35
-
36
- def _convert_kws_ref2value(kws: Dict) -> Dict:
37
- return {key: to_value(value) for key, value in kws.items()}
14
+ from ex4nicegui.reactive.systems.reactive_system import (
15
+ convert_kws_ref2value,
16
+ inject_method,
17
+ )
38
18
 
39
19
 
40
20
  class ParameterClassifier:
@@ -75,7 +55,7 @@ class ParameterClassifier:
75
55
  )
76
56
 
77
57
  def get_values_kws(self) -> Dict:
78
- value_kws = _convert_kws_ref2value(
58
+ value_kws = convert_kws_ref2value(
79
59
  {k: v for k, v in self._args.items() if k not in self.events}
80
60
  )
81
61
 
@@ -105,43 +85,5 @@ class ParameterClassifier:
105
85
  }
106
86
 
107
87
 
108
- def get_attribute(obj: Union[object, GetItemProtocol], name: Union[str, int]) -> Any:
109
- if isinstance(obj, (GetItemProtocol)):
110
- return obj[name]
111
- return getattr(obj, name) # type: ignore
112
-
113
-
114
- def set_attribute(
115
- obj: Union[object, SetItemProtocol], name: Union[str, int], value: Any
116
- ) -> None:
117
- if isinstance(obj, SetItemProtocol):
118
- obj[name] = value
119
- else:
120
- setattr(obj, name, value) # type: ignore
121
-
122
-
123
- def dataframe2col_str(df, copy=True):
124
- if isinstance(df.columns, pd.MultiIndex):
125
- raise ValueError(
126
- "MultiIndex columns are not supported. "
127
- "You can convert them to strings using something like "
128
- '`df.columns = ["_".join(col) for col in df.columns.values]`.'
129
- )
130
-
131
- date_cols = df.columns[df.dtypes == "datetime64[ns]"]
132
- time_cols = df.columns[df.dtypes == "timedelta64[ns]"]
133
- complex_cols = df.columns[df.dtypes == "complex128"]
134
- period_cols = df.columns[df.dtypes == "period[M]"]
135
- if (
136
- len(date_cols) != 0
137
- or len(time_cols) != 0
138
- or len(complex_cols) != 0
139
- or len(period_cols) != 0
140
- ):
141
- df = df.copy() if copy else df
142
- df[date_cols] = df[date_cols].astype(str)
143
- df[time_cols] = df[time_cols].astype(str)
144
- df[complex_cols] = df[complex_cols].astype(str)
145
- df[period_cols] = df[period_cols].astype(str)
146
-
147
- return df
88
+ def inject_handle_delete(element: ui.element, on_delete: Callable[[], None]):
89
+ inject_method(element, "_handle_delete", on_delete)
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from nicegui.elements.mixins.color_elements import (
6
+ QUASAR_COLORS,
7
+ TAILWIND_COLORS,
8
+ )
9
+
10
+
11
+ _color_system_type = Literal["QUASAR", "TAILWIND", "STYLE"]
12
+
13
+
14
+ def get_text_color_info(name: str):
15
+ system_type: _color_system_type = "STYLE"
16
+
17
+ if name in QUASAR_COLORS:
18
+ system_type = "QUASAR"
19
+ elif name in TAILWIND_COLORS:
20
+ system_type = "TAILWIND"
21
+ name = f"text-{name}"
22
+ else:
23
+ pass
24
+
25
+ return system_type, name
@@ -0,0 +1,33 @@
1
+ from typing import (
2
+ Any,
3
+ Protocol,
4
+ runtime_checkable,
5
+ Union,
6
+ )
7
+
8
+
9
+ @runtime_checkable
10
+ class GetItemProtocol(Protocol):
11
+ def __getitem__(self, key):
12
+ ...
13
+
14
+
15
+ @runtime_checkable
16
+ class SetItemProtocol(Protocol):
17
+ def __setitem__(self, key, value):
18
+ ...
19
+
20
+
21
+ def get_attribute(obj: Union[object, GetItemProtocol], name: Union[str, int]) -> Any:
22
+ if isinstance(obj, (GetItemProtocol)):
23
+ return obj[name]
24
+ return getattr(obj, name) # type: ignore
25
+
26
+
27
+ def set_attribute(
28
+ obj: Union[object, SetItemProtocol], name: Union[str, int], value: Any
29
+ ) -> None:
30
+ if isinstance(obj, SetItemProtocol):
31
+ obj[name] = value
32
+ else:
33
+ setattr(obj, name, value) # type: ignore
@@ -0,0 +1,21 @@
1
+ from typing import Callable, Dict
2
+ from ex4nicegui.utils.signals import to_value
3
+
4
+
5
+ def convert_kws_ref2value(kws: Dict) -> Dict:
6
+ return {key: to_value(value) for key, value in kws.items()}
7
+
8
+
9
+ def inject_method(obj, method_name: str, new_handle: Callable):
10
+ if hasattr(obj, method_name):
11
+ original_method = getattr(obj, method_name)
12
+
13
+ def injected_method(*args, **kwargs):
14
+ new_handle(*args, **kwargs)
15
+ return original_method(*args, **kwargs)
16
+
17
+ setattr(obj, method_name, injected_method)
18
+ else:
19
+ raise AttributeError(
20
+ f"'{type(obj).__name__}' object has no attribute '{method_name}'."
21
+ )
@@ -4,7 +4,7 @@ from nicegui.dataclasses import KWONLY_SLOTS
4
4
  from nicegui.events import handle_event, UiEventArguments
5
5
  from nicegui.element import Element
6
6
 
7
- from ex4nicegui.utils.signals import ReadonlyRef, batch, to_ref
7
+ from ex4nicegui.utils.signals import TReadonlyRef, batch, to_ref
8
8
 
9
9
  _Update_Args = [
10
10
  "x",
@@ -42,15 +42,15 @@ class UseMouse(Element, component="UseMouse.js"):
42
42
 
43
43
  @property
44
44
  def x(self):
45
- return cast(ReadonlyRef[float], self.__x)
45
+ return cast(TReadonlyRef[float], self.__x)
46
46
 
47
47
  @property
48
48
  def y(self):
49
- return cast(ReadonlyRef[float], self.__y)
49
+ return cast(TReadonlyRef[float], self.__y)
50
50
 
51
51
  @property
52
52
  def sourceType(self):
53
- return cast(ReadonlyRef[float], self.__sourceType)
53
+ return cast(TReadonlyRef[float], self.__sourceType)
54
54
 
55
55
  def on_update(self, handler: Optional[Callable[..., Any]]):
56
56
  def inner_handler(e):
@@ -4,7 +4,7 @@ from ex4nicegui.utils.signals import (
4
4
  to_ref,
5
5
  to_value,
6
6
  effect,
7
- _TMaybeRef as TMaybeRef,
7
+ TMaybeRef,
8
8
  )
9
9
  from typing import Any
10
10
  from typing_extensions import Protocol
@@ -26,9 +26,8 @@ from typing import (
26
26
  from functools import partial
27
27
  from dataclasses import dataclass
28
28
  from signe.core.scope import Scope
29
- from .utils import get_attribute
29
+ from ex4nicegui.reactive.systems.object_system import get_attribute
30
30
  from ex4nicegui.reactive.empty import Empty
31
- # from .transitionGroup import TransitionGroup
32
31
 
33
32
  _T = TypeVar("_T")
34
33
  _T_data = Union[List[Any], TGetterOrReadonlyRef[List[Any]], RefWrapper]
@@ -25,7 +25,7 @@ import tokenize
25
25
  import executing
26
26
  import ast
27
27
  import warnings
28
- from .utils import get_attribute, set_attribute
28
+ from ex4nicegui.reactive.systems.object_system import get_attribute, set_attribute
29
29
 
30
30
  _T = TypeVar("_T")
31
31
 
@@ -0,0 +1,147 @@
1
+ from functools import partial
2
+ import types
3
+ import signe
4
+ from .clientScope import _CLIENT_SCOPE_MANAGER
5
+ from typing import (
6
+ Any,
7
+ Dict,
8
+ Protocol,
9
+ Type,
10
+ TypeVar,
11
+ Generic,
12
+ overload,
13
+ Optional,
14
+ Callable,
15
+ cast,
16
+ Union,
17
+ )
18
+ from .scheduler import get_uiScheduler
19
+ from .types import (
20
+ ReadonlyRef,
21
+ DescReadonlyRef,
22
+ )
23
+
24
+
25
+ T = TypeVar("T", covariant=True)
26
+
27
+
28
+ class TInstanceCall(Protocol[T]):
29
+ def __call__(_, self) -> T: # type: ignore
30
+ ...
31
+
32
+
33
+ @overload
34
+ def ref_computed(
35
+ fn: Union[Callable[[], T], TInstanceCall[T]],
36
+ *,
37
+ desc="",
38
+ debug_trigger: Optional[Callable[..., None]] = None,
39
+ priority_level: int = 1,
40
+ debug_name: Optional[str] = None,
41
+ ) -> ReadonlyRef[T]:
42
+ """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.
43
+
44
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#ref_computed
45
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#ref_computed
46
+
47
+
48
+ Args:
49
+ fn (Callable[[], T]): _description_
50
+ desc (str, optional): _description_. Defaults to "".
51
+ debug_trigger (Optional[Callable[..., None]], optional): _description_. Defaults to None.
52
+ priority_level (int, optional): _description_. Defaults to 1.
53
+ debug_name (Optional[str], optional): _description_. Defaults to None.
54
+
55
+ """
56
+ ...
57
+
58
+
59
+ @overload
60
+ def ref_computed(
61
+ fn=None,
62
+ *,
63
+ desc="",
64
+ debug_trigger: Optional[Callable[..., None]] = None,
65
+ priority_level: int = 1,
66
+ debug_name: Optional[str] = None,
67
+ ) -> Callable[[Callable[..., T]], ReadonlyRef[T]]:
68
+ ...
69
+
70
+
71
+ def ref_computed(
72
+ fn: Optional[Union[Callable[[], T], TInstanceCall[T]]] = None,
73
+ *,
74
+ desc="",
75
+ debug_trigger: Optional[Callable[..., None]] = None,
76
+ priority_level: int = 1,
77
+ debug_name: Optional[str] = None,
78
+ ) -> Union[ReadonlyRef[T], Callable[[Callable[..., T]], ReadonlyRef[T]]]:
79
+ kws = {
80
+ "debug_trigger": debug_trigger,
81
+ "priority_level": priority_level,
82
+ "debug_name": debug_name,
83
+ }
84
+
85
+ if fn:
86
+ if _helpers.is_class_define_method(fn):
87
+ return cast(
88
+ ref_computed_method[T],
89
+ ref_computed_method(fn, computed_args=kws), # type: ignore
90
+ ) # type: ignore
91
+
92
+ getter = signe.Computed(
93
+ cast(Callable[[], T], fn),
94
+ **kws,
95
+ scope=_CLIENT_SCOPE_MANAGER.get_current_scope(),
96
+ scheduler=get_uiScheduler(),
97
+ )
98
+ return cast(DescReadonlyRef[T], getter)
99
+
100
+ else:
101
+
102
+ def wrap(fn: Callable[[], T]):
103
+ return ref_computed(fn, **kws)
104
+
105
+ return wrap
106
+
107
+
108
+ class ref_computed_method(Generic[T]):
109
+ __isabstractmethod__: bool
110
+
111
+ def __init__(self, fget: Callable[[Any], T], computed_args: Dict) -> None:
112
+ self._fget = fget
113
+ self._computed_args = computed_args
114
+
115
+ def __set_name__(self, owner, name):
116
+ _helpers.add_computed_to_instance(owner, name, self._fget, self._computed_args)
117
+
118
+
119
+ class _helpers:
120
+ @staticmethod
121
+ def is_class_define_method(fn: Callable):
122
+ has_name = hasattr(fn, "__name__")
123
+ qualname_prefix = f".<locals>.{fn.__name__}" if has_name else ""
124
+
125
+ return (
126
+ hasattr(fn, "__qualname__")
127
+ and has_name
128
+ and "." in fn.__qualname__
129
+ and qualname_prefix != fn.__qualname__[-len(qualname_prefix) :]
130
+ and (isinstance(fn, types.FunctionType))
131
+ )
132
+
133
+ @staticmethod
134
+ def add_computed_to_instance(
135
+ cls_type: Type, attr_name: str, fn: Callable, computed_args: Dict
136
+ ):
137
+ """
138
+ Add an attribute to an instance of a class.
139
+ """
140
+ original_init = cls_type.__init__
141
+
142
+ def new_init(self, *args, **kwargs):
143
+ original_init(self, *args, **kwargs)
144
+ setattr(self, attr_name, ref_computed(partial(fn, self), **computed_args))
145
+
146
+ cls_type.__init__ = new_init
147
+ return cls_type
@@ -0,0 +1,57 @@
1
+ import signe
2
+ from typing import (
3
+ TypeVar,
4
+ Generic,
5
+ Optional,
6
+ Callable,
7
+ cast,
8
+ )
9
+ import warnings
10
+ from .types import (
11
+ TGetterOrReadonlyRef,
12
+ )
13
+
14
+ T = TypeVar("T")
15
+
16
+
17
+ class RefWrapper(Generic[T]):
18
+ __slot__ = ("_getter_fn", "_setter_fn", "")
19
+
20
+ def __init__(
21
+ self,
22
+ getter_or_ref: TGetterOrReadonlyRef[T],
23
+ setter_or_ref: Optional[Callable[[T], None]] = None,
24
+ ):
25
+ if signe.is_signal(getter_or_ref):
26
+ self._getter_fn = lambda: getter_or_ref.value
27
+
28
+ def ref_setter(v):
29
+ getter_or_ref.value = v # type: ignore
30
+
31
+ self._setter_fn = ref_setter
32
+ elif isinstance(getter_or_ref, Callable):
33
+ self._getter_fn = getter_or_ref
34
+ self._setter_fn = setter_or_ref or (lambda x: None)
35
+ else:
36
+ self._getter_fn = lambda: getter_or_ref
37
+ self._setter_fn = lambda x: None
38
+
39
+ self._is_readonly = False
40
+
41
+ @property
42
+ def value(self) -> T:
43
+ return cast(T, self._getter_fn())
44
+
45
+ @value.setter
46
+ def value(self, new_value: T):
47
+ if self._is_readonly:
48
+ warnings.warn("readonly ref cannot be assigned.")
49
+ return
50
+ return self._setter_fn(new_value)
51
+
52
+
53
+ def to_ref_wrapper(
54
+ getter_or_ref: TGetterOrReadonlyRef[T],
55
+ setter_or_ref: Optional[Callable[[T], None]] = None,
56
+ ):
57
+ return RefWrapper(getter_or_ref, setter_or_ref)