ex4nicegui 0.9.0__tar.gz → 0.9.2__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.
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/PKG-INFO +53 -2
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/README.md +51 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/__init__.py +3 -2
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/protocols.py +10 -20
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/UseDraggable/UseDraggable.py +3 -3
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/mermaid/mermaid.py +1 -1
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/mixins/flexLayout.py +4 -8
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/mixins/value_element.py +1 -2
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/echarts.py +1 -1
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/systems/object_system.py +2 -4
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/usePagination.py +2 -4
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/apiEffect.py +1 -2
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/effect.py +1 -2
- ex4nicegui-0.9.2/ex4nicegui/utils/page_state.py +70 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/refComputed.py +1 -2
- ex4nicegui-0.9.2/ex4nicegui/utils/refreshable.py +122 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/signals.py +3 -87
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/pyproject.toml +2 -2
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/.gitignore +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/LICENSE +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/dataSource.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/dataSourceFacade.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/containers.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/layouts.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/models.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/text.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_aggrid.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_date_picker.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_date_picker.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_echarts.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_radio.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_range.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_select.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_slider.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/elements/ui_table.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/index.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/bi/types.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/experimental_/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/experimental_/gridLayout/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/experimental_/gridLayout/index.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/helper/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/helper/client_instance_locker.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/gridFlex/GridFlex.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/gridFlex/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/gridFlex/gridFlex.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/gridFlex/utils.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/rxFlex/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/rxFlex/index.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/layout/rxFlex/types.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-color.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-dispatch.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-drag.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-ease.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-interpolate.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-selection.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-timer.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-transition.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/libs/d3/d3-zoom.ems.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/EChartsComponent/ECharts.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/EChartsComponent/ECharts.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/EChartsComponent/events.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/EChartsComponent/types.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/EChartsComponent/utils.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/UseDraggable/UseDraggable.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/_vmodel.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/base.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/deferredTask.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/dropZone/dropZone.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/dropZone/dropZone.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/empty.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/empty.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/fileWatcher.py +0 -0
- /ex4nicegui-0.9.0/ex4nicegui/reactive/mermaid/mermaid.js → /ex4nicegui-0.9.2/ex4nicegui/reactive/mermaid/ex4ng_mermaid.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/mixins/backgroundColor.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/mixins/disableable.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/mixins/textColor.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/aggrid.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/avatar.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/badge.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/base.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/button.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/card.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/checkbox.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/chip.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/circular_progress.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/color_picker.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/column.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/date.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/dialog.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/drawer.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/element.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/expansion.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/grid.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/html.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/html.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/icon.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/image.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/input.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/knob.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/label.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/linear_progress.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/number.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/radio.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/range.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/row.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/select.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/slider.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/spinner.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/switch.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/tab.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/tab_panel.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/tab_panels.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/table.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/tabs.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/textarea.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/toggle.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/tooltip.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/tree.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/officials/upload.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/q_pagination.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/rxui.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/scopedStyle.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/scopedStyle.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/services/pandas_service.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/services/reactive_service.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/systems/color_system.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/systems/reactive_system.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/transitionGroup.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/transitionGroup.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/useMouse/UseMouse.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/useMouse/UseMouse.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/vfor.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/vfor.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/reactive/view_model.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/toolbox/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/toolbox/core/VueUse.js +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/toolbox/core/vue_use.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/toolbox/functions/breakpoint.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/toolbox/functions/dark.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/toolbox/functions/qr_code.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/tools/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/tools/debug.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/asyncComputed.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/clientScope.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/common.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/__init__.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/base.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/bool.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/date.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/descriptor.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/dict.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/float.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/int.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/list.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/string.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/proxy/utils.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/refWrapper.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/scheduler.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/utils/types.py +0 -0
- {ex4nicegui-0.9.0 → ex4nicegui-0.9.2}/ex4nicegui/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ex4nicegui
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.2
|
|
4
4
|
Summary: Extension library based on nicegui, providing data responsive,BI functionality modules.
|
|
5
5
|
Author-email: CrystalWindSnake <568166495@qq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,7 +8,7 @@ License-File: LICENSE
|
|
|
8
8
|
Keywords: ex4nicegui,gui,nicegui,ui,web,webui
|
|
9
9
|
Requires-Python: >=3.9
|
|
10
10
|
Requires-Dist: executing~=2.0.1
|
|
11
|
-
Requires-Dist: nicegui~=3.
|
|
11
|
+
Requires-Dist: nicegui~=3.5
|
|
12
12
|
Requires-Dist: signe~=0.4.22
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
|
|
@@ -453,6 +453,7 @@ class MyApp(rxui.ViewModel):
|
|
|
453
453
|
- [tab\_panels](#tab_panels)
|
|
454
454
|
- [lazy\_tab\_panels](#lazy_tab_panels)
|
|
455
455
|
- [scoped\_style](#scoped_style)
|
|
456
|
+
- [PageState](#pagestate)
|
|
456
457
|
- [BI 模块](#bi-模块)
|
|
457
458
|
- [`bi.data_source`](#bidata_source)
|
|
458
459
|
- [ui\_select](#ui_select)
|
|
@@ -1474,6 +1475,56 @@ with rxui.row().scoped_style(":self:hover *", "outline: 1px solid red;") as row:
|
|
|
1474
1475
|
ui.label("World")
|
|
1475
1476
|
```
|
|
1476
1477
|
|
|
1478
|
+
---
|
|
1479
|
+
|
|
1480
|
+
#### PageState
|
|
1481
|
+
|
|
1482
|
+
复杂的页面,可能需要在不同模块的函数中传递状态。`PageState` 类可以更方便管理页面范围的共享状态。
|
|
1483
|
+
|
|
1484
|
+
在 state.py 中定义页面状态
|
|
1485
|
+
```python
|
|
1486
|
+
from ex4nicegui import PageState, to_ref, on
|
|
1487
|
+
|
|
1488
|
+
class CounterState(PageState):
|
|
1489
|
+
|
|
1490
|
+
def __init__(self):
|
|
1491
|
+
self.count = to_ref(0)
|
|
1492
|
+
|
|
1493
|
+
@on(self.a)
|
|
1494
|
+
def on_a_change(a):
|
|
1495
|
+
print(f"a changed to {a}")
|
|
1496
|
+
|
|
1497
|
+
```
|
|
1498
|
+
|
|
1499
|
+
在 view.py 中封装各种视图
|
|
1500
|
+
```python
|
|
1501
|
+
from ex4nicegui import rxui
|
|
1502
|
+
from state import CounterState
|
|
1503
|
+
|
|
1504
|
+
def view1():
|
|
1505
|
+
state = CounterState.get() # 与 view2 函数的状态是共享的
|
|
1506
|
+
ui.label(f"count: {state.count.value} in view1")
|
|
1507
|
+
|
|
1508
|
+
def view2():
|
|
1509
|
+
state = CounterState.get()
|
|
1510
|
+
ui.label(f"count: {state.count.value} in view2")
|
|
1511
|
+
|
|
1512
|
+
```
|
|
1513
|
+
|
|
1514
|
+
在 `main.py` 中正常导入并调用视图函数即可
|
|
1515
|
+
```python
|
|
1516
|
+
from ex4nicegui import ui
|
|
1517
|
+
from view import view1, view2
|
|
1518
|
+
|
|
1519
|
+
@ui.page("/")
|
|
1520
|
+
def index():
|
|
1521
|
+
view1()
|
|
1522
|
+
view2()
|
|
1523
|
+
|
|
1524
|
+
ui.run()
|
|
1525
|
+
|
|
1526
|
+
```
|
|
1527
|
+
|
|
1477
1528
|
|
|
1478
1529
|
---
|
|
1479
1530
|
|
|
@@ -439,6 +439,7 @@ class MyApp(rxui.ViewModel):
|
|
|
439
439
|
- [tab\_panels](#tab_panels)
|
|
440
440
|
- [lazy\_tab\_panels](#lazy_tab_panels)
|
|
441
441
|
- [scoped\_style](#scoped_style)
|
|
442
|
+
- [PageState](#pagestate)
|
|
442
443
|
- [BI 模块](#bi-模块)
|
|
443
444
|
- [`bi.data_source`](#bidata_source)
|
|
444
445
|
- [ui\_select](#ui_select)
|
|
@@ -1460,6 +1461,56 @@ with rxui.row().scoped_style(":self:hover *", "outline: 1px solid red;") as row:
|
|
|
1460
1461
|
ui.label("World")
|
|
1461
1462
|
```
|
|
1462
1463
|
|
|
1464
|
+
---
|
|
1465
|
+
|
|
1466
|
+
#### PageState
|
|
1467
|
+
|
|
1468
|
+
复杂的页面,可能需要在不同模块的函数中传递状态。`PageState` 类可以更方便管理页面范围的共享状态。
|
|
1469
|
+
|
|
1470
|
+
在 state.py 中定义页面状态
|
|
1471
|
+
```python
|
|
1472
|
+
from ex4nicegui import PageState, to_ref, on
|
|
1473
|
+
|
|
1474
|
+
class CounterState(PageState):
|
|
1475
|
+
|
|
1476
|
+
def __init__(self):
|
|
1477
|
+
self.count = to_ref(0)
|
|
1478
|
+
|
|
1479
|
+
@on(self.a)
|
|
1480
|
+
def on_a_change(a):
|
|
1481
|
+
print(f"a changed to {a}")
|
|
1482
|
+
|
|
1483
|
+
```
|
|
1484
|
+
|
|
1485
|
+
在 view.py 中封装各种视图
|
|
1486
|
+
```python
|
|
1487
|
+
from ex4nicegui import rxui
|
|
1488
|
+
from state import CounterState
|
|
1489
|
+
|
|
1490
|
+
def view1():
|
|
1491
|
+
state = CounterState.get() # 与 view2 函数的状态是共享的
|
|
1492
|
+
ui.label(f"count: {state.count.value} in view1")
|
|
1493
|
+
|
|
1494
|
+
def view2():
|
|
1495
|
+
state = CounterState.get()
|
|
1496
|
+
ui.label(f"count: {state.count.value} in view2")
|
|
1497
|
+
|
|
1498
|
+
```
|
|
1499
|
+
|
|
1500
|
+
在 `main.py` 中正常导入并调用视图函数即可
|
|
1501
|
+
```python
|
|
1502
|
+
from ex4nicegui import ui
|
|
1503
|
+
from view import view1, view2
|
|
1504
|
+
|
|
1505
|
+
@ui.page("/")
|
|
1506
|
+
def index():
|
|
1507
|
+
view1()
|
|
1508
|
+
view2()
|
|
1509
|
+
|
|
1510
|
+
ui.run()
|
|
1511
|
+
|
|
1512
|
+
```
|
|
1513
|
+
|
|
1463
1514
|
|
|
1464
1515
|
---
|
|
1465
1516
|
|
|
@@ -8,8 +8,6 @@ from ex4nicegui.utils.types import (
|
|
|
8
8
|
)
|
|
9
9
|
from ex4nicegui.utils.scheduler import next_tick
|
|
10
10
|
from ex4nicegui.utils.signals import (
|
|
11
|
-
effect,
|
|
12
|
-
effect_refreshable,
|
|
13
11
|
to_raw,
|
|
14
12
|
is_ref,
|
|
15
13
|
to_ref,
|
|
@@ -23,9 +21,11 @@ from ex4nicegui.utils.signals import (
|
|
|
23
21
|
batch,
|
|
24
22
|
is_reactive,
|
|
25
23
|
)
|
|
24
|
+
from ex4nicegui.utils.refreshable import effect, effect_refreshable
|
|
26
25
|
from ex4nicegui.utils.asyncComputed import async_computed
|
|
27
26
|
from ex4nicegui.utils.clientScope import new_scope
|
|
28
27
|
from ex4nicegui.reactive.EChartsComponent.ECharts import reset_echarts_dependencies
|
|
28
|
+
from ex4nicegui.utils.page_state import PageState
|
|
29
29
|
from .version import __version__
|
|
30
30
|
|
|
31
31
|
__all__ = [
|
|
@@ -53,5 +53,6 @@ __all__ = [
|
|
|
53
53
|
"new_scope",
|
|
54
54
|
"next_tick",
|
|
55
55
|
"reset_echarts_dependencies",
|
|
56
|
+
"PageState",
|
|
56
57
|
"__version__",
|
|
57
58
|
]
|
|
@@ -9,14 +9,11 @@ from ex4nicegui.utils import common as utils_common
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class IDataSourceAble(Protocol):
|
|
12
|
-
def get_data(self) -> Any:
|
|
13
|
-
...
|
|
12
|
+
def get_data(self) -> Any: ...
|
|
14
13
|
|
|
15
|
-
def reload(self, data) -> None:
|
|
16
|
-
...
|
|
14
|
+
def reload(self, data) -> None: ...
|
|
17
15
|
|
|
18
|
-
def apply_filters(self, data, filters: List[_TFilterCallback]) -> Any:
|
|
19
|
-
...
|
|
16
|
+
def apply_filters(self, data, filters: List[_TFilterCallback]) -> Any: ...
|
|
20
17
|
|
|
21
18
|
def duplicates_column_values(
|
|
22
19
|
self,
|
|
@@ -25,30 +22,23 @@ class IDataSourceAble(Protocol):
|
|
|
25
22
|
*,
|
|
26
23
|
exclude_null_value=True,
|
|
27
24
|
sort_options: Optional[_TDuplicates_column_values_sort_options] = None,
|
|
28
|
-
) -> List:
|
|
29
|
-
...
|
|
25
|
+
) -> List: ...
|
|
30
26
|
|
|
31
|
-
def get_aggrid_options(self, data) -> Dict:
|
|
32
|
-
...
|
|
27
|
+
def get_aggrid_options(self, data) -> Dict: ...
|
|
33
28
|
|
|
34
|
-
def get_table_options(self, data) -> Dict:
|
|
35
|
-
...
|
|
29
|
+
def get_table_options(self, data) -> Dict: ...
|
|
36
30
|
|
|
37
|
-
def slider_check(self, data, column_name: str) -> None:
|
|
38
|
-
...
|
|
31
|
+
def slider_check(self, data, column_name: str) -> None: ...
|
|
39
32
|
|
|
40
33
|
def slider_min_max(
|
|
41
34
|
self, data, column_name: str
|
|
42
|
-
) -> Tuple[Optional[float], Optional[float]]:
|
|
43
|
-
...
|
|
35
|
+
) -> Tuple[Optional[float], Optional[float]]: ...
|
|
44
36
|
|
|
45
|
-
def range_check(self, data, column_name: str) -> None:
|
|
46
|
-
...
|
|
37
|
+
def range_check(self, data, column_name: str) -> None: ...
|
|
47
38
|
|
|
48
39
|
def range_min_max(
|
|
49
40
|
self, data, column_name: str
|
|
50
|
-
) -> Tuple[Optional[float], Optional[float]]:
|
|
51
|
-
...
|
|
41
|
+
) -> Tuple[Optional[float], Optional[float]]: ...
|
|
52
42
|
|
|
53
43
|
|
|
54
44
|
class CallableDataSourceAble(IDataSourceAble):
|
|
@@ -125,9 +125,9 @@ class UseDraggable(Element, component="UseDraggable.js"):
|
|
|
125
125
|
self.on("update", inner_handler, args=_Update_Args)
|
|
126
126
|
|
|
127
127
|
def apply(self, target: Element):
|
|
128
|
-
assert (
|
|
129
|
-
|
|
130
|
-
)
|
|
128
|
+
assert self.__target_id is None, (
|
|
129
|
+
"draggable can only be applied to one current element"
|
|
130
|
+
)
|
|
131
131
|
self.__target_id = target.id
|
|
132
132
|
self._props["elementId"] = self.__target_id
|
|
133
133
|
# self.run_method("applyTargetId", str(self.__target_id))
|
|
@@ -13,11 +13,9 @@ class FlexWrapMixin(Protocol):
|
|
|
13
13
|
_ui_signal_on: Callable[[Callable[..., Any]], signe.Effect[None]]
|
|
14
14
|
|
|
15
15
|
@property
|
|
16
|
-
def element(self) -> ui.element:
|
|
17
|
-
...
|
|
16
|
+
def element(self) -> ui.element: ...
|
|
18
17
|
|
|
19
|
-
def bind_style(self, classes) -> Self:
|
|
20
|
-
...
|
|
18
|
+
def bind_style(self, classes) -> Self: ...
|
|
21
19
|
|
|
22
20
|
def bind_wrap(self, value: TMaybeRef[bool]) -> Self:
|
|
23
21
|
return self.bind_style(
|
|
@@ -35,11 +33,9 @@ class FlexAlignItemsMixin(Protocol):
|
|
|
35
33
|
_ui_signal_on: Callable[[Callable[..., Any]], signe.Effect[None]]
|
|
36
34
|
|
|
37
35
|
@property
|
|
38
|
-
def element(self) -> ui.element:
|
|
39
|
-
...
|
|
36
|
+
def element(self) -> ui.element: ...
|
|
40
37
|
|
|
41
|
-
def bind_classes(self, classes) -> Self:
|
|
42
|
-
...
|
|
38
|
+
def bind_classes(self, classes) -> Self: ...
|
|
43
39
|
|
|
44
40
|
def bind_align_items(self, value: TMaybeRef[str]):
|
|
45
41
|
return self.bind_classes(lambda: f"items-{to_value(value)}")
|
|
@@ -10,8 +10,7 @@ class ValueElementMixin(Protocol, Generic[T]):
|
|
|
10
10
|
_ui_signal_on: Callable[[Callable[..., Any]], signe.Effect[None]]
|
|
11
11
|
|
|
12
12
|
@property
|
|
13
|
-
def element(self) -> ValueElement:
|
|
14
|
-
...
|
|
13
|
+
def element(self) -> ValueElement: ...
|
|
15
14
|
|
|
16
15
|
def bind_value(self, value: TMaybeRef[T]):
|
|
17
16
|
@self._ui_signal_on(value) # type: ignore
|
|
@@ -140,7 +140,7 @@ class EChartsBindableUi(BindableUi[echarts]):
|
|
|
140
140
|
const value = {{
|
|
141
141
|
src: '{src}',
|
|
142
142
|
type: '{type}',
|
|
143
|
-
specialAreas: {json.dumps(special_areas).decode(
|
|
143
|
+
specialAreas: {json.dumps(special_areas).decode("utf-8")}
|
|
144
144
|
}}
|
|
145
145
|
|
|
146
146
|
window.ex4ngEchartsMapTasks.set('{map_name}', value);
|
|
@@ -8,14 +8,12 @@ from typing import (
|
|
|
8
8
|
|
|
9
9
|
@runtime_checkable
|
|
10
10
|
class GetItemProtocol(Protocol):
|
|
11
|
-
def __getitem__(self, key):
|
|
12
|
-
...
|
|
11
|
+
def __getitem__(self, key): ...
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
@runtime_checkable
|
|
16
15
|
class SetItemProtocol(Protocol):
|
|
17
|
-
def __setitem__(self, key, value):
|
|
18
|
-
...
|
|
16
|
+
def __setitem__(self, key, value): ...
|
|
19
17
|
|
|
20
18
|
|
|
21
19
|
def get_attribute(obj: Union[object, GetItemProtocol], name: Union[str, int]) -> Any:
|
|
@@ -17,11 +17,9 @@ def _clamp(value, min_v, max_v) -> int:
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class _SourceProtocol(Protocol):
|
|
20
|
-
def __len__(self) -> int:
|
|
21
|
-
...
|
|
20
|
+
def __len__(self) -> int: ...
|
|
22
21
|
|
|
23
|
-
def __getitem__(self, __idx: slice) -> Any:
|
|
24
|
-
...
|
|
22
|
+
def __getitem__(self, __idx: slice) -> Any: ...
|
|
25
23
|
|
|
26
24
|
|
|
27
25
|
class PaginationRef:
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from typing import ClassVar
|
|
2
|
+
from typing_extensions import Self
|
|
3
|
+
from contextvars import ContextVar
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PageState:
|
|
7
|
+
"""
|
|
8
|
+
A base class for defining per-page reactive state containers.
|
|
9
|
+
|
|
10
|
+
Each subclass of `PageState` provides an isolated state context that is automatically
|
|
11
|
+
managed through a `ContextVar`. When used inside different `ui.page` definitions,
|
|
12
|
+
each page will maintain its own independent instance of the subclass, ensuring
|
|
13
|
+
states do not interfere across pages.
|
|
14
|
+
|
|
15
|
+
Subclasses should define reactive variables (e.g., created via `to_ref`) within
|
|
16
|
+
their `__init__` method. The instance can then be accessed anywhere in the same
|
|
17
|
+
page context using `MyState.get()` — without needing to pass it through function parameters.
|
|
18
|
+
|
|
19
|
+
Typical use cases include sharing state across multiple components or functions
|
|
20
|
+
within the same page.
|
|
21
|
+
|
|
22
|
+
@see - https://github.com/CrystalWindSnake/ex4nicegui/blob/main/README.en.md#PageState
|
|
23
|
+
@中文文档 - https://gitee.com/carson_add/ex4nicegui/tree/main/#PageState
|
|
24
|
+
|
|
25
|
+
# Example:
|
|
26
|
+
.. code-block:: python
|
|
27
|
+
from ex4nicegui import rxui, to_ref, PageState
|
|
28
|
+
from nicegui import ui
|
|
29
|
+
|
|
30
|
+
class MyState(PageState):
|
|
31
|
+
def __init__(self):
|
|
32
|
+
self.a = to_ref(1.0)
|
|
33
|
+
|
|
34
|
+
def sub_view():
|
|
35
|
+
state = MyState.get()
|
|
36
|
+
rxui.label(lambda: f"{state.a.value=}")
|
|
37
|
+
|
|
38
|
+
@ui.page('/')
|
|
39
|
+
def _():
|
|
40
|
+
state = MyState.get()
|
|
41
|
+
rxui.number(value=state.a)
|
|
42
|
+
sub_view()
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
_ctx: ClassVar[ContextVar["PageState"]]
|
|
46
|
+
|
|
47
|
+
def __init_subclass__(cls, **kwargs):
|
|
48
|
+
super().__init_subclass__(**kwargs)
|
|
49
|
+
cls._ctx = ContextVar(f"{cls.__name__}_ctx")
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def get(cls) -> Self:
|
|
53
|
+
"""
|
|
54
|
+
Retrieves the current instance of the page state for this subclass.
|
|
55
|
+
|
|
56
|
+
If no instance exists yet in the current context, a new one is created
|
|
57
|
+
and stored. Subsequent calls within the same page will return the same instance.
|
|
58
|
+
|
|
59
|
+
This method allows components and functions within the same page
|
|
60
|
+
to share reactive state seamlessly without passing references explicitly.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Self: The current `PageState` subclass instance associated with this page.
|
|
64
|
+
"""
|
|
65
|
+
inst = cls._ctx.get(None)
|
|
66
|
+
|
|
67
|
+
if inst is None:
|
|
68
|
+
inst = cls()
|
|
69
|
+
cls._ctx.set(inst)
|
|
70
|
+
return inst # type: ignore
|
|
@@ -64,8 +64,7 @@ def ref_computed(
|
|
|
64
64
|
debug_trigger: Optional[Callable[..., None]] = None,
|
|
65
65
|
priority_level: int = 1,
|
|
66
66
|
debug_name: Optional[str] = None,
|
|
67
|
-
) -> Callable[[Callable[..., T]], ReadonlyRef[T]]:
|
|
68
|
-
...
|
|
67
|
+
) -> Callable[[Callable[..., T]], ReadonlyRef[T]]: ...
|
|
69
68
|
|
|
70
69
|
|
|
71
70
|
def ref_computed(
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from typing import (
|
|
3
|
+
Any,
|
|
4
|
+
Awaitable,
|
|
5
|
+
Callable,
|
|
6
|
+
Union,
|
|
7
|
+
Sequence,
|
|
8
|
+
)
|
|
9
|
+
from nicegui.functions.refreshable import RefreshableContainer
|
|
10
|
+
from ex4nicegui.utils.effect import effect
|
|
11
|
+
from ex4nicegui.utils.types import (
|
|
12
|
+
_TMaybeRef,
|
|
13
|
+
TGetterOrReadonlyRef, # noqa: F401
|
|
14
|
+
)
|
|
15
|
+
from ex4nicegui.utils.refWrapper import RefWrapper # noqa: F401
|
|
16
|
+
from ex4nicegui.utils.proxy import (
|
|
17
|
+
to_ref_if_base_type_proxy,
|
|
18
|
+
)
|
|
19
|
+
from ex4nicegui.utils.signals import is_ref, on
|
|
20
|
+
|
|
21
|
+
_T_effect_refreshable_refs = Union[
|
|
22
|
+
TGetterOrReadonlyRef,
|
|
23
|
+
RefWrapper,
|
|
24
|
+
Sequence[TGetterOrReadonlyRef],
|
|
25
|
+
_TMaybeRef,
|
|
26
|
+
Sequence[_TMaybeRef],
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class effect_refreshable:
|
|
31
|
+
def __init__(self, fn: Callable, refs: _T_effect_refreshable_refs = []) -> None:
|
|
32
|
+
self._fn = fn
|
|
33
|
+
|
|
34
|
+
refs = to_ref_if_base_type_proxy(refs)
|
|
35
|
+
|
|
36
|
+
if isinstance(refs, Sequence):
|
|
37
|
+
ref_arg = [ref for ref in refs if self._is_valid_ref(ref)]
|
|
38
|
+
else:
|
|
39
|
+
ref_arg = [refs] if self._is_valid_ref(refs) else []
|
|
40
|
+
|
|
41
|
+
self._refs = ref_arg
|
|
42
|
+
self()
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
def _is_valid_ref(cls, ref):
|
|
46
|
+
return is_ref(ref) or isinstance(ref, Callable)
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def on(refs: _T_effect_refreshable_refs):
|
|
50
|
+
def warp(
|
|
51
|
+
fn: Callable,
|
|
52
|
+
):
|
|
53
|
+
if inspect.iscoroutinefunction(fn):
|
|
54
|
+
return async_effect_refreshable(refs)(fn)
|
|
55
|
+
|
|
56
|
+
return effect_refreshable(fn, refs)
|
|
57
|
+
|
|
58
|
+
return warp
|
|
59
|
+
|
|
60
|
+
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
|
61
|
+
buffered_view = AsyncBufferedView()
|
|
62
|
+
|
|
63
|
+
first = True
|
|
64
|
+
|
|
65
|
+
def runner():
|
|
66
|
+
nonlocal first
|
|
67
|
+
if first:
|
|
68
|
+
buffered_view.render(self._fn)
|
|
69
|
+
first = False
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
buffered_view.render(self._fn)
|
|
73
|
+
|
|
74
|
+
if len(self._refs) == 0:
|
|
75
|
+
runner = effect(runner)
|
|
76
|
+
else:
|
|
77
|
+
runner = on(self._refs)(runner) # type: ignore
|
|
78
|
+
|
|
79
|
+
return runner
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def async_effect_refreshable(source: _T_effect_refreshable_refs):
|
|
83
|
+
def wrapper(fn: Callable[[], Any]):
|
|
84
|
+
buffered_view = AsyncBufferedView()
|
|
85
|
+
|
|
86
|
+
@on(source, onchanges=False)
|
|
87
|
+
async def on_source_changed():
|
|
88
|
+
await buffered_view.async_render(fn)
|
|
89
|
+
|
|
90
|
+
return wrapper
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class AsyncBufferedView:
|
|
94
|
+
"""
|
|
95
|
+
临时容器做中转,避免异步等待时,页面内容空白的问题
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
def __init__(self):
|
|
99
|
+
self.viewport = RefreshableContainer()
|
|
100
|
+
self.staging = RefreshableContainer()
|
|
101
|
+
|
|
102
|
+
async def async_render(self, content_creator: Callable[[], Awaitable[Any]]):
|
|
103
|
+
with self.staging:
|
|
104
|
+
await content_creator()
|
|
105
|
+
|
|
106
|
+
self.viewport.clear()
|
|
107
|
+
|
|
108
|
+
for child in list(self.staging):
|
|
109
|
+
child.move(self.viewport)
|
|
110
|
+
|
|
111
|
+
self.staging.clear()
|
|
112
|
+
|
|
113
|
+
def render(self, content_creator: Callable[[], Any]):
|
|
114
|
+
with self.staging:
|
|
115
|
+
content_creator()
|
|
116
|
+
|
|
117
|
+
self.viewport.clear()
|
|
118
|
+
|
|
119
|
+
for child in list(self.staging):
|
|
120
|
+
child.move(self.viewport)
|
|
121
|
+
|
|
122
|
+
self.staging.clear()
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from datetime import date, datetime
|
|
2
|
-
import inspect
|
|
3
2
|
import signe
|
|
4
3
|
from signe.core.scope import Scope
|
|
5
4
|
from .clientScope import _CLIENT_SCOPE_MANAGER
|
|
@@ -14,19 +13,18 @@ from typing import (
|
|
|
14
13
|
Union,
|
|
15
14
|
Sequence,
|
|
16
15
|
)
|
|
17
|
-
from nicegui import ui
|
|
18
|
-
from nicegui.functions.refreshable import RefreshableContainer
|
|
19
|
-
from .effect import effect
|
|
20
16
|
from .scheduler import get_uiScheduler
|
|
17
|
+
from .effect import effect # noqa: F401
|
|
21
18
|
from .types import (
|
|
22
19
|
_TMaybeRef,
|
|
23
20
|
TGetterOrReadonlyRef,
|
|
24
|
-
Ref,
|
|
21
|
+
Ref, # noqa: F401
|
|
25
22
|
TReadonlyRef, # noqa: F401
|
|
26
23
|
TRef, # noqa: F401
|
|
27
24
|
DescReadonlyRef, # noqa: F401
|
|
28
25
|
_TMaybeRef as TMaybeRef, # noqa: F401
|
|
29
26
|
)
|
|
27
|
+
|
|
30
28
|
from .refWrapper import RefWrapper, to_ref_wrapper # noqa: F401
|
|
31
29
|
from .refComputed import ref_computed # noqa: F401
|
|
32
30
|
from ex4nicegui.utils.proxy import (
|
|
@@ -139,88 +137,6 @@ def deep_ref(value: T) -> Ref[T]:
|
|
|
139
137
|
return to_ref(value, is_deep=True)
|
|
140
138
|
|
|
141
139
|
|
|
142
|
-
_T_effect_refreshable_refs = Union[
|
|
143
|
-
TGetterOrReadonlyRef,
|
|
144
|
-
RefWrapper,
|
|
145
|
-
Sequence[TGetterOrReadonlyRef],
|
|
146
|
-
_TMaybeRef,
|
|
147
|
-
Sequence[_TMaybeRef],
|
|
148
|
-
]
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
class effect_refreshable:
|
|
152
|
-
def __init__(self, fn: Callable, refs: _T_effect_refreshable_refs = []) -> None:
|
|
153
|
-
self._fn = fn
|
|
154
|
-
|
|
155
|
-
refs = to_ref_if_base_type_proxy(refs)
|
|
156
|
-
|
|
157
|
-
if isinstance(refs, Sequence):
|
|
158
|
-
ref_arg = [ref for ref in refs if self._is_valid_ref(ref)]
|
|
159
|
-
else:
|
|
160
|
-
ref_arg = [refs] if self._is_valid_ref(refs) else []
|
|
161
|
-
|
|
162
|
-
self._refs = ref_arg
|
|
163
|
-
self()
|
|
164
|
-
|
|
165
|
-
@classmethod
|
|
166
|
-
def _is_valid_ref(cls, ref):
|
|
167
|
-
return is_ref(ref) or isinstance(ref, Callable)
|
|
168
|
-
|
|
169
|
-
@staticmethod
|
|
170
|
-
def on(refs: _T_effect_refreshable_refs):
|
|
171
|
-
def warp(
|
|
172
|
-
fn: Callable,
|
|
173
|
-
):
|
|
174
|
-
if inspect.iscoroutinefunction(fn):
|
|
175
|
-
return async_effect_refreshable(refs)(fn)
|
|
176
|
-
|
|
177
|
-
return effect_refreshable(fn, refs)
|
|
178
|
-
|
|
179
|
-
return warp
|
|
180
|
-
|
|
181
|
-
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
|
182
|
-
re_func = ui.refreshable(self._fn)
|
|
183
|
-
|
|
184
|
-
first = True
|
|
185
|
-
|
|
186
|
-
def runner():
|
|
187
|
-
nonlocal first
|
|
188
|
-
if first:
|
|
189
|
-
re_func()
|
|
190
|
-
first = False
|
|
191
|
-
return
|
|
192
|
-
|
|
193
|
-
re_func.refresh()
|
|
194
|
-
|
|
195
|
-
if len(self._refs) == 0:
|
|
196
|
-
runner = effect(runner)
|
|
197
|
-
else:
|
|
198
|
-
runner = on(self._refs)(runner) # type: ignore
|
|
199
|
-
|
|
200
|
-
return runner
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def async_effect_refreshable(source: _T_effect_refreshable_refs):
|
|
204
|
-
def wrapper(fn: Callable[[], Any]):
|
|
205
|
-
@on(source, onchanges=False)
|
|
206
|
-
async def on_source_changed():
|
|
207
|
-
with temp_box:
|
|
208
|
-
await fn()
|
|
209
|
-
|
|
210
|
-
container.clear()
|
|
211
|
-
|
|
212
|
-
for child in list(temp_box):
|
|
213
|
-
child.move(container)
|
|
214
|
-
|
|
215
|
-
temp_box.clear()
|
|
216
|
-
|
|
217
|
-
# 临时容器做中转,避免异步等待时,页面内容空白的问题
|
|
218
|
-
temp_box = RefreshableContainer()
|
|
219
|
-
container = RefreshableContainer()
|
|
220
|
-
|
|
221
|
-
return wrapper
|
|
222
|
-
|
|
223
|
-
|
|
224
140
|
def on(
|
|
225
141
|
refs: Union[TGetterOrReadonlyRef, RefWrapper, Sequence[TGetterOrReadonlyRef], Any],
|
|
226
142
|
onchanges=False,
|