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.
Files changed (283) hide show
  1. instaui/__init__.py +9 -0
  2. instaui/_helper/observable_helper.py +45 -0
  3. instaui/arco/__init__.py +191 -0
  4. instaui/arco/_settings.py +25 -0
  5. instaui/arco/_use_tools/locale.py +50 -0
  6. instaui/arco/component_types.py +1019 -0
  7. instaui/arco/components/_utils.py +22 -0
  8. instaui/arco/components/affix.py +29 -0
  9. instaui/arco/components/alert.py +42 -0
  10. instaui/arco/components/anchor.py +42 -0
  11. instaui/arco/components/auto_complete.py +96 -0
  12. instaui/arco/components/avatar.py +55 -0
  13. instaui/arco/components/back_top.py +14 -0
  14. instaui/arco/components/badge.py +14 -0
  15. instaui/arco/components/breadcrumb.py +14 -0
  16. instaui/arco/components/button.py +43 -0
  17. instaui/arco/components/calendar.py +47 -0
  18. instaui/arco/components/card.py +14 -0
  19. instaui/arco/components/carousel.py +33 -0
  20. instaui/arco/components/cascader.py +111 -0
  21. instaui/arco/components/checkbox.py +32 -0
  22. instaui/arco/components/collapse.py +31 -0
  23. instaui/arco/components/color_picker.py +45 -0
  24. instaui/arco/components/comment.py +14 -0
  25. instaui/arco/components/config_provider.py +13 -0
  26. instaui/arco/components/date_picker.py +111 -0
  27. instaui/arco/components/descriptions.py +14 -0
  28. instaui/arco/components/divider.py +13 -0
  29. instaui/arco/components/drawer.py +98 -0
  30. instaui/arco/components/dropdown.py +45 -0
  31. instaui/arco/components/empty.py +14 -0
  32. instaui/arco/components/form.py +55 -0
  33. instaui/arco/components/icon.py +17 -0
  34. instaui/arco/components/image.py +33 -0
  35. instaui/arco/components/input.py +102 -0
  36. instaui/arco/components/input_number.py +97 -0
  37. instaui/arco/components/input_password.py +38 -0
  38. instaui/arco/components/input_search.py +37 -0
  39. instaui/arco/components/input_tag.py +110 -0
  40. instaui/arco/components/layout.py +13 -0
  41. instaui/arco/components/layout_content.py +6 -0
  42. instaui/arco/components/layout_footer.py +6 -0
  43. instaui/arco/components/layout_header.py +6 -0
  44. instaui/arco/components/layout_sider.py +53 -0
  45. instaui/arco/components/link.py +36 -0
  46. instaui/arco/components/list.py +68 -0
  47. instaui/arco/components/mention.py +97 -0
  48. instaui/arco/components/menu.py +88 -0
  49. instaui/arco/components/modal.py +97 -0
  50. instaui/arco/components/overflow_list.py +29 -0
  51. instaui/arco/components/page_header.py +29 -0
  52. instaui/arco/components/pagination.py +45 -0
  53. instaui/arco/components/pop_confirm.py +58 -0
  54. instaui/arco/components/popover.py +32 -0
  55. instaui/arco/components/progress.py +14 -0
  56. instaui/arco/components/radio.py +40 -0
  57. instaui/arco/components/radio_group.py +42 -0
  58. instaui/arco/components/rate.py +45 -0
  59. instaui/arco/components/resize_box.py +62 -0
  60. instaui/arco/components/result.py +14 -0
  61. instaui/arco/components/select.py +182 -0
  62. instaui/arco/components/skeleton.py +14 -0
  63. instaui/arco/components/slider.py +38 -0
  64. instaui/arco/components/space.py +14 -0
  65. instaui/arco/components/spin.py +14 -0
  66. instaui/arco/components/split.py +76 -0
  67. instaui/arco/components/statistic.py +14 -0
  68. instaui/arco/components/steps.py +32 -0
  69. instaui/arco/components/switch.py +57 -0
  70. instaui/arco/components/tab_pane.py +12 -0
  71. instaui/arco/components/table.py +276 -0
  72. instaui/arco/components/tabs.py +101 -0
  73. instaui/arco/components/tag.py +42 -0
  74. instaui/arco/components/textarea.py +84 -0
  75. instaui/arco/components/time_picker.py +76 -0
  76. instaui/arco/components/timeline.py +14 -0
  77. instaui/arco/components/tooltip.py +29 -0
  78. instaui/arco/components/transfer.py +58 -0
  79. instaui/arco/components/tree.py +120 -0
  80. instaui/arco/components/tree_select.py +86 -0
  81. instaui/arco/components/trigger.py +58 -0
  82. instaui/arco/components/typography.py +142 -0
  83. instaui/arco/components/upload.py +71 -0
  84. instaui/arco/components/verification_code.py +58 -0
  85. instaui/arco/components/watermark.py +14 -0
  86. instaui/arco/locales/__init__.py +4 -0
  87. instaui/arco/locales/_index.py +31 -0
  88. instaui/arco/locales/en_us.py +227 -0
  89. instaui/arco/locales/zh_cn.py +224 -0
  90. instaui/arco/setup.py +36 -0
  91. instaui/arco/static/instaui-arco.css +1 -0
  92. instaui/arco/static/instaui-arco.js +55771 -0
  93. instaui/arco/types.py +24 -0
  94. instaui/boot_info.py +43 -0
  95. instaui/common/jsonable.py +37 -0
  96. instaui/components/__init__.py +0 -0
  97. instaui/components/column.py +26 -0
  98. instaui/components/component.py +47 -0
  99. instaui/components/content.py +34 -0
  100. instaui/components/directive.py +55 -0
  101. instaui/components/element.py +573 -0
  102. instaui/components/grid.py +213 -0
  103. instaui/components/html/__init__.py +49 -0
  104. instaui/components/html/_mixins.py +34 -0
  105. instaui/components/html/_preset.py +4 -0
  106. instaui/components/html/button.py +38 -0
  107. instaui/components/html/checkbox.py +35 -0
  108. instaui/components/html/date.py +28 -0
  109. instaui/components/html/div.py +7 -0
  110. instaui/components/html/form.py +7 -0
  111. instaui/components/html/heading.py +51 -0
  112. instaui/components/html/input.py +28 -0
  113. instaui/components/html/label.py +21 -0
  114. instaui/components/html/li.py +17 -0
  115. instaui/components/html/link.py +31 -0
  116. instaui/components/html/number.py +34 -0
  117. instaui/components/html/paragraph.py +29 -0
  118. instaui/components/html/range.py +48 -0
  119. instaui/components/html/select.py +69 -0
  120. instaui/components/html/span.py +19 -0
  121. instaui/components/html/table.py +36 -0
  122. instaui/components/html/textarea.py +28 -0
  123. instaui/components/html/ul.py +20 -0
  124. instaui/components/label.py +5 -0
  125. instaui/components/markdown/markdown.js +33 -0
  126. instaui/components/markdown/markdown.py +41 -0
  127. instaui/components/markdown/static/github-markdown.css +12 -0
  128. instaui/components/markdown/static/marked.esm.js +2579 -0
  129. instaui/components/match.py +108 -0
  130. instaui/components/row.py +17 -0
  131. instaui/components/shiki_code/shiki_code.js +126 -0
  132. instaui/components/shiki_code/shiki_code.py +99 -0
  133. instaui/components/shiki_code/static/langs/css.mjs +5 -0
  134. instaui/components/shiki_code/static/langs/markdown.mjs +5 -0
  135. instaui/components/shiki_code/static/langs/python.mjs +5 -0
  136. instaui/components/shiki_code/static/langs/shell.mjs +2 -0
  137. instaui/components/shiki_code/static/langs/shellscript.mjs +5 -0
  138. instaui/components/shiki_code/static/shiki-core.js +5784 -0
  139. instaui/components/shiki_code/static/shiki-style.css +179 -0
  140. instaui/components/shiki_code/static/shiki-transformers.js +461 -0
  141. instaui/components/shiki_code/static/themes/vitesse-dark.mjs +2 -0
  142. instaui/components/shiki_code/static/themes/vitesse-light.mjs +2 -0
  143. instaui/components/slot.py +81 -0
  144. instaui/components/transition_group.py +9 -0
  145. instaui/components/value_element.py +52 -0
  146. instaui/components/vfor.py +142 -0
  147. instaui/components/vif.py +42 -0
  148. instaui/consts.py +23 -0
  149. instaui/dependencies/component_dependency.py +22 -0
  150. instaui/dependencies/plugin_dependency.py +28 -0
  151. instaui/event/event_mixin.py +12 -0
  152. instaui/event/js_event.py +82 -0
  153. instaui/event/vue_event.py +66 -0
  154. instaui/event/web_event.py +123 -0
  155. instaui/experimental/__init__.py +3 -0
  156. instaui/experimental/debug.py +48 -0
  157. instaui/extra_libs/_echarts.py +3 -0
  158. instaui/extra_libs/_import_error.py +9 -0
  159. instaui/extra_libs/_mermaid.py +3 -0
  160. instaui/extra_libs/_shiki_code.py +3 -0
  161. instaui/fastapi_server/_utils.py +42 -0
  162. instaui/fastapi_server/_uvicorn.py +37 -0
  163. instaui/fastapi_server/debug_mode_router.py +60 -0
  164. instaui/fastapi_server/dependency_router.py +28 -0
  165. instaui/fastapi_server/event_router.py +58 -0
  166. instaui/fastapi_server/middlewares.py +19 -0
  167. instaui/fastapi_server/request_context.py +19 -0
  168. instaui/fastapi_server/resource.py +30 -0
  169. instaui/fastapi_server/server.py +308 -0
  170. instaui/fastapi_server/watch_router.py +53 -0
  171. instaui/handlers/_utils.py +88 -0
  172. instaui/handlers/event_handler.py +60 -0
  173. instaui/handlers/watch_handler.py +61 -0
  174. instaui/html_tools.py +94 -0
  175. instaui/inject.py +33 -0
  176. instaui/js/__init__.py +4 -0
  177. instaui/js/js_output.py +15 -0
  178. instaui/js/lambda_func.py +35 -0
  179. instaui/launch_collector.py +52 -0
  180. instaui/page_info.py +13 -0
  181. instaui/runtime/__init__.py +29 -0
  182. instaui/runtime/_app.py +234 -0
  183. instaui/runtime/_inner_helper.py +9 -0
  184. instaui/runtime/_link_manager.py +89 -0
  185. instaui/runtime/context.py +47 -0
  186. instaui/runtime/dataclass.py +30 -0
  187. instaui/runtime/resource.py +65 -0
  188. instaui/runtime/scope.py +133 -0
  189. instaui/runtime/ui_state_scope.py +15 -0
  190. instaui/settings/__init__.py +4 -0
  191. instaui/settings/__settings.py +13 -0
  192. instaui/shadcn_classless/_index.py +42 -0
  193. instaui/shadcn_classless/static/shadcn-classless.css +403 -0
  194. instaui/skip.py +12 -0
  195. instaui/spa_router/__init__.py +26 -0
  196. instaui/spa_router/_components.py +35 -0
  197. instaui/spa_router/_file_base_utils.py +273 -0
  198. instaui/spa_router/_functions.py +122 -0
  199. instaui/spa_router/_install.py +11 -0
  200. instaui/spa_router/_route_model.py +117 -0
  201. instaui/spa_router/_router_box.py +40 -0
  202. instaui/spa_router/_router_output.py +22 -0
  203. instaui/spa_router/_router_param_var.py +51 -0
  204. instaui/spa_router/_types.py +4 -0
  205. instaui/spa_router/templates/page_routes +60 -0
  206. instaui/static/insta-ui.css +1 -0
  207. instaui/static/insta-ui.esm-browser.prod.js +3717 -0
  208. instaui/static/insta-ui.ico +0 -0
  209. instaui/static/insta-ui.js.map +1 -0
  210. instaui/static/instaui-tools-browser.js +511 -0
  211. instaui/static/templates/debug/sse.html +117 -0
  212. instaui/static/templates/web.html +74 -0
  213. instaui/static/templates/webview.html +78 -0
  214. instaui/static/templates/zero.html +71 -0
  215. instaui/static/vue.esm-browser.prod.js +9 -0
  216. instaui/static/vue.global.prod.js +9 -0
  217. instaui/static/vue.runtime.esm-browser.prod.js +5 -0
  218. instaui/systems/file_system.py +6 -0
  219. instaui/systems/func_system.py +119 -0
  220. instaui/systems/js_system.py +22 -0
  221. instaui/systems/module_system.py +46 -0
  222. instaui/systems/pydantic_system.py +27 -0
  223. instaui/systems/string_system.py +10 -0
  224. instaui/tailwind/__init__.py +6 -0
  225. instaui/tailwind/_index.py +24 -0
  226. instaui/tailwind/static/tailwindcss-v3.min.js +62 -0
  227. instaui/tailwind/static/tailwindcss-v4.min.js +8 -0
  228. instaui/template/__init__.py +4 -0
  229. instaui/template/_utils.py +23 -0
  230. instaui/template/env.py +7 -0
  231. instaui/template/web_template.py +49 -0
  232. instaui/template/webview_template.py +48 -0
  233. instaui/template/zero_template.py +105 -0
  234. instaui/ui/__init__.py +144 -0
  235. instaui/ui/__init__.pyi +149 -0
  236. instaui/ui/events.py +25 -0
  237. instaui/ui_functions/input_slient_data.py +16 -0
  238. instaui/ui_functions/server.py +15 -0
  239. instaui/ui_functions/str_format.py +36 -0
  240. instaui/ui_functions/ui_page.py +16 -0
  241. instaui/ui_functions/ui_types.py +13 -0
  242. instaui/ui_functions/url_location.py +33 -0
  243. instaui/vars/_types.py +8 -0
  244. instaui/vars/data.py +68 -0
  245. instaui/vars/element_ref.py +40 -0
  246. instaui/vars/event_context.py +49 -0
  247. instaui/vars/event_extend.py +0 -0
  248. instaui/vars/js_computed.py +117 -0
  249. instaui/vars/mixin_types/common_type.py +5 -0
  250. instaui/vars/mixin_types/element_binding.py +16 -0
  251. instaui/vars/mixin_types/observable.py +7 -0
  252. instaui/vars/mixin_types/pathable.py +14 -0
  253. instaui/vars/mixin_types/py_binding.py +13 -0
  254. instaui/vars/mixin_types/str_format_binding.py +8 -0
  255. instaui/vars/mixin_types/var_type.py +5 -0
  256. instaui/vars/path_var.py +90 -0
  257. instaui/vars/ref.py +103 -0
  258. instaui/vars/slot_prop.py +46 -0
  259. instaui/vars/state.py +97 -0
  260. instaui/vars/types.py +24 -0
  261. instaui/vars/vfor_item.py +204 -0
  262. instaui/vars/vue_computed.py +81 -0
  263. instaui/vars/web_computed.py +209 -0
  264. instaui/vars/web_view_computed.py +1 -0
  265. instaui/version.py +3 -0
  266. instaui/watch/_types.py +4 -0
  267. instaui/watch/_utils.py +3 -0
  268. instaui/watch/js_watch.py +110 -0
  269. instaui/watch/vue_watch.py +77 -0
  270. instaui/watch/web_watch.py +181 -0
  271. instaui/webview/__init__.py +2 -0
  272. instaui/webview/_utils.py +8 -0
  273. instaui/webview/api.py +72 -0
  274. instaui/webview/func.py +114 -0
  275. instaui/webview/index.py +161 -0
  276. instaui/webview/resource.py +172 -0
  277. instaui/zero/__init__.py +3 -0
  278. instaui/zero/func.py +123 -0
  279. instaui/zero/scope.py +109 -0
  280. instaui-0.1.15.dist-info/METADATA +152 -0
  281. instaui-0.1.15.dist-info/RECORD +283 -0
  282. instaui-0.1.15.dist-info/WHEEL +5 -0
  283. 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