ex4nicegui 0.5.1__tar.gz → 0.5.3__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 (154) hide show
  1. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/PKG-INFO +58 -33
  2. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/README.md +54 -33
  3. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/__init__.py +3 -6
  4. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/dataSourceFacade.py +16 -61
  5. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/text.py +1 -1
  6. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_aggrid.py +2 -2
  7. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_echarts.py +3 -3
  8. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_slider.py +1 -1
  9. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_table.py +2 -2
  10. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/protocols.py +0 -1
  11. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/types.py +0 -1
  12. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/experimental_/__init__.py +4 -0
  13. ex4nicegui-0.5.3/ex4nicegui/experimental_/gridLayout/__init__.py +8 -0
  14. ex4nicegui-0.5.3/ex4nicegui/gsap/__init__.py +12 -0
  15. ex4nicegui-0.5.3/ex4nicegui/gsap/timeline.js +56 -0
  16. ex4nicegui-0.5.3/ex4nicegui/gsap/timeline.py +78 -0
  17. ex4nicegui-0.5.3/ex4nicegui/layout/__init__.py +13 -0
  18. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/layout/gridFlex/gridFlex.py +1 -3
  19. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/layout/rxFlex/index.py +16 -6
  20. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/__init__.py +57 -2
  21. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/fileWatcher.py +1 -1
  22. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/local_file_picker.py +1 -1
  23. ex4nicegui-0.5.3/ex4nicegui/reactive/officials/__init__.py +1 -0
  24. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/button.py +0 -1
  25. ex4nicegui-0.5.3/ex4nicegui/reactive/officials/circular_progress.py +64 -0
  26. ex4nicegui-0.5.3/ex4nicegui/reactive/officials/column.py +36 -0
  27. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/html.py +1 -1
  28. ex4nicegui-0.5.3/ex4nicegui/reactive/officials/knob.py +75 -0
  29. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/label.py +0 -1
  30. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/number.py +1 -2
  31. ex4nicegui-0.5.3/ex4nicegui/reactive/officials/row.py +35 -0
  32. ex4nicegui-0.5.3/ex4nicegui/reactive/q_pagination.py +49 -0
  33. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/usePagination.py +6 -4
  34. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/utils.py +42 -3
  35. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/vfor.py +19 -39
  36. ex4nicegui-0.5.3/ex4nicegui/reactive/vmodel.py +210 -0
  37. ex4nicegui-0.5.3/ex4nicegui/tools/__init__.py +0 -0
  38. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/tools/debug.py +1 -1
  39. ex4nicegui-0.5.3/ex4nicegui/utils/__init__.py +0 -0
  40. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/utils/signals.py +12 -2
  41. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui.egg-info/PKG-INFO +58 -33
  42. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui.egg-info/SOURCES.txt +5 -0
  43. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui.egg-info/requires.txt +2 -1
  44. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/setup.py +2 -2
  45. ex4nicegui-0.5.1/ex4nicegui/experimental_/gridLayout/__init__.py +0 -1
  46. ex4nicegui-0.5.1/ex4nicegui/gsap/__init__.py +0 -1
  47. ex4nicegui-0.5.1/ex4nicegui/layout/__init__.py +0 -2
  48. ex4nicegui-0.5.1/ex4nicegui/layout/gridFlex/__init__.py +0 -1
  49. ex4nicegui-0.5.1/ex4nicegui/layout/rxFlex/__init__.py +0 -1
  50. ex4nicegui-0.5.1/ex4nicegui/reactive/officials/column.py +0 -21
  51. ex4nicegui-0.5.1/ex4nicegui/reactive/officials/row.py +0 -21
  52. ex4nicegui-0.5.1/ex4nicegui/reactive/q_pagination.py +0 -45
  53. ex4nicegui-0.5.1/ex4nicegui/tools/__init__.py +0 -1
  54. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/LICENSE +0 -0
  55. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/__init__.py +0 -0
  56. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/dataSource.py +0 -0
  57. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/__init__.py +0 -0
  58. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/containers.py +0 -0
  59. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/layouts.py +0 -0
  60. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/models.py +0 -0
  61. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_date_picker.js +0 -0
  62. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_date_picker.py +0 -0
  63. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_radio.py +0 -0
  64. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_range.py +0 -0
  65. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/elements/ui_select.py +0 -0
  66. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/bi/index.py +0 -0
  67. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/experimental_/gridLayout/index.py +0 -0
  68. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/gsap/gsap.py +0 -0
  69. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/gsap/wrapGsap.js +0 -0
  70. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/layout/gridFlex/GridFlex.js +0 -0
  71. {ex4nicegui-0.5.1/ex4nicegui/reactive/officials → ex4nicegui-0.5.3/ex4nicegui/layout/gridFlex}/__init__.py +0 -0
  72. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/layout/gridFlex/utils.py +0 -0
  73. {ex4nicegui-0.5.1/ex4nicegui/libs → ex4nicegui-0.5.3/ex4nicegui/layout/rxFlex}/__init__.py +0 -0
  74. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/layout/rxFlex/types.py +0 -0
  75. {ex4nicegui-0.5.1/ex4nicegui/libs/d3 → ex4nicegui-0.5.3/ex4nicegui/libs}/__init__.py +0 -0
  76. {ex4nicegui-0.5.1/ex4nicegui/libs/gsap → ex4nicegui-0.5.3/ex4nicegui/libs/d3}/__init__.py +0 -0
  77. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-color.ems.js +0 -0
  78. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-dispatch.ems.js +0 -0
  79. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-drag.ems.js +0 -0
  80. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-ease.ems.js +0 -0
  81. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-interpolate.ems.js +0 -0
  82. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-selection.ems.js +0 -0
  83. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-timer.ems.js +0 -0
  84. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-transition.ems.js +0 -0
  85. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/d3/d3-zoom.ems.js +0 -0
  86. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/CSSPlugin.js +0 -0
  87. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/CSSRulePlugin.js +0 -0
  88. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/CustomEase.js +0 -0
  89. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/Draggable.js +0 -0
  90. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/EasePack.js +0 -0
  91. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/EaselPlugin.js +0 -0
  92. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/Flip.js +0 -0
  93. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/MotionPathPlugin.js +0 -0
  94. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/Observer.js +0 -0
  95. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/PixiPlugin.js +0 -0
  96. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/ScrollToPlugin.js +0 -0
  97. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/ScrollTrigger.js +0 -0
  98. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/TextPlugin.js +0 -0
  99. {ex4nicegui-0.5.1/ex4nicegui/libs/gsap/utils → ex4nicegui-0.5.3/ex4nicegui/libs/gsap}/__init__.py +0 -0
  100. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/all.js +0 -0
  101. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/gsap-core.js +0 -0
  102. {ex4nicegui-0.5.1/ex4nicegui/reactive/EChartsComponent → ex4nicegui-0.5.3/ex4nicegui/libs/gsap/utils}/__init__.py +0 -0
  103. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/utils/matrix.js +0 -0
  104. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/utils/paths.js +0 -0
  105. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/libs/gsap/utils/strings.js +0 -0
  106. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/EChartsComponent/ECharts.js +0 -0
  107. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/EChartsComponent/ECharts.py +0 -0
  108. {ex4nicegui-0.5.1/ex4nicegui/reactive/UseDraggable → ex4nicegui-0.5.3/ex4nicegui/reactive/EChartsComponent}/__init__.py +0 -0
  109. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/UseDraggable/UseDraggable.js +0 -0
  110. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/UseDraggable/UseDraggable.py +0 -0
  111. {ex4nicegui-0.5.1/ex4nicegui/reactive/dropZone → ex4nicegui-0.5.3/ex4nicegui/reactive/UseDraggable}/__init__.py +0 -0
  112. {ex4nicegui-0.5.1/ex4nicegui/reactive/mermaid → ex4nicegui-0.5.3/ex4nicegui/reactive/dropZone}/__init__.py +0 -0
  113. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/dropZone/dropZone.js +0 -0
  114. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/dropZone/dropZone.py +0 -0
  115. {ex4nicegui-0.5.1/ex4nicegui/reactive/useMouse → ex4nicegui-0.5.3/ex4nicegui/reactive/mermaid}/__init__.py +0 -0
  116. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/mermaid/mermaid.js +0 -0
  117. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/mermaid/mermaid.py +0 -0
  118. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/aggrid.py +0 -0
  119. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/base.py +0 -0
  120. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/card.py +0 -0
  121. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/checkbox.py +0 -0
  122. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/color_picker.py +0 -0
  123. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/date.py +0 -0
  124. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/drawer.py +0 -0
  125. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/echarts.py +0 -0
  126. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/expansion.py +0 -0
  127. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/grid.py +0 -0
  128. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/html.js +0 -0
  129. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/icon.py +0 -0
  130. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/image.py +0 -0
  131. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/input.py +0 -0
  132. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/linear_progress.py +0 -0
  133. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/radio.py +0 -0
  134. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/select.py +0 -0
  135. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/slider.py +0 -0
  136. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/switch.py +0 -0
  137. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/table.py +0 -0
  138. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/textarea.py +0 -0
  139. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/upload.py +0 -0
  140. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/officials/utils.py +0 -0
  141. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/rxui.py +0 -0
  142. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/useMouse/UseMouse.js +0 -0
  143. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/useMouse/UseMouse.py +0 -0
  144. {ex4nicegui-0.5.1/ex4nicegui/utils → ex4nicegui-0.5.3/ex4nicegui/reactive/useMouse}/__init__.py +0 -0
  145. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/reactive/vfor.js +0 -0
  146. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/utils/apiEffect.py +0 -0
  147. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/utils/clientScope.py +0 -0
  148. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/utils/common.py +0 -0
  149. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/utils/effect.py +0 -0
  150. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui/utils/scheduler.py +0 -0
  151. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui.egg-info/dependency_links.txt +0 -0
  152. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui.egg-info/not-zip-safe +0 -0
  153. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/ex4nicegui.egg-info/top_level.txt +0 -0
  154. {ex4nicegui-0.5.1 → ex4nicegui-0.5.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ex4nicegui
3
- Version: 0.5.1
3
+ Version: 0.5.3
4
4
  Summary: Extension library based on nicegui, providing data responsive,BI functionality modules
5
5
  Home-page:
6
6
  Author: carson_jia
@@ -32,6 +32,11 @@ An extension library for [nicegui](https://github.com/zauberzeug/nicegui). It ha
32
32
  pip install ex4nicegui -U
33
33
  ```
34
34
 
35
+ ## examples
36
+ - [basic](./examples/basic/)
37
+ - [todo list mvc](./examples/todomvc/)
38
+
39
+
35
40
  ## 🦄 Usage
36
41
 
37
42
  ```python
@@ -381,16 +386,58 @@ ui.button("change b", on_click=change_b)
381
386
 
382
387
  ---
383
388
 
389
+ ## functionality
390
+
391
+ ### vmodel
392
+ Create two-way bindings on form input elements or components.
393
+
394
+ Bidirectional bindings are supported by default for `ref` simple value types
395
+ ```python
396
+ from ex4nicegui import rxui, to_ref, deep_ref
397
+
398
+ data = to_ref("init")
399
+
400
+ rxui.label(lambda: f"{data.value=}")
401
+ # two-way binding
402
+ rxui.input(value=data)
403
+ ```
404
+ - Simple value types are generally immutable values such as `str`, `int`, etc.
405
+
406
+ When using complex data structures, `deep_ref` is used to keep nested values responsive.
407
+ ```python
408
+ data = deep_ref({"a": 1, "b": [1, 2, 3, 4]})
409
+
410
+ rxui.label(lambda: f"{data.value=!s}")
411
+
412
+ # No binding effect
413
+ rxui.input(value=data.value["a"])
414
+
415
+ # readonly binding
416
+ rxui.input(value=lambda: data.value["a"])
417
+
418
+ # two-way binding
419
+ rxui.input(value=rxui.vmodel(data.value["a"]))
420
+ ```
421
+
422
+ - The first input box will be completely unresponsive because the code is equivalent to passing in a value `1` directly
423
+ - The second input box will get read responsiveness due to the use of a function.
424
+ - The third input box, wrapped in `rxui.vmodel`, can be bi-directionally bound.
425
+
426
+ Most use `vmodel` with `vfor`, see [todo list examples](./examples/todomvc/)
427
+
428
+ ---
429
+
384
430
  ### vfor
385
431
  Render list components based on list responsive data. Each component is updated on demand. Data items support dictionaries or objects of any type
386
432
 
387
433
  ```python
388
434
  from nicegui import ui
389
435
  from ex4nicegui.reactive import rxui
390
- from ex4nicegui import to_ref, ref_computed
436
+ from ex4nicegui import deep_ref, ref_computed
437
+ from typing import Dict
391
438
 
392
439
  # refs
393
- items = to_ref(
440
+ items = deep_ref(
394
441
  [
395
442
  {"id": 1, "message": "foo", "done": False},
396
443
  {"id": 2, "message": "bar", "done": True},
@@ -406,7 +453,6 @@ def done_count_info():
406
453
  def check():
407
454
  for item in items.value:
408
455
  item["done"] = not item["done"]
409
- items.value = items.value
410
456
 
411
457
 
412
458
  # ui
@@ -415,54 +461,33 @@ ui.button("check", on_click=check)
415
461
 
416
462
 
417
463
  @rxui.vfor(items,key='id')
418
- def _(store: rxui.VforStore):
464
+ def _(store: rxui.VforStore[Dict]):
419
465
  # function to build the interface for each row of data
420
- msg_ref = store.get("message") # Get responsive object with `store.get`
466
+ item = store.get() # Get responsive object with `store.get`
467
+ mes = rxui.vmodel(item.value['message'])
421
468
 
422
469
  # Enter the content of the input box,
423
470
  # you can see the title of the radio box changes synchronously
424
471
  with ui.card():
425
- rxui.input(value=msg_ref)
426
- rxui.checkbox(text=msg_ref, value=store.get("done"))
472
+ with ui.row():
473
+ rxui.input(value=mes)
474
+ rxui.label(lambda: f"{mes.value=!s}")
475
+ rxui.checkbox(text=mes, value=rxui.vmodel(item.value['done']))
427
476
 
428
477
  ```
429
478
 
430
479
  - `rxui.vfor` decorator to custom function
431
480
  - The first argument is passed to the responsive list. Each item in the list can be a dictionary or other object (`dataclasses` etc.)
432
481
  - Second parameter `key`: In order to be able to keep track of the identity of each node, and thus reuse and reorder existing elements, you can provide a unique key for the block corresponding to each element. The default(`None`) is to use the list element index.
433
- - The custom function takes one argument. The current row's attribute can be retrieved via `store.get`, which is a responsive object.
482
+ - The custom function takes one argument. The current row's can be retrieved via `store.get`, which is a responsive object.
434
483
 
435
484
 
436
485
  > vfor are created only when new data is added.
437
486
 
438
- In the above example, you'll notice that when the checkbox is clicked, the text of the number of completed counts (`done_count_info`) doesn't change synchronously
439
-
440
- This is because responsive data changes in the `vfor` function do not affect the data source list. This is a restriction to prevent writing overly complex bi-directional data flow response logic.
441
-
442
- We should make changes to the data source list via events in the function
443
-
444
- ```python
445
- ...
446
-
447
- @rxui.vfor(items, key="id")
448
- def _(store: rxui.VforStore):
449
- msg_ref = store.get("message")
450
-
451
- def on_check_change(e):
452
- items.value[store.row_index]["done"] = e.value
453
- items.value = items.value
454
-
455
- with ui.card():
456
- rxui.input(value=msg_ref)
457
- rxui.checkbox(text=msg_ref, value=store.get("done"),on_change=on_check_change)
458
-
459
- ```
460
487
 
461
488
  ---
462
489
 
463
490
 
464
- ## functionality
465
-
466
491
  ### Bind class names
467
492
 
468
493
  All component classes provide `bind_classes` for binding `class`, supporting three different data structures.
@@ -25,7 +25,8 @@ pip install ex4nicegui -U
25
25
 
26
26
 
27
27
  ## 示例项目
28
- - [todo list mvc](./examples/todomvc/README.md)
28
+ - [入门](./examples/basic/)
29
+ - [todo list mvc](./examples/todomvc/)
29
30
 
30
31
  ---
31
32
 
@@ -382,16 +383,56 @@ ui.button("change b", on_click=change_b)
382
383
 
383
384
  ## 组件功能
384
385
 
386
+ ### vmodel
387
+ 在表单输入元素或组件上创建双向绑定。
388
+
389
+ 简单值类型的 `ref` 默认支持双向绑定
390
+ ```python
391
+ from ex4nicegui import rxui, to_ref, deep_ref
392
+
393
+ data = to_ref("init")
394
+
395
+ rxui.label(lambda: f"{data.value=}")
396
+ # 默认就是双向绑定
397
+ rxui.input(value=data)
398
+ ```
399
+
400
+ - 简单值类型一般是 `str`,`int` 等不可变值类型
401
+
402
+ 当使用复杂数据结构时,会使用 `deep_ref` 保持嵌套值的响应性
403
+ ```python
404
+ data = deep_ref({"a": 1, "b": [1, 2, 3, 4]})
405
+
406
+ rxui.label(lambda: f"{data.value=!s}")
407
+
408
+ # 当前版本没有任何绑定效果.或许未来的版本可以解决
409
+ rxui.input(value=data.value["a"])
410
+
411
+ # 只读绑定.其他途径修改了 `data.value["a"]` ,此输入框会同步,但反过来不行
412
+ rxui.input(value=lambda: data.value["a"])
413
+
414
+ # 要使用 vmodel 才能双向绑定
415
+ rxui.input(value=rxui.vmodel(data.value["a"]))
416
+ ```
417
+
418
+ - 第一个输入框将完全失去响应性,因为代码等价于直接传入一个数值`1`
419
+ - 第二个输入框由于使用函数,将得到读取响应性(第三个输入框输入值,将得到同步)
420
+ - 第三个输入框,使用 `rxui.vmodel` 包裹,即可实现双向绑定
421
+
422
+ 多数在配合 `vfor` 时使用 `vmodel`,可参考 [todo list 案例](./examples/todomvc/)
423
+
424
+
385
425
  ### vfor
386
426
  基于列表响应式数据,渲染列表组件。每项组件按需更新。数据项支持字典或任意类型对象
387
427
 
388
428
  ```python
389
429
  from nicegui import ui
390
430
  from ex4nicegui.reactive import rxui
391
- from ex4nicegui import to_ref, ref_computed
431
+ from ex4nicegui import deep_ref, ref_computed
432
+ from typing import Dict
392
433
 
393
434
  # refs
394
- items = to_ref(
435
+ items = deep_ref(
395
436
  [
396
437
  {"id": 1, "message": "foo", "done": False},
397
438
  {"id": 2, "message": "bar", "done": True},
@@ -407,55 +448,35 @@ def done_count_info():
407
448
  def check():
408
449
  for item in items.value:
409
450
  item["done"] = not item["done"]
410
- items.value = items.value
411
451
 
412
452
 
413
453
  # ui
414
454
  rxui.label(done_count_info)
415
455
  ui.button("check", on_click=check)
416
456
 
417
- @rxui.vfor(items, key="id")
418
- def _(store: rxui.VforStore):
457
+
458
+ @rxui.vfor(items,key='id')
459
+ def _(store: rxui.VforStore[Dict]):
419
460
  # 函数中构建每一行数据的界面
420
- msg_ref = store.get("message") # 通过 store.get 获取对应行的属性响应式对象
461
+ item = store.get() # 通过 store.get 获取对应行的响应式对象(相当于每行的数据 to_ref(...))
462
+ mes = rxui.vmodel(item.value['message']) # 复杂结构默认没有双向绑定,需要使用 `vmodel`
421
463
 
422
464
  # 输入框输入内容,可以看到单选框的标题同步变化
423
465
  with ui.card():
424
- rxui.input(value=msg_ref)
425
- rxui.checkbox(text=msg_ref, value=store.get("done"))
466
+ with ui.row():
467
+ rxui.input(value=mes)
468
+ rxui.label(lambda: f"{mes.value=!s}")
469
+ rxui.checkbox(text=mes, value=rxui.vmodel(item.value['done']))
426
470
 
427
471
  ```
428
472
 
429
473
  - `rxui.vfor` 装饰器到自定义函数
430
474
  - 第一个参数传入响应式列表。列表中每一项可以是字典或其他对象(`dataclasses` 等等)
431
475
  - 第二个参数 `key`: 为了可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你可以为每个元素对应的块提供一个唯一的 key 。默认情况使用列表元素索引。
432
- - 自定义函数带有一个参数。通过 `store.get` 可以获取当前行对应的属性,此为响应式对象
476
+ - 自定义函数带有一个参数。通过 `store.get` 可以获取当前行的响应式对象
433
477
 
434
478
  > vfor 渲染的项目,只有在新增数据时,才会创建
435
479
 
436
- 上述的例子中,你会发现,当点击 checkbox 时,完成数量的文本(`done_count_info`)并没有同步变化
437
-
438
- 因为 `vfor` 函数中对响应式数据修改,不会影响数据源列表。这是为了防止写出过于复杂的双向数据流响应逻辑而限制。
439
-
440
- 我们应该在函数中通过事件,对数据源列表做修改
441
-
442
- ```python
443
- ...
444
-
445
- @rxui.vfor(items, key="id")
446
- def _(store: rxui.VforStore):
447
- msg_ref = store.get("message")
448
-
449
- def on_check_change(e):
450
- items.value[store.row_index]["done"] = e.value
451
- items.value = items.value
452
-
453
- with ui.card():
454
- rxui.input(value=msg_ref)
455
- rxui.checkbox(text=msg_ref, value=store.get("done"),on_change=on_check_change)
456
-
457
- ```
458
-
459
480
 
460
481
  ---
461
482
 
@@ -17,15 +17,12 @@ from ex4nicegui.utils.signals import (
17
17
  deep_ref,
18
18
  is_setter_ref,
19
19
  batch,
20
- )
21
- from ex4nicegui import tools
22
- from signe import batch
23
- from ex4nicegui.experimental_ import (
24
- gridLayout as exp_ui,
20
+ is_reactive,
25
21
  )
26
22
 
27
23
 
28
24
  __all__ = [
25
+ "is_reactive",
29
26
  "rxui",
30
27
  "ref_computed",
31
28
  "effect",
@@ -46,4 +43,4 @@ __all__ = [
46
43
  "is_setter_ref",
47
44
  ]
48
45
 
49
- __version__ = "0.5.1"
46
+ __version__ = "0.5.3"
@@ -21,7 +21,6 @@ from .elements.ui_range import ui_range
21
21
  from .elements.ui_echarts import ui_echarts
22
22
  from .elements.ui_aggrid import ui_aggrid
23
23
  from .elements.ui_table import ui_table
24
- from ex4nicegui.bi import types as bi_types
25
24
 
26
25
  if TYPE_CHECKING:
27
26
  from ex4nicegui.bi.elements.models import (
@@ -43,9 +42,7 @@ class DataSourceFacade(Generic[_TData]):
43
42
  @property
44
43
  def filtered_data(self) -> _TData:
45
44
  """Data after filtering"""
46
- return cast(
47
- _TData, self._dataSource.filtered_data
48
- )
45
+ return cast(_TData, self._dataSource.filtered_data)
49
46
 
50
47
  def reload(self, data, reset_filters=True):
51
48
  """Reload the data source with the provided new data.
@@ -59,9 +56,7 @@ class DataSourceFacade(Generic[_TData]):
59
56
  if reset_filters:
60
57
  self.remove_filters()
61
58
 
62
- def remove_filters(
63
- self, *components: UiResult
64
- ):
59
+ def remove_filters(self, *components: UiResult):
65
60
  """Remove the filter from the data source"""
66
61
  if len(components) == 0:
67
62
  # remove all
@@ -73,9 +68,7 @@ class DataSourceFacade(Generic[_TData]):
73
68
  self,
74
69
  column: str,
75
70
  *,
76
- sort_options: Optional[
77
- bi_types._TDuplicates_column_values_sort_options
78
- ] = None,
71
+ sort_options: Optional[bi_types._TDuplicates_column_values_sort_options] = None,
79
72
  exclude_null_value=False,
80
73
  clearable=True,
81
74
  multiple=True,
@@ -97,11 +90,7 @@ class DataSourceFacade(Generic[_TData]):
97
90
  Returns:
98
91
  SelectResult: An instance of a user interface select box.
99
92
  """
100
- kws = {
101
- key: value
102
- for key, value in locals().items()
103
- if key not in ("kwargs")
104
- }
93
+ kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
105
94
  kws.update(kwargs)
106
95
  return ui_select(**kws)
107
96
 
@@ -124,11 +113,7 @@ class DataSourceFacade(Generic[_TData]):
124
113
  Returns:
125
114
  ui.aggrid: aggrid table.
126
115
  """
127
- kws = {
128
- key: value
129
- for key, value in locals().items()
130
- if key not in ("kwargs")
131
- }
116
+ kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
132
117
  kws.update(kwargs)
133
118
  return ui_aggrid(**kws)
134
119
 
@@ -152,11 +137,7 @@ class DataSourceFacade(Generic[_TData]):
152
137
  Returns:
153
138
  ui.table: ui.table.
154
139
  """
155
- kws = {
156
- key: value
157
- for key, value in locals().items()
158
- if key not in ("kwargs")
159
- }
140
+ kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
160
141
  kws.update(kwargs)
161
142
  return ui_table(**kws)
162
143
 
@@ -164,14 +145,10 @@ class DataSourceFacade(Generic[_TData]):
164
145
  self,
165
146
  column: str,
166
147
  *,
167
- sort_options: Optional[
168
- bi_types._TDuplicates_column_values_sort_options
169
- ] = None,
148
+ sort_options: Optional[bi_types._TDuplicates_column_values_sort_options] = None,
170
149
  exclude_null_value=False,
171
150
  hide_filtered=True,
172
- custom_options_map: Optional[
173
- Union[Dict, Callable[[Any], Any]]
174
- ] = None,
151
+ custom_options_map: Optional[Union[Dict, Callable[[Any], Any]]] = None,
175
152
  **kwargs,
176
153
  ):
177
154
  """
@@ -189,11 +166,7 @@ class DataSourceFacade(Generic[_TData]):
189
166
  Returns:
190
167
  RadioResult: An radio Selection.
191
168
  """
192
- kws = {
193
- key: value
194
- for key, value in locals().items()
195
- if key not in ("kwargs")
196
- }
169
+ kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
197
170
  kws.update(kwargs)
198
171
  return ui_radio(**kws)
199
172
 
@@ -213,11 +186,7 @@ class DataSourceFacade(Generic[_TData]):
213
186
  Returns:
214
187
  ui.radio: An Slider.
215
188
  """
216
- kws = {
217
- key: value
218
- for key, value in locals().items()
219
- if key not in ("kwargs")
220
- }
189
+ kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
221
190
  kws.update(kwargs)
222
191
  return ui_slider(**kws)
223
192
 
@@ -237,19 +206,13 @@ class DataSourceFacade(Generic[_TData]):
237
206
  Returns:
238
207
  QRange: An Range.
239
208
  """
240
- kws = {
241
- key: value
242
- for key, value in locals().items()
243
- if key not in ("kwargs")
244
- }
209
+ kws = {key: value for key, value in locals().items() if key not in ("kwargs")}
245
210
  kws.update(kwargs)
246
211
  return ui_range(**kws)
247
212
 
248
213
  def ui_echarts(
249
214
  self,
250
- fn: Callable[
251
- [Any], Union[Dict, "pyecharts.Base"]
252
- ], # pyright: ignore
215
+ fn: Callable[[Any], Union[Dict, "pyecharts.Base"]], # pyright: ignore # noqa: F821
253
216
  ):
254
217
  """Create charts
255
218
 
@@ -295,15 +258,7 @@ class DataSourceFacade(Generic[_TData]):
295
258
  filter: bi_types._TFilterCallback[_TData],
296
259
  ):
297
260
  ele_id = element.id
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
- )
261
+ key = self._dataSource.get_component_info_key(ele_id)
262
+ if not self._dataSource._component_map.has_record(key):
263
+ self._dataSource._register_component(ele_id)
264
+ self._dataSource.send_filter(ele_id, Filter(filter))
@@ -1,4 +1,4 @@
1
- from typing import Callable, Any, Union
1
+ from typing import Callable, Any
2
2
  from nicegui import ui
3
3
  from ex4nicegui.utils.signals import effect
4
4
 
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union
2
+ from typing import TYPE_CHECKING, Callable, Dict, Optional, Union
3
3
  from nicegui import ui
4
4
  from ex4nicegui.bi.dataSource import DataSource
5
5
  from .models import UiResult
@@ -60,7 +60,7 @@ def ui_aggrid(
60
60
  cp._props["options"] = options
61
61
  cp.update()
62
62
 
63
- info = self._dataSource._register_component(cp.id, on_source_update)
63
+ self._dataSource._register_component(cp.id, on_source_update)
64
64
 
65
65
  on_source_update()
66
66
 
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Union, cast
2
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Union, cast
3
3
  from nicegui.events import UiEventArguments
4
4
  from ex4nicegui.reactive import rxui
5
5
  from ex4nicegui.reactive.EChartsComponent.ECharts import (
@@ -36,7 +36,7 @@ class EChartsResult(UiResult[echarts]):
36
36
 
37
37
  def ui_echarts(
38
38
  self: DataSourceFacade,
39
- fn: Callable[[Any], Union[Dict, "pyecharts.Base"]], # pyright: ignore
39
+ fn: Callable[[Any], Union[Dict, "pyecharts.Base"]], # pyright: ignore # noqa: F821
40
40
  **kwargs,
41
41
  ):
42
42
  def create_options(data):
@@ -60,7 +60,7 @@ def ui_echarts(
60
60
  options = create_options(data)
61
61
  cp.element.update_options(options)
62
62
 
63
- info = self._dataSource._register_component(ele_id, on_source_update)
63
+ self._dataSource._register_component(ele_id, on_source_update)
64
64
 
65
65
  cp.element.update_options(
66
66
  create_options(self._dataSource.get_filtered_data(cp.element))
@@ -28,7 +28,7 @@ class SliderResult(UiResult[ui.slider]):
28
28
 
29
29
  def _reset_state(self):
30
30
  min = self._init_data["min"]
31
- max = self._init_data["max"]
31
+ max = self._init_data["max"] # noqa: F841
32
32
  self._ref_value.value = min
33
33
  self.element.set_value(min)
34
34
 
@@ -1,5 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
2
+ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Union
3
3
  from nicegui import ui
4
4
  from ex4nicegui.bi.dataSource import DataSource
5
5
  from .models import UiResult
@@ -52,7 +52,7 @@ def ui_table(
52
52
  cp.columns = _merge_columns(fixed_columns, opts["columns"])
53
53
  cp.update()
54
54
 
55
- info = self._dataSource._register_component(cp.id, on_source_update)
55
+ self._dataSource._register_component(cp.id, on_source_update)
56
56
 
57
57
  on_source_update()
58
58
 
@@ -5,7 +5,6 @@ from ex4nicegui.bi.types import (
5
5
  _TFilterCallback,
6
6
  _TDuplicates_column_values_sort_options,
7
7
  )
8
- from .types import _TFilterCallback
9
8
  from ex4nicegui.utils import common as utils_common
10
9
 
11
10
 
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
  from typing import Callable, Dict, Literal, TypeVar
3
- from typing import TYPE_CHECKING
4
3
 
5
4
 
6
5
  _TData = TypeVar("_TData")
@@ -1 +1,5 @@
1
1
  from . import gridLayout as exp_ui
2
+
3
+ __all__ = [
4
+ "exp_ui",
5
+ ]
@@ -0,0 +1,8 @@
1
+ from .index import column, row, item, grid_flex
2
+
3
+ __all__ = [
4
+ "column",
5
+ "row",
6
+ "item",
7
+ "grid_flex",
8
+ ]
@@ -0,0 +1,12 @@
1
+ from .gsap import set_defaults, from_, to, new, run_script
2
+ from .timeline import Timeline as timeline
3
+
4
+
5
+ __all__ = [
6
+ "set_defaults",
7
+ "from_",
8
+ "to",
9
+ "new",
10
+ "run_script",
11
+ "timeline",
12
+ ]
@@ -0,0 +1,56 @@
1
+ import { gsap } from "gsap";
2
+ import { convertDynamicProperties } from "../../static/utils/dynamic_properties.js";
3
+
4
+
5
+ export default {
6
+ template: `<template></template>`,
7
+ data() {
8
+
9
+ const tl = gsap.timeline(this.defaults)
10
+ this.tl = tl
11
+
12
+ return {
13
+ }
14
+
15
+ },
16
+ mounted() {
17
+ document.addEventListener('DOMContentLoaded', () => {
18
+ /**
19
+ * @type any[]
20
+ */
21
+ const tasks = this.tasks
22
+ tasks.forEach(t => {
23
+ this[t.method](t.targets, t.vars, t.position)
24
+ })
25
+
26
+ this.scriptTasks.forEach(script => {
27
+ const fn = new Function('return ' + script)()
28
+ fn(this.tl, gsap)
29
+ })
30
+
31
+ })
32
+ },
33
+
34
+ methods: {
35
+ from(targets, vars, position) {
36
+ convertDynamicProperties(vars, false)
37
+ this.tl.from(targets, vars, position)
38
+ },
39
+ to(targets, vars, position) {
40
+ convertDynamicProperties(vars, false)
41
+ this.tl.to(targets, vars, position)
42
+ },
43
+ runScript(script) {
44
+ const fn = new Function('return ' + script)()
45
+ fn(this.tl, gsap)
46
+ },
47
+ callTimeline(name, ...args) {
48
+ this.tl[name](...args)
49
+ }
50
+ },
51
+ props: {
52
+ defaults: Object,
53
+ tasks: Array,
54
+ scriptTasks: Array,
55
+ },
56
+ };