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
@@ -228,26 +228,26 @@ class DataSourceFacade(Generic[_TData]):
228
228
 
229
229
  Support pyecharts
230
230
 
231
- ```py
232
- import pandas as pd
233
- from ex4nicegui import bi
234
- from pyecharts.charts import Bar
235
-
236
- df = pd.DataFrame({"name": list("abcdc"), "value": range(5)})
237
- ds = bi.data_source(df)
238
-
239
- @ds.ui_echarts
240
- def bar(data: pd.DataFrame):
241
- c = (
242
- Bar()
243
- .add_xaxis(data["name"].tolist())
244
- .add_yaxis("value", data["value"].tolist())
245
- )
246
-
247
- return c
248
-
249
- bar.classes("h-[20rem]")
250
- ```
231
+ .. code-block:: python
232
+ import pandas as pd
233
+ from ex4nicegui import bi
234
+ from pyecharts.charts import Bar
235
+
236
+ df = pd.DataFrame({"name": list("abcdc"), "value": range(5)})
237
+ ds = bi.data_source(df)
238
+
239
+ @ds.ui_echarts
240
+ def bar(data: pd.DataFrame):
241
+ c = (
242
+ Bar()
243
+ .add_xaxis(data["name"].tolist())
244
+ .add_yaxis("value", data["value"].tolist())
245
+ )
246
+
247
+ return c
248
+
249
+ bar.classes("h-[20rem]")
250
+
251
251
 
252
252
  """
253
253
  return ui_echarts(self, fn)
ex4nicegui/bi/index.py CHANGED
@@ -24,43 +24,40 @@ def data_source(data: Union[Callable[..., _TData], _TData]) -> DataSourceFacade[
24
24
 
25
25
  ## Examples
26
26
 
27
- ---
28
-
29
27
  pandas dataframe source:
30
- ```python
31
- df = pd.DataFrame({"name": list("abcdc"), "value": range(5)})
32
- ds = bi.data_source(df)
33
- ```
28
+
29
+ .. code-block:: python
30
+ df = pd.DataFrame({"name": list("abcdc"), "value": range(5)})
31
+ ds = bi.data_source(df)
32
+
34
33
 
35
34
  ---
36
35
 
37
36
  Link multiple data sources
38
37
 
39
- ---
40
- ```python
41
- df = pd.DataFrame({"name": list("abcdc"), "value": range(5)})
42
- ds = bi.data_source(df)
38
+ .. code-block:: python
39
+ df = pd.DataFrame({"name": list("abcdc"), "value": range(5)})
40
+ ds = bi.data_source(df)
43
41
 
44
- @bi.data_source
45
- def ds_other():
46
- # ds.filtered_data is DataFrame after filtering
47
- where = ds.filtered_data[''].isin(['b','c','d'])
48
- return ds.filtered_data[where]
42
+ @bi.data_source
43
+ def ds_other():
44
+ # ds.filtered_data is DataFrame after filtering
45
+ where = ds.filtered_data[''].isin(['b','c','d'])
46
+ return ds.filtered_data[where]
49
47
 
50
- ```
51
48
 
52
49
  ---
53
50
 
54
51
  Now, when `ds` changes, it will trigger changes to `ds_other` and thus drive the related interface components to change.
55
52
 
56
- ```python
57
- # select box of data source 'ds'
58
- # it change will trigger changes to table
59
- ds.ui_select('name')
53
+ .. code-block:: python
54
+ # select box of data source 'ds'
55
+ # it change will trigger changes to table
56
+ ds.ui_select('name')
57
+
58
+ # table of data 'ds_other'
59
+ ds_other.ui_aggrid()
60
60
 
61
- # table of data 'ds_other'
62
- ds_other.ui_aggrid()
63
- ```
64
61
 
65
62
 
66
63
  """
@@ -64,14 +64,15 @@ class echarts(Element, component="ECharts.js", libraries=libraries): # type: ig
64
64
  Args:
65
65
  options (dict): chart setting options dict
66
66
  opts (Optional[dict], optional): update options. Defaults to None.
67
- ```python
68
- {
69
- 'notMerge':False,
70
- 'lazyUpdate':False,
71
- 'silent':False,
72
- 'replaceMerge': None,
73
- }
74
- ```
67
+
68
+ .. code-block:: python
69
+ {
70
+ 'notMerge':False,
71
+ 'lazyUpdate':False,
72
+ 'silent':False,
73
+ 'replaceMerge': None,
74
+ }
75
+
75
76
  [open echarts setOption docs](https://echarts.apache.org/zh/api.html#echartsInstance.setOption)
76
77
 
77
78
  """
@@ -54,6 +54,10 @@ from .officials.element import ElementBindableUi as element
54
54
  from .officials.tab_panels import LazyTabPanelsBindableUi as lazy_tab_panels
55
55
  from .q_pagination import PaginationBindableUi as q_pagination
56
56
  from .officials.chip import ChipBindableUi as chip
57
+ from .officials.tooltip import TooltipBindableUi as tooltip
58
+ from .officials.toggle import ToggleBindableUi as toggle
59
+ from .officials.avatar import AvatarBindableUi as avatar
60
+ from .officials.badge import BadgeBindableUi as badge
57
61
 
58
62
  from .local_file_picker import local_file_picker
59
63
  from .UseDraggable.UseDraggable import use_draggable
@@ -63,8 +67,10 @@ from .usePagination import PaginationRef as use_pagination
63
67
  from .dropZone.dropZone import use_drag_zone
64
68
  from .fileWatcher import FilesWatcher
65
69
  from .mermaid.mermaid import Mermaid as mermaid
70
+ from .officials.dialog import DialogBindableUi as dialog
66
71
  from .vfor import vfor, VforStore
67
72
  from .vmodel import vmodel
73
+ from .view_model import ViewModel, var, cached_var
68
74
 
69
75
  pagination = q_pagination
70
76
 
@@ -88,6 +94,9 @@ __all__ = [
88
94
  "vfor",
89
95
  "VforStore",
90
96
  "vmodel",
97
+ "ViewModel",
98
+ "var",
99
+ "cached_var",
91
100
  "html",
92
101
  "aggrid",
93
102
  "button",
@@ -124,4 +133,9 @@ __all__ = [
124
133
  "pagination",
125
134
  "mermaid",
126
135
  "chip",
136
+ "dialog",
137
+ "tooltip",
138
+ "toggle",
139
+ "avatar",
140
+ "badge",
127
141
  ]
@@ -24,6 +24,7 @@ from ex4nicegui.utils.signals import (
24
24
  on,
25
25
  )
26
26
  from ex4nicegui.utils.clientScope import new_scope
27
+ from ex4nicegui.utils.types import _TMaybeRef as TMaybeRef
27
28
  from nicegui import Tailwind, ui
28
29
  from nicegui.elements.mixins.text_element import TextElement
29
30
  from ex4nicegui.reactive.services.reactive_service import inject_handle_delete
@@ -72,7 +73,9 @@ class BindableUi(Generic[TWidget]):
72
73
 
73
74
  @property
74
75
  def _ui_signal_on(self):
75
- return partial(on, scope=self._effect_scope)
76
+ """equivalent to `on`, but with the effect scope,and with `onchanges`=True and `deep` = False"""
77
+
78
+ return partial(on, scope=self._effect_scope, onchanges=True, deep=False)
76
79
 
77
80
  def props(self, add: Optional[str] = None, *, remove: Optional[str] = None):
78
81
  cast(ui.element, self.element).props(add, remove=remove)
@@ -105,8 +108,12 @@ class BindableUi(Generic[TWidget]):
105
108
  def __exit__(self, *_):
106
109
  self.element.default_slot.__exit__(*_)
107
110
 
108
- def tooltip(self, text: str) -> Self:
109
- cast(ui.element, self.element).tooltip(text)
111
+ def tooltip(self, text: TMaybeRef[str]) -> Self:
112
+ from ex4nicegui.reactive.officials.tooltip import TooltipBindableUi
113
+
114
+ with self:
115
+ TooltipBindableUi(text)
116
+
110
117
  return self
111
118
 
112
119
  def add_slot(self, name: str, template: Optional[str] = None):
@@ -143,7 +150,7 @@ class BindableUi(Generic[TWidget]):
143
150
  """
144
151
  return self.element.remove(element)
145
152
 
146
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef[Any]):
153
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef[Any]):
147
154
  """data binding is manipulating an element's property
148
155
 
149
156
  @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bind_prop
@@ -151,37 +158,37 @@ class BindableUi(Generic[TWidget]):
151
158
 
152
159
  Args:
153
160
  prop (str): property name
154
- ref_ui (TGetterOrReadonlyRef[Any]): a reference to the value to bind to
161
+ value (TGetterOrReadonlyRef[Any]): a reference to the value to bind to
155
162
 
156
163
  """
157
164
  if prop == "visible":
158
- return self.bind_visible(ref_ui)
165
+ return self.bind_visible(value)
159
166
 
160
167
  if prop == "text" and isinstance(self.element, TextElement):
161
168
 
162
169
  @self._ui_effect
163
170
  def _():
164
- cast(TextElement, self.element).set_text(to_value(ref_ui))
171
+ cast(TextElement, self.element).set_text(to_value(value))
165
172
  self.element.update()
166
173
 
167
174
  @self._ui_effect
168
175
  def _():
169
176
  element = cast(ui.element, self.element)
170
- element._props[prop] = to_value(ref_ui)
177
+ element._props[prop] = to_value(value)
171
178
  element.update()
172
179
 
173
180
  return self
174
181
 
175
- def bind_visible(self, ref_ui: TGetterOrReadonlyRef[bool]):
182
+ def bind_visible(self, value: TGetterOrReadonlyRef[bool]):
176
183
  @self._ui_effect
177
184
  def _():
178
185
  element = cast(ui.element, self.element)
179
- element.set_visibility(to_value(ref_ui))
186
+ element.set_visibility(to_value(value))
180
187
 
181
188
  return self
182
189
 
183
- def bind_not_visible(self, ref_ui: TGetterOrReadonlyRef[bool]):
184
- return self.bind_visible(lambda: not to_value(ref_ui))
190
+ def bind_not_visible(self, value: TGetterOrReadonlyRef[bool]):
191
+ return self.bind_visible(lambda: not to_value(value))
185
192
 
186
193
  def on(
187
194
  self,
@@ -209,22 +216,22 @@ class BindableUi(Generic[TWidget]):
209
216
  cast(ui.element, self.element).clear()
210
217
 
211
218
  @overload
212
- def bind_classes(self, classes: Dict[str, TGetterOrReadonlyRef[bool]]):
219
+ def bind_classes(self, classes: Dict[str, TGetterOrReadonlyRef[bool]]) -> Self:
213
220
  ...
214
221
 
215
222
  @overload
216
- def bind_classes(self, classes: TGetterOrReadonlyRef[Dict[str, bool]]):
223
+ def bind_classes(self, classes: TGetterOrReadonlyRef[Dict[str, bool]]) -> Self:
217
224
  ...
218
225
 
219
226
  @overload
220
- def bind_classes(self, classes: List[TGetterOrReadonlyRef[str]]):
227
+ def bind_classes(self, classes: List[TGetterOrReadonlyRef[str]]) -> Self:
221
228
  ...
222
229
 
223
230
  @overload
224
- def bind_classes(self, classes: TGetterOrReadonlyRef[str]):
231
+ def bind_classes(self, classes: TGetterOrReadonlyRef[str]) -> Self:
225
232
  ...
226
233
 
227
- def bind_classes(self, classes: _T_bind_classes_type):
234
+ def bind_classes(self, classes: _T_bind_classes_type) -> Self:
228
235
  """data binding is manipulating an element's class list
229
236
 
230
237
  @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bind-class-names
@@ -237,30 +244,30 @@ class BindableUi(Generic[TWidget]):
237
244
 
238
245
  bind class names with dict,value is bool ref, for example:
239
246
 
240
- ```python
247
+ .. code-block:: python
241
248
  bg_color = to_ref(True)
242
249
  has_error = to_ref(False)
243
250
 
244
251
  rxui.label('Hello').bind_classes({'bg-blue':bg_color, 'text-red':has_error})
245
- ```
252
+
246
253
 
247
254
  bind list of class names with ref
248
255
 
249
- ```python
256
+ .. code-block:: python
250
257
  color = to_ref('red')
251
258
  bg_color = lambda: f"bg-{color.value}"
252
259
 
253
260
  rxui.label('Hello').bind_classes([bg_color])
254
- ```
261
+
255
262
 
256
263
  bind single class name with ref
257
264
 
258
- ```python
265
+ .. code-block:: python
259
266
  color = to_ref('red')
260
267
  bg_color = lambda: f"bg-{color.value}"
261
268
 
262
269
  rxui.label('Hello').bind_classes(bg_color)
263
- ```
270
+
264
271
 
265
272
  """
266
273
  if isinstance(classes, dict):
@@ -316,17 +323,18 @@ class BindableUi(Generic[TWidget]):
316
323
 
317
324
 
318
325
  ## usage
319
- ```python
320
- bg_color = to_ref("blue")
321
- text_color = to_ref("red")
322
-
323
- rxui.label("test").bind_style(
324
- {
325
- "background-color": bg_color,
326
- "color": text_color,
327
- }
328
- )
329
- ```
326
+
327
+ .. code-block:: python
328
+ bg_color = to_ref("blue")
329
+ text_color = to_ref("red")
330
+
331
+ rxui.label("test").bind_style(
332
+ {
333
+ "background-color": bg_color,
334
+ "color": text_color,
335
+ }
336
+ )
337
+
330
338
  """
331
339
  if isinstance(style, dict):
332
340
  for name, ref_obj in style.items():
@@ -350,27 +358,28 @@ class BindableUi(Generic[TWidget]):
350
358
  style (Union[str, Path]): path to css file or inline style string
351
359
 
352
360
  ## usage
353
- ```python
354
- # all children of the element will have red outline, excluding itself
355
- with rxui.row().scoped_style("*", "outline: 1px solid red;") as row:
356
- ui.label("Hello")
357
- ui.label("World")
358
-
359
- # all children of the element will have red outline, including the element itself
360
- with rxui.row().scoped_style(":self *", "outline: 1px solid red;") as row:
361
- ui.label("Hello")
362
- ui.label("World")
363
-
364
- # all children of the element will have red outline when element is hovered
365
- with rxui.row().scoped_style(":hover *", "outline: 1px solid red;") as row:
366
- ui.label("Hello")
367
- ui.label("World")
368
-
369
- # all children of the element and itself will have red outline when element is hovered
370
- with rxui.row().scoped_style(":self:hover *", "outline: 1px solid red;") as row:
371
- ui.label("Hello")
372
- ui.label("World")
373
- ```
361
+
362
+ .. code-block:: python
363
+ # all children of the element will have red outline, excluding itself
364
+ with rxui.row().scoped_style("*", "outline: 1px solid red;") as row:
365
+ ui.label("Hello")
366
+ ui.label("World")
367
+
368
+ # all children of the element will have red outline, including the element itself
369
+ with rxui.row().scoped_style(":self *", "outline: 1px solid red;") as row:
370
+ ui.label("Hello")
371
+ ui.label("World")
372
+
373
+ # all children of the element will have red outline when element is hovered
374
+ with rxui.row().scoped_style(":hover *", "outline: 1px solid red;") as row:
375
+ ui.label("Hello")
376
+ ui.label("World")
377
+
378
+ # all children of the element and itself will have red outline when element is hovered
379
+ with rxui.row().scoped_style(":self:hover *", "outline: 1px solid red;") as row:
380
+ ui.label("Hello")
381
+ ui.label("World")
382
+
374
383
  """
375
384
 
376
385
  is_css_file = isinstance(style, Path)
@@ -20,8 +20,8 @@ class BackgroundColorableMixin(Protocol):
20
20
  def element(self) -> ui.element:
21
21
  ...
22
22
 
23
- def _bind_background_color(self, ref_ui: TGetterOrReadonlyRef[str]):
24
- @self._ui_signal_on(ref_ui) # type: ignore
23
+ def _bind_background_color(self, value: TGetterOrReadonlyRef[str]):
24
+ @self._ui_signal_on(value, onchanges=False) # type: ignore
25
25
  def _(state: WatchedState):
26
26
  if state.previous is not None:
27
27
  color_system.remove_background_color(self.element, state.previous)
@@ -30,12 +30,12 @@ class BackgroundColorableMixin(Protocol):
30
30
 
31
31
  self.element.update()
32
32
 
33
- def bind_color(self, ref_ui: TGetterOrReadonlyRef[str]):
33
+ def bind_color(self, color: TGetterOrReadonlyRef[str]):
34
34
  """bind color to the element
35
35
 
36
36
  Args:
37
- ref_ui (TGetterOrReadonlyRef[str]): a reference to the color value
37
+ color (TGetterOrReadonlyRef[str]): a reference to the color value
38
38
 
39
39
  """
40
- self._bind_background_color(ref_ui)
40
+ self._bind_background_color(color)
41
41
  return self
@@ -25,20 +25,20 @@ class DisableableMixin(Protocol):
25
25
  def element(self) -> DisableableElement:
26
26
  ...
27
27
 
28
- def bind_enabled(self, ref_ui: TGetterOrReadonlyRef[bool]):
28
+ def bind_enabled(self, value: TGetterOrReadonlyRef[bool]):
29
29
  @self._ui_effect
30
30
  def _():
31
- value = to_value(ref_ui)
32
- self.element.set_enabled(value)
33
- self.element._handle_enabled_change(value)
31
+ raw_value = to_value(value)
32
+ self.element.set_enabled(raw_value)
33
+ self.element._handle_enabled_change(raw_value)
34
34
 
35
35
  return self
36
36
 
37
- def bind_disable(self, ref_ui: TGetterOrReadonlyRef[bool]):
37
+ def bind_disable(self, value: TGetterOrReadonlyRef[bool]):
38
38
  @self._ui_effect
39
39
  def _():
40
- value = not to_value(ref_ui)
41
- self.element.set_enabled(value)
42
- self.element._handle_enabled_change(value)
40
+ raw_value = not to_value(value)
41
+ self.element.set_enabled(raw_value)
42
+ self.element._handle_enabled_change(raw_value)
43
43
 
44
44
  return self
@@ -21,8 +21,8 @@ class TextColorableMixin(Protocol):
21
21
  def element(self) -> ui.element:
22
22
  ...
23
23
 
24
- def _bind_text_color(self, ref_ui: TGetterOrReadonlyRef[str]):
25
- @self._ui_signal_on(ref_ui) # type: ignore
24
+ def _bind_text_color(self, color: TGetterOrReadonlyRef[str]):
25
+ @self._ui_signal_on(color, onchanges=False) # type: ignore
26
26
  def _(state: WatchedState):
27
27
  if state.previous is not None:
28
28
  color_system.remove_text_color(self.element, state.previous)
@@ -31,14 +31,14 @@ class TextColorableMixin(Protocol):
31
31
 
32
32
  self.element.update()
33
33
 
34
- def bind_color(self, ref_ui: TGetterOrReadonlyRef[str]):
34
+ def bind_color(self, color: TGetterOrReadonlyRef[str]):
35
35
  """bind text color to the element
36
36
 
37
37
  Args:
38
- ref_ui (TGetterOrReadonlyRef[str]): a reference to the color value
38
+ color (TGetterOrReadonlyRef[str]): a reference to the color value
39
39
 
40
40
  """
41
- self._bind_text_color(ref_ui)
41
+ self._bind_text_color(color)
42
42
  return self
43
43
 
44
44
 
@@ -52,15 +52,15 @@ class HtmlTextColorableMixin(Protocol):
52
52
  def bind_style(self, style: Dict[str, TGetterOrReadonlyRef[Any]]):
53
53
  ...
54
54
 
55
- def _bind_text_color(self, ref_ui: TGetterOrReadonlyRef[str]):
56
- return self.bind_style({"color": ref_ui})
55
+ def _bind_text_color(self, value: TGetterOrReadonlyRef[str]):
56
+ return self.bind_style({"color": value})
57
57
 
58
- def bind_color(self, ref_ui: TGetterOrReadonlyRef[str]):
58
+ def bind_color(self, color: TGetterOrReadonlyRef[str]):
59
59
  """bind text color to the element
60
60
 
61
61
  Args:
62
- ref_ui (TGetterOrReadonlyRef[str]): a reference to the color value
62
+ color (TGetterOrReadonlyRef[str]): a reference to the color value
63
63
 
64
64
  """
65
- self._bind_text_color(ref_ui)
65
+ self._bind_text_color(color)
66
66
  return self
@@ -78,17 +78,17 @@ class AggridBindableUi(BindableUi[ui.aggrid]):
78
78
  options = {"columnDefs": columnDefs, "rowData": rowData}
79
79
  return cls(options, **org_kws)
80
80
 
81
- def bind_prop(self, prop: str, ref_ui: TGetterOrReadonlyRef[Any]):
81
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef[Any]):
82
82
  if prop == "options":
83
- return self.bind_options(ref_ui)
83
+ return self.bind_options(value)
84
84
 
85
- return super().bind_prop(prop, ref_ui)
85
+ return super().bind_prop(prop, value)
86
86
 
87
- def bind_options(self, ref_ui: TGetterOrReadonlyRef[List[Dict]]):
87
+ def bind_options(self, options: TGetterOrReadonlyRef[List[Dict]]):
88
88
  @self._ui_effect
89
89
  def _():
90
90
  ele = self.element
91
- data = to_value(ref_ui)
91
+ data = to_value(options)
92
92
  ele._props["options"].update(data)
93
93
  ele.update()
94
94
 
@@ -0,0 +1,86 @@
1
+ from typing import Optional
2
+ from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
3
+ from ex4nicegui.utils.signals import (
4
+ TGetterOrReadonlyRef,
5
+ _TMaybeRef as TMaybeRef,
6
+ )
7
+ from nicegui import ui
8
+ from .base import BindableUi
9
+ from ex4nicegui.reactive.mixins.backgroundColor import BackgroundColorableMixin
10
+ from ex4nicegui.reactive.mixins.textColor import TextColorableMixin
11
+
12
+
13
+ class AvatarBindableUi(
14
+ BindableUi[ui.avatar], TextColorableMixin, BackgroundColorableMixin
15
+ ):
16
+ def __init__(
17
+ self,
18
+ icon: Optional[TMaybeRef[str]] = None,
19
+ *,
20
+ color: Optional[TMaybeRef[str]] = "primary",
21
+ text_color: Optional[TMaybeRef[str]] = None,
22
+ size: Optional[TMaybeRef[str]] = None,
23
+ font_size: Optional[TMaybeRef[str]] = None,
24
+ square: TMaybeRef[bool] = False,
25
+ rounded: TMaybeRef[bool] = False,
26
+ ) -> None:
27
+ """Avatar
28
+
29
+ A avatar element wrapping Quasar's
30
+ `QAvatar <https://quasar.dev/vue-components/avatar>`_ component.
31
+
32
+ :param icon: name of the icon or image path with "img:" prefix (e.g. "map", "img:path/to/image.png")
33
+ :param color: background color (either a Quasar, Tailwind, or CSS color or `None`, default: "primary")
34
+ :param text_color: color name from the Quasar Color Palette (e.g. "primary", "teal-10")
35
+ :param size: size in CSS units, including unit name or standard size name (xs|sm|md|lg|xl) (e.g. "16px", "2rem")
36
+ :param font_size: size in CSS units, including unit name, of the content (icon, text) (e.g. "18px", "2rem")
37
+ :param square: removes border-radius so borders are squared (default: False)
38
+ :param rounded: applies a small standard border-radius for a squared shape of the component (default: False)
39
+ """
40
+ pc = ParameterClassifier(
41
+ locals(),
42
+ maybeRefs=[
43
+ "icon",
44
+ "color",
45
+ "text_color",
46
+ "size",
47
+ "font_size",
48
+ "square",
49
+ "rounded",
50
+ ],
51
+ events=[],
52
+ )
53
+
54
+ init_kws = pc.get_values_kws()
55
+ element = ui.avatar(**init_kws)
56
+ super().__init__(element)
57
+
58
+ for key, value in pc.get_bindings().items():
59
+ self.bind_prop(key, value) # type: ignore
60
+
61
+ def bind_prop(self, prop: str, value: TGetterOrReadonlyRef):
62
+ if prop == "color":
63
+ return self.bind_color(value)
64
+ if prop == "text-color":
65
+ return self.bind_text_color(value)
66
+
67
+ return super().bind_prop(prop, value)
68
+
69
+ def bind_color(self, color: TGetterOrReadonlyRef):
70
+ """Binds the background color property of the chip to a ui element.
71
+
72
+ Args:
73
+ color (TGetterOrReadonlyRef): background color ui element or getter function
74
+
75
+ """
76
+ BackgroundColorableMixin.bind_color(self, color)
77
+ return self
78
+
79
+ def bind_text_color(self, color: TGetterOrReadonlyRef):
80
+ """Binds the text color property of the chip to a ui element.
81
+
82
+ Args:
83
+ color (TGetterOrReadonlyRef): text color ui element or getter function
84
+ """
85
+ TextColorableMixin.bind_color(self, color)
86
+ return self