@icen.ai/ui 0.8.1 → 0.10.0

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 (335) hide show
  1. package/AGENTS.md +176 -75
  2. package/README.md +66 -88
  3. package/dist/base.css +208 -179
  4. package/dist/behaviors/accordion.mjs +8 -8
  5. package/dist/behaviors/ai-branch.d.mts +19 -0
  6. package/dist/behaviors/ai-branch.mjs +1133 -0
  7. package/dist/behaviors/ai-chat.d.mts +12 -10
  8. package/dist/behaviors/ai-chat.mjs +1125 -155
  9. package/dist/behaviors/ai-composer.d.mts +44 -12
  10. package/dist/behaviors/ai-composer.mjs +2084 -523
  11. package/dist/behaviors/ai-core.d.mts +1 -1
  12. package/dist/behaviors/ai-core.mjs +1016 -107
  13. package/dist/behaviors/ai-diff.mjs +1019 -127
  14. package/dist/behaviors/ai-feedback.d.mts +26 -0
  15. package/dist/behaviors/ai-feedback.mjs +1212 -0
  16. package/dist/behaviors/ai-panel.d.mts +21 -7
  17. package/dist/behaviors/ai-panel.mjs +1308 -264
  18. package/dist/behaviors/ai-provider.mjs +1003 -101
  19. package/dist/behaviors/ai-threads.d.mts +38 -0
  20. package/dist/behaviors/ai-threads.mjs +1233 -0
  21. package/dist/behaviors/ai-tool.d.mts +2 -2
  22. package/dist/behaviors/ai-tool.mjs +2042 -396
  23. package/dist/behaviors/ai-tools.d.mts +89 -16
  24. package/dist/behaviors/ai-tools.mjs +4453 -372
  25. package/dist/behaviors/autocomplete.d.mts +53 -0
  26. package/dist/behaviors/autocomplete.mjs +1600 -0
  27. package/dist/behaviors/back-top.d.mts +1 -1
  28. package/dist/behaviors/back-top.mjs +951 -14
  29. package/dist/behaviors/carousel.d.mts +1 -1
  30. package/dist/behaviors/carousel.mjs +906 -11
  31. package/dist/behaviors/cascader.d.mts +48 -0
  32. package/dist/behaviors/cascader.mjs +1853 -0
  33. package/dist/behaviors/charts.d.mts +174 -8
  34. package/dist/behaviors/charts.mjs +2632 -192
  35. package/dist/behaviors/code-block.d.mts +36 -0
  36. package/dist/behaviors/code-block.mjs +1611 -0
  37. package/dist/behaviors/command-palette.d.mts +9 -6
  38. package/dist/behaviors/command-palette.mjs +161 -59
  39. package/dist/behaviors/context-menu.d.mts +9 -8
  40. package/dist/behaviors/context-menu.mjs +1112 -44
  41. package/dist/behaviors/controls.d.mts +13 -13
  42. package/dist/behaviors/controls.mjs +989 -130
  43. package/dist/behaviors/copy.d.mts +21 -2
  44. package/dist/behaviors/copy.mjs +1206 -42
  45. package/dist/behaviors/datatable.d.mts +53 -3
  46. package/dist/behaviors/datatable.mjs +1963 -207
  47. package/dist/behaviors/date-picker.d.mts +0 -1
  48. package/dist/behaviors/date-picker.mjs +1340 -293
  49. package/dist/behaviors/design.d.mts +54 -0
  50. package/dist/behaviors/design.mjs +109 -0
  51. package/dist/behaviors/dropdown.d.mts +5 -6
  52. package/dist/behaviors/dropdown.mjs +262 -110
  53. package/dist/behaviors/events.d.mts +313 -3
  54. package/dist/behaviors/events.mjs +47 -2
  55. package/dist/behaviors/feedback.d.mts +30 -0
  56. package/dist/behaviors/feedback.mjs +296 -0
  57. package/dist/behaviors/focus.d.mts +8 -0
  58. package/dist/behaviors/focus.mjs +24 -0
  59. package/dist/behaviors/form-validate.d.mts +102 -0
  60. package/dist/behaviors/form-validate.mjs +6091 -0
  61. package/dist/behaviors/i18n.d.mts +789 -0
  62. package/dist/behaviors/i18n.mjs +1711 -0
  63. package/dist/behaviors/icons.d.mts +93 -0
  64. package/dist/behaviors/icons.mjs +113 -0
  65. package/dist/behaviors/input.d.mts +9 -1
  66. package/dist/behaviors/input.mjs +1056 -60
  67. package/dist/behaviors/kb-access.d.mts +34 -0
  68. package/dist/behaviors/kb-access.mjs +2459 -0
  69. package/dist/behaviors/kb-acl.d.mts +50 -0
  70. package/dist/behaviors/kb-acl.mjs +1345 -0
  71. package/dist/behaviors/kb-answer.d.mts +38 -0
  72. package/dist/behaviors/kb-answer.mjs +3707 -0
  73. package/dist/behaviors/kb-audit.d.mts +23 -0
  74. package/dist/behaviors/kb-audit.mjs +1297 -0
  75. package/dist/behaviors/kb-canvas.d.mts +44 -0
  76. package/dist/behaviors/kb-canvas.mjs +1512 -0
  77. package/dist/behaviors/kb-chain.d.mts +15 -0
  78. package/dist/behaviors/kb-chain.mjs +1192 -0
  79. package/dist/behaviors/kb-checkpoint.d.mts +16 -0
  80. package/dist/behaviors/kb-checkpoint.mjs +1492 -0
  81. package/dist/behaviors/kb-chunks.d.mts +31 -0
  82. package/dist/behaviors/kb-chunks.mjs +1414 -0
  83. package/dist/behaviors/kb-citation.d.mts +38 -0
  84. package/dist/behaviors/kb-citation.mjs +1699 -0
  85. package/dist/behaviors/kb-clarify.d.mts +20 -0
  86. package/dist/behaviors/kb-clarify.mjs +1176 -0
  87. package/dist/behaviors/kb-conflict.d.mts +22 -0
  88. package/dist/behaviors/kb-conflict.mjs +1206 -0
  89. package/dist/behaviors/kb-connector.d.mts +17 -0
  90. package/dist/behaviors/kb-connector.mjs +1303 -0
  91. package/dist/behaviors/kb-core.d.mts +534 -0
  92. package/dist/behaviors/kb-core.mjs +1805 -0
  93. package/dist/behaviors/kb-eval.d.mts +22 -0
  94. package/dist/behaviors/kb-eval.mjs +2235 -0
  95. package/dist/behaviors/kb-explain.d.mts +11 -0
  96. package/dist/behaviors/kb-explain.mjs +1165 -0
  97. package/dist/behaviors/kb-filter.d.mts +31 -0
  98. package/dist/behaviors/kb-filter.mjs +2417 -0
  99. package/dist/behaviors/kb-gap.d.mts +27 -0
  100. package/dist/behaviors/kb-gap.mjs +1195 -0
  101. package/dist/behaviors/kb-hittest.d.mts +34 -0
  102. package/dist/behaviors/kb-hittest.mjs +1352 -0
  103. package/dist/behaviors/kb-metadata.d.mts +29 -0
  104. package/dist/behaviors/kb-metadata.mjs +1248 -0
  105. package/dist/behaviors/kb-passage.d.mts +41 -0
  106. package/dist/behaviors/kb-passage.mjs +1469 -0
  107. package/dist/behaviors/kb-pipeline.d.mts +18 -0
  108. package/dist/behaviors/kb-pipeline.mjs +1301 -0
  109. package/dist/behaviors/kb-qa.d.mts +26 -0
  110. package/dist/behaviors/kb-qa.mjs +1260 -0
  111. package/dist/behaviors/kb-rerank.d.mts +20 -0
  112. package/dist/behaviors/kb-rerank.mjs +1248 -0
  113. package/dist/behaviors/kb-retrieval.d.mts +49 -0
  114. package/dist/behaviors/kb-retrieval.mjs +2585 -0
  115. package/dist/behaviors/kb-review.d.mts +44 -0
  116. package/dist/behaviors/kb-review.mjs +2282 -0
  117. package/dist/behaviors/kb-sandbox.d.mts +33 -0
  118. package/dist/behaviors/kb-sandbox.mjs +1247 -0
  119. package/dist/behaviors/kb-segment.d.mts +32 -0
  120. package/dist/behaviors/kb-segment.mjs +1431 -0
  121. package/dist/behaviors/kb-select.d.mts +24 -0
  122. package/dist/behaviors/kb-select.mjs +1989 -0
  123. package/dist/behaviors/kb-sources.d.mts +27 -0
  124. package/dist/behaviors/kb-sources.mjs +1287 -0
  125. package/dist/behaviors/kb-sql.d.mts +43 -0
  126. package/dist/behaviors/kb-sql.mjs +1865 -0
  127. package/dist/behaviors/kb-trace.d.mts +16 -0
  128. package/dist/behaviors/kb-trace.mjs +1328 -0
  129. package/dist/behaviors/kb-visibility.d.mts +44 -0
  130. package/dist/behaviors/kb-visibility.mjs +1331 -0
  131. package/dist/behaviors/kb-who-can.d.mts +32 -0
  132. package/dist/behaviors/kb-who-can.mjs +2216 -0
  133. package/dist/behaviors/mentions.d.mts +93 -0
  134. package/dist/behaviors/mentions.mjs +2152 -0
  135. package/dist/behaviors/modal.d.mts +4 -3
  136. package/dist/behaviors/modal.mjs +1055 -33
  137. package/dist/behaviors/nav.d.mts +1 -1
  138. package/dist/behaviors/nav.mjs +6 -6
  139. package/dist/behaviors/notification.d.mts +16 -8
  140. package/dist/behaviors/notification.mjs +1615 -265
  141. package/dist/behaviors/panel.d.mts +4 -0
  142. package/dist/behaviors/panel.mjs +994 -0
  143. package/dist/behaviors/popover.d.mts +28 -5
  144. package/dist/behaviors/popover.mjs +225 -24
  145. package/dist/behaviors/select.d.mts +5 -2
  146. package/dist/behaviors/select.mjs +1410 -117
  147. package/dist/behaviors/sidebar.d.mts +1 -1
  148. package/dist/behaviors/sidebar.mjs +13 -13
  149. package/dist/behaviors/slider.d.mts +1 -1
  150. package/dist/behaviors/slider.mjs +9 -9
  151. package/dist/behaviors/split-pane.d.mts +1 -1
  152. package/dist/behaviors/split-pane.mjs +7 -7
  153. package/dist/behaviors/suggestions.d.mts +27 -0
  154. package/dist/behaviors/suggestions.mjs +1089 -0
  155. package/dist/behaviors/svg-parse.d.mts +14 -0
  156. package/dist/behaviors/svg-parse.mjs +37 -0
  157. package/dist/behaviors/tabs.d.mts +2 -2
  158. package/dist/behaviors/tabs.mjs +25 -25
  159. package/dist/behaviors/tag-input.d.mts +23 -5
  160. package/dist/behaviors/tag-input.mjs +1359 -104
  161. package/dist/behaviors/theme-switcher.d.mts +24 -0
  162. package/dist/behaviors/theme-switcher.mjs +1981 -0
  163. package/dist/behaviors/theme.d.mts +15 -8
  164. package/dist/behaviors/theme.mjs +390 -28
  165. package/dist/behaviors/toast.d.mts +24 -25
  166. package/dist/behaviors/toast.mjs +1266 -88
  167. package/dist/behaviors/tooltip.d.mts +4 -0
  168. package/dist/behaviors/tooltip.mjs +378 -0
  169. package/dist/behaviors/tree-select.d.mts +69 -0
  170. package/dist/behaviors/tree-select.mjs +1907 -0
  171. package/dist/behaviors/tree.d.mts +1 -1
  172. package/dist/behaviors/tree.mjs +15 -15
  173. package/dist/behaviors/upload.d.mts +3 -2
  174. package/dist/behaviors/upload.mjs +1076 -66
  175. package/dist/cli.mjs +5 -6
  176. package/dist/components/ai-branch.mjs +3 -0
  177. package/dist/components/ai-chat.css +846 -458
  178. package/dist/components/ai-diff.css +153 -132
  179. package/dist/components/ai-feedback.mjs +3 -0
  180. package/dist/components/ai-panel.css +495 -270
  181. package/dist/components/ai-threads.mjs +3 -0
  182. package/dist/components/ai-tool.css +393 -238
  183. package/dist/components/autocomplete.css +61 -0
  184. package/dist/components/autocomplete.mjs +3 -0
  185. package/dist/components/back-top.css +34 -31
  186. package/dist/components/badge.css +44 -41
  187. package/dist/components/breadcrumb.css +67 -46
  188. package/dist/components/btn.css +80 -74
  189. package/dist/components/card.css +117 -106
  190. package/dist/components/cascader.css +311 -0
  191. package/dist/components/cascader.mjs +3 -0
  192. package/dist/components/chart-area.css +8 -2
  193. package/dist/components/chart-bar.css +95 -33
  194. package/dist/components/chart-gauge.css +14 -11
  195. package/dist/components/chart-graph.css +60 -0
  196. package/dist/components/chart-graph.mjs +4 -0
  197. package/dist/components/chart-heatmap.css +96 -90
  198. package/dist/components/chart-line.css +8 -3
  199. package/dist/components/chart-map.mjs +3 -0
  200. package/dist/components/chart-pie.css +9 -6
  201. package/dist/components/chart-radar.css +8 -5
  202. package/dist/components/chart-scatter.css +9 -6
  203. package/dist/components/chart-scatter.mjs +1 -1
  204. package/dist/components/chart-sparkline.css +5 -2
  205. package/dist/components/chart-stack.css +14 -11
  206. package/dist/components/charts.css +190 -67
  207. package/dist/components/charts.mjs +1 -0
  208. package/dist/components/code-block.css +418 -0
  209. package/dist/components/code-block.mjs +4 -0
  210. package/dist/components/command-palette.css +138 -117
  211. package/dist/components/content.css +257 -251
  212. package/dist/components/copy.css +72 -44
  213. package/dist/components/datatable.css +423 -181
  214. package/dist/components/date-picker.css +135 -104
  215. package/dist/components/empty.css +68 -65
  216. package/dist/components/feedback.css +201 -183
  217. package/dist/components/form-validate.css +120 -0
  218. package/dist/components/form-validate.mjs +3 -0
  219. package/dist/components/form.css +150 -127
  220. package/dist/components/icon.css +102 -0
  221. package/dist/components/icon.mjs +3 -0
  222. package/dist/components/input.css +159 -104
  223. package/dist/components/kb-access.mjs +4 -0
  224. package/dist/components/kb-acl.mjs +4 -0
  225. package/dist/components/kb-agent.css +496 -0
  226. package/dist/components/kb-answer.mjs +4 -0
  227. package/dist/components/kb-audit.mjs +4 -0
  228. package/dist/components/kb-canvas.mjs +4 -0
  229. package/dist/components/kb-chain.mjs +4 -0
  230. package/dist/components/kb-checkpoint.mjs +4 -0
  231. package/dist/components/kb-chunks.mjs +4 -0
  232. package/dist/components/kb-citation.mjs +4 -0
  233. package/dist/components/kb-clarify.mjs +4 -0
  234. package/dist/components/kb-conflict.mjs +4 -0
  235. package/dist/components/kb-connector.mjs +4 -0
  236. package/dist/components/kb-data.css +653 -0
  237. package/dist/components/kb-eval.mjs +4 -0
  238. package/dist/components/kb-explain.mjs +4 -0
  239. package/dist/components/kb-filter.mjs +4 -0
  240. package/dist/components/kb-gap.mjs +4 -0
  241. package/dist/components/kb-ground.css +578 -0
  242. package/dist/components/kb-hittest.mjs +4 -0
  243. package/dist/components/kb-ingest.css +882 -0
  244. package/dist/components/kb-metadata.mjs +4 -0
  245. package/dist/components/kb-ops.css +554 -0
  246. package/dist/components/kb-passage.mjs +4 -0
  247. package/dist/components/kb-perm.css +433 -0
  248. package/dist/components/kb-pipeline.mjs +4 -0
  249. package/dist/components/kb-qa.mjs +4 -0
  250. package/dist/components/kb-rerank.mjs +4 -0
  251. package/dist/components/kb-retrieval.mjs +4 -0
  252. package/dist/components/kb-review.mjs +4 -0
  253. package/dist/components/kb-sandbox.mjs +4 -0
  254. package/dist/components/kb-search.css +897 -0
  255. package/dist/components/kb-segment.mjs +4 -0
  256. package/dist/components/kb-sources.mjs +4 -0
  257. package/dist/components/kb-sql.mjs +4 -0
  258. package/dist/components/kb-trace.mjs +4 -0
  259. package/dist/components/kb-visibility.mjs +4 -0
  260. package/dist/components/kb-who-can.mjs +4 -0
  261. package/dist/components/kb.css +263 -0
  262. package/dist/components/kb.mjs +9 -0
  263. package/dist/components/layout.css +85 -82
  264. package/dist/components/material-chinese.css +73 -0
  265. package/dist/components/material-soviet.css +76 -0
  266. package/dist/components/material.css +275 -0
  267. package/dist/components/media.css +220 -166
  268. package/dist/components/mentions.css +189 -0
  269. package/dist/components/mentions.mjs +3 -0
  270. package/dist/components/menu.css +113 -105
  271. package/dist/components/modal.css +107 -112
  272. package/dist/components/nav.css +118 -115
  273. package/dist/components/notification.css +238 -174
  274. package/dist/components/pagination.css +56 -53
  275. package/dist/components/panel.css +66 -63
  276. package/dist/components/panel.mjs +1 -0
  277. package/dist/components/pill.css +81 -71
  278. package/dist/components/popover.css +67 -53
  279. package/dist/components/scroll-area.css +113 -110
  280. package/dist/components/segmented.css +146 -143
  281. package/dist/components/select.css +206 -186
  282. package/dist/components/sidebar.css +137 -127
  283. package/dist/components/slider.css +117 -114
  284. package/dist/components/split-pane.css +112 -109
  285. package/dist/components/stat.css +112 -106
  286. package/dist/components/steps.css +109 -103
  287. package/dist/components/switch.css +138 -134
  288. package/dist/components/table.css +131 -107
  289. package/dist/components/tabs.css +114 -108
  290. package/dist/components/tag-input.css +48 -133
  291. package/dist/components/tag.css +81 -71
  292. package/dist/components/theme-switcher.css +105 -0
  293. package/dist/components/theme-switcher.mjs +3 -0
  294. package/dist/components/toast.css +100 -86
  295. package/dist/components/toolbar.css +45 -42
  296. package/dist/components/tooltip.css +102 -43
  297. package/dist/components/tooltip.mjs +1 -0
  298. package/dist/components/tree-select.css +416 -0
  299. package/dist/components/tree-select.mjs +3 -0
  300. package/dist/components/upload.css +135 -92
  301. package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
  302. package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
  303. package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
  304. package/dist/fonts/OFL.txt +96 -0
  305. package/dist/fonts/README.md +14 -0
  306. package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
  307. package/dist/index.d.mts +64 -15
  308. package/dist/index.mjs +28049 -8595
  309. package/dist/react.d.mts +91 -0
  310. package/dist/react.mjs +8208 -0
  311. package/dist/registry.json +454 -15
  312. package/dist/tokens/chinese.css +44 -0
  313. package/dist/tokens/colors.css +365 -1222
  314. package/dist/tokens/design.css +109 -0
  315. package/dist/tokens/dtcg.json +11198 -0
  316. package/dist/tokens/figma.variables.json +7017 -0
  317. package/dist/tokens/icon-masks.css +78 -0
  318. package/dist/tokens/pixel.css +50 -0
  319. package/dist/tokens/soviet.css +44 -0
  320. package/dist/tokens/style-profiles.css +36 -547
  321. package/dist/tokens/themes.json +308 -0
  322. package/dist/tokens/tokens-studio.json +6728 -0
  323. package/dist/tokens/typography.css +21 -18
  324. package/dist/tokens.css +1555 -1801
  325. package/dist/ui.css +16147 -8597
  326. package/dist/vue.d.mts +344 -0
  327. package/dist/vue.mjs +7781 -0
  328. package/docs/spec/ai-input-experience.md +75 -0
  329. package/docs/spec/ai-native.md +238 -147
  330. package/docs/spec/design-philosophy.md +189 -0
  331. package/docs/spec/design-primitives.md +196 -0
  332. package/docs/spec/kb-family.md +475 -0
  333. package/package.json +42 -7
  334. package/dist/retro-effects.css +0 -255
  335. package/dist/tokens/retro-effects.css +0 -255
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @icen.ai/ui — 内联 SVG 字符串 → 消毒 SVGElement(全库单点,ai-core.svgIcon / notification / toast /
3
+ * back-top / charts 全部经此)。SSR 安全:无 document/DOMParser 返回 null。
4
+ *
5
+ * 纪律:
6
+ * - 缺 xmlns 自动补——image/svg+xml 是 XML 严格解析,无 xmlns 的 <svg> 落在空命名空间,
7
+ * 浏览器一律不渲染(图标作者按 HTML 习惯常省 xmlns,曾致库内 19 处图标存量隐身);
8
+ * - 消毒:剥全部 on* 事件属性、剔除 script/foreignObject 子树、剔除 javascript: 协议的
9
+ * href/xlink:href(纵深防御);
10
+ * - 只接纳 <svg> 根元素,解析失败/含 parsererror 返回 null(不猜不兜底)。
11
+ */
12
+ declare function parseSvg(source: string): SVGElement | null;
13
+
14
+ export { parseSvg };
@@ -0,0 +1,37 @@
1
+ // src/behaviors/svg-parse.ts
2
+ function parseSvg(source) {
3
+ if (typeof document === "undefined" || typeof DOMParser === "undefined") return null;
4
+ const trimmed = source.trimStart();
5
+ if (!trimmed.startsWith("<svg")) return null;
6
+ const src = /^<svg(?![^>]*\bxmlns[=:])/i.test(trimmed) ? trimmed.replace(/^<svg/i, '<svg xmlns="http://www.w3.org/2000/svg"') : trimmed;
7
+ let parsed;
8
+ try {
9
+ parsed = new DOMParser().parseFromString(src, "image/svg+xml");
10
+ } catch {
11
+ return null;
12
+ }
13
+ const root = parsed.documentElement;
14
+ if (!root || root.tagName.toLowerCase() !== "svg" || parsed.querySelector("parsererror")) return null;
15
+ const sanitize = (el) => {
16
+ for (const attr of Array.from(el.attributes)) {
17
+ const name = attr.name.toLowerCase();
18
+ if (name.startsWith("on")) el.removeAttribute(attr.name);
19
+ if ((name === "href" || name === "xlink:href") && attr.value.trim().toLowerCase().startsWith("javascript:")) {
20
+ el.removeAttribute(attr.name);
21
+ }
22
+ }
23
+ for (const child of Array.from(el.children)) {
24
+ const tag = child.tagName.toLowerCase();
25
+ if (tag === "script" || tag === "foreignobject") {
26
+ child.remove();
27
+ continue;
28
+ }
29
+ sanitize(child);
30
+ }
31
+ };
32
+ sanitize(root);
33
+ return document.importNode(root, true);
34
+ }
35
+ export {
36
+ parseSvg
37
+ };
@@ -1,7 +1,7 @@
1
1
  /**
2
- * 为 root 下每个 [data-tabs] 容器初始化(root 自身是 [data-tabs] 也算)。
2
+ * 为 root 下每个 [data-icen-tabs] 容器初始化(root 自身是 [data-icen-tabs] 也算)。
3
3
  * 返回销毁函数:调用后移除所有容器监听、window hashchange/resize 监听与行为层创建的
4
- * .tabs-ink 元素,并复位幂等标记(销毁后的容器可被再次 initTabs 重新接管)。
4
+ * .icen-tabs-ink 元素,并复位幂等标记(销毁后的容器可被再次 initTabs 重新接管)。
5
5
  * SSR 下返回 no-op 函数。
6
6
  */
7
7
  declare function initTabs(root?: ParentNode): () => void;
@@ -7,24 +7,24 @@ function emitIcen(source, type, detail) {
7
7
 
8
8
  // src/behaviors/tabs.ts
9
9
  function tabButtons(container) {
10
- return Array.from(container.querySelectorAll("[data-tab]"));
10
+ return Array.from(container.querySelectorAll("[data-icen-tab]"));
11
11
  }
12
12
  function tabNames(container) {
13
- return tabButtons(container).map((t) => t.getAttribute("data-tab")).filter((n) => n !== null);
13
+ return tabButtons(container).map((t) => t.getAttribute("data-icen-tab")).filter((n) => n !== null);
14
14
  }
15
15
  function currentHash() {
16
16
  return window.location.hash.replace(/^#/, "");
17
17
  }
18
18
  function hashWriteMethod(container) {
19
- const raw = container.getAttribute("data-tabs-hash");
19
+ const raw = container.getAttribute("data-icen-tabs-hash");
20
20
  if (raw === null || raw === "false") return null;
21
21
  return raw === "push" ? "push" : "replace";
22
22
  }
23
23
  function syncInk(container, name) {
24
- const btn = tabButtons(container).find((b) => b.getAttribute("data-tab") === name);
24
+ const btn = tabButtons(container).find((b) => b.getAttribute("data-icen-tab") === name);
25
25
  const tablist = btn?.parentElement;
26
26
  if (!btn || !tablist) return;
27
- const ink = tablist.querySelector(":scope > .tabs-ink");
27
+ const ink = tablist.querySelector(":scope > .icen-tabs-ink");
28
28
  if (!ink) return;
29
29
  ink.style.width = `${btn.offsetWidth}px`;
30
30
  ink.style.transform = `translateX(${btn.offsetLeft}px)`;
@@ -33,7 +33,7 @@ function activate(container, name, writeHash, emit = false) {
33
33
  const buttons = tabButtons(container);
34
34
  let matched = false;
35
35
  buttons.forEach((t) => {
36
- const on = t.getAttribute("data-tab") === name;
36
+ const on = t.getAttribute("data-icen-tab") === name;
37
37
  if (on) matched = true;
38
38
  t.classList.toggle("is-active", on);
39
39
  t.setAttribute("aria-selected", String(on));
@@ -41,13 +41,13 @@ function activate(container, name, writeHash, emit = false) {
41
41
  });
42
42
  if (!matched) return;
43
43
  let panel = null;
44
- container.querySelectorAll("[data-tab-panel]").forEach((p) => {
45
- const isOn = p.getAttribute("data-tab-panel") === name;
44
+ container.querySelectorAll("[data-icen-tab-panel]").forEach((p) => {
45
+ const isOn = p.getAttribute("data-icen-tab-panel") === name;
46
46
  p.hidden = !isOn;
47
47
  if (isOn) {
48
48
  panel = p;
49
49
  if (!p.getAttribute("aria-labelledby")) {
50
- const btn = buttons.find((b) => b.getAttribute("data-tab") === name);
50
+ const btn = buttons.find((b) => b.getAttribute("data-icen-tab") === name);
51
51
  if (btn?.id) p.setAttribute("aria-labelledby", btn.id);
52
52
  }
53
53
  }
@@ -58,7 +58,7 @@ function activate(container, name, writeHash, emit = false) {
58
58
  }
59
59
  syncInk(container, name);
60
60
  if (emit) {
61
- const index = buttons.findIndex((b) => b.getAttribute("data-tab") === name);
61
+ const index = buttons.findIndex((b) => b.getAttribute("data-icen-tab") === name);
62
62
  const tab = buttons[index] ?? null;
63
63
  emitIcen(container, "icen:tab-change", { tab, panel, index });
64
64
  }
@@ -86,7 +86,7 @@ function setup(container) {
86
86
  const el = container;
87
87
  if (el.__icenTabsInit) return void 0;
88
88
  const useHash = hashWriteMethod(container) !== null;
89
- const autoActivate = container.getAttribute("data-tabs-activation") === "auto";
89
+ const autoActivate = container.getAttribute("data-icen-tabs-activation") === "auto";
90
90
  const names = tabNames(container);
91
91
  if (names.length === 0) return;
92
92
  el.__icenTabsInit = true;
@@ -98,11 +98,11 @@ function setup(container) {
98
98
  const tablist = buttons[0]?.parentElement;
99
99
  if (tablist && !tablist.getAttribute("role")) tablist.setAttribute("role", "tablist");
100
100
  let ink = null;
101
- if (tablist instanceof HTMLElement && tablist.hasAttribute("data-tabs-ink")) {
101
+ if (tablist instanceof HTMLElement && tablist.hasAttribute("data-icen-tabs-ink")) {
102
102
  ink = document.createElement("div");
103
- ink.className = "tabs-ink";
103
+ ink.className = "icen-tabs-ink";
104
104
  ink.setAttribute("aria-hidden", "true");
105
- const initialBtn = buttons.find((b) => b.classList.contains("is-active")) ?? buttons.find((b) => b.getAttribute("data-tab") === names[0]);
105
+ const initialBtn = buttons.find((b) => b.classList.contains("is-active")) ?? buttons.find((b) => b.getAttribute("data-icen-tab") === names[0]);
106
106
  if (initialBtn) {
107
107
  ink.style.width = `${initialBtn.offsetWidth}px`;
108
108
  ink.style.transform = `translateX(${initialBtn.offsetLeft}px)`;
@@ -112,10 +112,10 @@ function setup(container) {
112
112
  const onClick = (ev) => {
113
113
  const target = ev.target;
114
114
  if (!(target instanceof Element)) return;
115
- const btn = target.closest("[data-tab]");
116
- if (!btn || btn.closest("[data-tabs]") !== container) return;
115
+ const btn = target.closest("[data-icen-tab]");
116
+ if (!btn || btn.closest("[data-icen-tabs]") !== container) return;
117
117
  if (btn instanceof HTMLElement && isDisabled(btn)) return;
118
- const name = btn.getAttribute("data-tab");
118
+ const name = btn.getAttribute("data-icen-tab");
119
119
  if (name) activate(container, name, useHash, true);
120
120
  };
121
121
  const followFocus = (idx) => {
@@ -123,15 +123,15 @@ function setup(container) {
123
123
  if (!autoActivate) return;
124
124
  const target = tabButtons(container)[idx];
125
125
  if (!target || isDisabled(target)) return;
126
- const name = target.getAttribute("data-tab");
126
+ const name = target.getAttribute("data-icen-tab");
127
127
  if (name) activate(container, name, useHash, true);
128
128
  };
129
129
  const onKeyDown = (ev) => {
130
130
  const kev = ev;
131
131
  const target = kev.target;
132
132
  if (!(target instanceof Element)) return;
133
- const btn = target.closest("[data-tab]");
134
- if (!btn || btn.closest("[data-tabs]") !== container) return;
133
+ const btn = target.closest("[data-icen-tab]");
134
+ if (!btn || btn.closest("[data-icen-tabs]") !== container) return;
135
135
  const buttonsList = tabButtons(container);
136
136
  const currentIdx = buttonsList.indexOf(btn);
137
137
  if (currentIdx === -1) return;
@@ -162,7 +162,7 @@ function setup(container) {
162
162
  case " ": {
163
163
  if (btn instanceof HTMLElement && !isDisabled(btn)) {
164
164
  kev.preventDefault();
165
- const name = btn.getAttribute("data-tab");
165
+ const name = btn.getAttribute("data-icen-tab");
166
166
  if (name) activate(container, name, useHash, true);
167
167
  }
168
168
  break;
@@ -176,7 +176,7 @@ function setup(container) {
176
176
  const h = currentHash();
177
177
  if (names.includes(h)) initial = h;
178
178
  } else {
179
- const n = container.querySelector("[data-tab].is-active")?.getAttribute("data-tab");
179
+ const n = container.querySelector("[data-icen-tab].is-active")?.getAttribute("data-icen-tab");
180
180
  if (n && names.includes(n)) initial = n;
181
181
  }
182
182
  activate(container, initial ?? names[0], false);
@@ -189,7 +189,7 @@ function setup(container) {
189
189
  }
190
190
  const onResize = () => {
191
191
  const active = tabButtons(container).find((b) => b.classList.contains("is-active"));
192
- const name = active?.getAttribute("data-tab");
192
+ const name = active?.getAttribute("data-icen-tab");
193
193
  if (name) syncInk(container, name);
194
194
  };
195
195
  if (ink && typeof window !== "undefined") {
@@ -213,8 +213,8 @@ function initTabs(root) {
213
213
  if (typeof document !== "undefined") {
214
214
  const scope = root ?? document;
215
215
  const containers = [];
216
- if (scope instanceof Element && scope.matches("[data-tabs]")) containers.push(scope);
217
- containers.push(...Array.from(scope.querySelectorAll("[data-tabs]")));
216
+ if (scope instanceof Element && scope.matches("[data-icen-tabs]")) containers.push(scope);
217
+ containers.push(...Array.from(scope.querySelectorAll("[data-icen-tabs]")));
218
218
  for (const c of containers) {
219
219
  const cleanup = setup(c);
220
220
  if (cleanup) cleanups.push(cleanup);
@@ -1,7 +1,25 @@
1
- /**
2
- * 为 root 下每个 .tag-input 容器初始化(root 自身匹配也算;data-tags 为可选初始值配置)。
3
- * 返回销毁函数:移除本次挂上的全部监听并复位幂等标记(销毁后可重新 init)。SSR 下返回 no-op。
4
- */
1
+ interface TagInputOptions {
2
+ value?: string[];
3
+ max?: number;
4
+ allowDuplicates?: boolean;
5
+ disabled?: boolean;
6
+ readOnly?: boolean;
7
+ /** Repeated native form entries, one per committed tag. Defaults to input.name. */
8
+ name?: string;
9
+ }
10
+ interface TagInputHandle {
11
+ getValue(): string[];
12
+ setValue(value: string[], options?: {
13
+ emit?: boolean;
14
+ }): void;
15
+ update(options: Omit<TagInputOptions, 'value'>): void;
16
+ focus(): void;
17
+ destroy(): void;
18
+ }
19
+ /** Explicit lifecycle handle; repeated creation reuses the editor and updates options. */
20
+ declare function createTagInput(root: HTMLElement, options?: TagInputOptions): TagInputHandle;
21
+ /** Dynamic scoped initialization. Overlapping scopes share each editor and only
22
+ * the last scope disposes it; an explicit createTagInput handle owns its lifecycle. */
5
23
  declare function initTagInput(root?: ParentNode): () => void;
6
24
 
7
- export { initTagInput };
25
+ export { type TagInputHandle, type TagInputOptions, createTagInput, initTagInput };