ex4nicegui 0.4.5__tar.gz → 0.4.7__tar.gz

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 (111) hide show
  1. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/PKG-INFO +1 -1
  2. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/README.md +217 -0
  3. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/__init__.py +1 -1
  4. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/dataSourceFacade.py +75 -21
  5. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/index.py +1 -1
  6. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/aggrid.py +4 -9
  7. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/base.py +79 -4
  8. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/echarts.py +2 -0
  9. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/number.py +10 -8
  10. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/table.py +7 -18
  11. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/utils/signals.py +51 -0
  12. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui.egg-info/PKG-INFO +1 -1
  13. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui.egg-info/requires.txt +1 -1
  14. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/setup.py +1 -1
  15. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/LICENSE +0 -0
  16. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/__init__.py +0 -0
  17. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/dataSource.py +0 -0
  18. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/__init__.py +0 -0
  19. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/containers.py +0 -0
  20. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/layouts.py +0 -0
  21. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/models.py +0 -0
  22. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/text.py +0 -0
  23. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_aggrid.py +0 -0
  24. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_date_picker.js +0 -0
  25. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_date_picker.py +0 -0
  26. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_echarts.py +0 -0
  27. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_radio.py +0 -0
  28. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_range.py +0 -0
  29. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_select.py +0 -0
  30. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_slider.py +0 -0
  31. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/elements/ui_table.py +0 -0
  32. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/protocols.py +0 -0
  33. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/bi/types.py +0 -0
  34. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/experimental_/__init__.py +0 -0
  35. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/experimental_/gridLayout/__init__.py +0 -0
  36. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/experimental_/gridLayout/index.py +0 -0
  37. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/__init__.py +0 -0
  38. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/gridFlex/GridFlex.js +0 -0
  39. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/gridFlex/__init__.py +0 -0
  40. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/gridFlex/gridFlex.py +0 -0
  41. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/gridFlex/utils.py +0 -0
  42. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/rxFlex/__init__.py +0 -0
  43. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/rxFlex/index.py +0 -0
  44. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/layout/rxFlex/types.py +0 -0
  45. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/EChartsComponent/ECharts.js +0 -0
  46. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/EChartsComponent/ECharts.py +0 -0
  47. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/EChartsComponent/__init__.py +0 -0
  48. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/UseDraggable/UseDraggable.js +0 -0
  49. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/UseDraggable/UseDraggable.py +0 -0
  50. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/UseDraggable/__init__.py +0 -0
  51. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/__index.py +0 -0
  52. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/__init__.py +0 -0
  53. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/drawer.py +0 -0
  54. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/dropZone/__init__.py +0 -0
  55. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/dropZone/dropZone.js +0 -0
  56. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/dropZone/dropZone.py +0 -0
  57. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/fileWatcher.py +0 -0
  58. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/__init__.py +0 -0
  59. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/__init__.py +0 -0
  60. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-color.ems.js +0 -0
  61. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-dispatch.ems.js +0 -0
  62. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-drag.ems.js +0 -0
  63. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-ease.ems.js +0 -0
  64. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-interpolate.ems.js +0 -0
  65. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-selection.ems.js +0 -0
  66. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-timer.ems.js +0 -0
  67. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-transition.ems.js +0 -0
  68. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/libs/d3/d3-zoom.ems.js +0 -0
  69. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/local_file_picker.py +0 -0
  70. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/mermaid/__init__.py +0 -0
  71. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/mermaid/mermaid.js +0 -0
  72. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/mermaid/mermaid.py +0 -0
  73. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/__init__.py +0 -0
  74. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/button.py +0 -0
  75. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/card.py +0 -0
  76. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/checkbox.py +0 -0
  77. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/color_picker.py +0 -0
  78. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/column.py +0 -0
  79. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/date.py +0 -0
  80. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/drawer.py +0 -0
  81. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/expansion.py +0 -0
  82. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/grid.py +0 -0
  83. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/html.py +0 -0
  84. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/icon.py +0 -0
  85. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/image.py +0 -0
  86. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/input.py +0 -0
  87. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/label.py +0 -0
  88. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/radio.py +0 -0
  89. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/row.py +0 -0
  90. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/select.py +0 -0
  91. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/slider.py +0 -0
  92. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/switch.py +0 -0
  93. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/textarea.py +0 -0
  94. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/upload.py +0 -0
  95. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/officials/utils.py +0 -0
  96. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/q_pagination.py +0 -0
  97. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/rxui.py +0 -0
  98. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/useMouse/UseMouse.js +0 -0
  99. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/useMouse/UseMouse.py +0 -0
  100. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/useMouse/__init__.py +0 -0
  101. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/reactive/usePagination.py +0 -0
  102. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/tools/__init__.py +0 -0
  103. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/tools/debug.py +0 -0
  104. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/utils/__init__.py +0 -0
  105. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/utils/clientScope.py +0 -0
  106. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui/utils/common.py +0 -0
  107. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui.egg-info/SOURCES.txt +0 -0
  108. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui.egg-info/dependency_links.txt +0 -0
  109. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui.egg-info/not-zip-safe +0 -0
  110. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/ex4nicegui.egg-info/top_level.txt +0 -0
  111. {ex4nicegui-0.4.5 → ex4nicegui-0.4.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ex4nicegui
3
- Version: 0.4.5
3
+ Version: 0.4.7
4
4
  Summary: ...
5
5
  Home-page:
6
6
  Author: carson_jia
@@ -159,6 +159,223 @@ ui.run()
159
159
  ```
160
160
 
161
161
 
162
+ ## 组件功能
163
+
164
+ ### 绑定类名
165
+
166
+ 所有的组件类提供 `bind_classes` 用于绑定 `class`,支持三种不同的数据结构。
167
+
168
+ 绑定字典
169
+
170
+ ```python
171
+ bg_color = to_ref(False)
172
+ has_error = to_ref(False)
173
+
174
+ rxui.label("test").bind_classes({"bg-blue": bg_color, "text-red": has_error})
175
+
176
+ rxui.switch("bg_color", value=bg_color)
177
+ rxui.switch("has_error", value=has_error)
178
+ ```
179
+
180
+ 字典键值为类名,对应值为 bool 的响应式变量。当响应式值为 `True`,类名应用到组件 class
181
+
182
+
183
+ ---
184
+
185
+ 绑定返回值为字典的响应式变量
186
+
187
+ ```python
188
+ bg_color = to_ref(False)
189
+ has_error = to_ref(False)
190
+
191
+ class_obj = ref_computed(
192
+ lambda: {"bg-blue": bg_color.value, "text-red": has_error.value}
193
+ )
194
+
195
+ rxui.switch("bg_color", value=bg_color)
196
+ rxui.switch("has_error", value=has_error)
197
+ rxui.label("bind to ref_computed").bind_classes(class_obj)
198
+ ```
199
+
200
+ ---
201
+
202
+ 绑定为列表
203
+
204
+ ```python
205
+ bg_color = to_ref("red")
206
+ bg_color_class = ref_computed(lambda: f"bg-{bg_color.value}")
207
+
208
+ text_color = to_ref("green")
209
+ text_color_class = ref_computed(lambda: f"text-{text_color.value}")
210
+
211
+ rxui.select(["red", "green", "yellow"], label="bg color", value=bg_color)
212
+ rxui.select(["red", "green", "yellow"], label="text color", value=text_color)
213
+
214
+ rxui.label("binding to arrays").bind_classes([bg_color_class, text_color_class])
215
+
216
+ ```
217
+
218
+ 列表中每个元素为返回类名的响应式变量
219
+
220
+ ---
221
+
222
+ ### bind-style
223
+
224
+ ```python
225
+ from nicegui import ui
226
+ from ex4nicegui.reactive import rxui
227
+ from ex4nicegui.utils.signals import to_ref
228
+
229
+
230
+ bg_color = to_ref("blue")
231
+ text_color = to_ref("red")
232
+
233
+ rxui.label("test").bind_style(
234
+ {
235
+ "background-color": bg_color,
236
+ "color": text_color,
237
+ }
238
+ )
239
+
240
+ rxui.select(["blue", "green", "yellow"], label="bg color", value=bg_color)
241
+ rxui.select(["red", "green", "yellow"], label="text color", value=text_color)
242
+ ```
243
+
244
+ `bind_style` 传入字典,`key` 为样式名字,`value` 为样式值,响应式字符串
245
+
246
+
247
+ ---
248
+
249
+ ## 响应式
250
+
251
+ ```python
252
+ from ex4nicegui import (
253
+ to_ref,
254
+ ref_computed,
255
+ on,
256
+ effect,
257
+ effect_refreshable,
258
+ batch,
259
+ event_batch,
260
+ )
261
+ ```
262
+ 常用 `to_ref`,`effect`,`ref_computed`,`on`
263
+
264
+ ---
265
+
266
+ ### `to_ref`
267
+ 定义响应式对象,通过 `.value` 读写
268
+ ```python
269
+ a = to_ref(1)
270
+ b = to_ref("text")
271
+
272
+ a.value =2
273
+ b.value = 'new text'
274
+
275
+ print(a.value)
276
+ ```
277
+
278
+ ---
279
+
280
+ ### `effect`
281
+ 接受一个函数,自动监控函数中使用到的响应式对象变化,从而自动执行函数
282
+
283
+ ```python
284
+ a = to_ref(1)
285
+ b = to_ref("text")
286
+
287
+
288
+ @effect
289
+ def auto_run_when_ref_value():
290
+ print(f"a:{a.value}")
291
+
292
+
293
+ def change_value():
294
+ a.value = 2
295
+ b.value = "new text"
296
+
297
+
298
+ ui.button("change", on_click=change_value)
299
+ ```
300
+
301
+ 首次执行 effect ,函数`auto_run_when_ref_value`将被执行一次.之后点击按钮,改变 `a` 的值(通过 `a.value`),函数`auto_run_when_ref_value`再次执行
302
+
303
+ ---
304
+
305
+ ### `ref_computed`
306
+ 与 `effect` 具备一样的功能,`ref_computed` 还能从函数中返回结果。一般用于从 `to_ref` 中进行二次计算
307
+
308
+ ```python
309
+ a = to_ref(1)
310
+ a_square = ref_computed(lambda: a.value * 2)
311
+
312
+
313
+ @effect
314
+ def effect1():
315
+ print(f"a_square:{a_square.value}")
316
+
317
+
318
+ def change_value():
319
+ a.value = 2
320
+
321
+
322
+ ui.button("change", on_click=change_value)
323
+ ```
324
+
325
+ 点击按钮后,`a.value` 值被修改,从而触发 `a_square` 重新计算.由于 `effect1` 中读取了 `a_square` 的值,从而触发 `effect1` 执行
326
+
327
+ > `ref_computed` 是只读的 `to_ref`
328
+
329
+ ---
330
+
331
+ ### `on`
332
+ 类似 `effect` 的功能,但是 `on` 需要明确指定监控的响应式对象
333
+
334
+ ```python
335
+
336
+ a1 = to_ref(1)
337
+ a2 = to_ref(10)
338
+ b = to_ref("text")
339
+
340
+
341
+ @on(a1)
342
+ def watch_a1_only():
343
+ print(f"watch_a1_only ... a1:{a1.value},a2:{a2.value}")
344
+
345
+
346
+ @on([a1, b], onchanges=True)
347
+ def watch_a1_and_b():
348
+ print(f"watch_a1_and_b ... a1:{a1.value},a2:{a2.value},b:{b.value}")
349
+
350
+
351
+ def change_a1():
352
+ a1.value += 1
353
+ ui.notify("change_a1")
354
+
355
+
356
+ ui.button("change a1", on_click=change_a1)
357
+
358
+
359
+ def change_a2():
360
+ a2.value += 1
361
+ ui.notify("change_a2")
362
+
363
+
364
+ ui.button("change a2", on_click=change_a2)
365
+
366
+
367
+ def change_b():
368
+ b.value += "x"
369
+ ui.notify("change_b")
370
+
371
+
372
+ ui.button("change b", on_click=change_b)
373
+
374
+ ```
375
+
376
+ - 参数 `onchanges` 为 True 时(默认值为 False),指定的函数不会在绑定时执行
377
+
378
+ ---
162
379
 
163
380
  ## BI 模块
164
381
 
@@ -19,4 +19,4 @@ from ex4nicegui.experimental_ import (
19
19
  )
20
20
 
21
21
 
22
- __version__ = "0.4.5"
22
+ __version__ = "0.4.7"
@@ -24,7 +24,9 @@ from .elements.ui_table import ui_table
24
24
  from ex4nicegui.bi import types as bi_types
25
25
 
26
26
  if TYPE_CHECKING:
27
- from ex4nicegui.bi.elements.models import UiResult
27
+ from ex4nicegui.bi.elements.models import (
28
+ UiResult,
29
+ )
28
30
 
29
31
  _TData = TypeVar("_TData")
30
32
 
@@ -41,7 +43,9 @@ class DataSourceFacade(Generic[_TData]):
41
43
  @property
42
44
  def filtered_data(self) -> _TData:
43
45
  """Data after filtering"""
44
- return cast(_TData, self._dataSource.filtered_data)
46
+ return cast(
47
+ _TData, self._dataSource.filtered_data
48
+ )
45
49
 
46
50
  def reload(self, data, reset_filters=True):
47
51
  """Reload the data source with the provided new data.
@@ -55,7 +59,9 @@ class DataSourceFacade(Generic[_TData]):
55
59
  if reset_filters:
56
60
  self.remove_filters()
57
61
 
58
- def remove_filters(self, *components: UiResult):
62
+ def remove_filters(
63
+ self, *components: UiResult
64
+ ):
59
65
  """Remove the filter from the data source"""
60
66
  if len(components) == 0:
61
67
  # remove all
@@ -67,7 +73,9 @@ class DataSourceFacade(Generic[_TData]):
67
73
  self,
68
74
  column: str,
69
75
  *,
70
- sort_options: Optional[bi_types._TDuplicates_column_values_sort_options] = None,
76
+ sort_options: Optional[
77
+ bi_types._TDuplicates_column_values_sort_options
78
+ ] = None,
71
79
  exclude_null_value=False,
72
80
  clearable=True,
73
81
  multiple=True,
@@ -76,8 +84,8 @@ class DataSourceFacade(Generic[_TData]):
76
84
  """
77
85
  Creates a user interface select box.
78
86
 
79
- @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#dsui_select
80
- @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#dsui_select
87
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#ui_select
88
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#ui_select
81
89
 
82
90
 
83
91
  Args:
@@ -89,11 +97,20 @@ class DataSourceFacade(Generic[_TData]):
89
97
  Returns:
90
98
  SelectResult: An instance of a user interface select box.
91
99
  """
92
- kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
100
+ kws = {
101
+ key: value
102
+ for key, value in locals().items()
103
+ if key not in ("kwargs")
104
+ }
93
105
  kws.update(kwargs)
94
106
  return ui_select(**kws)
95
107
 
96
- def ui_aggrid(self, *, options: Optional[Dict] = None, **kwargs):
108
+ def ui_aggrid(
109
+ self,
110
+ *,
111
+ options: Optional[Dict] = None,
112
+ **kwargs,
113
+ ):
97
114
  """
98
115
  Creates aggrid table.
99
116
 
@@ -107,7 +124,11 @@ class DataSourceFacade(Generic[_TData]):
107
124
  Returns:
108
125
  ui.aggrid: aggrid table.
109
126
  """
110
- kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
127
+ kws = {
128
+ key: value
129
+ for key, value in locals().items()
130
+ if key not in ("kwargs")
131
+ }
111
132
  kws.update(kwargs)
112
133
  return ui_aggrid(**kws)
113
134
 
@@ -131,7 +152,11 @@ class DataSourceFacade(Generic[_TData]):
131
152
  Returns:
132
153
  ui.table: ui.table.
133
154
  """
134
- kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
155
+ kws = {
156
+ key: value
157
+ for key, value in locals().items()
158
+ if key not in ("kwargs")
159
+ }
135
160
  kws.update(kwargs)
136
161
  return ui_table(**kws)
137
162
 
@@ -139,10 +164,14 @@ class DataSourceFacade(Generic[_TData]):
139
164
  self,
140
165
  column: str,
141
166
  *,
142
- sort_options: Optional[bi_types._TDuplicates_column_values_sort_options] = None,
167
+ sort_options: Optional[
168
+ bi_types._TDuplicates_column_values_sort_options
169
+ ] = None,
143
170
  exclude_null_value=False,
144
171
  hide_filtered=True,
145
- custom_options_map: Optional[Union[Dict, Callable[[Any], Any]]] = None,
172
+ custom_options_map: Optional[
173
+ Union[Dict, Callable[[Any], Any]]
174
+ ] = None,
146
175
  **kwargs,
147
176
  ):
148
177
  """
@@ -160,7 +189,11 @@ class DataSourceFacade(Generic[_TData]):
160
189
  Returns:
161
190
  RadioResult: An radio Selection.
162
191
  """
163
- kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
192
+ kws = {
193
+ key: value
194
+ for key, value in locals().items()
195
+ if key not in ("kwargs")
196
+ }
164
197
  kws.update(kwargs)
165
198
  return ui_radio(**kws)
166
199
 
@@ -180,7 +213,11 @@ class DataSourceFacade(Generic[_TData]):
180
213
  Returns:
181
214
  ui.radio: An Slider.
182
215
  """
183
- kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
216
+ kws = {
217
+ key: value
218
+ for key, value in locals().items()
219
+ if key not in ("kwargs")
220
+ }
184
221
  kws.update(kwargs)
185
222
  return ui_slider(**kws)
186
223
 
@@ -200,12 +237,19 @@ class DataSourceFacade(Generic[_TData]):
200
237
  Returns:
201
238
  QRange: An Range.
202
239
  """
203
- kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
240
+ kws = {
241
+ key: value
242
+ for key, value in locals().items()
243
+ if key not in ("kwargs")
244
+ }
204
245
  kws.update(kwargs)
205
246
  return ui_range(**kws)
206
247
 
207
248
  def ui_echarts(
208
- self, fn: Callable[[Any], Union[Dict, "pyecharts.Base"]] # pyright: ignore
249
+ self,
250
+ fn: Callable[
251
+ [Any], Union[Dict, "pyecharts.Base"]
252
+ ], # pyright: ignore
209
253
  ):
210
254
  """Create charts
211
255
 
@@ -246,10 +290,20 @@ class DataSourceFacade(Generic[_TData]):
246
290
  return ui_echarts(self, fn)
247
291
 
248
292
  def send_filter(
249
- self, element: ui.element, filter: bi_types._TFilterCallback[_TData]
293
+ self,
294
+ element: ui.element,
295
+ filter: bi_types._TFilterCallback[_TData],
250
296
  ):
251
297
  ele_id = element.id
252
- key = self._dataSource.get_component_info_key(ele_id)
253
- if not self._dataSource._component_map.has_record(key):
254
- self._dataSource._register_component(ele_id)
255
- self._dataSource.send_filter(ele_id, Filter(filter))
298
+ key = self._dataSource.get_component_info_key(
299
+ ele_id
300
+ )
301
+ if not self._dataSource._component_map.has_record(
302
+ key
303
+ ):
304
+ self._dataSource._register_component(
305
+ ele_id
306
+ )
307
+ self._dataSource.send_filter(
308
+ ele_id, Filter(filter)
309
+ )
@@ -10,7 +10,7 @@ _TData = TypeVar("_TData")
10
10
  def data_source(data: Union[Callable[..., _TData], _TData]) -> DataSourceFacade[_TData]:
11
11
  """Create a data source
12
12
 
13
- @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/docs/apis/README.en.md#bidata_source
13
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bidata_source
14
14
  @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#bidata_source
15
15
 
16
16
  Args:
@@ -4,7 +4,6 @@ from typing import (
4
4
  Dict,
5
5
  Optional,
6
6
  )
7
- import ex4nicegui.utils.common as utils_common
8
7
  from ex4nicegui.utils.signals import (
9
8
  effect,
10
9
  ReadonlyRef,
@@ -25,7 +24,7 @@ class AggridBindableUi(BindableUi[ui.aggrid]):
25
24
  html_columns: TMaybeRef[List[int]] = [],
26
25
  theme: TMaybeRef[str] = "balham",
27
26
  auto_size_columns: bool = True,
28
- **org_kws
27
+ **org_kws,
29
28
  ) -> None:
30
29
  kws = {
31
30
  "options": options,
@@ -54,21 +53,17 @@ class AggridBindableUi(BindableUi[ui.aggrid]):
54
53
  def from_pandas(
55
54
  df: TMaybeRef,
56
55
  columns_define_fn: Optional[Callable[[str], Dict]] = None,
57
- **org_kws
56
+ **org_kws,
58
57
  ):
59
58
  columns_define_fn = columns_define_fn or (lambda x: {})
60
59
  if is_ref(df):
61
60
 
62
- @ref_computed
63
- def cp_convert_df():
64
- return utils_common.convert_dataframe(df.value)
65
-
66
61
  @ref_computed
67
62
  def cp_options():
68
63
  columnDefs = AggridBindableUi._get_columnDefs_from_dataframe(
69
- cp_convert_df.value, columns_define_fn
64
+ df.value, columns_define_fn
70
65
  )
71
- rowData = cp_convert_df.value.to_dict("records")
66
+ rowData = df.value.to_dict("records")
72
67
  data = {"columnDefs": columnDefs, "rowData": rowData}
73
68
  return data
74
69
 
@@ -3,12 +3,13 @@ from __future__ import annotations
3
3
  from typing import (
4
4
  Any,
5
5
  Callable,
6
+ Dict,
6
7
  List,
7
8
  Optional,
8
9
  TypeVar,
9
10
  Generic,
11
+ Union,
10
12
  cast,
11
- overload,
12
13
  )
13
14
  from typing_extensions import Self
14
15
  from ex4nicegui.utils.signals import (
@@ -18,6 +19,10 @@ from ex4nicegui.utils.signals import (
18
19
  ref_computed,
19
20
  _TMaybeRef as TMaybeRef,
20
21
  effect,
22
+ to_value,
23
+ is_ref,
24
+ on,
25
+ signe_utils,
21
26
  )
22
27
  from nicegui import Tailwind, ui
23
28
  from nicegui.elements.mixins.color_elements import (
@@ -26,11 +31,22 @@ from nicegui.elements.mixins.color_elements import (
26
31
  TAILWIND_COLORS,
27
32
  )
28
33
  from nicegui.elements.mixins.text_element import TextElement
34
+ from nicegui.elements.mixins.disableable_element import DisableableElement
35
+
29
36
 
30
37
  T = TypeVar("T")
31
38
 
32
39
  TWidget = TypeVar("TWidget", bound=ui.element)
33
40
 
41
+ _T_bind_classes_type_dict = Dict[str, TMaybeRef[bool]]
42
+ _T_bind_classes_type_ref_dict = ReadonlyRef[Dict[str, bool]]
43
+ _T_bind_classes_type_array = List[Union[ReadonlyRef[str], Ref[str]]]
44
+
45
+
46
+ _T_bind_classes_type = Union[
47
+ _T_bind_classes_type_dict, _T_bind_classes_type_ref_dict, _T_bind_classes_type_array
48
+ ]
49
+
34
50
 
35
51
  class BindableUi(Generic[TWidget]):
36
52
  def __init__(self, element: TWidget) -> None:
@@ -144,6 +160,68 @@ class BindableUi(Generic[TWidget]):
144
160
  def clear(self) -> None:
145
161
  cast(ui.element, self.element).clear()
146
162
 
163
+ def bind_classes(self, classes: _T_bind_classes_type):
164
+ """data binding is manipulating an element's class list
165
+
166
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bind-class-names
167
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#%E7%BB%91%E5%AE%9A%E7%B1%BB%E5%90%8D
168
+
169
+ Args:
170
+ classes (_T_bind_classes_type):
171
+ """
172
+ if isinstance(classes, dict):
173
+ for name, ref_obj in classes.items():
174
+
175
+ @effect
176
+ def _(name=name, ref_obj=ref_obj):
177
+ if to_value(ref_obj):
178
+ self.classes(add=name)
179
+ else:
180
+ self.classes(remove=name)
181
+
182
+ elif isinstance(classes, (Ref, ReadonlyRef)):
183
+ ref_obj = to_value(classes)
184
+ assert isinstance(ref_obj, dict)
185
+
186
+ @effect
187
+ def _():
188
+ for name, value in to_value(classes).items():
189
+ if value:
190
+ self.classes(add=name)
191
+ else:
192
+ self.classes(remove=name)
193
+ elif isinstance(classes, list):
194
+ for ref_name in classes:
195
+ if is_ref(ref_name):
196
+
197
+ @on(ref_name)
198
+ def _(state: signe_utils.WatchedState):
199
+ self.classes(add=state.current, remove=state.previous)
200
+ else:
201
+ self.classes(ref_name) # type: ignore
202
+
203
+ return self
204
+
205
+ def bind_style(self, style: Dict[str, Union[ReadonlyRef[str], Ref[str]]]):
206
+ """data binding is manipulating an element's style
207
+
208
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#bind-style
209
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#bind-style
210
+
211
+ Args:
212
+ style (Dict[str, Union[ReadonlyRef[str], Ref[str]]]): _description_
213
+ """
214
+ if isinstance(style, dict):
215
+ for name, ref_obj in style.items():
216
+ if is_ref(ref_obj):
217
+
218
+ @effect
219
+ def _(name=name, ref_obj=ref_obj):
220
+ self.element._style[name] = ref_obj.value
221
+ self.element.update()
222
+
223
+ return self
224
+
147
225
 
148
226
  class SingleValueBindableUi(BindableUi[TWidget], Generic[T, TWidget]):
149
227
  def __init__(self, value: TMaybeRef[T], element: TWidget) -> None:
@@ -162,9 +240,6 @@ class SingleValueBindableUi(BindableUi[TWidget], Generic[T, TWidget]):
162
240
  return self
163
241
 
164
242
 
165
- from nicegui.elements.mixins.disableable_element import DisableableElement
166
-
167
-
168
243
  _T_DisableableBinder = TypeVar("_T_DisableableBinder", bound=DisableableElement)
169
244
 
170
245
 
@@ -68,6 +68,8 @@ class EChartsBindableUi(BindableUi[echarts]):
68
68
 
69
69
  @ref_computed
70
70
  def chart_opt():
71
+ if not bool(chart.value):
72
+ return {}
71
73
  return EChartsBindableUi._pyecharts2opts(chart.value)
72
74
 
73
75
  return EChartsBindableUi(chart_opt)
@@ -21,15 +21,10 @@ T = TypeVar("T")
21
21
  class NumberBindableUi(SingleValueBindableUi[float, ui.number]):
22
22
  @staticmethod
23
23
  def _setup_(binder: "NumberBindableUi"):
24
- def onValueChanged(e):
25
- binder._ref.value = e.args # type: ignore
26
-
27
24
  @effect
28
25
  def _():
29
26
  binder.element.value = binder.value
30
27
 
31
- binder.element.on("update:modelValue", handler=onValueChanged)
32
-
33
28
  def __init__(
34
29
  self,
35
30
  label: Optional[TMaybeRef[str]] = None,
@@ -61,13 +56,20 @@ class NumberBindableUi(SingleValueBindableUi[float, ui.number]):
61
56
 
62
57
  value_kws = _convert_kws_ref2value(kws)
63
58
 
59
+ def inject_on_change(e):
60
+ self._ref.value = e.value
61
+ if on_change:
62
+ on_change(e)
63
+
64
+ value_kws.update({"on_change": inject_on_change})
65
+
64
66
  element = ui.number(**value_kws)
65
67
  element.classes("min-w-[10rem]")
66
68
 
67
- super().__init__(value, element)
69
+ super().__init__(value, element) # type: ignore
68
70
 
69
71
  for key, value in kws.items():
70
- if is_ref(value):
71
- self.bind_prop(key, value)
72
+ if key != "value" and is_ref(value):
73
+ self.bind_prop(key, value) # type: ignore
72
74
 
73
75
  NumberBindableUi._setup_(self)
@@ -4,7 +4,6 @@ from typing import (
4
4
  List,
5
5
  Optional,
6
6
  Dict,
7
- cast,
8
7
  )
9
8
  from typing_extensions import Literal
10
9
  import ex4nicegui.utils.common as utils_common
@@ -19,11 +18,6 @@ from ex4nicegui.utils.signals import (
19
18
  from nicegui import ui
20
19
  from .base import BindableUi
21
20
  from .utils import _convert_kws_ref2value
22
- from nicegui.events import (
23
- GenericEventArguments,
24
- TableSelectionEventArguments,
25
- handle_event,
26
- )
27
21
 
28
22
 
29
23
  class TableBindableUi(BindableUi[ui.table]):
@@ -61,10 +55,10 @@ class TableBindableUi(BindableUi[ui.table]):
61
55
  self._arg_row_key = row_key
62
56
  self._selection_ref: ReadonlyRef[List[Any]] = to_ref([])
63
57
 
64
- def on_select(_):
58
+ def on_selection(_):
65
59
  self._selection_ref.value = self.element.selected # type: ignore
66
60
 
67
- self.element.on("selection", on_select)
61
+ self.element.on("selection", on_selection)
68
62
 
69
63
  @property
70
64
  def selection_ref(self):
@@ -92,13 +86,9 @@ class TableBindableUi(BindableUi[ui.table]):
92
86
 
93
87
  if is_ref(df):
94
88
 
95
- @ref_computed
96
- def cp_convert_df():
97
- return utils_common.convert_dataframe(df.value)
98
-
99
89
  @ref_computed
100
90
  def cp_rows():
101
- return cp_convert_df.value.to_dict("records")
91
+ return df.value.to_dict("records")
102
92
 
103
93
  @ref_computed
104
94
  def cp_cols():
@@ -109,15 +99,14 @@ class TableBindableUi(BindableUi[ui.table]):
109
99
  "label": col,
110
100
  "field": col,
111
101
  },
112
- **columns_define_fn(col),
102
+ **columns_define_fn(col), # type: ignore
113
103
  }
114
- for col in cp_convert_df.value.columns
104
+ for col in df.value.columns
115
105
  ]
116
106
 
117
107
  return TableBindableUi(cp_cols, cp_rows, **other_kws)
118
108
 
119
- df = utils_common.convert_dataframe(df)
120
- rows = df.to_dict("records")
109
+ rows = df.to_dict("records") # type: ignore
121
110
 
122
111
  cols = [
123
112
  {
@@ -128,7 +117,7 @@ class TableBindableUi(BindableUi[ui.table]):
128
117
  },
129
118
  **columns_define_fn(col),
130
119
  }
131
- for col in df.columns
120
+ for col in df.columns # type: ignore
132
121
  ]
133
122
  return TableBindableUi(cols, rows, **other_kws)
134
123
 
@@ -94,6 +94,17 @@ def to_value(maybe_ref: _TMaybeRef[T]) -> T:
94
94
 
95
95
 
96
96
  def to_ref(maybe_ref: _TMaybeRef[T]):
97
+ """Takes an inner value and returns a reactive and mutable ref object, which has a single property .value that points to the inner value.
98
+
99
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#to_ref
100
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#to_ref
101
+
102
+
103
+ Args:
104
+ maybe_ref (_TMaybeRef[T]): _description_
105
+
106
+
107
+ """
97
108
  if is_ref(maybe_ref):
98
109
  return cast(Ref[T], maybe_ref)
99
110
 
@@ -128,6 +139,19 @@ def effect(
128
139
  debug_trigger: Optional[Callable] = None,
129
140
  debug_name: Optional[str] = None,
130
141
  ) -> signe_utils._TEffect_Fn[None]:
142
+ """Runs a function immediately while reactively tracking its dependencies and re-runs it whenever the dependencies are changed.
143
+
144
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#effect
145
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#effect
146
+
147
+
148
+ Args:
149
+ fn (None, optional): _description_. Defaults to ....
150
+ priority_level (int, optional): _description_. Defaults to 1.
151
+ debug_trigger (Optional[Callable], optional): _description_. Defaults to None.
152
+ debug_name (Optional[str], optional): _description_. Defaults to None.
153
+
154
+ """
131
155
  ...
132
156
 
133
157
 
@@ -166,6 +190,20 @@ def ref_computed(
166
190
  priority_level: int = 1,
167
191
  debug_name: Optional[str] = None,
168
192
  ) -> ReadonlyRef[T]:
193
+ """Takes a getter function and returns a readonly reactive ref object for the returned value from the getter. It can also take an object with get and set functions to create a writable ref object.
194
+
195
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#ref_computed
196
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#ref_computed
197
+
198
+
199
+ Args:
200
+ fn (Callable[[], T]): _description_
201
+ desc (str, optional): _description_. Defaults to "".
202
+ debug_trigger (Optional[Callable[..., None]], optional): _description_. Defaults to None.
203
+ priority_level (int, optional): _description_. Defaults to 1.
204
+ debug_name (Optional[str], optional): _description_. Defaults to None.
205
+
206
+ """
169
207
  ...
170
208
 
171
209
 
@@ -251,6 +289,19 @@ def on(
251
289
  priority_level=1,
252
290
  effect_kws: Optional[Dict[str, Any]] = None,
253
291
  ):
292
+ """Watches one or more reactive data sources and invokes a callback function when the sources change.
293
+
294
+ @see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#on
295
+ @中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#on
296
+
297
+
298
+ Args:
299
+ refs (Union[ReadonlyRef, Sequence[ReadonlyRef]]): _description_
300
+ onchanges (bool, optional): _description_. Defaults to False.
301
+ priority_level (int, optional): _description_. Defaults to 1.
302
+ effect_kws (Optional[Dict[str, Any]], optional): _description_. Defaults to None.
303
+
304
+ """
254
305
  effect_kws = effect_kws or {}
255
306
  if not isinstance(refs, Sequence):
256
307
  refs = [refs]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ex4nicegui
3
- Version: 0.4.5
3
+ Version: 0.4.7
4
4
  Summary: ...
5
5
  Home-page:
6
6
  Author: carson_jia
@@ -1,3 +1,3 @@
1
- signe>=0.2.5
1
+ signe>=0.2.6
2
2
  nicegui>=1.4.0
3
3
  typing_extensions
@@ -21,7 +21,7 @@ def get_data_files(base):
21
21
  with open("README.md", encoding="utf8") as readme_file:
22
22
  readme = readme_file.read()
23
23
 
24
- requirements = ["signe>=0.2.5", "nicegui>=1.4.0", "typing_extensions"]
24
+ requirements = ["signe>=0.2.6", "nicegui>=1.4.0", "typing_extensions"]
25
25
 
26
26
  test_requirements = ["pytest>=3", "playwright", "pandas"]
27
27
 
File without changes
File without changes