instaui 0.1.15__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- instaui/__init__.py +9 -0
- instaui/_helper/observable_helper.py +45 -0
- instaui/arco/__init__.py +191 -0
- instaui/arco/_settings.py +25 -0
- instaui/arco/_use_tools/locale.py +50 -0
- instaui/arco/component_types.py +1019 -0
- instaui/arco/components/_utils.py +22 -0
- instaui/arco/components/affix.py +29 -0
- instaui/arco/components/alert.py +42 -0
- instaui/arco/components/anchor.py +42 -0
- instaui/arco/components/auto_complete.py +96 -0
- instaui/arco/components/avatar.py +55 -0
- instaui/arco/components/back_top.py +14 -0
- instaui/arco/components/badge.py +14 -0
- instaui/arco/components/breadcrumb.py +14 -0
- instaui/arco/components/button.py +43 -0
- instaui/arco/components/calendar.py +47 -0
- instaui/arco/components/card.py +14 -0
- instaui/arco/components/carousel.py +33 -0
- instaui/arco/components/cascader.py +111 -0
- instaui/arco/components/checkbox.py +32 -0
- instaui/arco/components/collapse.py +31 -0
- instaui/arco/components/color_picker.py +45 -0
- instaui/arco/components/comment.py +14 -0
- instaui/arco/components/config_provider.py +13 -0
- instaui/arco/components/date_picker.py +111 -0
- instaui/arco/components/descriptions.py +14 -0
- instaui/arco/components/divider.py +13 -0
- instaui/arco/components/drawer.py +98 -0
- instaui/arco/components/dropdown.py +45 -0
- instaui/arco/components/empty.py +14 -0
- instaui/arco/components/form.py +55 -0
- instaui/arco/components/icon.py +17 -0
- instaui/arco/components/image.py +33 -0
- instaui/arco/components/input.py +102 -0
- instaui/arco/components/input_number.py +97 -0
- instaui/arco/components/input_password.py +38 -0
- instaui/arco/components/input_search.py +37 -0
- instaui/arco/components/input_tag.py +110 -0
- instaui/arco/components/layout.py +13 -0
- instaui/arco/components/layout_content.py +6 -0
- instaui/arco/components/layout_footer.py +6 -0
- instaui/arco/components/layout_header.py +6 -0
- instaui/arco/components/layout_sider.py +53 -0
- instaui/arco/components/link.py +36 -0
- instaui/arco/components/list.py +68 -0
- instaui/arco/components/mention.py +97 -0
- instaui/arco/components/menu.py +88 -0
- instaui/arco/components/modal.py +97 -0
- instaui/arco/components/overflow_list.py +29 -0
- instaui/arco/components/page_header.py +29 -0
- instaui/arco/components/pagination.py +45 -0
- instaui/arco/components/pop_confirm.py +58 -0
- instaui/arco/components/popover.py +32 -0
- instaui/arco/components/progress.py +14 -0
- instaui/arco/components/radio.py +40 -0
- instaui/arco/components/radio_group.py +42 -0
- instaui/arco/components/rate.py +45 -0
- instaui/arco/components/resize_box.py +62 -0
- instaui/arco/components/result.py +14 -0
- instaui/arco/components/select.py +182 -0
- instaui/arco/components/skeleton.py +14 -0
- instaui/arco/components/slider.py +38 -0
- instaui/arco/components/space.py +14 -0
- instaui/arco/components/spin.py +14 -0
- instaui/arco/components/split.py +76 -0
- instaui/arco/components/statistic.py +14 -0
- instaui/arco/components/steps.py +32 -0
- instaui/arco/components/switch.py +57 -0
- instaui/arco/components/tab_pane.py +12 -0
- instaui/arco/components/table.py +276 -0
- instaui/arco/components/tabs.py +101 -0
- instaui/arco/components/tag.py +42 -0
- instaui/arco/components/textarea.py +84 -0
- instaui/arco/components/time_picker.py +76 -0
- instaui/arco/components/timeline.py +14 -0
- instaui/arco/components/tooltip.py +29 -0
- instaui/arco/components/transfer.py +58 -0
- instaui/arco/components/tree.py +120 -0
- instaui/arco/components/tree_select.py +86 -0
- instaui/arco/components/trigger.py +58 -0
- instaui/arco/components/typography.py +142 -0
- instaui/arco/components/upload.py +71 -0
- instaui/arco/components/verification_code.py +58 -0
- instaui/arco/components/watermark.py +14 -0
- instaui/arco/locales/__init__.py +4 -0
- instaui/arco/locales/_index.py +31 -0
- instaui/arco/locales/en_us.py +227 -0
- instaui/arco/locales/zh_cn.py +224 -0
- instaui/arco/setup.py +36 -0
- instaui/arco/static/instaui-arco.css +1 -0
- instaui/arco/static/instaui-arco.js +55771 -0
- instaui/arco/types.py +24 -0
- instaui/boot_info.py +43 -0
- instaui/common/jsonable.py +37 -0
- instaui/components/__init__.py +0 -0
- instaui/components/column.py +26 -0
- instaui/components/component.py +47 -0
- instaui/components/content.py +34 -0
- instaui/components/directive.py +55 -0
- instaui/components/element.py +573 -0
- instaui/components/grid.py +213 -0
- instaui/components/html/__init__.py +49 -0
- instaui/components/html/_mixins.py +34 -0
- instaui/components/html/_preset.py +4 -0
- instaui/components/html/button.py +38 -0
- instaui/components/html/checkbox.py +35 -0
- instaui/components/html/date.py +28 -0
- instaui/components/html/div.py +7 -0
- instaui/components/html/form.py +7 -0
- instaui/components/html/heading.py +51 -0
- instaui/components/html/input.py +28 -0
- instaui/components/html/label.py +21 -0
- instaui/components/html/li.py +17 -0
- instaui/components/html/link.py +31 -0
- instaui/components/html/number.py +34 -0
- instaui/components/html/paragraph.py +29 -0
- instaui/components/html/range.py +48 -0
- instaui/components/html/select.py +69 -0
- instaui/components/html/span.py +19 -0
- instaui/components/html/table.py +36 -0
- instaui/components/html/textarea.py +28 -0
- instaui/components/html/ul.py +20 -0
- instaui/components/label.py +5 -0
- instaui/components/markdown/markdown.js +33 -0
- instaui/components/markdown/markdown.py +41 -0
- instaui/components/markdown/static/github-markdown.css +12 -0
- instaui/components/markdown/static/marked.esm.js +2579 -0
- instaui/components/match.py +108 -0
- instaui/components/row.py +17 -0
- instaui/components/shiki_code/shiki_code.js +126 -0
- instaui/components/shiki_code/shiki_code.py +99 -0
- instaui/components/shiki_code/static/langs/css.mjs +5 -0
- instaui/components/shiki_code/static/langs/markdown.mjs +5 -0
- instaui/components/shiki_code/static/langs/python.mjs +5 -0
- instaui/components/shiki_code/static/langs/shell.mjs +2 -0
- instaui/components/shiki_code/static/langs/shellscript.mjs +5 -0
- instaui/components/shiki_code/static/shiki-core.js +5784 -0
- instaui/components/shiki_code/static/shiki-style.css +179 -0
- instaui/components/shiki_code/static/shiki-transformers.js +461 -0
- instaui/components/shiki_code/static/themes/vitesse-dark.mjs +2 -0
- instaui/components/shiki_code/static/themes/vitesse-light.mjs +2 -0
- instaui/components/slot.py +81 -0
- instaui/components/transition_group.py +9 -0
- instaui/components/value_element.py +52 -0
- instaui/components/vfor.py +142 -0
- instaui/components/vif.py +42 -0
- instaui/consts.py +23 -0
- instaui/dependencies/component_dependency.py +22 -0
- instaui/dependencies/plugin_dependency.py +28 -0
- instaui/event/event_mixin.py +12 -0
- instaui/event/js_event.py +82 -0
- instaui/event/vue_event.py +66 -0
- instaui/event/web_event.py +123 -0
- instaui/experimental/__init__.py +3 -0
- instaui/experimental/debug.py +48 -0
- instaui/extra_libs/_echarts.py +3 -0
- instaui/extra_libs/_import_error.py +9 -0
- instaui/extra_libs/_mermaid.py +3 -0
- instaui/extra_libs/_shiki_code.py +3 -0
- instaui/fastapi_server/_utils.py +42 -0
- instaui/fastapi_server/_uvicorn.py +37 -0
- instaui/fastapi_server/debug_mode_router.py +60 -0
- instaui/fastapi_server/dependency_router.py +28 -0
- instaui/fastapi_server/event_router.py +58 -0
- instaui/fastapi_server/middlewares.py +19 -0
- instaui/fastapi_server/request_context.py +19 -0
- instaui/fastapi_server/resource.py +30 -0
- instaui/fastapi_server/server.py +308 -0
- instaui/fastapi_server/watch_router.py +53 -0
- instaui/handlers/_utils.py +88 -0
- instaui/handlers/event_handler.py +60 -0
- instaui/handlers/watch_handler.py +61 -0
- instaui/html_tools.py +94 -0
- instaui/inject.py +33 -0
- instaui/js/__init__.py +4 -0
- instaui/js/js_output.py +15 -0
- instaui/js/lambda_func.py +35 -0
- instaui/launch_collector.py +52 -0
- instaui/page_info.py +13 -0
- instaui/runtime/__init__.py +29 -0
- instaui/runtime/_app.py +234 -0
- instaui/runtime/_inner_helper.py +9 -0
- instaui/runtime/_link_manager.py +89 -0
- instaui/runtime/context.py +47 -0
- instaui/runtime/dataclass.py +30 -0
- instaui/runtime/resource.py +65 -0
- instaui/runtime/scope.py +133 -0
- instaui/runtime/ui_state_scope.py +15 -0
- instaui/settings/__init__.py +4 -0
- instaui/settings/__settings.py +13 -0
- instaui/shadcn_classless/_index.py +42 -0
- instaui/shadcn_classless/static/shadcn-classless.css +403 -0
- instaui/skip.py +12 -0
- instaui/spa_router/__init__.py +26 -0
- instaui/spa_router/_components.py +35 -0
- instaui/spa_router/_file_base_utils.py +273 -0
- instaui/spa_router/_functions.py +122 -0
- instaui/spa_router/_install.py +11 -0
- instaui/spa_router/_route_model.py +117 -0
- instaui/spa_router/_router_box.py +40 -0
- instaui/spa_router/_router_output.py +22 -0
- instaui/spa_router/_router_param_var.py +51 -0
- instaui/spa_router/_types.py +4 -0
- instaui/spa_router/templates/page_routes +60 -0
- instaui/static/insta-ui.css +1 -0
- instaui/static/insta-ui.esm-browser.prod.js +3717 -0
- instaui/static/insta-ui.ico +0 -0
- instaui/static/insta-ui.js.map +1 -0
- instaui/static/instaui-tools-browser.js +511 -0
- instaui/static/templates/debug/sse.html +117 -0
- instaui/static/templates/web.html +74 -0
- instaui/static/templates/webview.html +78 -0
- instaui/static/templates/zero.html +71 -0
- instaui/static/vue.esm-browser.prod.js +9 -0
- instaui/static/vue.global.prod.js +9 -0
- instaui/static/vue.runtime.esm-browser.prod.js +5 -0
- instaui/systems/file_system.py +6 -0
- instaui/systems/func_system.py +119 -0
- instaui/systems/js_system.py +22 -0
- instaui/systems/module_system.py +46 -0
- instaui/systems/pydantic_system.py +27 -0
- instaui/systems/string_system.py +10 -0
- instaui/tailwind/__init__.py +6 -0
- instaui/tailwind/_index.py +24 -0
- instaui/tailwind/static/tailwindcss-v3.min.js +62 -0
- instaui/tailwind/static/tailwindcss-v4.min.js +8 -0
- instaui/template/__init__.py +4 -0
- instaui/template/_utils.py +23 -0
- instaui/template/env.py +7 -0
- instaui/template/web_template.py +49 -0
- instaui/template/webview_template.py +48 -0
- instaui/template/zero_template.py +105 -0
- instaui/ui/__init__.py +144 -0
- instaui/ui/__init__.pyi +149 -0
- instaui/ui/events.py +25 -0
- instaui/ui_functions/input_slient_data.py +16 -0
- instaui/ui_functions/server.py +15 -0
- instaui/ui_functions/str_format.py +36 -0
- instaui/ui_functions/ui_page.py +16 -0
- instaui/ui_functions/ui_types.py +13 -0
- instaui/ui_functions/url_location.py +33 -0
- instaui/vars/_types.py +8 -0
- instaui/vars/data.py +68 -0
- instaui/vars/element_ref.py +40 -0
- instaui/vars/event_context.py +49 -0
- instaui/vars/event_extend.py +0 -0
- instaui/vars/js_computed.py +117 -0
- instaui/vars/mixin_types/common_type.py +5 -0
- instaui/vars/mixin_types/element_binding.py +16 -0
- instaui/vars/mixin_types/observable.py +7 -0
- instaui/vars/mixin_types/pathable.py +14 -0
- instaui/vars/mixin_types/py_binding.py +13 -0
- instaui/vars/mixin_types/str_format_binding.py +8 -0
- instaui/vars/mixin_types/var_type.py +5 -0
- instaui/vars/path_var.py +90 -0
- instaui/vars/ref.py +103 -0
- instaui/vars/slot_prop.py +46 -0
- instaui/vars/state.py +97 -0
- instaui/vars/types.py +24 -0
- instaui/vars/vfor_item.py +204 -0
- instaui/vars/vue_computed.py +81 -0
- instaui/vars/web_computed.py +209 -0
- instaui/vars/web_view_computed.py +1 -0
- instaui/version.py +3 -0
- instaui/watch/_types.py +4 -0
- instaui/watch/_utils.py +3 -0
- instaui/watch/js_watch.py +110 -0
- instaui/watch/vue_watch.py +77 -0
- instaui/watch/web_watch.py +181 -0
- instaui/webview/__init__.py +2 -0
- instaui/webview/_utils.py +8 -0
- instaui/webview/api.py +72 -0
- instaui/webview/func.py +114 -0
- instaui/webview/index.py +161 -0
- instaui/webview/resource.py +172 -0
- instaui/zero/__init__.py +3 -0
- instaui/zero/func.py +123 -0
- instaui/zero/scope.py +109 -0
- instaui-0.1.15.dist-info/METADATA +152 -0
- instaui-0.1.15.dist-info/RECORD +283 -0
- instaui-0.1.15.dist-info/WHEEL +5 -0
- instaui-0.1.15.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,573 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import ast
|
4
|
+
from copy import copy
|
5
|
+
import inspect
|
6
|
+
from pathlib import Path
|
7
|
+
import re
|
8
|
+
from typing import (
|
9
|
+
Any,
|
10
|
+
Callable,
|
11
|
+
Dict,
|
12
|
+
Iterable,
|
13
|
+
List,
|
14
|
+
ClassVar,
|
15
|
+
Optional,
|
16
|
+
Set,
|
17
|
+
Tuple,
|
18
|
+
Union,
|
19
|
+
cast,
|
20
|
+
overload,
|
21
|
+
TYPE_CHECKING,
|
22
|
+
)
|
23
|
+
from typing_extensions import Self
|
24
|
+
from collections import defaultdict
|
25
|
+
from instaui.runtime._app import get_app_slot
|
26
|
+
from instaui.runtime._app import get_current_scope
|
27
|
+
from instaui.vars.element_ref import ElementRef
|
28
|
+
from instaui.vars.vfor_item import VForItem
|
29
|
+
from instaui.components.directive import Directive
|
30
|
+
from instaui.dependencies.component_dependency import (
|
31
|
+
ComponentDependencyInfo,
|
32
|
+
)
|
33
|
+
from .slot import SlotManager, Slot
|
34
|
+
from instaui import consts
|
35
|
+
from instaui.components.component import Component
|
36
|
+
|
37
|
+
from instaui.vars.mixin_types.element_binding import ElementBindingMixin
|
38
|
+
|
39
|
+
if TYPE_CHECKING:
|
40
|
+
from instaui.event.event_mixin import EventMixin
|
41
|
+
from instaui.vars.types import TMaybeRef
|
42
|
+
|
43
|
+
|
44
|
+
# Refer to the NiceGUI project.
|
45
|
+
# https://github.com/zauberzeug/nicegui/blob/main/nicegui/element.py
|
46
|
+
PROPS_PATTERN = re.compile(
|
47
|
+
r"""
|
48
|
+
# Match a key-value pair optionally followed by whitespace or end of string
|
49
|
+
([:\w\-]+) # Capture group 1: Key
|
50
|
+
(?: # Optional non-capturing group for value
|
51
|
+
= # Match the equal sign
|
52
|
+
(?: # Non-capturing group for value options
|
53
|
+
( # Capture group 2: Value enclosed in double quotes
|
54
|
+
" # Match double quote
|
55
|
+
[^"\\]* # Match any character except quotes or backslashes zero or more times
|
56
|
+
(?:\\.[^"\\]*)* # Match any escaped character followed by any character except quotes or backslashes zero or more times
|
57
|
+
" # Match the closing quote
|
58
|
+
)
|
59
|
+
|
|
60
|
+
( # Capture group 3: Value enclosed in single quotes
|
61
|
+
' # Match a single quote
|
62
|
+
[^'\\]* # Match any character except quotes or backslashes zero or more times
|
63
|
+
(?:\\.[^'\\]*)* # Match any escaped character followed by any character except quotes or backslashes zero or more times
|
64
|
+
' # Match the closing quote
|
65
|
+
)
|
66
|
+
| # Or
|
67
|
+
([\w\-.%:\/]+) # Capture group 4: Value without quotes
|
68
|
+
)
|
69
|
+
)? # End of optional non-capturing group for value
|
70
|
+
(?:$|\s) # Match end of string or whitespace
|
71
|
+
""",
|
72
|
+
re.VERBOSE,
|
73
|
+
)
|
74
|
+
|
75
|
+
|
76
|
+
class Element(Component):
|
77
|
+
dependency: ClassVar[Optional[ComponentDependencyInfo]] = None
|
78
|
+
_default_props: ClassVar[Dict[str, Any]] = {}
|
79
|
+
_default_classes: ClassVar[List[str]] = []
|
80
|
+
_default_style: ClassVar[Dict[str, str]] = {}
|
81
|
+
|
82
|
+
def __init__(self, tag: Optional[Union[str, ElementBindingMixin]] = None):
|
83
|
+
if self.dependency:
|
84
|
+
tag = self.dependency.tag_name or ""
|
85
|
+
|
86
|
+
super().__init__(tag)
|
87
|
+
|
88
|
+
self._str_classes: List[str] = []
|
89
|
+
self._dict_classes: Dict[str, ElementBindingMixin[bool]] = {}
|
90
|
+
self._bind_str_classes: List[ElementBindingMixin[str]] = []
|
91
|
+
self._str_classes.extend(self._default_classes)
|
92
|
+
self._style: Dict[str, str] = {}
|
93
|
+
self._style.update(self._default_style)
|
94
|
+
self._style_str_binds: List[ElementBindingMixin[str]] = []
|
95
|
+
self._props: Dict[str, Any] = {}
|
96
|
+
self._props.update(self._default_props)
|
97
|
+
self._proxy_props: List[ElementBindingMixin] = []
|
98
|
+
|
99
|
+
self._events: defaultdict[str, List[EventMixin]] = defaultdict(list)
|
100
|
+
self._directives: Dict[Directive, None] = {}
|
101
|
+
|
102
|
+
self._slot_manager = SlotManager()
|
103
|
+
self._element_ref: Optional[ElementRef] = None
|
104
|
+
|
105
|
+
def __init_subclass__(
|
106
|
+
cls,
|
107
|
+
*,
|
108
|
+
esm: Union[str, Path, None] = None,
|
109
|
+
externals: Optional[Dict[str, Path]] = None,
|
110
|
+
css: Union[List[Union[str, Path]], None] = None,
|
111
|
+
) -> None:
|
112
|
+
super().__init_subclass__()
|
113
|
+
|
114
|
+
if esm:
|
115
|
+
esm = _make_dependency_path(esm, cls)
|
116
|
+
|
117
|
+
if externals:
|
118
|
+
externals = {
|
119
|
+
key: _make_dependency_path(value, cls)
|
120
|
+
for key, value in externals.items()
|
121
|
+
}
|
122
|
+
|
123
|
+
if css:
|
124
|
+
css = set(_make_dependency_path(c, cls) for c in css) # type: ignore
|
125
|
+
|
126
|
+
tag_name = f"instaui-{esm.stem}"
|
127
|
+
|
128
|
+
cls.dependency = ComponentDependencyInfo(
|
129
|
+
tag_name=tag_name,
|
130
|
+
esm=esm,
|
131
|
+
externals=cast(Dict[str, Path], externals or {}),
|
132
|
+
css=cast(Set[Path], css or set()),
|
133
|
+
)
|
134
|
+
|
135
|
+
cls._default_props = copy(cls._default_props)
|
136
|
+
cls._default_classes = copy(cls._default_classes)
|
137
|
+
cls._default_style = copy(cls._default_style)
|
138
|
+
|
139
|
+
@staticmethod
|
140
|
+
def _update_classes(
|
141
|
+
classes: List[str],
|
142
|
+
add: str,
|
143
|
+
) -> List[str]:
|
144
|
+
return list(dict.fromkeys(classes + add.split()))
|
145
|
+
|
146
|
+
@staticmethod
|
147
|
+
def _parse_style(text: Union[str, Dict[str, str]]) -> Dict[str, str]:
|
148
|
+
if isinstance(text, dict):
|
149
|
+
return text
|
150
|
+
|
151
|
+
if not text:
|
152
|
+
return {}
|
153
|
+
|
154
|
+
result = {}
|
155
|
+
for item in text.split(";"):
|
156
|
+
item = item.strip()
|
157
|
+
if item:
|
158
|
+
key, value = item.split(":")
|
159
|
+
key = key.strip()
|
160
|
+
value = value.strip()
|
161
|
+
result[key] = value
|
162
|
+
|
163
|
+
return result
|
164
|
+
|
165
|
+
@staticmethod
|
166
|
+
def _parse_props(props: Union[str, Dict[str, Any]]) -> Dict[str, Any]:
|
167
|
+
if isinstance(props, dict):
|
168
|
+
return props
|
169
|
+
|
170
|
+
if not props:
|
171
|
+
return {}
|
172
|
+
|
173
|
+
dictionary = {}
|
174
|
+
for match in PROPS_PATTERN.finditer(props or ""):
|
175
|
+
key = match.group(1)
|
176
|
+
value = match.group(2) or match.group(3) or match.group(4)
|
177
|
+
if value is None:
|
178
|
+
dictionary[key] = True
|
179
|
+
else:
|
180
|
+
if (value.startswith("'") and value.endswith("'")) or (
|
181
|
+
value.startswith('"') and value.endswith('"')
|
182
|
+
):
|
183
|
+
value = ast.literal_eval(value)
|
184
|
+
dictionary[key] = value
|
185
|
+
return dictionary
|
186
|
+
|
187
|
+
def key(self, key: Any):
|
188
|
+
"""Set the key prop of the component.
|
189
|
+
|
190
|
+
Args:
|
191
|
+
key (str): The key prop value.
|
192
|
+
|
193
|
+
"""
|
194
|
+
self.props({"key": key})
|
195
|
+
return self
|
196
|
+
|
197
|
+
def vmodel(
|
198
|
+
self,
|
199
|
+
value: Any,
|
200
|
+
modifiers: Union[consts.TModifier, List[consts.TModifier], None] = None,
|
201
|
+
*,
|
202
|
+
prop_name: str = "value",
|
203
|
+
is_html_component=False,
|
204
|
+
):
|
205
|
+
if prop_name == "value":
|
206
|
+
prop_name = "modelValue"
|
207
|
+
|
208
|
+
modifiers = modifiers or []
|
209
|
+
if isinstance(modifiers, str):
|
210
|
+
modifiers = [modifiers]
|
211
|
+
|
212
|
+
self.directive(
|
213
|
+
Directive(
|
214
|
+
is_sys=is_html_component,
|
215
|
+
name="vmodel",
|
216
|
+
arg=prop_name,
|
217
|
+
modifiers=modifiers,
|
218
|
+
value=value, # type: ignore
|
219
|
+
)
|
220
|
+
)
|
221
|
+
|
222
|
+
if is_html_component is False:
|
223
|
+
model_modifiers = {m: True for m in modifiers}
|
224
|
+
self.props({"modelModifiers": model_modifiers})
|
225
|
+
|
226
|
+
return self
|
227
|
+
|
228
|
+
def add_slot(self, name: str) -> Slot:
|
229
|
+
return self._slot_manager.get_slot(name)
|
230
|
+
|
231
|
+
@overload
|
232
|
+
def classes(self, add: str) -> Self: ...
|
233
|
+
@overload
|
234
|
+
def classes(self, add: Dict[str, TMaybeRef[bool]]) -> Self: ...
|
235
|
+
|
236
|
+
@overload
|
237
|
+
def classes(self, add: TMaybeRef[str]) -> Self: ...
|
238
|
+
|
239
|
+
def classes(
|
240
|
+
self,
|
241
|
+
add: Union[
|
242
|
+
str,
|
243
|
+
Dict[str, TMaybeRef[bool]],
|
244
|
+
TMaybeRef[str],
|
245
|
+
VForItem,
|
246
|
+
],
|
247
|
+
) -> Self:
|
248
|
+
"""Add classes to the component.
|
249
|
+
|
250
|
+
Args:
|
251
|
+
add (Union[ str, Dict[str, TMaybeRef[bool]], TMaybeRef[str], VForItem, ]): classes to add.
|
252
|
+
|
253
|
+
|
254
|
+
Examples:
|
255
|
+
.. code-block:: python
|
256
|
+
|
257
|
+
elemelt = html.span('test')
|
258
|
+
elemelt.classes('class1 class2')
|
259
|
+
|
260
|
+
# dynamically classes
|
261
|
+
class_name = ui.state('x')
|
262
|
+
elemelt.classes(class_name)
|
263
|
+
|
264
|
+
# apply name if True
|
265
|
+
apply = ui.state(True)
|
266
|
+
elemelt.classes({'x': apply})
|
267
|
+
"""
|
268
|
+
|
269
|
+
if isinstance(add, str):
|
270
|
+
self._str_classes = self._update_classes(self._str_classes, add)
|
271
|
+
|
272
|
+
if isinstance(add, dict):
|
273
|
+
self._dict_classes.update(**add) # type: ignore
|
274
|
+
for value in (
|
275
|
+
v for v in add.values() if isinstance(v, ElementBindingMixin)
|
276
|
+
):
|
277
|
+
value._mark_used()
|
278
|
+
|
279
|
+
if isinstance(add, ElementBindingMixin):
|
280
|
+
self._bind_str_classes.append(add) # type: ignore
|
281
|
+
add._mark_used()
|
282
|
+
|
283
|
+
return self
|
284
|
+
|
285
|
+
def style(self, add: Union[str, Dict[str, Any], TMaybeRef[str]]) -> Self:
|
286
|
+
if isinstance(add, dict):
|
287
|
+
add = {key: value for key, value in add.items()}
|
288
|
+
for value in (
|
289
|
+
v for v in add.values() if isinstance(v, ElementBindingMixin)
|
290
|
+
):
|
291
|
+
value._mark_used()
|
292
|
+
|
293
|
+
if isinstance(add, ElementBindingMixin):
|
294
|
+
self._style_str_binds.append(add)
|
295
|
+
add._mark_used()
|
296
|
+
return self
|
297
|
+
|
298
|
+
new_style = self._parse_style(add)
|
299
|
+
self._style.update(new_style)
|
300
|
+
return self
|
301
|
+
|
302
|
+
def props(self, add: Union[str, Dict[str, Any], TMaybeRef]) -> Self:
|
303
|
+
if isinstance(add, ElementBindingMixin):
|
304
|
+
self._proxy_props.append(add)
|
305
|
+
add._mark_used()
|
306
|
+
return self
|
307
|
+
|
308
|
+
if isinstance(add, dict):
|
309
|
+
add = {key: value for key, value in add.items() if value is not None}
|
310
|
+
|
311
|
+
for value in (
|
312
|
+
v for v in add.values() if isinstance(v, ElementBindingMixin)
|
313
|
+
):
|
314
|
+
value._mark_used()
|
315
|
+
|
316
|
+
new_props = self._parse_props(add)
|
317
|
+
self._props.update(new_props)
|
318
|
+
return self
|
319
|
+
|
320
|
+
@classmethod
|
321
|
+
def default_classes(cls, add: str) -> type[Self]:
|
322
|
+
cls._default_classes = cls._update_classes(cls._default_classes, add)
|
323
|
+
return cls
|
324
|
+
|
325
|
+
@classmethod
|
326
|
+
def default_style(cls, add: Union[str, Dict[str, str]]) -> type[Self]:
|
327
|
+
new_style = cls._parse_style(add)
|
328
|
+
cls._default_style.update(new_style)
|
329
|
+
return cls
|
330
|
+
|
331
|
+
@classmethod
|
332
|
+
def default_props(cls, add: Union[str, Dict[str, Any]]) -> type[Self]:
|
333
|
+
new_props = cls._parse_props(add)
|
334
|
+
cls._default_props.update(new_props)
|
335
|
+
return cls
|
336
|
+
|
337
|
+
def on(
|
338
|
+
self,
|
339
|
+
event_name: str,
|
340
|
+
handler: EventMixin,
|
341
|
+
*,
|
342
|
+
extends: Optional[List] = None,
|
343
|
+
):
|
344
|
+
if extends:
|
345
|
+
handler = handler.copy_with_extends(extends)
|
346
|
+
|
347
|
+
self._events[event_name].append(handler)
|
348
|
+
|
349
|
+
return self
|
350
|
+
|
351
|
+
def directive(self, directive: Directive) -> Self:
|
352
|
+
self._directives[directive] = None
|
353
|
+
return self
|
354
|
+
|
355
|
+
def display(self, value: Union[ElementBindingMixin[bool], bool]) -> Self:
|
356
|
+
return self.directive(Directive(is_sys=False, name="vshow", value=value))
|
357
|
+
|
358
|
+
def event_dataset(self, data: Any, name: str = "event-data") -> Self:
|
359
|
+
from instaui.vars.js_computed import JsComputed
|
360
|
+
|
361
|
+
value = JsComputed(inputs=[data], code="(data)=> JSON.stringify(data)")
|
362
|
+
self.props({f"data-{name}": value})
|
363
|
+
return self
|
364
|
+
|
365
|
+
def element_ref(self, ref: ElementRef):
|
366
|
+
self._element_ref = ref
|
367
|
+
return self
|
368
|
+
|
369
|
+
def update_dependencies(
|
370
|
+
self,
|
371
|
+
*,
|
372
|
+
css: Optional[Iterable[Path]] = None,
|
373
|
+
externals: Optional[Dict[str, Path]] = None,
|
374
|
+
replace: bool = False,
|
375
|
+
):
|
376
|
+
if not self.dependency:
|
377
|
+
return
|
378
|
+
|
379
|
+
app = get_app_slot()
|
380
|
+
dep = self.dependency.copy()
|
381
|
+
if replace:
|
382
|
+
dep.css.clear()
|
383
|
+
dep.externals.clear()
|
384
|
+
|
385
|
+
if css:
|
386
|
+
dep.css.update(css)
|
387
|
+
|
388
|
+
if externals:
|
389
|
+
dep.externals.update(externals)
|
390
|
+
|
391
|
+
app.add_temp_component_dependency(dep)
|
392
|
+
|
393
|
+
def use(self, *use_fns: Callable[[Self], None]) -> Self:
|
394
|
+
"""Use functions to the component object.
|
395
|
+
|
396
|
+
Args:
|
397
|
+
use_fns (Callable[[Self], None]): The list of use functions.
|
398
|
+
|
399
|
+
Examples:
|
400
|
+
.. code-block:: python
|
401
|
+
def use_red_color(element: html.paragraph):
|
402
|
+
element.style('color: red')
|
403
|
+
|
404
|
+
html.paragraph('Hello').use(use_red_color)
|
405
|
+
"""
|
406
|
+
|
407
|
+
for fn in use_fns:
|
408
|
+
fn(self)
|
409
|
+
return self
|
410
|
+
|
411
|
+
@classmethod
|
412
|
+
def use_init(cls, init_fn: Callable[[type[Self]], Self]) -> Self:
|
413
|
+
"""Use this method to initialize the component.
|
414
|
+
|
415
|
+
Args:
|
416
|
+
init_fn (Callable[[type[Self]], Self]): The initialization function.
|
417
|
+
|
418
|
+
Examples:
|
419
|
+
.. code-block:: python
|
420
|
+
def fack_init(cls: type[html.table]) -> html.table:
|
421
|
+
return cls(columns=['name', 'age'],rows = [{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}])
|
422
|
+
|
423
|
+
ui.table.use_init(fack_init)
|
424
|
+
"""
|
425
|
+
return init_fn(cls)
|
426
|
+
|
427
|
+
def _to_json_dict(self):
|
428
|
+
data = super()._to_json_dict()
|
429
|
+
|
430
|
+
if self._style or self._style_str_binds:
|
431
|
+
value_styles, bind_styles = _classifyBindableDict(self._style)
|
432
|
+
if value_styles:
|
433
|
+
data["style"] = value_styles
|
434
|
+
|
435
|
+
b_style_list = []
|
436
|
+
|
437
|
+
if bind_styles:
|
438
|
+
b_style_list.append(bind_styles)
|
439
|
+
|
440
|
+
if self._style_str_binds:
|
441
|
+
b_style_list.append(
|
442
|
+
[v._to_element_binding_config() for v in self._style_str_binds]
|
443
|
+
)
|
444
|
+
|
445
|
+
if b_style_list:
|
446
|
+
data["bStyle"] = b_style_list
|
447
|
+
|
448
|
+
if self._str_classes or self._dict_classes or self._bind_str_classes:
|
449
|
+
data["classes"] = _normalize_classes_data(
|
450
|
+
self._str_classes, self._dict_classes, self._bind_str_classes
|
451
|
+
)
|
452
|
+
|
453
|
+
if self._props:
|
454
|
+
value_props, bind_props = _classifyBindableDict(self._props)
|
455
|
+
|
456
|
+
if value_props:
|
457
|
+
data["props"] = value_props
|
458
|
+
|
459
|
+
if bind_props:
|
460
|
+
data["bProps"] = bind_props
|
461
|
+
|
462
|
+
if self._proxy_props:
|
463
|
+
data["proxyProps"] = [
|
464
|
+
v._to_element_binding_config() for v in self._proxy_props
|
465
|
+
]
|
466
|
+
|
467
|
+
if self._events:
|
468
|
+
data["events"] = _normalize_events(self._events)
|
469
|
+
|
470
|
+
if self._slot_manager.has_slot():
|
471
|
+
data["slots"] = self._slot_manager
|
472
|
+
|
473
|
+
if self._directives:
|
474
|
+
data["dir"] = list(self._directives.keys())
|
475
|
+
|
476
|
+
if self.dependency:
|
477
|
+
app_slot = get_app_slot()
|
478
|
+
tag_name = self.dependency.tag_name
|
479
|
+
app_slot.use_component_dependency(
|
480
|
+
app_slot.get_temp_component_dependency(tag_name, self.dependency)
|
481
|
+
)
|
482
|
+
|
483
|
+
if self._element_ref:
|
484
|
+
scope = get_current_scope()
|
485
|
+
data["eRef"] = self._element_ref._to_element_config()
|
486
|
+
scope.register_element_ref(self._element_ref)
|
487
|
+
|
488
|
+
return data
|
489
|
+
|
490
|
+
|
491
|
+
def _normalize_events(
|
492
|
+
events: defaultdict[str, List[EventMixin]],
|
493
|
+
):
|
494
|
+
return {
|
495
|
+
_normalize_event_name(name): event_list for name, event_list in events.items()
|
496
|
+
}
|
497
|
+
|
498
|
+
|
499
|
+
def _normalize_event_name(event_name: str):
|
500
|
+
"""'click' -> 'onClick' , 'press-enter' -> 'onPressEnter' , 'pressEnter' -> 'onPressEnter'"""
|
501
|
+
|
502
|
+
if event_name.startswith("on-"):
|
503
|
+
event_name = event_name[3:]
|
504
|
+
|
505
|
+
if event_name.startswith("on"):
|
506
|
+
event_name = event_name[2:]
|
507
|
+
|
508
|
+
parts = event_name.split("-")
|
509
|
+
formatted_parts = [part[0].upper() + part[1:] for part in parts]
|
510
|
+
|
511
|
+
return "".join(["on", *formatted_parts])
|
512
|
+
|
513
|
+
|
514
|
+
def _normalize_classes_data(
|
515
|
+
str_classes: List[str],
|
516
|
+
dict_classes: Dict[str, ElementBindingMixin[bool]],
|
517
|
+
bind_str_classes: List[ElementBindingMixin[str]],
|
518
|
+
):
|
519
|
+
_str_result = " ".join(str_classes)
|
520
|
+
|
521
|
+
_dict_classes = {k: v._to_element_binding_config() for k, v in dict_classes.items()}
|
522
|
+
|
523
|
+
_bind_str_classes = [v._to_element_binding_config() for v in bind_str_classes]
|
524
|
+
|
525
|
+
if _dict_classes or _bind_str_classes:
|
526
|
+
result = {}
|
527
|
+
|
528
|
+
if _str_result:
|
529
|
+
result["str"] = _str_result
|
530
|
+
|
531
|
+
if _dict_classes:
|
532
|
+
result["map"] = _dict_classes
|
533
|
+
|
534
|
+
if _bind_str_classes:
|
535
|
+
result["bind"] = _bind_str_classes
|
536
|
+
|
537
|
+
return result
|
538
|
+
else:
|
539
|
+
return _str_result
|
540
|
+
|
541
|
+
|
542
|
+
def _classifyBindableDict(
|
543
|
+
data: Dict[str, Any],
|
544
|
+
) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
545
|
+
"""Return value_data, bind_data
|
546
|
+
|
547
|
+
Args:
|
548
|
+
data (Dict[str, Any]): _description_
|
549
|
+
|
550
|
+
Returns:
|
551
|
+
Tuple[Dict[str, Any], Dict[str, Any]]: _description_
|
552
|
+
"""
|
553
|
+
|
554
|
+
value_data = {}
|
555
|
+
bind_data = {}
|
556
|
+
|
557
|
+
for key, value in data.items():
|
558
|
+
if isinstance(value, ElementBindingMixin):
|
559
|
+
bind_data[key] = value._to_element_binding_config()
|
560
|
+
else:
|
561
|
+
value_data[key] = value
|
562
|
+
|
563
|
+
return value_data, bind_data
|
564
|
+
|
565
|
+
|
566
|
+
def _make_dependency_path(path: Union[str, Path], cls: type):
|
567
|
+
if isinstance(path, str):
|
568
|
+
path = Path(path)
|
569
|
+
|
570
|
+
if not path.is_absolute():
|
571
|
+
path = Path(inspect.getfile(cls)).parent / path
|
572
|
+
|
573
|
+
return path
|