@icen.ai/ui 0.9.0 → 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.
- package/AGENTS.md +138 -80
- package/README.md +66 -91
- package/dist/base.css +208 -179
- package/dist/behaviors/accordion.mjs +8 -8
- package/dist/behaviors/ai-branch.d.mts +1 -1
- package/dist/behaviors/ai-branch.mjs +1010 -94
- package/dist/behaviors/ai-chat.d.mts +7 -7
- package/dist/behaviors/ai-chat.mjs +1071 -161
- package/dist/behaviors/ai-composer.d.mts +44 -12
- package/dist/behaviors/ai-composer.mjs +1997 -524
- package/dist/behaviors/ai-core.d.mts +1 -1
- package/dist/behaviors/ai-core.mjs +1016 -107
- package/dist/behaviors/ai-diff.mjs +1019 -127
- package/dist/behaviors/ai-feedback.d.mts +1 -1
- package/dist/behaviors/ai-feedback.mjs +1035 -126
- package/dist/behaviors/ai-panel.d.mts +8 -8
- package/dist/behaviors/ai-panel.mjs +1284 -266
- package/dist/behaviors/ai-provider.mjs +1003 -101
- package/dist/behaviors/ai-threads.d.mts +1 -1
- package/dist/behaviors/ai-threads.mjs +1068 -154
- package/dist/behaviors/ai-tool.d.mts +2 -2
- package/dist/behaviors/ai-tool.mjs +2037 -396
- package/dist/behaviors/ai-tools.d.mts +89 -16
- package/dist/behaviors/ai-tools.mjs +4448 -372
- package/dist/behaviors/autocomplete.d.mts +53 -0
- package/dist/behaviors/autocomplete.mjs +1600 -0
- package/dist/behaviors/back-top.d.mts +1 -1
- package/dist/behaviors/back-top.mjs +951 -14
- package/dist/behaviors/carousel.d.mts +1 -1
- package/dist/behaviors/carousel.mjs +906 -11
- package/dist/behaviors/cascader.d.mts +48 -0
- package/dist/behaviors/cascader.mjs +1853 -0
- package/dist/behaviors/charts.d.mts +72 -8
- package/dist/behaviors/charts.mjs +1901 -256
- package/dist/behaviors/code-block.d.mts +36 -0
- package/dist/behaviors/code-block.mjs +1611 -0
- package/dist/behaviors/command-palette.d.mts +9 -6
- package/dist/behaviors/command-palette.mjs +161 -59
- package/dist/behaviors/context-menu.d.mts +9 -8
- package/dist/behaviors/context-menu.mjs +1112 -44
- package/dist/behaviors/controls.d.mts +13 -13
- package/dist/behaviors/controls.mjs +989 -130
- package/dist/behaviors/copy.d.mts +21 -2
- package/dist/behaviors/copy.mjs +1206 -42
- package/dist/behaviors/datatable.d.mts +53 -3
- package/dist/behaviors/datatable.mjs +1963 -207
- package/dist/behaviors/date-picker.d.mts +0 -1
- package/dist/behaviors/date-picker.mjs +1340 -293
- package/dist/behaviors/design.d.mts +54 -0
- package/dist/behaviors/design.mjs +109 -0
- package/dist/behaviors/dropdown.d.mts +5 -6
- package/dist/behaviors/dropdown.mjs +262 -110
- package/dist/behaviors/events.d.mts +120 -3
- package/dist/behaviors/events.mjs +47 -2
- package/dist/behaviors/feedback.d.mts +30 -0
- package/dist/behaviors/feedback.mjs +296 -0
- package/dist/behaviors/focus.d.mts +8 -0
- package/dist/behaviors/focus.mjs +24 -0
- package/dist/behaviors/form-validate.d.mts +102 -0
- package/dist/behaviors/form-validate.mjs +6091 -0
- package/dist/behaviors/i18n.d.mts +789 -0
- package/dist/behaviors/i18n.mjs +1711 -0
- package/dist/behaviors/icons.d.mts +93 -0
- package/dist/behaviors/icons.mjs +113 -0
- package/dist/behaviors/input.d.mts +9 -1
- package/dist/behaviors/input.mjs +1056 -60
- package/dist/behaviors/kb-access.d.mts +1 -1
- package/dist/behaviors/kb-access.mjs +2129 -239
- package/dist/behaviors/kb-acl.d.mts +6 -6
- package/dist/behaviors/kb-acl.mjs +1119 -179
- package/dist/behaviors/kb-answer.mjs +2070 -418
- package/dist/behaviors/kb-audit.d.mts +1 -1
- package/dist/behaviors/kb-audit.mjs +1076 -154
- package/dist/behaviors/kb-canvas.mjs +1100 -177
- package/dist/behaviors/kb-chain.mjs +1022 -100
- package/dist/behaviors/kb-checkpoint.d.mts +1 -1
- package/dist/behaviors/kb-checkpoint.mjs +1319 -169
- package/dist/behaviors/kb-chunks.mjs +1152 -213
- package/dist/behaviors/kb-citation.d.mts +1 -1
- package/dist/behaviors/kb-citation.mjs +1201 -179
- package/dist/behaviors/kb-clarify.mjs +1058 -130
- package/dist/behaviors/kb-conflict.mjs +1041 -119
- package/dist/behaviors/kb-connector.mjs +1104 -176
- package/dist/behaviors/kb-core.d.mts +6 -1
- package/dist/behaviors/kb-core.mjs +1077 -162
- package/dist/behaviors/kb-eval.mjs +1971 -144
- package/dist/behaviors/kb-explain.d.mts +1 -1
- package/dist/behaviors/kb-explain.mjs +1024 -102
- package/dist/behaviors/kb-filter.mjs +2008 -178
- package/dist/behaviors/kb-gap.d.mts +1 -1
- package/dist/behaviors/kb-gap.mjs +1043 -121
- package/dist/behaviors/kb-hittest.d.mts +1 -1
- package/dist/behaviors/kb-hittest.mjs +1093 -150
- package/dist/behaviors/kb-metadata.mjs +1052 -130
- package/dist/behaviors/kb-passage.d.mts +2 -2
- package/dist/behaviors/kb-passage.mjs +1101 -161
- package/dist/behaviors/kb-pipeline.d.mts +2 -2
- package/dist/behaviors/kb-pipeline.mjs +1082 -162
- package/dist/behaviors/kb-qa.mjs +1088 -160
- package/dist/behaviors/kb-rerank.mjs +1047 -114
- package/dist/behaviors/kb-retrieval.mjs +2063 -224
- package/dist/behaviors/kb-review.mjs +1990 -159
- package/dist/behaviors/kb-sandbox.d.mts +1 -1
- package/dist/behaviors/kb-sandbox.mjs +1026 -104
- package/dist/behaviors/kb-segment.mjs +1111 -179
- package/dist/behaviors/kb-select.d.mts +24 -0
- package/dist/behaviors/kb-select.mjs +1989 -0
- package/dist/behaviors/kb-sources.d.mts +1 -1
- package/dist/behaviors/kb-sources.mjs +1084 -170
- package/dist/behaviors/kb-sql.d.mts +1 -1
- package/dist/behaviors/kb-sql.mjs +1143 -226
- package/dist/behaviors/kb-trace.d.mts +1 -1
- package/dist/behaviors/kb-trace.mjs +1042 -128
- package/dist/behaviors/kb-visibility.mjs +1086 -158
- package/dist/behaviors/kb-who-can.mjs +1974 -137
- package/dist/behaviors/mentions.d.mts +93 -0
- package/dist/behaviors/mentions.mjs +2152 -0
- package/dist/behaviors/modal.d.mts +4 -3
- package/dist/behaviors/modal.mjs +1055 -33
- package/dist/behaviors/nav.d.mts +1 -1
- package/dist/behaviors/nav.mjs +6 -6
- package/dist/behaviors/notification.d.mts +16 -8
- package/dist/behaviors/notification.mjs +1615 -265
- package/dist/behaviors/panel.d.mts +4 -0
- package/dist/behaviors/panel.mjs +994 -0
- package/dist/behaviors/popover.d.mts +28 -5
- package/dist/behaviors/popover.mjs +225 -24
- package/dist/behaviors/select.d.mts +5 -2
- package/dist/behaviors/select.mjs +1410 -117
- package/dist/behaviors/sidebar.d.mts +1 -1
- package/dist/behaviors/sidebar.mjs +13 -13
- package/dist/behaviors/slider.d.mts +1 -1
- package/dist/behaviors/slider.mjs +9 -9
- package/dist/behaviors/split-pane.d.mts +1 -1
- package/dist/behaviors/split-pane.mjs +7 -7
- package/dist/behaviors/suggestions.d.mts +27 -0
- package/dist/behaviors/suggestions.mjs +1089 -0
- package/dist/behaviors/svg-parse.d.mts +14 -0
- package/dist/behaviors/svg-parse.mjs +37 -0
- package/dist/behaviors/tabs.d.mts +2 -2
- package/dist/behaviors/tabs.mjs +25 -25
- package/dist/behaviors/tag-input.d.mts +23 -5
- package/dist/behaviors/tag-input.mjs +1359 -104
- package/dist/behaviors/theme-switcher.d.mts +24 -0
- package/dist/behaviors/theme-switcher.mjs +1981 -0
- package/dist/behaviors/theme.d.mts +15 -8
- package/dist/behaviors/theme.mjs +390 -28
- package/dist/behaviors/toast.d.mts +24 -25
- package/dist/behaviors/toast.mjs +1266 -88
- package/dist/behaviors/tooltip.d.mts +4 -0
- package/dist/behaviors/tooltip.mjs +378 -0
- package/dist/behaviors/tree-select.d.mts +69 -0
- package/dist/behaviors/tree-select.mjs +1907 -0
- package/dist/behaviors/tree.d.mts +1 -1
- package/dist/behaviors/tree.mjs +15 -15
- package/dist/behaviors/upload.d.mts +3 -2
- package/dist/behaviors/upload.mjs +1076 -66
- package/dist/cli.mjs +5 -6
- package/dist/components/ai-chat.css +666 -573
- package/dist/components/ai-diff.css +153 -132
- package/dist/components/ai-panel.css +351 -343
- package/dist/components/ai-tool.css +393 -238
- package/dist/components/autocomplete.css +61 -0
- package/dist/components/autocomplete.mjs +3 -0
- package/dist/components/back-top.css +34 -31
- package/dist/components/badge.css +44 -41
- package/dist/components/breadcrumb.css +67 -46
- package/dist/components/btn.css +80 -74
- package/dist/components/card.css +117 -106
- package/dist/components/cascader.css +311 -0
- package/dist/components/cascader.mjs +3 -0
- package/dist/components/chart-area.css +8 -2
- package/dist/components/chart-bar.css +95 -33
- package/dist/components/chart-gauge.css +14 -11
- package/dist/components/chart-graph.css +20 -17
- package/dist/components/chart-heatmap.css +96 -90
- package/dist/components/chart-line.css +8 -3
- package/dist/components/chart-pie.css +9 -6
- package/dist/components/chart-radar.css +8 -5
- package/dist/components/chart-scatter.css +9 -6
- package/dist/components/chart-sparkline.css +5 -2
- package/dist/components/chart-stack.css +14 -11
- package/dist/components/charts.css +164 -73
- package/dist/components/code-block.css +418 -0
- package/dist/components/code-block.mjs +4 -0
- package/dist/components/command-palette.css +138 -117
- package/dist/components/content.css +257 -251
- package/dist/components/copy.css +72 -44
- package/dist/components/datatable.css +423 -181
- package/dist/components/date-picker.css +135 -104
- package/dist/components/empty.css +68 -65
- package/dist/components/feedback.css +201 -183
- package/dist/components/form-validate.css +120 -0
- package/dist/components/form-validate.mjs +3 -0
- package/dist/components/form.css +150 -127
- package/dist/components/icon.css +102 -0
- package/dist/components/icon.mjs +3 -0
- package/dist/components/input.css +159 -104
- package/dist/components/kb-agent.css +188 -173
- package/dist/components/kb-data.css +257 -253
- package/dist/components/kb-ground.css +197 -185
- package/dist/components/kb-ingest.css +334 -350
- package/dist/components/kb-ops.css +265 -259
- package/dist/components/kb-perm.css +260 -271
- package/dist/components/kb-search.css +317 -360
- package/dist/components/kb.css +120 -109
- package/dist/components/layout.css +85 -82
- package/dist/components/material-chinese.css +73 -0
- package/dist/components/material-soviet.css +76 -0
- package/dist/components/material.css +275 -0
- package/dist/components/media.css +220 -166
- package/dist/components/mentions.css +189 -0
- package/dist/components/mentions.mjs +3 -0
- package/dist/components/menu.css +113 -105
- package/dist/components/modal.css +107 -112
- package/dist/components/nav.css +118 -115
- package/dist/components/notification.css +238 -174
- package/dist/components/pagination.css +56 -53
- package/dist/components/panel.css +66 -63
- package/dist/components/panel.mjs +1 -0
- package/dist/components/pill.css +81 -71
- package/dist/components/popover.css +67 -53
- package/dist/components/scroll-area.css +113 -110
- package/dist/components/segmented.css +146 -143
- package/dist/components/select.css +206 -186
- package/dist/components/sidebar.css +137 -127
- package/dist/components/slider.css +117 -114
- package/dist/components/split-pane.css +112 -109
- package/dist/components/stat.css +112 -106
- package/dist/components/steps.css +109 -103
- package/dist/components/switch.css +138 -134
- package/dist/components/table.css +131 -107
- package/dist/components/tabs.css +114 -108
- package/dist/components/tag-input.css +48 -133
- package/dist/components/tag.css +81 -71
- package/dist/components/theme-switcher.css +105 -0
- package/dist/components/theme-switcher.mjs +3 -0
- package/dist/components/toast.css +100 -86
- package/dist/components/toolbar.css +45 -42
- package/dist/components/tooltip.css +102 -43
- package/dist/components/tooltip.mjs +1 -0
- package/dist/components/tree-select.css +416 -0
- package/dist/components/tree-select.mjs +3 -0
- package/dist/components/upload.css +135 -92
- package/dist/fonts/LICENSES/ark-pixel/OFL.txt +96 -0
- package/dist/fonts/LICENSES/cubic-11/OFL.txt +108 -0
- package/dist/fonts/LICENSES/galmuri/LICENSE.txt +93 -0
- package/dist/fonts/OFL.txt +96 -0
- package/dist/fonts/README.md +14 -0
- package/dist/fonts/fusion-pixel-12px-zh-hans.woff2 +0 -0
- package/dist/index.d.mts +28 -14
- package/dist/index.mjs +20705 -9601
- package/dist/react.d.mts +91 -0
- package/dist/react.mjs +8208 -0
- package/dist/registry.json +130 -13
- package/dist/tokens/chinese.css +44 -0
- package/dist/tokens/colors.css +365 -1222
- package/dist/tokens/design.css +109 -0
- package/dist/tokens/dtcg.json +11198 -0
- package/dist/tokens/figma.variables.json +7017 -0
- package/dist/tokens/icon-masks.css +78 -0
- package/dist/tokens/pixel.css +50 -0
- package/dist/tokens/soviet.css +44 -0
- package/dist/tokens/style-profiles.css +36 -547
- package/dist/tokens/themes.json +308 -0
- package/dist/tokens/tokens-studio.json +6728 -0
- package/dist/tokens/typography.css +21 -18
- package/dist/tokens.css +1555 -1801
- package/dist/ui.css +11975 -9831
- package/dist/vue.d.mts +344 -0
- package/dist/vue.mjs +7781 -0
- package/docs/spec/ai-input-experience.md +75 -0
- package/docs/spec/ai-native.md +238 -147
- package/docs/spec/design-philosophy.md +189 -0
- package/docs/spec/design-primitives.md +196 -0
- package/docs/spec/kb-family.md +147 -115
- package/package.json +43 -8
- package/dist/retro-effects.css +0 -255
- package/dist/tokens/retro-effects.css +0 -255
- package/docs/research/2026-10-03-ai-kb-components.md +0 -392
- package/docs/research/2026-10-03-kb-permissions.md +0 -992
|
@@ -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;
|
package/dist/behaviors/tabs.mjs
CHANGED
|
@@ -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
|
-
|
|
3
|
-
|
|
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 };
|