ex4nicegui 0.6.9__py3-none-any.whl → 0.7.1__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 (51) hide show
  1. ex4nicegui/bi/dataSourceFacade.py +20 -20
  2. ex4nicegui/bi/index.py +20 -23
  3. ex4nicegui/reactive/EChartsComponent/ECharts.py +9 -8
  4. ex4nicegui/reactive/__init__.py +14 -0
  5. ex4nicegui/reactive/base.py +64 -55
  6. ex4nicegui/reactive/mixins/backgroundColor.py +5 -5
  7. ex4nicegui/reactive/mixins/disableable.py +8 -8
  8. ex4nicegui/reactive/mixins/textColor.py +10 -10
  9. ex4nicegui/reactive/officials/aggrid.py +5 -5
  10. ex4nicegui/reactive/officials/avatar.py +86 -0
  11. ex4nicegui/reactive/officials/badge.py +102 -0
  12. ex4nicegui/reactive/officials/button.py +15 -15
  13. ex4nicegui/reactive/officials/checkbox.py +6 -7
  14. ex4nicegui/reactive/officials/chip.py +6 -7
  15. ex4nicegui/reactive/officials/circular_progress.py +7 -7
  16. ex4nicegui/reactive/officials/color_picker.py +8 -8
  17. ex4nicegui/reactive/officials/column.py +5 -5
  18. ex4nicegui/reactive/officials/date.py +6 -6
  19. ex4nicegui/reactive/officials/dialog.py +49 -0
  20. ex4nicegui/reactive/officials/echarts.py +49 -51
  21. ex4nicegui/reactive/officials/expansion.py +6 -6
  22. ex4nicegui/reactive/officials/icon.py +7 -13
  23. ex4nicegui/reactive/officials/image.py +6 -6
  24. ex4nicegui/reactive/officials/input.py +10 -11
  25. ex4nicegui/reactive/officials/knob.py +7 -7
  26. ex4nicegui/reactive/officials/label.py +11 -9
  27. ex4nicegui/reactive/officials/linear_progress.py +7 -7
  28. ex4nicegui/reactive/officials/number.py +10 -10
  29. ex4nicegui/reactive/officials/radio.py +10 -10
  30. ex4nicegui/reactive/officials/row.py +5 -5
  31. ex4nicegui/reactive/officials/select.py +11 -10
  32. ex4nicegui/reactive/officials/slider.py +6 -6
  33. ex4nicegui/reactive/officials/switch.py +6 -7
  34. ex4nicegui/reactive/officials/tab.py +0 -12
  35. ex4nicegui/reactive/officials/tab_panels.py +5 -5
  36. ex4nicegui/reactive/officials/table.py +13 -13
  37. ex4nicegui/reactive/officials/tabs.py +5 -5
  38. ex4nicegui/reactive/officials/textarea.py +6 -6
  39. ex4nicegui/reactive/officials/toggle.py +88 -0
  40. ex4nicegui/reactive/officials/tooltip.py +40 -0
  41. ex4nicegui/reactive/q_pagination.py +5 -5
  42. ex4nicegui/reactive/systems/reactive_system.py +2 -2
  43. ex4nicegui/reactive/vfor.js +14 -4
  44. ex4nicegui/reactive/vfor.py +128 -58
  45. ex4nicegui/reactive/view_model.py +160 -0
  46. ex4nicegui/reactive/vmodel.py +42 -12
  47. ex4nicegui/utils/signals.py +23 -21
  48. {ex4nicegui-0.6.9.dist-info → ex4nicegui-0.7.1.dist-info}/METADATA +223 -48
  49. {ex4nicegui-0.6.9.dist-info → ex4nicegui-0.7.1.dist-info}/RECORD +51 -45
  50. {ex4nicegui-0.6.9.dist-info → ex4nicegui-0.7.1.dist-info}/LICENSE +0 -0
  51. {ex4nicegui-0.6.9.dist-info → ex4nicegui-0.7.1.dist-info}/WHEEL +0 -0
@@ -61,17 +61,17 @@ class KnobBindableUi(
61
61
  def value(self):
62
62
  return self.element.value
63
63
 
64
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
64
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
65
65
  if prop == "value":
66
- return self.bind_value(ref_ui)
66
+ return self.bind_value(value)
67
67
  if prop == "color":
68
- return self.bind_color(ref_ui)
68
+ return self.bind_color(value)
69
69
 
70
- return super().bind_prop(prop, ref_ui)
70
+ return super().bind_prop(prop, value)
71
71
 
72
- def bind_value(self, ref_ui: TGetterOrReadonlyRef[float]):
73
- @self._ui_effect
72
+ def bind_value(self, value: TGetterOrReadonlyRef[float]):
73
+ @self._ui_signal_on(value)
74
74
  def _():
75
- self.element.set_value(to_value(ref_ui))
75
+ self.element.set_value(to_value(value))
76
76
 
77
77
  return self
@@ -3,6 +3,7 @@ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
3
3
  from ex4nicegui.utils.signals import (
4
4
  TGetterOrReadonlyRef,
5
5
  to_value,
6
+ to_raw,
6
7
  _TMaybeRef as TMaybeRef,
7
8
  )
8
9
  from nicegui import ui
@@ -17,7 +18,9 @@ class LabelBindableUi(BindableUi[ui.label], HtmlTextColorableMixin):
17
18
  ) -> None:
18
19
  pc = ParameterClassifier(locals(), maybeRefs=["text"], events=[])
19
20
 
20
- element = ui.label(**pc.get_values_kws())
21
+ init_kws = pc.get_values_kws()
22
+ init_kws.update({"text": str(init_kws.get("text", ""))})
23
+ element = ui.label(**init_kws)
21
24
  super().__init__(element)
22
25
 
23
26
  for key, value in pc.get_bindings().items():
@@ -27,19 +30,18 @@ class LabelBindableUi(BindableUi[ui.label], HtmlTextColorableMixin):
27
30
  def text(self):
28
31
  return self.element.text
29
32
 
30
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
33
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
31
34
  if prop == "text":
32
- return self.bind_text(ref_ui)
35
+ return self.bind_text(value)
33
36
 
34
37
  if prop == "color":
35
- return self.bind_color(ref_ui)
38
+ return self.bind_color(value)
36
39
 
37
- return super().bind_prop(prop, ref_ui)
40
+ return super().bind_prop(prop, value)
38
41
 
39
- def bind_text(self, ref_ui: TGetterOrReadonlyRef):
40
- @self._ui_effect
42
+ def bind_text(self, text: TGetterOrReadonlyRef):
43
+ @self._ui_signal_on(text, deep=True)
41
44
  def _():
42
- self.element.set_text(str(to_value(ref_ui)))
43
- self.element.update()
45
+ self.element.set_text(str(to_raw(to_value(text))))
44
46
 
45
47
  return self
@@ -46,18 +46,18 @@ class LinearProgressBindableUi(BindableUi[ui.linear_progress], TextColorableMixi
46
46
  def value(self):
47
47
  return self.element.value
48
48
 
49
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
49
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
50
50
  if prop == "value":
51
- return self.bind_value(ref_ui)
51
+ return self.bind_value(value)
52
52
 
53
53
  if prop == "color":
54
- return self.bind_color(ref_ui)
54
+ return self.bind_color(value)
55
55
 
56
- return super().bind_prop(prop, ref_ui)
56
+ return super().bind_prop(prop, value)
57
57
 
58
- def bind_value(self, ref_ui: TGetterOrReadonlyRef):
59
- @self._ui_effect
58
+ def bind_value(self, value: TGetterOrReadonlyRef):
59
+ @self._ui_signal_on(value)
60
60
  def _():
61
- self.element.set_value(to_value(ref_ui))
61
+ self.element.set_value(to_value(value))
62
62
 
63
63
  return self
@@ -70,26 +70,26 @@ class NumberBindableUi(BindableUi[ui.number]):
70
70
  def value(self):
71
71
  return self.element.value
72
72
 
73
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
73
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
74
74
  if prop == "value":
75
- return self.bind_value(ref_ui)
75
+ return self.bind_value(value)
76
76
 
77
77
  if prop == "precision":
78
- return self._bind_precision(ref_ui)
78
+ return self._bind_precision(value)
79
79
 
80
- return super().bind_prop(prop, ref_ui)
80
+ return super().bind_prop(prop, value)
81
81
 
82
- def bind_value(self, ref_ui: TGetterOrReadonlyRef[float]):
83
- @self._ui_effect
82
+ def bind_value(self, value: TGetterOrReadonlyRef[float]):
83
+ @self._ui_signal_on(value)
84
84
  def _():
85
- self.element.set_value(to_value(ref_ui))
85
+ self.element.set_value(to_value(value))
86
86
 
87
87
  return self
88
88
 
89
- def _bind_precision(self, ref_ui: TGetterOrReadonlyRef[int]):
90
- @self._ui_signal_on(ref_ui, onchanges=True)
89
+ def _bind_precision(self, precision: TGetterOrReadonlyRef[int]):
90
+ @self._ui_signal_on(precision)
91
91
  def _():
92
- self.element.precision = to_value(ref_ui)
92
+ self.element.precision = to_value(precision)
93
93
  self.element.sanitize()
94
94
 
95
95
  return self
@@ -51,25 +51,25 @@ class RadioBindableUi(BindableUi[ui.radio]):
51
51
  def value(self):
52
52
  return self.element.value
53
53
 
54
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
54
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
55
55
  if prop == "value":
56
- return self.bind_value(ref_ui)
56
+ return self.bind_value(value)
57
57
 
58
58
  if prop == "options":
59
- return self.bind_options(ref_ui)
59
+ return self.bind_options(value)
60
60
 
61
- return super().bind_prop(prop, ref_ui)
61
+ return super().bind_prop(prop, value)
62
62
 
63
- def bind_options(self, ref_ui: TGetterOrReadonlyRef):
64
- @self._ui_effect
63
+ def bind_options(self, options: TGetterOrReadonlyRef):
64
+ @self._ui_signal_on(options, deep=True)
65
65
  def _():
66
- self.element.set_options(to_value(ref_ui))
66
+ self.element.set_options(to_value(options))
67
67
 
68
68
  return self
69
69
 
70
- def bind_value(self, ref_ui: TGetterOrReadonlyRef):
71
- @self._ui_effect
70
+ def bind_value(self, value: TGetterOrReadonlyRef):
71
+ @self._ui_signal_on(value)
72
72
  def _():
73
- cast(ValueElement, self.element).set_value(to_value(ref_ui))
73
+ cast(ValueElement, self.element).set_value(to_value(value))
74
74
 
75
75
  return self
@@ -18,14 +18,14 @@ class RowBindableUi(BindableUi[ui.row]):
18
18
  for key, value in pc.get_bindings().items():
19
19
  self.bind_prop(key, value) # type: ignore
20
20
 
21
- def bind_prop(self, prop: str, ref_ui: TMaybeRef):
21
+ def bind_prop(self, prop: str, value: TMaybeRef):
22
22
  if prop == "wrap":
23
- return self.bind_wrap(ref_ui)
23
+ return self.bind_wrap(value)
24
24
 
25
- return super().bind_prop(prop, ref_ui)
25
+ return super().bind_prop(prop, value)
26
26
 
27
- def bind_wrap(self, ref_ui: TMaybeRef):
28
- self.bind_classes({"wrap": ref_ui})
27
+ def bind_wrap(self, value: TMaybeRef):
28
+ self.bind_classes({"wrap": value})
29
29
 
30
30
  def __enter__(self):
31
31
  self.element.__enter__()
@@ -13,6 +13,7 @@ from ex4nicegui.utils.signals import (
13
13
  TGetterOrReadonlyRef,
14
14
  _TMaybeRef as TMaybeRef,
15
15
  to_value,
16
+ to_raw,
16
17
  )
17
18
  from nicegui import ui
18
19
  from nicegui.elements.mixins.value_element import ValueElement
@@ -73,25 +74,25 @@ class SelectBindableUi(BindableUi[ui.select]):
73
74
  def value(self):
74
75
  return self.element.value
75
76
 
76
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
77
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
77
78
  if prop == "value":
78
- return self.bind_value(ref_ui)
79
+ return self.bind_value(value)
79
80
 
80
81
  if prop == "options":
81
- return self.bind_options(ref_ui)
82
+ return self.bind_options(value)
82
83
 
83
- return super().bind_prop(prop, ref_ui)
84
+ return super().bind_prop(prop, value)
84
85
 
85
- def bind_options(self, ref_ui: TGetterOrReadonlyRef):
86
- @self._ui_effect()
86
+ def bind_options(self, options: TGetterOrReadonlyRef):
87
+ @self._ui_signal_on(options, deep=True)
87
88
  def _():
88
- self.element.set_options(to_value(ref_ui))
89
+ self.element.set_options(to_value(options))
89
90
 
90
91
  return self
91
92
 
92
- def bind_value(self, ref_ui: TGetterOrReadonlyRef):
93
- @self._ui_effect()
93
+ def bind_value(self, value: TGetterOrReadonlyRef):
94
+ @self._ui_signal_on(value, deep=True)
94
95
  def _():
95
- cast(ValueElement, self.element).set_value(to_value(ref_ui) or None)
96
+ cast(ValueElement, self.element).set_value(to_raw(to_value(value)) or None)
96
97
 
97
98
  return self
@@ -58,16 +58,16 @@ class SliderBindableUi(
58
58
  def value(self):
59
59
  return self.element.value
60
60
 
61
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
61
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
62
62
  if prop == "value":
63
- return self.bind_value(ref_ui)
63
+ return self.bind_value(value)
64
64
 
65
- return super().bind_prop(prop, ref_ui)
65
+ return super().bind_prop(prop, value)
66
66
 
67
- def bind_value(self, ref_ui: TGetterOrReadonlyRef[float]):
68
- @self._ui_effect
67
+ def bind_value(self, value: TGetterOrReadonlyRef[float]):
68
+ @self._ui_signal_on(value)
69
69
  def _():
70
- self.element.set_value(to_value(ref_ui))
70
+ self.element.set_value(to_value(value))
71
71
  self.element.update()
72
72
 
73
73
  return self
@@ -35,7 +35,6 @@ class SwitchBindableUi(BindableUi[ui.switch]):
35
35
  )
36
36
 
37
37
  value_kws = pc.get_values_kws()
38
- value_kws.update({"value": 0 if value is None else value})
39
38
 
40
39
  element = ui.switch(**value_kws)
41
40
  super().__init__(element) # type: ignore
@@ -47,15 +46,15 @@ class SwitchBindableUi(BindableUi[ui.switch]):
47
46
  def value(self):
48
47
  return self.element.value
49
48
 
50
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
49
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
51
50
  if prop == "value":
52
- return self.bind_value(ref_ui)
51
+ return self.bind_value(value)
53
52
 
54
- return super().bind_prop(prop, ref_ui)
53
+ return super().bind_prop(prop, value)
55
54
 
56
- def bind_value(self, ref_ui: TGetterOrReadonlyRef[bool]):
57
- @self._ui_effect
55
+ def bind_value(self, value: TGetterOrReadonlyRef[bool]):
56
+ @self._ui_signal_on(value)
58
57
  def _():
59
- self.element.set_value(to_value(ref_ui))
58
+ self.element.set_value(to_value(value))
60
59
 
61
60
  return self
@@ -33,12 +33,6 @@ class TabBindableUi(BindableUi[ui.tab]):
33
33
  for key, value in bindings_kws.items():
34
34
  self.bind_prop(key, value) # type: ignore
35
35
 
36
- # def bind_prop(self, prop: str, ref_ui: TMaybeRef):
37
- # if prop == "name":
38
- # return self.bind_name(ref_ui)
39
-
40
- # return super().bind_prop(prop, ref_ui)
41
-
42
36
  def __bind_label(self, binding_kws: Dict, value_kws: Dict):
43
37
  name_ref = binding_kws.get("name") or value_kws.get("name")
44
38
  label_ref = binding_kws.get("label") or value_kws.get("label")
@@ -49,9 +43,3 @@ class TabBindableUi(BindableUi[ui.tab]):
49
43
  to_value(label_ref) if label_ref is not None else to_value(name_ref)
50
44
  )
51
45
  self.element.update()
52
-
53
- # def bind_name(self, ref_ui: TMaybeRef):
54
- # @self._ui_effect
55
- # def _():
56
- # self.element._props["name"] = to_value(ref_ui)
57
- # self.element.update()
@@ -49,16 +49,16 @@ class TabPanelsBindableUi(BindableUi[ui.tab_panels]):
49
49
  def value(self):
50
50
  return self.element.value
51
51
 
52
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
52
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
53
53
  if prop == "value":
54
- return self.bind_value(ref_ui)
54
+ return self.bind_value(value)
55
55
 
56
- return super().bind_prop(prop, ref_ui)
56
+ return super().bind_prop(prop, value)
57
57
 
58
- def bind_value(self, ref_ui: TGetterOrReadonlyRef):
58
+ def bind_value(self, value: TGetterOrReadonlyRef):
59
59
  @self._ui_effect
60
60
  def _():
61
- self.element.set_value(to_value(ref_ui))
61
+ self.element.set_value(to_value(value))
62
62
 
63
63
 
64
64
  class lazy_tab_panel(ui.tab_panel):
@@ -145,22 +145,22 @@ class TableBindableUi(BindableUi[ui.table]):
145
145
  ]
146
146
  return cls(cols, rows, **other_kws)
147
147
 
148
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
148
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
149
149
  if prop == "dataframe":
150
- return self.bind_dataframe(ref_ui)
150
+ return self.bind_dataframe(value)
151
151
 
152
152
  if prop == "rows":
153
- return self.bind_rows(ref_ui)
153
+ return self.bind_rows(value)
154
154
 
155
155
  if prop == "columns":
156
- return self.bind_columns(ref_ui)
156
+ return self.bind_columns(value)
157
157
 
158
- return super().bind_prop(prop, ref_ui)
158
+ return super().bind_prop(prop, value)
159
159
 
160
- def bind_dataframe(self, ref_df: TGetterOrReadonlyRef):
160
+ def bind_dataframe(self, dataframe: TGetterOrReadonlyRef):
161
161
  @ref_computed
162
162
  def cp_converted_df():
163
- df = ref_df.value
163
+ df = dataframe.value
164
164
  return utils_common.convert_dataframe(df)
165
165
 
166
166
  @ref_computed
@@ -182,20 +182,20 @@ class TableBindableUi(BindableUi[ui.table]):
182
182
 
183
183
  return self
184
184
 
185
- def bind_rows(self, ref_ui: TGetterOrReadonlyRef[List[Dict]]):
186
- @self._ui_signal_on(ref_ui, deep=True)
185
+ def bind_rows(self, rows: TGetterOrReadonlyRef[List[Dict]]):
186
+ @self._ui_signal_on(rows, deep=True)
187
187
  def _():
188
188
  ele = self.element
189
- ele._props["rows"] = list(to_raw(to_value(ref_ui)))
189
+ ele._props["rows"] = list(to_raw(to_value(rows)))
190
190
  ele.update()
191
191
 
192
192
  return self
193
193
 
194
- def bind_columns(self, ref_ui: TGetterOrReadonlyRef[List[Dict]]):
195
- @self._ui_signal_on(ref_ui, deep=True)
194
+ def bind_columns(self, columns: TGetterOrReadonlyRef[List[Dict]]):
195
+ @self._ui_signal_on(columns, deep=True)
196
196
  def _():
197
197
  ele = self.element
198
- ele._props["columns"] = list(to_raw(to_value(ref_ui)))
198
+ ele._props["columns"] = list(to_raw(to_value(columns)))
199
199
  ele.update()
200
200
 
201
201
  return self
@@ -32,13 +32,13 @@ class TabsBindableUi(BindableUi[ui.tabs]):
32
32
  def value(self):
33
33
  return self.element.value
34
34
 
35
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
35
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
36
36
  if prop == "value":
37
- return self.bind_value(ref_ui)
37
+ return self.bind_value(value)
38
38
 
39
- return super().bind_prop(prop, ref_ui)
39
+ return super().bind_prop(prop, value)
40
40
 
41
- def bind_value(self, ref_ui: TGetterOrReadonlyRef):
41
+ def bind_value(self, value: TGetterOrReadonlyRef):
42
42
  @self._ui_effect
43
43
  def _():
44
- self.element.set_value(to_value(ref_ui))
44
+ self.element.set_value(to_value(value))
@@ -52,16 +52,16 @@ class TextareaBindableUi(BindableUi[ui.textarea]):
52
52
  def value(self):
53
53
  return self.element.value
54
54
 
55
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
55
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
56
56
  if prop == "value":
57
- return self.bind_value(ref_ui)
57
+ return self.bind_value(value)
58
58
 
59
- return super().bind_prop(prop, ref_ui)
59
+ return super().bind_prop(prop, value)
60
60
 
61
- def bind_value(self, ref_ui: TGetterOrReadonlyRef[str]):
62
- @self._ui_effect
61
+ def bind_value(self, value: TGetterOrReadonlyRef[str]):
62
+ @self._ui_signal_on(value)
63
63
  def _():
64
- self.element.set_value(to_value(ref_ui))
64
+ self.element.set_value(to_value(value))
65
65
 
66
66
  return self
67
67
 
@@ -0,0 +1,88 @@
1
+ from typing import (
2
+ Any,
3
+ Callable,
4
+ List,
5
+ Optional,
6
+ TypeVar,
7
+ Dict,
8
+ Union,
9
+ )
10
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
11
+ from ex4nicegui.utils.signals import (
12
+ TGetterOrReadonlyRef,
13
+ _TMaybeRef as TMaybeRef,
14
+ to_value,
15
+ to_raw,
16
+ )
17
+ from nicegui import ui
18
+ from .base import BindableUi
19
+
20
+ T = TypeVar("T")
21
+
22
+
23
+ class ToggleBindableUi(BindableUi[ui.toggle]):
24
+ def __init__(
25
+ self,
26
+ options: Union[TMaybeRef[List], TMaybeRef[Dict]],
27
+ *,
28
+ value: TMaybeRef[Any] = None,
29
+ on_change: Optional[Callable[..., Any]] = None,
30
+ clearable: TMaybeRef[bool] = False,
31
+ ) -> None:
32
+ """Toggle
33
+
34
+ This element is based on Quasar's `QBtnToggle <https://quasar.dev/vue-components/button-toggle>`_ component.
35
+
36
+ The options can be specified as a list of values, or as a dictionary mapping values to labels.
37
+ After manipulating the options, call `update()` to update the options in the UI.
38
+
39
+ :param options: a list ['value1', ...] or dictionary `{'value1':'label1', ...}` specifying the options
40
+ :param value: the initial value
41
+ :param on_change: callback to execute when selection changes
42
+ :param clearable: whether the toggle can be cleared by clicking the selected option
43
+ """
44
+ pc = ParameterClassifier(
45
+ locals(),
46
+ maybeRefs=[
47
+ "options",
48
+ "value",
49
+ "clearable",
50
+ ],
51
+ v_model=("value", "on_change"),
52
+ events=["on_change"],
53
+ )
54
+
55
+ value_kws = pc.get_values_kws()
56
+
57
+ element = ui.toggle(**value_kws)
58
+ super().__init__(element) # type: ignore
59
+
60
+ for key, value in pc.get_bindings().items():
61
+ self.bind_prop(key, value) # type: ignore
62
+
63
+ @property
64
+ def value(self):
65
+ return self.element.value
66
+
67
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
68
+ if prop == "value":
69
+ return self.bind_value(value)
70
+
71
+ if prop == "options":
72
+ return self.bind_options(value)
73
+
74
+ return super().bind_prop(prop, value)
75
+
76
+ def bind_options(self, options: TGetterOrReadonlyRef):
77
+ @self._ui_signal_on(options, deep=True)
78
+ def _():
79
+ self.element.set_options(to_value(options))
80
+
81
+ return self
82
+
83
+ def bind_value(self, value: TGetterOrReadonlyRef):
84
+ @self._ui_signal_on(value, deep=True)
85
+ def _():
86
+ self.element.set_value(to_raw(to_value(value)) or None)
87
+
88
+ return self
@@ -0,0 +1,40 @@
1
+ from typing import Any
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
+
11
+
12
+ class TooltipBindableUi(BindableUi[ui.tooltip]):
13
+ def __init__(
14
+ self,
15
+ text: TMaybeRef[Any] = "",
16
+ ) -> None:
17
+ pc = ParameterClassifier(locals(), maybeRefs=["text"], events=[])
18
+
19
+ element = ui.tooltip(**pc.get_values_kws())
20
+ super().__init__(element)
21
+
22
+ for key, value in pc.get_bindings().items():
23
+ self.bind_prop(key, value) # type: ignore
24
+
25
+ @property
26
+ def text(self):
27
+ return self.element.text
28
+
29
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
30
+ if prop == "text":
31
+ return self.bind_text(value)
32
+
33
+ return super().bind_prop(prop, value)
34
+
35
+ def bind_text(self, text: TGetterOrReadonlyRef):
36
+ @self._ui_signal_on(text)
37
+ def _():
38
+ self.element.set_text(str(to_value(text)))
39
+
40
+ return self
@@ -36,15 +36,15 @@ class PaginationBindableUi(BindableUi[ui.pagination]):
36
36
  def value(self):
37
37
  return self.element.value
38
38
 
39
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef):
39
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
40
40
  if prop == "value":
41
- return self.bind_value(ref_ui)
41
+ return self.bind_value(value)
42
42
 
43
- return super().bind_prop(prop, ref_ui)
43
+ return super().bind_prop(prop, value)
44
44
 
45
- def bind_value(self, ref_ui: TGetterOrReadonlyRef[int]):
45
+ def bind_value(self, value: TGetterOrReadonlyRef[int]):
46
46
  @self._ui_effect
47
47
  def _():
48
- self.element.set_value(to_value(ref_ui))
48
+ self.element.set_value(to_value(value))
49
49
 
50
50
  return self
@@ -1,9 +1,9 @@
1
1
  from typing import Callable, Dict
2
- from ex4nicegui.utils.signals import to_value
2
+ from ex4nicegui.utils.signals import to_value, to_raw
3
3
 
4
4
 
5
5
  def convert_kws_ref2value(kws: Dict) -> Dict:
6
- return {key: to_value(value) for key, value in kws.items()}
6
+ return {key: to_raw(to_value(value)) for key, value in kws.items()}
7
7
 
8
8
 
9
9
  def inject_method(obj, method_name: str, new_handle: Callable):
@@ -1,13 +1,23 @@
1
- export default {
2
- props: { itemIds: Array },
1
+ const { h, TransitionGroup } = Vue;
3
2
 
3
+ export default {
4
+ props: { itemIds: Array, transitionProps: Object },
4
5
  render() {
6
+ const is_transition = !!this.transitionProps;
5
7
  const slotBox = this.$slots.default()
6
-
7
8
  const slots = this.itemIds.map(({ elementId }) => {
8
9
  return slotBox.find(v => v.key === elementId)
9
10
  });
10
11
 
11
- return slots
12
+ function beforeLeave(el) {
13
+ const { marginLeft, marginTop, width, height } = window.getComputedStyle(el)
14
+ console.log('beforeLeave');
15
+ el.style.left = `${el.offsetLeft - parseFloat(marginLeft, 10)}px`
16
+ el.style.top = `${el.offsetTop - parseFloat(marginTop, 10)}px`
17
+ el.style.width = width
18
+ el.style.height = height
19
+ }
20
+
21
+ return is_transition ? h(TransitionGroup, { ...this.transitionProps, onBeforeLeave: beforeLeave }, slots) : slots;
12
22
  }
13
23
  }