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
@@ -6,11 +6,9 @@ from typing import (
6
6
  Dict,
7
7
  Union,
8
8
  )
9
- from ex4nicegui.reactive.utils import ParameterClassifier
10
- from ex4nicegui.utils.apiEffect import ui_effect
11
-
9
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
12
10
  from ex4nicegui.utils.signals import (
13
- ReadonlyRef,
11
+ TGetterOrReadonlyRef,
14
12
  _TMaybeRef as TMaybeRef,
15
13
  to_value,
16
14
  )
@@ -20,6 +18,10 @@ from .base import BindableUi
20
18
  T = TypeVar("T")
21
19
 
22
20
 
21
+ def _default_vmodel_args_getter(e):
22
+ return e.sender.value
23
+
24
+
23
25
  class NumberBindableUi(BindableUi[ui.number]):
24
26
  def __init__(
25
27
  self,
@@ -29,6 +31,7 @@ class NumberBindableUi(BindableUi[ui.number]):
29
31
  value: Optional[Union[TMaybeRef[float], TMaybeRef[int]]] = None,
30
32
  min: Optional[TMaybeRef[float]] = None,
31
33
  max: Optional[TMaybeRef[float]] = None,
34
+ precision: Optional[TMaybeRef[int]] = None,
32
35
  step: Optional[TMaybeRef[float]] = None,
33
36
  prefix: Optional[TMaybeRef[str]] = None,
34
37
  suffix: Optional[TMaybeRef[str]] = None,
@@ -44,6 +47,7 @@ class NumberBindableUi(BindableUi[ui.number]):
44
47
  "value",
45
48
  "min",
46
49
  "max",
50
+ "precision",
47
51
  "step",
48
52
  "prefix",
49
53
  "suffix",
@@ -52,10 +56,10 @@ class NumberBindableUi(BindableUi[ui.number]):
52
56
  ],
53
57
  v_model=("value", "on_change"),
54
58
  events=["on_change"],
59
+ v_model_arg_getter=_default_vmodel_args_getter,
55
60
  )
56
61
 
57
62
  value_kws = pc.get_values_kws()
58
-
59
63
  element = ui.number(**value_kws)
60
64
  super().__init__(element) # type: ignore
61
65
 
@@ -66,15 +70,26 @@ class NumberBindableUi(BindableUi[ui.number]):
66
70
  def value(self):
67
71
  return self.element.value
68
72
 
69
- def bind_prop(self, prop: str, ref_ui: ReadonlyRef):
73
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
70
74
  if prop == "value":
71
75
  return self.bind_value(ref_ui)
72
76
 
77
+ if prop == "precision":
78
+ return self._bind_precision(ref_ui)
79
+
73
80
  return super().bind_prop(prop, ref_ui)
74
81
 
75
- def bind_value(self, ref_ui: ReadonlyRef[float]):
76
- @ui_effect
82
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef[float]):
83
+ @self._ui_effect
77
84
  def _():
78
85
  self.element.set_value(to_value(ref_ui))
79
86
 
80
87
  return self
88
+
89
+ def _bind_precision(self, ref_ui: TGetterOrReadonlyRef[int]):
90
+ @self._ui_signal_on(ref_ui, onchanges=True)
91
+ def _():
92
+ self.element.precision = to_value(ref_ui)
93
+ self.element.sanitize()
94
+
95
+ return self
@@ -8,11 +8,9 @@ from typing import (
8
8
  Dict,
9
9
  Union,
10
10
  )
11
- from ex4nicegui.reactive.utils import ParameterClassifier
12
- from ex4nicegui.utils.apiEffect import ui_effect
13
-
11
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
14
12
  from ex4nicegui.utils.signals import (
15
- ReadonlyRef,
13
+ TGetterOrReadonlyRef,
16
14
  _TMaybeRef as TMaybeRef,
17
15
  to_value,
18
16
  )
@@ -53,7 +51,7 @@ class RadioBindableUi(BindableUi[ui.radio]):
53
51
  def value(self):
54
52
  return self.element.value
55
53
 
56
- def bind_prop(self, prop: str, ref_ui: ReadonlyRef):
54
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
57
55
  if prop == "value":
58
56
  return self.bind_value(ref_ui)
59
57
 
@@ -62,15 +60,15 @@ class RadioBindableUi(BindableUi[ui.radio]):
62
60
 
63
61
  return super().bind_prop(prop, ref_ui)
64
62
 
65
- def bind_options(self, ref_ui: ReadonlyRef):
66
- @ui_effect
63
+ def bind_options(self, ref_ui: TGetterOrReadonlyRef):
64
+ @self._ui_effect
67
65
  def _():
68
66
  self.element.set_options(to_value(ref_ui))
69
67
 
70
68
  return self
71
69
 
72
- def bind_value(self, ref_ui: ReadonlyRef):
73
- @ui_effect
70
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef):
71
+ @self._ui_effect
74
72
  def _():
75
73
  cast(ValueElement, self.element).set_value(to_value(ref_ui))
76
74
 
@@ -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
  _TMaybeRef as TMaybeRef,
7
7
  )
@@ -8,11 +8,9 @@ from typing import (
8
8
  Dict,
9
9
  Union,
10
10
  )
11
- from ex4nicegui.reactive.utils import ParameterClassifier
12
- from ex4nicegui.utils.apiEffect import ui_effect
13
-
11
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
14
12
  from ex4nicegui.utils.signals import (
15
- ReadonlyRef,
13
+ TGetterOrReadonlyRef,
16
14
  _TMaybeRef as TMaybeRef,
17
15
  to_value,
18
16
  )
@@ -75,7 +73,7 @@ class SelectBindableUi(BindableUi[ui.select]):
75
73
  def value(self):
76
74
  return self.element.value
77
75
 
78
- def bind_prop(self, prop: str, ref_ui: ReadonlyRef):
76
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
79
77
  if prop == "value":
80
78
  return self.bind_value(ref_ui)
81
79
 
@@ -84,15 +82,15 @@ class SelectBindableUi(BindableUi[ui.select]):
84
82
 
85
83
  return super().bind_prop(prop, ref_ui)
86
84
 
87
- def bind_options(self, ref_ui: ReadonlyRef):
88
- @ui_effect()
85
+ def bind_options(self, ref_ui: TGetterOrReadonlyRef):
86
+ @self._ui_effect()
89
87
  def _():
90
88
  self.element.set_options(to_value(ref_ui))
91
89
 
92
90
  return self
93
91
 
94
- def bind_value(self, ref_ui: ReadonlyRef):
95
- @ui_effect()
92
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef):
93
+ @self._ui_effect()
96
94
  def _():
97
95
  cast(ValueElement, self.element).set_value(to_value(ref_ui) or None)
98
96
 
@@ -5,11 +5,9 @@ from typing import (
5
5
  TypeVar,
6
6
  cast,
7
7
  )
8
- from ex4nicegui.reactive.utils import ParameterClassifier
9
- from ex4nicegui.utils.apiEffect import ui_effect
10
-
8
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
11
9
  from ex4nicegui.utils.signals import (
12
- ReadonlyRef,
10
+ TGetterOrReadonlyRef,
13
11
  Ref,
14
12
  _TMaybeRef as TMaybeRef,
15
13
  is_setter_ref,
@@ -60,14 +58,14 @@ class SliderBindableUi(
60
58
  def value(self):
61
59
  return self.element.value
62
60
 
63
- def bind_prop(self, prop: str, ref_ui: ReadonlyRef):
61
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
64
62
  if prop == "value":
65
63
  return self.bind_value(ref_ui)
66
64
 
67
65
  return super().bind_prop(prop, ref_ui)
68
66
 
69
- def bind_value(self, ref_ui: ReadonlyRef[float]):
70
- @ui_effect
67
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef[float]):
68
+ @self._ui_effect
71
69
  def _():
72
70
  self.element.set_value(to_value(ref_ui))
73
71
  self.element.update()
@@ -95,7 +93,7 @@ class LazySliderBindableUi(SliderBindableUi):
95
93
  ref = cast(Ref, org_value)
96
94
  ele = self.element
97
95
 
98
- @ui_effect
96
+ @self._ui_effect
99
97
  def _():
100
98
  ele.value = ref.value
101
99
 
@@ -4,11 +4,9 @@ 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
9
-
7
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
10
8
  from ex4nicegui.utils.signals import (
11
- ReadonlyRef,
9
+ TGetterOrReadonlyRef,
12
10
  _TMaybeRef as TMaybeRef,
13
11
  to_value,
14
12
  )
@@ -49,14 +47,14 @@ class SwitchBindableUi(BindableUi[ui.switch]):
49
47
  def value(self):
50
48
  return self.element.value
51
49
 
52
- def bind_prop(self, prop: str, ref_ui: ReadonlyRef):
50
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
53
51
  if prop == "value":
54
52
  return self.bind_value(ref_ui)
55
53
 
56
54
  return super().bind_prop(prop, ref_ui)
57
55
 
58
- def bind_value(self, ref_ui: ReadonlyRef[bool]):
59
- @ui_effect
56
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef[bool]):
57
+ @self._ui_effect
60
58
  def _():
61
59
  self.element.set_value(to_value(ref_ui))
62
60
 
@@ -1,5 +1,5 @@
1
1
  from typing import Dict, Optional
2
- from ex4nicegui.reactive.utils import ParameterClassifier
2
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
3
3
  from ex4nicegui.utils.signals import (
4
4
  to_value,
5
5
  _TMaybeRef as TMaybeRef,
@@ -1,4 +1,4 @@
1
- from ex4nicegui.reactive.utils import ParameterClassifier
1
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
2
2
  from ex4nicegui.utils.signals import (
3
3
  _TMaybeRef as TMaybeRef,
4
4
  )
@@ -1,6 +1,7 @@
1
1
  from typing import Any, Callable, Optional
2
- from ex4nicegui.reactive.utils import ParameterClassifier
2
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
3
3
  from ex4nicegui.utils.signals import (
4
+ TGetterOrReadonlyRef,
4
5
  to_value,
5
6
  _TMaybeRef as TMaybeRef,
6
7
  )
@@ -17,6 +18,17 @@ class TabPanelsBindableUi(BindableUi[ui.tab_panels]):
17
18
  animated: TMaybeRef[bool] = True,
18
19
  keep_alive: TMaybeRef[bool] = True,
19
20
  ) -> None:
21
+ """Tab Panels
22
+
23
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#tab_panels
24
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#tab_panels
25
+
26
+ Args:
27
+ value (TMaybeRef[str], optional): The value of the tab panel. Defaults to None.
28
+ on_change (Callable[..., Any], optional): The callback function when the value of the tab panel changes. Defaults to None.
29
+ animated (TMaybeRef[bool], optional): Whether to animate the tab panel. Defaults to True.
30
+ keep_alive (TMaybeRef[bool], optional): Whether to keep the tab panel alive. Defaults to True.
31
+ """
20
32
  pc = ParameterClassifier(
21
33
  locals(),
22
34
  maybeRefs=["value", "animated", "keep_alive"],
@@ -34,13 +46,13 @@ class TabPanelsBindableUi(BindableUi[ui.tab_panels]):
34
46
  def value(self):
35
47
  return self.element.value
36
48
 
37
- def bind_prop(self, prop: str, ref_ui: TMaybeRef):
49
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
38
50
  if prop == "value":
39
51
  return self.bind_value(ref_ui)
40
52
 
41
53
  return super().bind_prop(prop, ref_ui)
42
54
 
43
- def bind_value(self, ref_ui: TMaybeRef):
55
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef):
44
56
  @self._ui_effect
45
57
  def _():
46
58
  self.element.set_value(to_value(ref_ui))
@@ -6,17 +6,19 @@ from typing import (
6
6
  Dict,
7
7
  )
8
8
  from typing_extensions import Literal
9
- from ex4nicegui.reactive.utils import ParameterClassifier, dataframe2col_str
9
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
10
+ from ex4nicegui.reactive.services.pandas_service import dataframe2col_str
11
+
10
12
  import ex4nicegui.utils.common as utils_common
11
13
  from ex4nicegui.utils.signals import (
12
- ReadonlyRef,
14
+ TGetterOrReadonlyRef,
15
+ TReadonlyRef,
13
16
  is_ref,
14
17
  ref_computed,
15
18
  to_ref,
16
19
  _TMaybeRef as TMaybeRef,
17
20
  to_value,
18
21
  to_raw,
19
- on,
20
22
  RefWrapper,
21
23
  )
22
24
  from nicegui import ui
@@ -66,7 +68,7 @@ class TableBindableUi(BindableUi[ui.table]):
66
68
 
67
69
  self._arg_selection = selection
68
70
  self._arg_row_key = row_key
69
- self._selection_ref: ReadonlyRef[List[Any]] = to_ref([]) # type: ignore
71
+ self._selection_ref: TReadonlyRef[List[Any]] = to_ref([]) # type: ignore
70
72
 
71
73
  def on_selection(_):
72
74
  self._selection_ref.value = self.element.selected # type: ignore
@@ -143,7 +145,7 @@ class TableBindableUi(BindableUi[ui.table]):
143
145
  ]
144
146
  return cls(cols, rows, **other_kws)
145
147
 
146
- def bind_prop(self, prop: str, ref_ui: ReadonlyRef):
148
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
147
149
  if prop == "dataframe":
148
150
  return self.bind_dataframe(ref_ui)
149
151
 
@@ -155,7 +157,7 @@ class TableBindableUi(BindableUi[ui.table]):
155
157
 
156
158
  return super().bind_prop(prop, ref_ui)
157
159
 
158
- def bind_dataframe(self, ref_df: ReadonlyRef):
160
+ def bind_dataframe(self, ref_df: TGetterOrReadonlyRef):
159
161
  @ref_computed
160
162
  def cp_converted_df():
161
163
  df = ref_df.value
@@ -180,8 +182,8 @@ class TableBindableUi(BindableUi[ui.table]):
180
182
 
181
183
  return self
182
184
 
183
- def bind_rows(self, ref_ui: ReadonlyRef[List[Dict]]):
184
- @on(ref_ui, deep=True)
185
+ def bind_rows(self, ref_ui: TGetterOrReadonlyRef[List[Dict]]):
186
+ @self._ui_signal_on(ref_ui, deep=True)
185
187
  def _():
186
188
  ele = self.element
187
189
  ele._props["rows"] = list(to_raw(to_value(ref_ui)))
@@ -189,8 +191,8 @@ class TableBindableUi(BindableUi[ui.table]):
189
191
 
190
192
  return self
191
193
 
192
- def bind_columns(self, ref_ui: ReadonlyRef[List[Dict]]):
193
- @on(ref_ui, deep=True)
194
+ def bind_columns(self, ref_ui: TGetterOrReadonlyRef[List[Dict]]):
195
+ @self._ui_signal_on(ref_ui, deep=True)
194
196
  def _():
195
197
  ele = self.element
196
198
  ele._props["columns"] = list(to_raw(to_value(ref_ui)))
@@ -1,6 +1,7 @@
1
1
  from typing import Any, Callable, Optional
2
- from ex4nicegui.reactive.utils import ParameterClassifier
2
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
3
3
  from ex4nicegui.utils.signals import (
4
+ TGetterOrReadonlyRef,
4
5
  to_value,
5
6
  _TMaybeRef as TMaybeRef,
6
7
  )
@@ -31,13 +32,13 @@ class TabsBindableUi(BindableUi[ui.tabs]):
31
32
  def value(self):
32
33
  return self.element.value
33
34
 
34
- def bind_prop(self, prop: str, ref_ui: TMaybeRef):
35
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
35
36
  if prop == "value":
36
37
  return self.bind_value(ref_ui)
37
38
 
38
39
  return super().bind_prop(prop, ref_ui)
39
40
 
40
- def bind_value(self, ref_ui: TMaybeRef):
41
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef):
41
42
  @self._ui_effect
42
43
  def _():
43
44
  self.element.set_value(to_value(ref_ui))
@@ -5,13 +5,11 @@ from typing import (
5
5
  Dict,
6
6
  cast,
7
7
  )
8
- from ex4nicegui.reactive.utils import ParameterClassifier
9
- from ex4nicegui.utils.apiEffect import ui_effect
8
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
10
9
  from ex4nicegui.utils.signals import (
11
- ReadonlyRef,
10
+ TGetterOrReadonlyRef,
12
11
  Ref,
13
12
  _TMaybeRef as TMaybeRef,
14
- effect,
15
13
  is_setter_ref,
16
14
  to_value,
17
15
  )
@@ -54,14 +52,14 @@ class TextareaBindableUi(BindableUi[ui.textarea]):
54
52
  def value(self):
55
53
  return self.element.value
56
54
 
57
- def bind_prop(self, prop: str, ref_ui: ReadonlyRef):
55
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
58
56
  if prop == "value":
59
57
  return self.bind_value(ref_ui)
60
58
 
61
59
  return super().bind_prop(prop, ref_ui)
62
60
 
63
- def bind_value(self, ref_ui: ReadonlyRef[str]):
64
- @ui_effect
61
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef[str]):
62
+ @self._ui_effect
65
63
  def _():
66
64
  self.element.set_value(to_value(ref_ui))
67
65
 
@@ -95,7 +93,7 @@ class LazyTextareaBindableUi(TextareaBindableUi):
95
93
  ref = cast(Ref, org_value)
96
94
  ele = self.element
97
95
 
98
- @effect
96
+ @self._ui_effect
99
97
  def _():
100
98
  ele.value = ref.value
101
99
 
@@ -11,7 +11,7 @@ from ex4nicegui.utils.signals import (
11
11
  from nicegui import ui
12
12
  from nicegui.events import handle_event
13
13
  from .base import BindableUi
14
- from .utils import _convert_kws_ref2value
14
+ from ex4nicegui.reactive.systems.reactive_system import convert_kws_ref2value
15
15
 
16
16
 
17
17
  class UploadResult:
@@ -57,7 +57,7 @@ class UploadBindableUi(BindableUi[ui.upload]):
57
57
  "auto_upload": auto_upload,
58
58
  }
59
59
 
60
- value_kws = _convert_kws_ref2value(kws)
60
+ value_kws = convert_kws_ref2value(kws)
61
61
 
62
62
  self._on_upload_callbacks = []
63
63
 
@@ -1,8 +1,9 @@
1
1
  from typing import Any, Optional, Callable
2
- from ex4nicegui.reactive.utils import ParameterClassifier
2
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
3
3
  from ex4nicegui.utils.signals import (
4
+ TGetterOrReadonlyRef,
4
5
  to_value,
5
- _TMaybeRef as TMaybeRef,
6
+ TMaybeRef,
6
7
  )
7
8
  from nicegui import ui
8
9
  from ex4nicegui.reactive.officials.base import BindableUi
@@ -35,13 +36,13 @@ class PaginationBindableUi(BindableUi[ui.pagination]):
35
36
  def value(self):
36
37
  return self.element.value
37
38
 
38
- def bind_prop(self, prop: str, ref_ui: TMaybeRef):
39
+ def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
39
40
  if prop == "value":
40
41
  return self.bind_value(ref_ui)
41
42
 
42
43
  return super().bind_prop(prop, ref_ui)
43
44
 
44
- def bind_value(self, ref_ui: TMaybeRef[int]):
45
+ def bind_value(self, ref_ui: TGetterOrReadonlyRef[int]):
45
46
  @self._ui_effect
46
47
  def _():
47
48
  self.element.set_value(to_value(ref_ui))
@@ -0,0 +1,55 @@
1
+
2
+ const REGEX_NEWLINE = /[\r\n]/g;
3
+ const REGEX_START_SPACES = /^\s+/gm;
4
+
5
+ function getClasses(id) {
6
+ return `ex4ng-scoped-style-${id}`;
7
+ }
8
+
9
+ function removeInvalidChars(str) {
10
+ str = str.replace(REGEX_START_SPACES, '');
11
+ return str.replace(REGEX_NEWLINE, '');
12
+ }
13
+
14
+ function appendCSS(styleElement, cssText) {
15
+ // 获取已有的 CSS 内容
16
+ let existingCSS = styleElement.textContent || '';
17
+
18
+ // 如果已有的 CSS 内容不为空,添加一个空行作为分隔符
19
+ if (existingCSS.trim() !== '') {
20
+ existingCSS += '\n';
21
+ }
22
+
23
+ // 拼接新的 CSS 内容
24
+ existingCSS += cssText;
25
+
26
+ // 将新的 CSS 内容设置回 style 标签
27
+ styleElement.textContent = existingCSS;
28
+ }
29
+
30
+ export default {
31
+ template: `<template></template>`,
32
+ methods: {
33
+ createStyle(id, css) {
34
+ css = removeInvalidChars(css);
35
+
36
+ const classes = getClasses(id);
37
+ const target = document.querySelector(`style.${classes}`);
38
+ if (target) {
39
+ appendCSS(target, css);
40
+ } else {
41
+ const style = document.createElement('style');
42
+ style.classList.add(classes);
43
+ style.innerHTML = css;
44
+ document.head.appendChild(style);
45
+ }
46
+ },
47
+ removeStyle(id) {
48
+ const classes = getClasses(id);
49
+ const target = document.querySelector(`style.${classes}`);
50
+ if (target) {
51
+ target.remove();
52
+ }
53
+ },
54
+ },
55
+ };
@@ -0,0 +1,22 @@
1
+ from nicegui.element import Element
2
+ from ex4nicegui.helper import client_instance_locker
3
+
4
+
5
+ class ScopedStyle(Element, component="scopedStyle.js"):
6
+ pass
7
+
8
+ @staticmethod
9
+ def get():
10
+ return _scoped_style_factory.get_object()
11
+
12
+ def create_style(self, element: Element, css: str):
13
+ element_id = f"c{element.id}"
14
+
15
+ self.run_method("createStyle", element_id, css)
16
+
17
+ def remove_style(self, element: Element):
18
+ element_id = f"c{element.id}"
19
+ self.run_method("removeStyle", element_id)
20
+
21
+
22
+ _scoped_style_factory = client_instance_locker.ClientInstanceLocker(ScopedStyle)
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+ from typing import TYPE_CHECKING, Literal, cast
3
+ from ex4nicegui.utils.signals import to_value
4
+ from nicegui.elements.mixins.color_elements import (
5
+ TextColorElement,
6
+ QUASAR_COLORS,
7
+ TAILWIND_COLORS,
8
+ )
9
+
10
+ if TYPE_CHECKING:
11
+ from ex4nicegui.reactive.officials.base import BindableUi
12
+ from ex4nicegui import TGetterOrReadonlyRef
13
+
14
+
15
+ _color_sys_type = Literal["QUASAR", "TAILWIND", "STYLE"]
16
+ _color_attr_name = "data-ex4ng-color"
17
+
18
+
19
+ def bind_color(bindable_ui: BindableUi, ref_ui: TGetterOrReadonlyRef):
20
+ @bindable_ui._ui_effect
21
+ def _():
22
+ ele = cast(TextColorElement, bindable_ui.element)
23
+ color = to_value(ref_ui)
24
+
25
+ # get exists color
26
+ # e.g 'QUASAR:red'
27
+ pre_color = ele._props.get(_color_attr_name) # type: str | None
28
+ if pre_color:
29
+ color_sys, value = pre_color.split(":") # type: ignore
30
+ color_sys: _color_sys_type
31
+
32
+ if color_sys == "QUASAR":
33
+ del ele._props[ele.TEXT_COLOR_PROP]
34
+ elif color_sys == "TAILWIND":
35
+ ele.classes(remove=value)
36
+ else:
37
+ del ele._style["color"]
38
+
39
+ cur_sys: _color_sys_type = "STYLE"
40
+ cur_color = color
41
+
42
+ if color in QUASAR_COLORS:
43
+ ele._props[ele.TEXT_COLOR_PROP] = color
44
+ cur_sys = "QUASAR"
45
+ elif color in TAILWIND_COLORS:
46
+ cur_color = f"text-{color}"
47
+ ele.classes(replace=cur_color)
48
+ cur_sys = "TAILWIND"
49
+ elif color is not None:
50
+ ele._style["color"] = color
51
+
52
+ ele._props[_color_attr_name] = f"{cur_sys}:{color}"
53
+
54
+ ele.update()
55
+
56
+ return bindable_ui
@@ -0,0 +1,31 @@
1
+ try:
2
+ import pandas as pd
3
+ except ImportError:
4
+ pass
5
+
6
+
7
+ def dataframe2col_str(df, copy=True):
8
+ if isinstance(df.columns, pd.MultiIndex):
9
+ raise ValueError(
10
+ "MultiIndex columns are not supported. "
11
+ "You can convert them to strings using something like "
12
+ '`df.columns = ["_".join(col) for col in df.columns.values]`.'
13
+ )
14
+
15
+ date_cols = df.columns[df.dtypes == "datetime64[ns]"]
16
+ time_cols = df.columns[df.dtypes == "timedelta64[ns]"]
17
+ complex_cols = df.columns[df.dtypes == "complex128"]
18
+ period_cols = df.columns[df.dtypes == "period[M]"]
19
+ if (
20
+ len(date_cols) != 0
21
+ or len(time_cols) != 0
22
+ or len(complex_cols) != 0
23
+ or len(period_cols) != 0
24
+ ):
25
+ df = df.copy() if copy else df
26
+ df[date_cols] = df[date_cols].astype(str)
27
+ df[time_cols] = df[time_cols].astype(str)
28
+ df[complex_cols] = df[complex_cols].astype(str)
29
+ df[period_cols] = df[period_cols].astype(str)
30
+
31
+ return df