ex4nicegui 0.7.0__py3-none-any.whl → 0.8.0__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 (44) hide show
  1. ex4nicegui/reactive/EChartsComponent/ECharts.js +2 -3
  2. ex4nicegui/reactive/EChartsComponent/ECharts.py +2 -4
  3. ex4nicegui/reactive/__init__.py +6 -0
  4. ex4nicegui/reactive/base.py +3 -1
  5. ex4nicegui/reactive/mermaid/mermaid.py +2 -5
  6. ex4nicegui/reactive/mixins/backgroundColor.py +1 -1
  7. ex4nicegui/reactive/mixins/flexLayout.py +51 -0
  8. ex4nicegui/reactive/mixins/textColor.py +1 -1
  9. ex4nicegui/reactive/mixins/value_element.py +27 -0
  10. ex4nicegui/reactive/officials/avatar.py +86 -0
  11. ex4nicegui/reactive/officials/badge.py +102 -0
  12. ex4nicegui/reactive/officials/card.py +32 -2
  13. ex4nicegui/reactive/officials/checkbox.py +7 -12
  14. ex4nicegui/reactive/officials/chip.py +12 -3
  15. ex4nicegui/reactive/officials/circular_progress.py +7 -11
  16. ex4nicegui/reactive/officials/color_picker.py +4 -10
  17. ex4nicegui/reactive/officials/column.py +19 -11
  18. ex4nicegui/reactive/officials/date.py +4 -11
  19. ex4nicegui/reactive/officials/dialog.py +4 -11
  20. ex4nicegui/reactive/officials/echarts.py +10 -8
  21. ex4nicegui/reactive/officials/expansion.py +4 -11
  22. ex4nicegui/reactive/officials/icon.py +2 -8
  23. ex4nicegui/reactive/officials/image.py +1 -1
  24. ex4nicegui/reactive/officials/input.py +13 -14
  25. ex4nicegui/reactive/officials/knob.py +4 -13
  26. ex4nicegui/reactive/officials/label.py +6 -4
  27. ex4nicegui/reactive/officials/linear_progress.py +6 -11
  28. ex4nicegui/reactive/officials/number.py +8 -12
  29. ex4nicegui/reactive/officials/radio.py +5 -13
  30. ex4nicegui/reactive/officials/row.py +18 -11
  31. ex4nicegui/reactive/officials/select.py +2 -2
  32. ex4nicegui/reactive/officials/slider.py +4 -12
  33. ex4nicegui/reactive/officials/switch.py +5 -13
  34. ex4nicegui/reactive/officials/tab_panels.py +4 -8
  35. ex4nicegui/reactive/officials/tabs.py +4 -9
  36. ex4nicegui/reactive/officials/textarea.py +4 -10
  37. ex4nicegui/reactive/officials/toggle.py +88 -0
  38. ex4nicegui/reactive/officials/tooltip.py +1 -1
  39. ex4nicegui/reactive/systems/reactive_system.py +2 -2
  40. ex4nicegui/reactive/view_model.py +4 -4
  41. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/METADATA +157 -118
  42. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/RECORD +44 -39
  43. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/LICENSE +0 -0
  44. {ex4nicegui-0.7.0.dist-info → ex4nicegui-0.8.0.dist-info}/WHEEL +0 -0
@@ -1,11 +1,11 @@
1
1
  from typing import Any, Callable, List, Optional, TypeVar
2
2
  from typing_extensions import TypedDict
3
3
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
4
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
4
5
 
5
6
  from ex4nicegui.utils.signals import (
6
7
  TGetterOrReadonlyRef,
7
8
  _TMaybeRef as TMaybeRef,
8
- to_value,
9
9
  )
10
10
  from nicegui import ui
11
11
  from .base import BindableUi
@@ -18,7 +18,7 @@ _TDateValue = TypeVar(
18
18
  )
19
19
 
20
20
 
21
- class DateBindableUi(BindableUi[ui.date]):
21
+ class DateBindableUi(BindableUi[ui.date], ValueElementMixin[_TDateValue]):
22
22
  def __init__(
23
23
  self,
24
24
  value: Optional[TMaybeRef[_TDateValue]] = None,
@@ -63,14 +63,7 @@ class DateBindableUi(BindableUi[ui.date]):
63
63
  return self.element.value
64
64
 
65
65
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
66
- if prop == "value":
67
- return self.bind_value(value)
66
+ if ValueElementMixin._bind_specified_props(self, prop, value):
67
+ return self
68
68
 
69
69
  return super().bind_prop(prop, value)
70
-
71
- def bind_value(self, value: TGetterOrReadonlyRef[bool]):
72
- @self._ui_effect
73
- def _():
74
- self.element.set_value(to_value(value))
75
-
76
- return self
@@ -1,15 +1,15 @@
1
1
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
2
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
2
3
  from ex4nicegui.utils.signals import (
3
4
  _TMaybeRef as TMaybeRef,
4
5
  is_setter_ref,
5
- to_value,
6
6
  TGetterOrReadonlyRef,
7
7
  )
8
8
  from nicegui import ui
9
9
  from .base import BindableUi
10
10
 
11
11
 
12
- class DialogBindableUi(BindableUi[ui.dialog]):
12
+ class DialogBindableUi(BindableUi[ui.dialog], ValueElementMixin[bool]):
13
13
  def __init__(
14
14
  self,
15
15
  *,
@@ -36,14 +36,7 @@ class DialogBindableUi(BindableUi[ui.dialog]):
36
36
  return self.element.value
37
37
 
38
38
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
39
- if prop == "value":
40
- return self.bind_value(value)
39
+ if ValueElementMixin._bind_specified_props(self, prop, value):
40
+ return self
41
41
 
42
42
  return super().bind_prop(prop, value)
43
-
44
- def bind_value(self, value: TGetterOrReadonlyRef[float]):
45
- @self._ui_effect
46
- def _():
47
- self.element.set_value(to_value(value))
48
-
49
- return self
@@ -34,7 +34,7 @@ class EChartsBindableUi(BindableUi[echarts]):
34
34
 
35
35
  value_kws = pc.get_values_kws()
36
36
 
37
- element = echarts(**value_kws).classes("grow self-stretch h-[16rem]")
37
+ element = echarts(**value_kws).classes("nicegui-echart")
38
38
 
39
39
  super().__init__(element) # type: ignore
40
40
 
@@ -94,13 +94,14 @@ class EChartsBindableUi(BindableUi[echarts]):
94
94
 
95
95
  @classmethod
96
96
  def from_pyecharts(cls, chart: TMaybeRef):
97
- if is_ref(chart):
97
+ if is_ref(chart) or callable(chart):
98
98
 
99
99
  @ref_computed
100
100
  def chart_opt():
101
- if not bool(chart.value):
101
+ chart_value = to_value(chart)
102
+ if not bool(chart_value):
102
103
  return {}
103
- return PyechartsUtils._chart2opts(chart.value)
104
+ return PyechartsUtils._chart2opts(chart_value)
104
105
 
105
106
  return cls(chart_opt)
106
107
 
@@ -139,7 +140,7 @@ class EChartsBindableUi(BindableUi[echarts]):
139
140
  return super().bind_prop(prop, value)
140
141
 
141
142
  def bind_options(self, options: TGetterOrReadonlyRef[Dict]):
142
- @self._ui_signal_on(options)
143
+ @self._ui_signal_on(options, deep=True)
143
144
  def _():
144
145
  ele = self.element
145
146
  ele.update_options(to_raw(to_value(options)), self.__update_setting)
@@ -228,7 +229,10 @@ class EChartsBindableUi(BindableUi[echarts]):
228
229
  return self
229
230
 
230
231
  def run_chart_method(
231
- self, name: str, *args, timeout: float = 1, check_interval: float = 0.01
232
+ self,
233
+ name: str,
234
+ *args,
235
+ timeout: float = 1,
232
236
  ) -> AwaitableResponse:
233
237
  """Run a method of the JSONEditor instance.
234
238
 
@@ -240,7 +244,6 @@ class EChartsBindableUi(BindableUi[echarts]):
240
244
  :param name: name of the method (a prefix ":" indicates that the arguments are JavaScript expressions)
241
245
  :param args: arguments to pass to the method (Python objects or JavaScript expressions)
242
246
  :param timeout: timeout in seconds (default: 1 second)
243
- :param check_interval: interval in seconds to check for a response (default: 0.01 seconds)
244
247
 
245
248
  :return: AwaitableResponse that can be awaited to get the result of the method call
246
249
  """
@@ -248,7 +251,6 @@ class EChartsBindableUi(BindableUi[echarts]):
248
251
  name,
249
252
  *args,
250
253
  timeout=timeout,
251
- check_interval=check_interval,
252
254
  )
253
255
 
254
256
 
@@ -1,15 +1,15 @@
1
1
  from typing import Any, Optional, Callable
2
2
  from nicegui import ui
3
3
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
4
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
4
5
  from ex4nicegui.utils.signals import (
5
6
  TGetterOrReadonlyRef,
6
7
  _TMaybeRef as TMaybeRef,
7
- to_value,
8
8
  )
9
9
  from .base import BindableUi
10
10
 
11
11
 
12
- class ExpansionBindableUi(BindableUi[ui.expansion]):
12
+ class ExpansionBindableUi(BindableUi[ui.expansion], ValueElementMixin[bool]):
13
13
  def __init__(
14
14
  self,
15
15
  text: Optional[TMaybeRef[str]] = None,
@@ -46,18 +46,11 @@ class ExpansionBindableUi(BindableUi[ui.expansion]):
46
46
  return self.element.value
47
47
 
48
48
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
49
- if prop == "value":
50
- return self.bind_value(value)
49
+ if ValueElementMixin._bind_specified_props(self, prop, value):
50
+ return self
51
51
 
52
52
  return super().bind_prop(prop, value)
53
53
 
54
- def bind_value(self, value: TGetterOrReadonlyRef):
55
- @self._ui_effect
56
- def _():
57
- self.element.set_value(to_value(value))
58
-
59
- return self
60
-
61
54
  def __enter__(self):
62
55
  self.element.__enter__()
63
56
  return self
@@ -1,6 +1,5 @@
1
1
  from typing import (
2
2
  Optional,
3
- cast,
4
3
  )
5
4
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
6
5
  from ex4nicegui.utils.signals import (
@@ -9,9 +8,6 @@ from ex4nicegui.utils.signals import (
9
8
  to_value,
10
9
  )
11
10
  from nicegui import ui
12
- from nicegui.elements.mixins.color_elements import (
13
- TextColorElement,
14
- )
15
11
  from .base import BindableUi
16
12
  from ex4nicegui.reactive.mixins.textColor import TextColorableMixin
17
13
 
@@ -44,10 +40,8 @@ class IconBindableUi(BindableUi[ui.icon], TextColorableMixin):
44
40
  return super().bind_prop(prop, value)
45
41
 
46
42
  def bind_name(self, name: TGetterOrReadonlyRef):
47
- @self._ui_effect
43
+ @self._ui_signal_on(name)
48
44
  def _():
49
- ele = cast(TextColorElement, self.element)
50
- ele._props["name"] = to_value(name)
51
- ele.update()
45
+ self.element.set_name(to_value(name))
52
46
 
53
47
  return self
@@ -32,6 +32,6 @@ class ImageBindableUi(BindableUi[ui.image]):
32
32
  return super().bind_prop(prop, value)
33
33
 
34
34
  def bind_source(self, source: TGetterOrReadonlyRef[Union[str, Path]]):
35
- @self._ui_effect
35
+ @self._ui_signal_on(source, deep=False)
36
36
  def _():
37
37
  self.element.set_source(to_value(source))
@@ -1,4 +1,4 @@
1
- from typing import Any, Callable, List, Optional, Dict, cast
1
+ from typing import Any, Callable, List, Optional, Dict, Union, cast
2
2
 
3
3
 
4
4
  from ex4nicegui.utils.signals import (
@@ -13,9 +13,14 @@ from nicegui import ui
13
13
  from nicegui.events import handle_event
14
14
  from .base import BindableUi, DisableableMixin
15
15
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
16
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
16
17
 
17
18
 
18
- class InputBindableUi(BindableUi[ui.input], DisableableMixin):
19
+ class InputBindableUi(
20
+ BindableUi[ui.input],
21
+ DisableableMixin,
22
+ ValueElementMixin[str],
23
+ ):
19
24
  def __init__(
20
25
  self,
21
26
  label: Optional[TMaybeRef[str]] = None,
@@ -26,7 +31,9 @@ class InputBindableUi(BindableUi[ui.input], DisableableMixin):
26
31
  password_toggle_button: TMaybeRef[bool] = False,
27
32
  on_change: Optional[Callable[..., Any]] = None,
28
33
  autocomplete: Optional[TMaybeRef[List[str]]] = None,
29
- validation: Dict[str, Callable[..., bool]] = {},
34
+ validation: Optional[
35
+ Union[Callable[..., Optional[str]], Dict[str, Callable[..., bool]]]
36
+ ] = None,
30
37
  ) -> None:
31
38
  pc = ParameterClassifier(
32
39
  locals(),
@@ -52,23 +59,15 @@ class InputBindableUi(BindableUi[ui.input], DisableableMixin):
52
59
  self.bind_prop(key, value) # type: ignore
53
60
 
54
61
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
55
- if prop == "value":
56
- return self.bind_value(value)
62
+ if ValueElementMixin._bind_specified_props(self, prop, value):
63
+ return self
57
64
  if prop == "password":
58
65
  return self.bind_password(value)
59
66
 
60
67
  return super().bind_prop(prop, value)
61
68
 
62
- def bind_value(self, value: TGetterOrReadonlyRef[str]):
63
- @self._ui_effect
64
- def _():
65
- self.element.set_value(to_value(value))
66
- self.element.update()
67
-
68
- return self
69
-
70
69
  def bind_password(self, password: TGetterOrReadonlyRef[bool]):
71
- @self._ui_effect
70
+ @self._ui_signal_on(password)
72
71
  def _():
73
72
  self.element._props["type"] = "password" if to_value(password) else "text"
74
73
  self.element.update()
@@ -6,18 +6,16 @@ from typing import (
6
6
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
7
7
  from ex4nicegui.utils.signals import (
8
8
  _TMaybeRef as TMaybeRef,
9
- to_value,
10
9
  TGetterOrReadonlyRef,
11
10
  )
12
11
  from nicegui import ui
13
12
  from .base import BindableUi, DisableableMixin
14
13
  from ex4nicegui.reactive.mixins.textColor import TextColorableMixin
14
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
15
15
 
16
16
 
17
17
  class KnobBindableUi(
18
- BindableUi[ui.knob],
19
- DisableableMixin,
20
- TextColorableMixin,
18
+ BindableUi[ui.knob], DisableableMixin, TextColorableMixin, ValueElementMixin[float]
21
19
  ):
22
20
  def __init__(
23
21
  self,
@@ -62,16 +60,9 @@ class KnobBindableUi(
62
60
  return self.element.value
63
61
 
64
62
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
65
- if prop == "value":
66
- return self.bind_value(value)
63
+ if ValueElementMixin._bind_specified_props(self, prop, value):
64
+ return self
67
65
  if prop == "color":
68
66
  return self.bind_color(value)
69
67
 
70
68
  return super().bind_prop(prop, value)
71
-
72
- def bind_value(self, value: TGetterOrReadonlyRef[float]):
73
- @self._ui_effect
74
- def _():
75
- self.element.set_value(to_value(value))
76
-
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():
@@ -37,9 +40,8 @@ class LabelBindableUi(BindableUi[ui.label], HtmlTextColorableMixin):
37
40
  return super().bind_prop(prop, value)
38
41
 
39
42
  def bind_text(self, text: TGetterOrReadonlyRef):
40
- @self._ui_effect
43
+ @self._ui_signal_on(text, deep=True)
41
44
  def _():
42
- self.element.set_text(str(to_value(text)))
43
- self.element.update()
45
+ self.element.set_text(str(to_raw(to_value(text))))
44
46
 
45
47
  return self
@@ -5,15 +5,17 @@ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
5
5
  from ex4nicegui.utils.signals import (
6
6
  TGetterOrReadonlyRef,
7
7
  _TMaybeRef as TMaybeRef,
8
- to_value,
9
8
  )
10
9
  from nicegui import ui
11
10
 
12
11
  from .base import BindableUi
13
12
  from ex4nicegui.reactive.mixins.textColor import TextColorableMixin
13
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
14
14
 
15
15
 
16
- class LinearProgressBindableUi(BindableUi[ui.linear_progress], TextColorableMixin):
16
+ class LinearProgressBindableUi(
17
+ BindableUi[ui.linear_progress], TextColorableMixin, ValueElementMixin[float]
18
+ ):
17
19
  def __init__(
18
20
  self,
19
21
  value: TMaybeRef[float] = 0.0,
@@ -47,17 +49,10 @@ class LinearProgressBindableUi(BindableUi[ui.linear_progress], TextColorableMixi
47
49
  return self.element.value
48
50
 
49
51
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
50
- if prop == "value":
51
- return self.bind_value(value)
52
+ if ValueElementMixin._bind_specified_props(self, prop, value):
53
+ return self
52
54
 
53
55
  if prop == "color":
54
56
  return self.bind_color(value)
55
57
 
56
58
  return super().bind_prop(prop, value)
57
-
58
- def bind_value(self, value: TGetterOrReadonlyRef):
59
- @self._ui_effect
60
- def _():
61
- self.element.set_value(to_value(value))
62
-
63
- return self
@@ -7,6 +7,7 @@ from typing import (
7
7
  Union,
8
8
  )
9
9
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
10
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
10
11
  from ex4nicegui.utils.signals import (
11
12
  TGetterOrReadonlyRef,
12
13
  _TMaybeRef as TMaybeRef,
@@ -22,7 +23,7 @@ def _default_vmodel_args_getter(e):
22
23
  return e.sender.value
23
24
 
24
25
 
25
- class NumberBindableUi(BindableUi[ui.number]):
26
+ class NumberBindableUi(BindableUi[ui.number], ValueElementMixin[Union[float, int]]):
26
27
  def __init__(
27
28
  self,
28
29
  label: Optional[TMaybeRef[str]] = None,
@@ -37,7 +38,9 @@ class NumberBindableUi(BindableUi[ui.number]):
37
38
  suffix: Optional[TMaybeRef[str]] = None,
38
39
  format: Optional[TMaybeRef[str]] = None,
39
40
  on_change: Optional[Callable[..., Any]] = None,
40
- validation: Dict[str, Callable[..., bool]] = {},
41
+ validation: Optional[
42
+ Union[Callable[..., Optional[str]], Dict[str, Callable[..., bool]]]
43
+ ] = None,
41
44
  ) -> None:
42
45
  pc = ParameterClassifier(
43
46
  locals(),
@@ -71,23 +74,16 @@ class NumberBindableUi(BindableUi[ui.number]):
71
74
  return self.element.value
72
75
 
73
76
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
74
- if prop == "value":
75
- return self.bind_value(value)
77
+ if ValueElementMixin._bind_specified_props(self, prop, value):
78
+ return self
76
79
 
77
80
  if prop == "precision":
78
81
  return self._bind_precision(value)
79
82
 
80
83
  return super().bind_prop(prop, value)
81
84
 
82
- def bind_value(self, value: TGetterOrReadonlyRef[float]):
83
- @self._ui_effect
84
- def _():
85
- self.element.set_value(to_value(value))
86
-
87
- return self
88
-
89
85
  def _bind_precision(self, precision: TGetterOrReadonlyRef[int]):
90
- @self._ui_signal_on(precision, onchanges=True)
86
+ @self._ui_signal_on(precision)
91
87
  def _():
92
88
  self.element.precision = to_value(precision)
93
89
  self.element.sanitize()
@@ -4,7 +4,6 @@ from typing import (
4
4
  List,
5
5
  Optional,
6
6
  TypeVar,
7
- cast,
8
7
  Dict,
9
8
  Union,
10
9
  )
@@ -15,13 +14,13 @@ from ex4nicegui.utils.signals import (
15
14
  to_value,
16
15
  )
17
16
  from nicegui import ui
18
- from nicegui.elements.mixins.value_element import ValueElement
17
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
19
18
  from .base import BindableUi
20
19
 
21
20
  T = TypeVar("T")
22
21
 
23
22
 
24
- class RadioBindableUi(BindableUi[ui.radio]):
23
+ class RadioBindableUi(BindableUi[ui.radio], ValueElementMixin[Any]):
25
24
  def __init__(
26
25
  self,
27
26
  options: Union[TMaybeRef[List], TMaybeRef[Dict]],
@@ -52,8 +51,8 @@ class RadioBindableUi(BindableUi[ui.radio]):
52
51
  return self.element.value
53
52
 
54
53
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
55
- if prop == "value":
56
- return self.bind_value(value)
54
+ if ValueElementMixin._bind_specified_props(self, prop, value):
55
+ return self
57
56
 
58
57
  if prop == "options":
59
58
  return self.bind_options(value)
@@ -61,15 +60,8 @@ class RadioBindableUi(BindableUi[ui.radio]):
61
60
  return super().bind_prop(prop, value)
62
61
 
63
62
  def bind_options(self, options: TGetterOrReadonlyRef):
64
- @self._ui_effect
63
+ @self._ui_signal_on(options, deep=True)
65
64
  def _():
66
65
  self.element.set_options(to_value(options))
67
66
 
68
67
  return self
69
-
70
- def bind_value(self, value: TGetterOrReadonlyRef):
71
- @self._ui_effect
72
- def _():
73
- cast(ValueElement, self.element).set_value(to_value(value))
74
-
75
- return self
@@ -1,17 +1,25 @@
1
1
  from typing import (
2
2
  Any,
3
+ Literal,
4
+ Optional,
3
5
  )
4
6
  from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
5
- from ex4nicegui.utils.signals import (
6
- _TMaybeRef as TMaybeRef,
7
- )
7
+ from ex4nicegui.reactive.mixins.flexLayout import FlexAlignItemsMixin, FlexWrapMixin
8
+ from ex4nicegui.utils.signals import TMaybeRef
8
9
  from nicegui import ui
9
10
  from .base import BindableUi
10
11
 
11
12
 
12
- class RowBindableUi(BindableUi[ui.row]):
13
- def __init__(self, *, wrap: TMaybeRef[bool] = True) -> None:
14
- pc = ParameterClassifier(locals(), maybeRefs=["wrap"], events=[])
13
+ class RowBindableUi(BindableUi[ui.row], FlexAlignItemsMixin, FlexWrapMixin):
14
+ def __init__(
15
+ self,
16
+ *,
17
+ wrap: TMaybeRef[bool] = True,
18
+ align_items: Optional[
19
+ TMaybeRef[Literal["start", "end", "center", "baseline", "stretch"]]
20
+ ] = None,
21
+ ) -> None:
22
+ pc = ParameterClassifier(locals(), maybeRefs=["wrap", "align_items"], events=[])
15
23
  element = ui.row(**pc.get_values_kws())
16
24
 
17
25
  super().__init__(element)
@@ -19,14 +27,13 @@ class RowBindableUi(BindableUi[ui.row]):
19
27
  self.bind_prop(key, value) # type: ignore
20
28
 
21
29
  def bind_prop(self, prop: str, value: TMaybeRef):
22
- if prop == "wrap":
23
- return self.bind_wrap(value)
30
+ if FlexAlignItemsMixin._bind_specified_props(self, prop, value):
31
+ return self
32
+ if FlexWrapMixin._bind_specified_props(self, prop, value):
33
+ return self
24
34
 
25
35
  return super().bind_prop(prop, value)
26
36
 
27
- def bind_wrap(self, value: TMaybeRef):
28
- self.bind_classes({"wrap": value})
29
-
30
37
  def __enter__(self):
31
38
  self.element.__enter__()
32
39
  return self
@@ -84,14 +84,14 @@ class SelectBindableUi(BindableUi[ui.select]):
84
84
  return super().bind_prop(prop, value)
85
85
 
86
86
  def bind_options(self, options: TGetterOrReadonlyRef):
87
- @self._ui_effect()
87
+ @self._ui_signal_on(options, deep=True)
88
88
  def _():
89
89
  self.element.set_options(to_value(options))
90
90
 
91
91
  return self
92
92
 
93
93
  def bind_value(self, value: TGetterOrReadonlyRef):
94
- @self._ui_effect()
94
+ @self._ui_signal_on(value, deep=True)
95
95
  def _():
96
96
  cast(ValueElement, self.element).set_value(to_raw(to_value(value)) or None)
97
97
 
@@ -16,14 +16,14 @@ from ex4nicegui.utils.signals import (
16
16
  from nicegui import ui
17
17
  from nicegui.events import handle_event
18
18
  from .base import BindableUi, DisableableMixin
19
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
19
20
 
20
21
 
21
22
  _TSliderValue = TypeVar("_TSliderValue", float, int, None)
22
23
 
23
24
 
24
25
  class SliderBindableUi(
25
- BindableUi[ui.slider],
26
- DisableableMixin,
26
+ BindableUi[ui.slider], DisableableMixin, ValueElementMixin[_TSliderValue]
27
27
  ):
28
28
  def __init__(
29
29
  self,
@@ -59,19 +59,11 @@ class SliderBindableUi(
59
59
  return self.element.value
60
60
 
61
61
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
62
- if prop == "value":
63
- return self.bind_value(value)
62
+ if ValueElementMixin._bind_specified_props(self, prop, value):
63
+ return self
64
64
 
65
65
  return super().bind_prop(prop, value)
66
66
 
67
- def bind_value(self, value: TGetterOrReadonlyRef[float]):
68
- @self._ui_effect
69
- def _():
70
- self.element.set_value(to_value(value))
71
- self.element.update()
72
-
73
- return self
74
-
75
67
 
76
68
  class LazySliderBindableUi(SliderBindableUi):
77
69
  def __init__(
@@ -8,15 +8,16 @@ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
8
8
  from ex4nicegui.utils.signals import (
9
9
  TGetterOrReadonlyRef,
10
10
  _TMaybeRef as TMaybeRef,
11
- to_value,
12
11
  )
13
12
  from nicegui import ui
14
13
  from .base import BindableUi
14
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
15
+
15
16
 
16
17
  T = TypeVar("T")
17
18
 
18
19
 
19
- class SwitchBindableUi(BindableUi[ui.switch]):
20
+ class SwitchBindableUi(BindableUi[ui.switch], ValueElementMixin[bool]):
20
21
  def __init__(
21
22
  self,
22
23
  text: TMaybeRef[str] = "",
@@ -35,7 +36,6 @@ class SwitchBindableUi(BindableUi[ui.switch]):
35
36
  )
36
37
 
37
38
  value_kws = pc.get_values_kws()
38
- value_kws.update({"value": 0 if value is None else value})
39
39
 
40
40
  element = ui.switch(**value_kws)
41
41
  super().__init__(element) # type: ignore
@@ -48,14 +48,6 @@ class SwitchBindableUi(BindableUi[ui.switch]):
48
48
  return self.element.value
49
49
 
50
50
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
51
- if prop == "value":
52
- return self.bind_value(value)
53
-
51
+ if ValueElementMixin._bind_specified_props(self, prop, value):
52
+ return self
54
53
  return super().bind_prop(prop, value)
55
-
56
- def bind_value(self, value: TGetterOrReadonlyRef[bool]):
57
- @self._ui_effect
58
- def _():
59
- self.element.set_value(to_value(value))
60
-
61
- return self
@@ -10,9 +10,10 @@ from ex4nicegui.utils.signals import (
10
10
  from ex4nicegui.utils.scheduler import next_tick
11
11
  from nicegui import ui, background_tasks, core
12
12
  from .base import BindableUi
13
+ from ex4nicegui.reactive.mixins.value_element import ValueElementMixin
13
14
 
14
15
 
15
- class TabPanelsBindableUi(BindableUi[ui.tab_panels]):
16
+ class TabPanelsBindableUi(BindableUi[ui.tab_panels], ValueElementMixin[bool]):
16
17
  def __init__(
17
18
  self,
18
19
  value: Optional[TMaybeRef[str]] = None,
@@ -50,16 +51,11 @@ class TabPanelsBindableUi(BindableUi[ui.tab_panels]):
50
51
  return self.element.value
51
52
 
52
53
  def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
53
- if prop == "value":
54
- return self.bind_value(value)
54
+ if ValueElementMixin._bind_specified_props(self, prop, value):
55
+ return self
55
56
 
56
57
  return super().bind_prop(prop, value)
57
58
 
58
- def bind_value(self, value: TGetterOrReadonlyRef):
59
- @self._ui_effect
60
- def _():
61
- self.element.set_value(to_value(value))
62
-
63
59
 
64
60
  class lazy_tab_panel(ui.tab_panel):
65
61
  def __init__(self, name: str) -> None: