@icen.ai/ui 0.8.0 → 0.9.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 +63 -14
- package/README.md +17 -9
- package/dist/base.css +4 -3
- package/dist/behaviors/accordion.d.mts +5 -2
- package/dist/behaviors/accordion.mjs +36 -11
- package/dist/behaviors/ai-branch.d.mts +19 -0
- package/dist/behaviors/ai-branch.mjs +217 -0
- package/dist/behaviors/ai-chat.d.mts +11 -7
- package/dist/behaviors/ai-chat.mjs +134 -51
- package/dist/behaviors/ai-composer.d.mts +28 -3
- package/dist/behaviors/ai-composer.mjs +399 -229
- package/dist/behaviors/ai-core.d.mts +9 -4
- package/dist/behaviors/ai-core.mjs +21 -8
- package/dist/behaviors/ai-diff.d.mts +2 -2
- package/dist/behaviors/ai-diff.mjs +172 -41
- package/dist/behaviors/ai-feedback.d.mts +26 -0
- package/dist/behaviors/ai-feedback.mjs +303 -0
- package/dist/behaviors/ai-panel.d.mts +26 -9
- package/dist/behaviors/ai-panel.mjs +211 -110
- package/dist/behaviors/ai-provider.mjs +54 -48
- package/dist/behaviors/ai-threads.d.mts +38 -0
- package/dist/behaviors/ai-threads.mjs +319 -0
- package/dist/behaviors/ai-tool.d.mts +12 -4
- package/dist/behaviors/ai-tool.mjs +316 -263
- package/dist/behaviors/ai-tools.d.mts +9 -6
- package/dist/behaviors/ai-tools.mjs +264 -155
- package/dist/behaviors/back-top.mjs +16 -1
- package/dist/behaviors/carousel.d.mts +5 -2
- package/dist/behaviors/carousel.mjs +53 -26
- package/dist/behaviors/charts.d.mts +170 -22
- package/dist/behaviors/charts.mjs +1016 -150
- package/dist/behaviors/command-palette.d.mts +40 -6
- package/dist/behaviors/command-palette.mjs +143 -15
- package/dist/behaviors/context-menu.d.mts +21 -4
- package/dist/behaviors/context-menu.mjs +122 -38
- package/dist/behaviors/controls.d.mts +59 -0
- package/dist/behaviors/controls.mjs +601 -0
- package/dist/behaviors/copy.d.mts +5 -2
- package/dist/behaviors/copy.mjs +37 -12
- package/dist/behaviors/datatable.d.mts +12 -0
- package/dist/behaviors/datatable.mjs +226 -43
- package/dist/behaviors/date-picker.d.mts +2 -2
- package/dist/behaviors/date-picker.mjs +171 -32
- package/dist/behaviors/dropdown.d.mts +6 -2
- package/dist/behaviors/dropdown.mjs +164 -25
- package/dist/behaviors/events.d.mts +523 -0
- package/dist/behaviors/events.mjs +208 -0
- package/dist/behaviors/input.mjs +25 -12
- package/dist/behaviors/kb-access.d.mts +34 -0
- package/dist/behaviors/kb-access.mjs +569 -0
- package/dist/behaviors/kb-acl.d.mts +50 -0
- package/dist/behaviors/kb-acl.mjs +405 -0
- package/dist/behaviors/kb-answer.d.mts +38 -0
- package/dist/behaviors/kb-answer.mjs +2055 -0
- package/dist/behaviors/kb-audit.d.mts +23 -0
- package/dist/behaviors/kb-audit.mjs +375 -0
- package/dist/behaviors/kb-canvas.d.mts +44 -0
- package/dist/behaviors/kb-canvas.mjs +589 -0
- package/dist/behaviors/kb-chain.d.mts +15 -0
- package/dist/behaviors/kb-chain.mjs +270 -0
- package/dist/behaviors/kb-checkpoint.d.mts +16 -0
- package/dist/behaviors/kb-checkpoint.mjs +342 -0
- package/dist/behaviors/kb-chunks.d.mts +31 -0
- package/dist/behaviors/kb-chunks.mjs +475 -0
- package/dist/behaviors/kb-citation.d.mts +38 -0
- package/dist/behaviors/kb-citation.mjs +677 -0
- package/dist/behaviors/kb-clarify.d.mts +20 -0
- package/dist/behaviors/kb-clarify.mjs +248 -0
- package/dist/behaviors/kb-conflict.d.mts +22 -0
- package/dist/behaviors/kb-conflict.mjs +284 -0
- package/dist/behaviors/kb-connector.d.mts +17 -0
- package/dist/behaviors/kb-connector.mjs +375 -0
- package/dist/behaviors/kb-core.d.mts +529 -0
- package/dist/behaviors/kb-core.mjs +890 -0
- package/dist/behaviors/kb-eval.d.mts +22 -0
- package/dist/behaviors/kb-eval.mjs +408 -0
- package/dist/behaviors/kb-explain.d.mts +11 -0
- package/dist/behaviors/kb-explain.mjs +243 -0
- package/dist/behaviors/kb-filter.d.mts +31 -0
- package/dist/behaviors/kb-filter.mjs +587 -0
- package/dist/behaviors/kb-gap.d.mts +27 -0
- package/dist/behaviors/kb-gap.mjs +273 -0
- package/dist/behaviors/kb-hittest.d.mts +34 -0
- package/dist/behaviors/kb-hittest.mjs +409 -0
- package/dist/behaviors/kb-metadata.d.mts +29 -0
- package/dist/behaviors/kb-metadata.mjs +326 -0
- package/dist/behaviors/kb-passage.d.mts +41 -0
- package/dist/behaviors/kb-passage.mjs +529 -0
- package/dist/behaviors/kb-pipeline.d.mts +18 -0
- package/dist/behaviors/kb-pipeline.mjs +381 -0
- package/dist/behaviors/kb-qa.d.mts +26 -0
- package/dist/behaviors/kb-qa.mjs +332 -0
- package/dist/behaviors/kb-rerank.d.mts +20 -0
- package/dist/behaviors/kb-rerank.mjs +315 -0
- package/dist/behaviors/kb-retrieval.d.mts +49 -0
- package/dist/behaviors/kb-retrieval.mjs +746 -0
- package/dist/behaviors/kb-review.d.mts +44 -0
- package/dist/behaviors/kb-review.mjs +451 -0
- package/dist/behaviors/kb-sandbox.d.mts +33 -0
- package/dist/behaviors/kb-sandbox.mjs +325 -0
- package/dist/behaviors/kb-segment.d.mts +32 -0
- package/dist/behaviors/kb-segment.mjs +499 -0
- package/dist/behaviors/kb-sources.d.mts +27 -0
- package/dist/behaviors/kb-sources.mjs +373 -0
- package/dist/behaviors/kb-sql.d.mts +43 -0
- package/dist/behaviors/kb-sql.mjs +948 -0
- package/dist/behaviors/kb-trace.d.mts +16 -0
- package/dist/behaviors/kb-trace.mjs +414 -0
- package/dist/behaviors/kb-visibility.d.mts +44 -0
- package/dist/behaviors/kb-visibility.mjs +403 -0
- package/dist/behaviors/kb-who-can.d.mts +32 -0
- package/dist/behaviors/kb-who-can.mjs +379 -0
- package/dist/behaviors/modal.d.mts +24 -5
- package/dist/behaviors/modal.mjs +76 -10
- package/dist/behaviors/nav.d.mts +1 -1
- package/dist/behaviors/nav.mjs +33 -7
- package/dist/behaviors/notification.d.mts +20 -4
- package/dist/behaviors/notification.mjs +53 -73
- package/dist/behaviors/popover.d.mts +39 -3
- package/dist/behaviors/popover.mjs +90 -4
- package/dist/behaviors/select.d.mts +4 -2
- package/dist/behaviors/select.mjs +161 -24
- package/dist/behaviors/sidebar.d.mts +5 -2
- package/dist/behaviors/sidebar.mjs +43 -13
- package/dist/behaviors/slider.d.mts +5 -2
- package/dist/behaviors/slider.mjs +54 -43
- package/dist/behaviors/split-pane.d.mts +6 -2
- package/dist/behaviors/split-pane.mjs +62 -21
- package/dist/behaviors/tabs.d.mts +3 -2
- package/dist/behaviors/tabs.mjs +65 -14
- package/dist/behaviors/tag-input.d.mts +5 -2
- package/dist/behaviors/tag-input.mjs +61 -21
- package/dist/behaviors/theme.d.mts +13 -2
- package/dist/behaviors/theme.mjs +48 -4
- package/dist/behaviors/toast.d.mts +30 -8
- package/dist/behaviors/toast.mjs +74 -7
- package/dist/behaviors/tree.d.mts +5 -2
- package/dist/behaviors/tree.mjs +38 -15
- package/dist/behaviors/upload.mjs +21 -23
- package/dist/cli.mjs +1 -1
- package/dist/components/ai-branch.mjs +3 -0
- package/dist/components/ai-chat.css +295 -0
- package/dist/components/ai-feedback.mjs +3 -0
- package/dist/components/ai-panel.css +218 -1
- package/dist/components/ai-threads.mjs +3 -0
- package/dist/components/ai-tool-call.mjs +1 -1
- package/dist/components/badge.css +1 -1
- package/dist/components/breadcrumb.css +0 -32
- package/dist/components/chart-calendar.mjs +1 -2
- package/dist/components/chart-graph.css +57 -0
- package/dist/components/chart-graph.mjs +4 -0
- package/dist/components/chart-map.mjs +3 -0
- package/dist/components/chart-pie.css +0 -6
- package/dist/components/chart-scatter.mjs +1 -1
- package/dist/components/charts.css +33 -1
- package/dist/components/charts.mjs +1 -0
- package/dist/components/content.css +3 -16
- package/dist/components/datatable.css +1 -1
- package/dist/components/date-picker.css +1 -1
- package/dist/components/kb-access.mjs +4 -0
- package/dist/components/kb-acl.mjs +4 -0
- package/dist/components/kb-agent.css +481 -0
- package/dist/components/kb-answer.mjs +4 -0
- package/dist/components/kb-audit.mjs +4 -0
- package/dist/components/kb-canvas.mjs +4 -0
- package/dist/components/kb-chain.mjs +4 -0
- package/dist/components/kb-checkpoint.mjs +4 -0
- package/dist/components/kb-chunks.mjs +4 -0
- package/dist/components/kb-citation.mjs +4 -0
- package/dist/components/kb-clarify.mjs +4 -0
- package/dist/components/kb-conflict.mjs +4 -0
- package/dist/components/kb-connector.mjs +4 -0
- package/dist/components/kb-data.css +649 -0
- package/dist/components/kb-eval.mjs +4 -0
- package/dist/components/kb-explain.mjs +4 -0
- package/dist/components/kb-filter.mjs +4 -0
- package/dist/components/kb-gap.mjs +4 -0
- package/dist/components/kb-ground.css +566 -0
- package/dist/components/kb-hittest.mjs +4 -0
- package/dist/components/kb-ingest.css +898 -0
- package/dist/components/kb-metadata.mjs +4 -0
- package/dist/components/kb-ops.css +548 -0
- package/dist/components/kb-passage.mjs +4 -0
- package/dist/components/kb-perm.css +444 -0
- package/dist/components/kb-pipeline.mjs +4 -0
- package/dist/components/kb-qa.mjs +4 -0
- package/dist/components/kb-rerank.mjs +4 -0
- package/dist/components/kb-retrieval.mjs +4 -0
- package/dist/components/kb-review.mjs +4 -0
- package/dist/components/kb-sandbox.mjs +4 -0
- package/dist/components/kb-search.css +940 -0
- package/dist/components/kb-segment.mjs +4 -0
- package/dist/components/kb-sources.mjs +4 -0
- package/dist/components/kb-sql.mjs +4 -0
- package/dist/components/kb-trace.mjs +4 -0
- package/dist/components/kb-visibility.mjs +4 -0
- package/dist/components/kb-who-can.mjs +4 -0
- package/dist/components/kb.css +252 -0
- package/dist/components/kb.mjs +9 -0
- package/dist/components/notification.css +2 -3
- package/dist/components/pagination.css +3 -1
- package/dist/components/pagination.mjs +1 -0
- package/dist/components/rating.mjs +1 -0
- package/dist/components/segmented.css +9 -1
- package/dist/components/segmented.mjs +1 -1
- package/dist/components/select.css +67 -4
- package/dist/components/steps.css +13 -3
- package/dist/components/steps.mjs +1 -0
- package/dist/components/switch.css +3 -1
- package/dist/components/switch.mjs +1 -0
- package/dist/components/table.mjs +1 -0
- package/dist/components/tabs.css +23 -0
- package/dist/components/tag-input.css +1 -6
- package/dist/components/upload.css +0 -15
- package/dist/index.d.mts +48 -11
- package/dist/index.mjs +13205 -3615
- package/dist/registry.json +366 -15
- package/dist/retro-effects.css +3 -16
- package/dist/tokens/retro-effects.css +3 -16
- package/dist/tokens/style-profiles.css +3 -2
- package/dist/tokens/typography.css +2 -0
- package/dist/tokens.css +5 -2
- package/dist/ui.css +5713 -267
- package/docs/research/2026-10-03-ai-kb-components.md +392 -0
- package/docs/research/2026-10-03-kb-permissions.md +992 -0
- package/docs/spec/ai-native.md +7 -4
- package/docs/spec/kb-family.md +443 -0
- package/package.json +2 -2
|
@@ -1,8 +1,42 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
/**
|
|
1
|
+
/** 编程命令条目(openCommandPalette 的 opts.items 元素类型)。 */
|
|
2
|
+
interface CommandPaletteCommand {
|
|
3
|
+
/** 条目名(.command-palette-item-label,textContent 渲染) */
|
|
4
|
+
label: string;
|
|
5
|
+
/** 副标题(.command-palette-item-hint) */
|
|
6
|
+
hint?: string;
|
|
7
|
+
/** 额外搜索关键字(data-command-palette-keyword) */
|
|
8
|
+
keyword?: string;
|
|
9
|
+
/** 选中回调:先派 icen:menu-select,再执行本回调 */
|
|
10
|
+
onSelect?: () => void;
|
|
11
|
+
/** 选中后保持面板打开(data-command-palette-keep-open) */
|
|
12
|
+
keepOpen?: boolean;
|
|
13
|
+
/** 附加到条目元素的自定义属性(如 data-*) */
|
|
14
|
+
attrs?: Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
interface CommandPaletteOpenOptions {
|
|
17
|
+
/** 编程条目:传入时重建面板条目 DOM(替换面板内全部 .command-palette-group) */
|
|
18
|
+
items?: CommandPaletteCommand[];
|
|
19
|
+
/** 覆盖默认 includes 过滤(query 为原始输入;空 query 仍视为匹配全部)。只作用于编程条目 */
|
|
20
|
+
filter?: (query: string, item: CommandPaletteCommand) => boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 打开指定 id 的命令面板。打开成功后从 document 广播 icen:command-palette-open。
|
|
24
|
+
* opts.items 传入时重建面板条目 DOM(编程条目,onSelect 选中时调用);
|
|
25
|
+
* opts.filter 覆盖默认 includes 过滤(仅编程条目生效);幂等不变(同 id 重复打开 no-op)。
|
|
26
|
+
*/
|
|
27
|
+
declare function openCommandPalette(id: string, opts?: CommandPaletteOpenOptions): void;
|
|
28
|
+
/**
|
|
29
|
+
* 关闭指定 id 的命令面板(backdrop 已被外部移除时也照常复位状态/监听/滚动锁)。
|
|
30
|
+
* 关闭已打开的面板后从 document 广播 icen:command-palette-close;
|
|
31
|
+
* 关闭未被接管打开的面板(幂等空操作路径)不派发。
|
|
32
|
+
*/
|
|
4
33
|
declare function closeCommandPalette(id: string): void;
|
|
5
|
-
/**
|
|
6
|
-
|
|
34
|
+
/**
|
|
35
|
+
* 初始化:委托监听触发器 / 搜索 / 外点 / 全局快捷键。
|
|
36
|
+
* 返回销毁函数:摘除全部委托监听并复位幂等标记(销毁后可重新 init);
|
|
37
|
+
* 销毁时若有面板开着会顺带关闭(复位滚动锁/监听/焦点)。
|
|
38
|
+
* 重复调用安全:已初始化时返回既有销毁函数(同一份,共享)。SSR 下返回 no-op。
|
|
39
|
+
*/
|
|
40
|
+
declare function initCommandPalette(root?: ParentNode): () => void;
|
|
7
41
|
|
|
8
|
-
export { closeCommandPalette, initCommandPalette, openCommandPalette };
|
|
42
|
+
export { type CommandPaletteCommand, type CommandPaletteOpenOptions, closeCommandPalette, initCommandPalette, openCommandPalette };
|
|
@@ -1,11 +1,111 @@
|
|
|
1
|
+
// src/behaviors/popover.ts
|
|
2
|
+
var PANEL_SIZING_ATTRS = {
|
|
3
|
+
width: "data-panel-width",
|
|
4
|
+
minWidth: "data-panel-min",
|
|
5
|
+
maxWidth: "data-panel-max",
|
|
6
|
+
minHeight: "data-panel-min-height",
|
|
7
|
+
maxHeight: "data-panel-max-height"
|
|
8
|
+
};
|
|
9
|
+
function readPanelSizing(el) {
|
|
10
|
+
const out = {};
|
|
11
|
+
if (!el) return out;
|
|
12
|
+
for (const key of Object.keys(PANEL_SIZING_ATTRS)) {
|
|
13
|
+
const raw = el.getAttribute(PANEL_SIZING_ATTRS[key]);
|
|
14
|
+
if (raw == null) continue;
|
|
15
|
+
const n = Number(raw);
|
|
16
|
+
if (Number.isFinite(n) && n > 0) out[key] = n;
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function applyPanelSizing(panel, sizing) {
|
|
21
|
+
if (sizing == null) {
|
|
22
|
+
panel.style.width = "";
|
|
23
|
+
panel.style.minWidth = "";
|
|
24
|
+
panel.style.maxWidth = "";
|
|
25
|
+
panel.style.minHeight = "";
|
|
26
|
+
panel.style.maxHeight = "";
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const vw = typeof document === "undefined" ? Number.POSITIVE_INFINITY : document.documentElement.clientWidth;
|
|
30
|
+
const fitW = (n) => Math.min(n, Math.max(80, vw - 24));
|
|
31
|
+
if (sizing.width != null) {
|
|
32
|
+
const w = fitW(sizing.width);
|
|
33
|
+
panel.style.width = `${w}px`;
|
|
34
|
+
panel.style.maxWidth = `${w}px`;
|
|
35
|
+
}
|
|
36
|
+
if (sizing.minWidth != null) panel.style.minWidth = `${fitW(sizing.minWidth)}px`;
|
|
37
|
+
if (sizing.maxWidth != null && sizing.width == null) panel.style.maxWidth = `${fitW(sizing.maxWidth)}px`;
|
|
38
|
+
if (sizing.minHeight != null) panel.style.minHeight = `${sizing.minHeight}px`;
|
|
39
|
+
if (sizing.maxHeight != null) panel.style.maxHeight = `${sizing.maxHeight}px`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/behaviors/events.ts
|
|
43
|
+
function emitIcen(source, type, detail) {
|
|
44
|
+
return source.dispatchEvent(
|
|
45
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/behaviors/context-menu.ts
|
|
50
|
+
function emitMenuSelect(source, item) {
|
|
51
|
+
emitIcen(item, "icen:menu-select", {
|
|
52
|
+
source,
|
|
53
|
+
item,
|
|
54
|
+
value: item.dataset.value ?? "",
|
|
55
|
+
/* 优先专用 label 子元素(避开快捷键/图标文本混入),无则退整项文本 */
|
|
56
|
+
label: (item.querySelector(".menu-item-label, .command-item-label")?.textContent ?? item.textContent ?? "").trim().slice(0, 80)
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/behaviors/modal.ts
|
|
61
|
+
var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]), [contenteditable]:not([contenteditable="false"]), audio, video, details>summary';
|
|
62
|
+
|
|
1
63
|
// src/behaviors/command-palette.ts
|
|
2
|
-
var FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
3
64
|
var openId = null;
|
|
4
65
|
var restoreFocusTo = null;
|
|
5
66
|
var prevBodyOverflow = "";
|
|
6
67
|
var keyHandler = null;
|
|
7
68
|
var globalKeyHandler = null;
|
|
8
|
-
var
|
|
69
|
+
var teardown = null;
|
|
70
|
+
var programmaticCommands = /* @__PURE__ */ new WeakMap();
|
|
71
|
+
var customFilter = null;
|
|
72
|
+
function buildCommandItems(panel, commands) {
|
|
73
|
+
const body = panel.querySelector(".command-palette-body");
|
|
74
|
+
if (!body) return;
|
|
75
|
+
body.querySelectorAll(".command-palette-group").forEach((g) => g.remove());
|
|
76
|
+
const group = document.createElement("div");
|
|
77
|
+
group.className = "command-palette-group";
|
|
78
|
+
for (const cmd of commands) group.appendChild(buildCommandItem(cmd));
|
|
79
|
+
const empty = body.querySelector(".command-palette-empty");
|
|
80
|
+
if (empty) body.insertBefore(group, empty);
|
|
81
|
+
else body.appendChild(group);
|
|
82
|
+
}
|
|
83
|
+
function buildCommandItem(cmd) {
|
|
84
|
+
const btn = document.createElement("button");
|
|
85
|
+
btn.type = "button";
|
|
86
|
+
btn.className = "command-palette-item";
|
|
87
|
+
const label = document.createElement("span");
|
|
88
|
+
label.className = "command-palette-item-label";
|
|
89
|
+
label.textContent = cmd.label;
|
|
90
|
+
btn.appendChild(label);
|
|
91
|
+
if (cmd.hint) {
|
|
92
|
+
const hint = document.createElement("span");
|
|
93
|
+
hint.className = "command-palette-item-hint";
|
|
94
|
+
hint.textContent = cmd.hint;
|
|
95
|
+
btn.appendChild(hint);
|
|
96
|
+
}
|
|
97
|
+
if (cmd.keyword) btn.setAttribute("data-command-palette-keyword", cmd.keyword);
|
|
98
|
+
if (cmd.keepOpen) btn.setAttribute("data-command-palette-keep-open", "");
|
|
99
|
+
if (cmd.attrs) {
|
|
100
|
+
for (const [name, value] of Object.entries(cmd.attrs)) btn.setAttribute(name, value);
|
|
101
|
+
}
|
|
102
|
+
programmaticCommands.set(btn, cmd);
|
|
103
|
+
btn.addEventListener("click", () => {
|
|
104
|
+
emitMenuSelect(btn.closest(".command-palette") ?? btn, btn);
|
|
105
|
+
cmd.onSelect?.();
|
|
106
|
+
});
|
|
107
|
+
return btn;
|
|
108
|
+
}
|
|
9
109
|
function findBackdrop(id) {
|
|
10
110
|
return document.querySelector(
|
|
11
111
|
`.command-palette-backdrop[data-command-palette="${CSS.escape(id)}"]`
|
|
@@ -34,10 +134,16 @@ function filterPanel(panel, query) {
|
|
|
34
134
|
let visibleCount = 0;
|
|
35
135
|
panel.querySelectorAll(".command-palette-item").forEach((item) => {
|
|
36
136
|
if (isDisabledItem(item)) return;
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
137
|
+
const def = programmaticCommands.get(item);
|
|
138
|
+
let match;
|
|
139
|
+
if (def && customFilter) {
|
|
140
|
+
match = !q || customFilter(query, def);
|
|
141
|
+
} else {
|
|
142
|
+
const label = (item.querySelector(".command-palette-item-label")?.textContent ?? "").toLowerCase();
|
|
143
|
+
const hint = (item.querySelector(".command-palette-item-hint")?.textContent ?? "").toLowerCase();
|
|
144
|
+
const keyword = (item.dataset.commandPaletteKeyword ?? "").toLowerCase();
|
|
145
|
+
match = !q || label.includes(q) || hint.includes(q) || keyword.includes(q);
|
|
146
|
+
}
|
|
41
147
|
item.hidden = !match;
|
|
42
148
|
item.classList.remove("is-active");
|
|
43
149
|
if (match) visibleCount++;
|
|
@@ -52,7 +158,7 @@ function filterPanel(panel, query) {
|
|
|
52
158
|
if (empty) empty.hidden = visibleCount !== 0;
|
|
53
159
|
if (visibleCount > 0) setActive(panel, 0);
|
|
54
160
|
}
|
|
55
|
-
function openCommandPalette(id) {
|
|
161
|
+
function openCommandPalette(id, opts) {
|
|
56
162
|
if (typeof document === "undefined") return;
|
|
57
163
|
if (openId === id) return;
|
|
58
164
|
if (openId) closeCommandPalette(openId);
|
|
@@ -63,6 +169,9 @@ function openCommandPalette(id) {
|
|
|
63
169
|
}
|
|
64
170
|
const panel = backdrop.querySelector(".command-palette");
|
|
65
171
|
if (!panel) return;
|
|
172
|
+
applyPanelSizing(panel, readPanelSizing(backdrop));
|
|
173
|
+
customFilter = opts?.filter ?? null;
|
|
174
|
+
if (opts?.items) buildCommandItems(panel, opts.items);
|
|
66
175
|
if (backdrop.parentElement !== document.body) document.body.appendChild(backdrop);
|
|
67
176
|
restoreFocusTo = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
68
177
|
openId = id;
|
|
@@ -96,6 +205,7 @@ function openCommandPalette(id) {
|
|
|
96
205
|
const active = panel.querySelector(".command-palette-item.is-active");
|
|
97
206
|
if (active && !isDisabledItem(active)) {
|
|
98
207
|
e.preventDefault();
|
|
208
|
+
if (!programmaticCommands.has(active)) emitMenuSelect(panel, active);
|
|
99
209
|
active.click();
|
|
100
210
|
}
|
|
101
211
|
return;
|
|
@@ -112,6 +222,7 @@ function openCommandPalette(id) {
|
|
|
112
222
|
}
|
|
113
223
|
};
|
|
114
224
|
window.addEventListener("keydown", keyHandler);
|
|
225
|
+
emitIcen(document, "icen:command-palette-open", {});
|
|
115
226
|
}
|
|
116
227
|
function closeCommandPalette(id) {
|
|
117
228
|
if (typeof document === "undefined") return;
|
|
@@ -126,15 +237,17 @@ function closeCommandPalette(id) {
|
|
|
126
237
|
document.body.style.overflow = prevBodyOverflow;
|
|
127
238
|
if (restoreFocusTo && restoreFocusTo.isConnected) restoreFocusTo.focus();
|
|
128
239
|
restoreFocusTo = null;
|
|
240
|
+
emitIcen(document, "icen:command-palette-close", {});
|
|
129
241
|
}
|
|
130
242
|
function initCommandPalette(root) {
|
|
131
|
-
if (typeof document === "undefined") return
|
|
132
|
-
|
|
243
|
+
if (typeof document === "undefined") return () => {
|
|
244
|
+
};
|
|
245
|
+
if (typeof window === "undefined") return () => {
|
|
246
|
+
};
|
|
133
247
|
const scope = root ?? document;
|
|
134
248
|
scope.querySelectorAll("[data-command-palette-open]").forEach((el) => el.setAttribute("aria-haspopup", "dialog"));
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
document.addEventListener("click", (e) => {
|
|
249
|
+
if (teardown) return teardown;
|
|
250
|
+
const onClick = (e) => {
|
|
138
251
|
const target = e.target instanceof Element ? e.target : null;
|
|
139
252
|
if (!target) return;
|
|
140
253
|
const opener = target.closest("[data-command-palette-open]");
|
|
@@ -146,6 +259,8 @@ function initCommandPalette(root) {
|
|
|
146
259
|
if (item) {
|
|
147
260
|
const backdrop = item.closest("[data-command-palette]");
|
|
148
261
|
if (backdrop?.dataset.commandPalette) {
|
|
262
|
+
const panelEl = item.closest(".command-palette");
|
|
263
|
+
if (panelEl && !programmaticCommands.has(item)) emitMenuSelect(panelEl, item);
|
|
149
264
|
if (!item.hasAttribute("data-command-palette-keep-open")) {
|
|
150
265
|
closeCommandPalette(backdrop.dataset.commandPalette);
|
|
151
266
|
}
|
|
@@ -155,14 +270,16 @@ function initCommandPalette(root) {
|
|
|
155
270
|
if (target instanceof HTMLElement && target.classList.contains("command-palette-backdrop") && target.dataset.commandPalette) {
|
|
156
271
|
closeCommandPalette(target.dataset.commandPalette);
|
|
157
272
|
}
|
|
158
|
-
}
|
|
159
|
-
document.addEventListener("
|
|
273
|
+
};
|
|
274
|
+
document.addEventListener("click", onClick);
|
|
275
|
+
const onInput = (e) => {
|
|
160
276
|
if (!(e.target instanceof HTMLElement)) return;
|
|
161
277
|
if (!e.target.matches(".command-palette-input")) return;
|
|
162
278
|
const backdrop = e.target.closest("[data-command-palette]");
|
|
163
279
|
const panel = backdrop?.querySelector(".command-palette");
|
|
164
280
|
if (panel) filterPanel(panel, e.target.value);
|
|
165
|
-
}
|
|
281
|
+
};
|
|
282
|
+
document.addEventListener("input", onInput);
|
|
166
283
|
globalKeyHandler = (e) => {
|
|
167
284
|
if (!(e.metaKey || e.ctrlKey)) return;
|
|
168
285
|
const key = e.key.toLowerCase();
|
|
@@ -181,6 +298,17 @@ function initCommandPalette(root) {
|
|
|
181
298
|
}
|
|
182
299
|
};
|
|
183
300
|
window.addEventListener("keydown", globalKeyHandler);
|
|
301
|
+
teardown = () => {
|
|
302
|
+
document.removeEventListener("click", onClick);
|
|
303
|
+
document.removeEventListener("input", onInput);
|
|
304
|
+
if (globalKeyHandler) {
|
|
305
|
+
window.removeEventListener("keydown", globalKeyHandler);
|
|
306
|
+
globalKeyHandler = null;
|
|
307
|
+
}
|
|
308
|
+
if (openId) closeCommandPalette(openId);
|
|
309
|
+
teardown = null;
|
|
310
|
+
};
|
|
311
|
+
return teardown;
|
|
184
312
|
}
|
|
185
313
|
export {
|
|
186
314
|
closeCommandPalette,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { PanelSizing } from './popover.js';
|
|
2
|
+
|
|
1
3
|
interface ContextMenuEntry {
|
|
2
4
|
label: string;
|
|
3
5
|
subLabel?: string;
|
|
@@ -21,16 +23,31 @@ interface ContextMenuOptions {
|
|
|
21
23
|
/** 替换内置默认菜单(未命中任何注册 id 时使用) */
|
|
22
24
|
items?: ContextMenuItem[];
|
|
23
25
|
}
|
|
26
|
+
|
|
27
|
+
/** 菜单选中统一事件(dropdown / context-menu / command-palette 同一契约)。
|
|
28
|
+
* 本模块为唯一定义点,dropdown / command-palette 改为 import 复用(收敛三份逐字拷贝)。 */
|
|
29
|
+
declare function emitMenuSelect(source: HTMLElement, item: HTMLElement): void;
|
|
24
30
|
/** 注册指定 id 的右键菜单项(对应 DOM 中的 [data-context-menu="id"])。 */
|
|
25
31
|
declare function registerContextMenu(id: string, items: ContextMenuItem[]): void;
|
|
26
|
-
/** 在 (x, y) 打开右键菜单(视口边缘自动翻转并 clamp)。
|
|
27
|
-
|
|
32
|
+
/** 在 (x, y) 打开右键菜单(视口边缘自动翻转并 clamp)。
|
|
33
|
+
尺寸走全库统一 PanelSizing 契约:opts.sizing 直接传入(面板无固定宿主元素,
|
|
34
|
+
由调用方从其根元素 readPanelSizing 读入,如 datatable 行右键)。 */
|
|
35
|
+
declare function openContextMenu(x: number, y: number, items: ContextMenuItem[], opts?: {
|
|
36
|
+
sizing?: PanelSizing;
|
|
37
|
+
}): void;
|
|
28
38
|
/** 关闭当前右键菜单(未打开时为 no-op)。 */
|
|
39
|
+
declare function closeContextMenu(): void;
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated 已更名 closeContextMenu(与全库浮层 close* 命名对齐);
|
|
42
|
+
* 本别名仅为兼容保留,下个大版本删除。
|
|
43
|
+
*/
|
|
29
44
|
declare function closeMenu(): void;
|
|
30
45
|
/**
|
|
31
46
|
* 启动全局右键菜单(重复调用安全)。
|
|
32
47
|
* opts.items 提供时替换内置默认菜单。
|
|
48
|
+
* 返回销毁函数:摘除 init 注册的全部 document 监听并复位幂等标记(销毁后可重新
|
|
49
|
+
* init);销毁时若有菜单开着会顺带关闭(摘净 openContextMenu 挂的浮层监听)。
|
|
33
50
|
*/
|
|
34
|
-
declare function initContextMenu(opts?: ContextMenuOptions): void;
|
|
51
|
+
declare function initContextMenu(opts?: ContextMenuOptions): () => void;
|
|
35
52
|
|
|
36
|
-
export { type ContextMenuEntry, type ContextMenuHeader, type ContextMenuItem, type ContextMenuOptions, type ContextMenuSeparator, closeMenu, initContextMenu, openContextMenu, registerContextMenu };
|
|
53
|
+
export { type ContextMenuEntry, type ContextMenuHeader, type ContextMenuItem, type ContextMenuOptions, type ContextMenuSeparator, closeContextMenu, closeMenu, emitMenuSelect, initContextMenu, openContextMenu, registerContextMenu };
|
|
@@ -1,8 +1,65 @@
|
|
|
1
|
+
// src/behaviors/popover.ts
|
|
2
|
+
var PANEL_SIZING_ATTRS = {
|
|
3
|
+
width: "data-panel-width",
|
|
4
|
+
minWidth: "data-panel-min",
|
|
5
|
+
maxWidth: "data-panel-max",
|
|
6
|
+
minHeight: "data-panel-min-height",
|
|
7
|
+
maxHeight: "data-panel-max-height"
|
|
8
|
+
};
|
|
9
|
+
function readPanelSizing(el) {
|
|
10
|
+
const out = {};
|
|
11
|
+
if (!el) return out;
|
|
12
|
+
for (const key of Object.keys(PANEL_SIZING_ATTRS)) {
|
|
13
|
+
const raw = el.getAttribute(PANEL_SIZING_ATTRS[key]);
|
|
14
|
+
if (raw == null) continue;
|
|
15
|
+
const n = Number(raw);
|
|
16
|
+
if (Number.isFinite(n) && n > 0) out[key] = n;
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function applyPanelSizing(panel2, sizing) {
|
|
21
|
+
if (sizing == null) {
|
|
22
|
+
panel2.style.width = "";
|
|
23
|
+
panel2.style.minWidth = "";
|
|
24
|
+
panel2.style.maxWidth = "";
|
|
25
|
+
panel2.style.minHeight = "";
|
|
26
|
+
panel2.style.maxHeight = "";
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const vw = typeof document === "undefined" ? Number.POSITIVE_INFINITY : document.documentElement.clientWidth;
|
|
30
|
+
const fitW = (n) => Math.min(n, Math.max(80, vw - 24));
|
|
31
|
+
if (sizing.width != null) {
|
|
32
|
+
const w = fitW(sizing.width);
|
|
33
|
+
panel2.style.width = `${w}px`;
|
|
34
|
+
panel2.style.maxWidth = `${w}px`;
|
|
35
|
+
}
|
|
36
|
+
if (sizing.minWidth != null) panel2.style.minWidth = `${fitW(sizing.minWidth)}px`;
|
|
37
|
+
if (sizing.maxWidth != null && sizing.width == null) panel2.style.maxWidth = `${fitW(sizing.maxWidth)}px`;
|
|
38
|
+
if (sizing.minHeight != null) panel2.style.minHeight = `${sizing.minHeight}px`;
|
|
39
|
+
if (sizing.maxHeight != null) panel2.style.maxHeight = `${sizing.maxHeight}px`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/behaviors/events.ts
|
|
43
|
+
function emitIcen(source, type, detail) {
|
|
44
|
+
return source.dispatchEvent(
|
|
45
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
1
49
|
// src/behaviors/context-menu.ts
|
|
2
50
|
var LONG_PRESS_DELAY = 520;
|
|
3
51
|
var LONG_PRESS_MOVE_LIMIT = 12;
|
|
4
52
|
var FLIP_MARGIN = 10;
|
|
5
53
|
var CLAMP_MARGIN = 8;
|
|
54
|
+
function emitMenuSelect(source, item) {
|
|
55
|
+
emitIcen(item, "icen:menu-select", {
|
|
56
|
+
source,
|
|
57
|
+
item,
|
|
58
|
+
value: item.dataset.value ?? "",
|
|
59
|
+
/* 优先专用 label 子元素(避开快捷键/图标文本混入),无则退整项文本 */
|
|
60
|
+
label: (item.querySelector(".menu-item-label, .command-item-label")?.textContent ?? item.textContent ?? "").trim().slice(0, 80)
|
|
61
|
+
});
|
|
62
|
+
}
|
|
6
63
|
var registry = /* @__PURE__ */ new Map();
|
|
7
64
|
var fallbackItems = null;
|
|
8
65
|
var initialized = false;
|
|
@@ -44,7 +101,7 @@ function resolveItems(target) {
|
|
|
44
101
|
function isEditable(target) {
|
|
45
102
|
return Boolean(target?.closest('input, textarea, [contenteditable="true"]'));
|
|
46
103
|
}
|
|
47
|
-
function buildItem(item) {
|
|
104
|
+
function buildItem(item, menuPanel) {
|
|
48
105
|
if ("type" in item && item.type === "separator") {
|
|
49
106
|
const sep = document.createElement("div");
|
|
50
107
|
sep.className = "menu-separator";
|
|
@@ -94,19 +151,21 @@ function buildItem(item) {
|
|
|
94
151
|
btn.appendChild(shortcut);
|
|
95
152
|
}
|
|
96
153
|
btn.addEventListener("click", () => {
|
|
154
|
+
emitMenuSelect(menuPanel, btn);
|
|
97
155
|
entry.onClick?.();
|
|
98
|
-
|
|
156
|
+
closeContextMenu();
|
|
99
157
|
});
|
|
100
158
|
return btn;
|
|
101
159
|
}
|
|
102
|
-
function openContextMenu(x, y, items) {
|
|
160
|
+
function openContextMenu(x, y, items, opts) {
|
|
103
161
|
if (typeof document === "undefined") return;
|
|
104
|
-
|
|
162
|
+
closeContextMenu();
|
|
105
163
|
panel = document.createElement("div");
|
|
106
164
|
panel.className = "menu menu--context";
|
|
107
165
|
panel.setAttribute("role", "menu");
|
|
108
166
|
panel.style.visibility = "hidden";
|
|
109
|
-
|
|
167
|
+
applyPanelSizing(panel, opts?.sizing ?? {});
|
|
168
|
+
for (const item of items) panel.appendChild(buildItem(item, panel));
|
|
110
169
|
document.body.appendChild(panel);
|
|
111
170
|
const rect = panel.getBoundingClientRect();
|
|
112
171
|
const vw = window.innerWidth;
|
|
@@ -117,6 +176,7 @@ function openContextMenu(x, y, items) {
|
|
|
117
176
|
if (y + rect.height > vh - FLIP_MARGIN) ny = y - rect.height;
|
|
118
177
|
if (nx < CLAMP_MARGIN) nx = CLAMP_MARGIN;
|
|
119
178
|
if (ny < CLAMP_MARGIN) ny = CLAMP_MARGIN;
|
|
179
|
+
panel.dataset.side = ny < y ? "top" : "bottom";
|
|
120
180
|
panel.style.left = `${nx}px`;
|
|
121
181
|
panel.style.top = `${ny}px`;
|
|
122
182
|
panel.style.visibility = "";
|
|
@@ -131,7 +191,7 @@ function openContextMenu(x, y, items) {
|
|
|
131
191
|
window.addEventListener("resize", onCloseSignal);
|
|
132
192
|
window.addEventListener("keydown", onKeyDown);
|
|
133
193
|
}
|
|
134
|
-
function
|
|
194
|
+
function closeContextMenu() {
|
|
135
195
|
if (!panel) return;
|
|
136
196
|
panel.remove();
|
|
137
197
|
panel = null;
|
|
@@ -142,6 +202,9 @@ function closeMenu() {
|
|
|
142
202
|
window.removeEventListener("resize", onCloseSignal);
|
|
143
203
|
window.removeEventListener("keydown", onKeyDown);
|
|
144
204
|
}
|
|
205
|
+
function closeMenu() {
|
|
206
|
+
closeContextMenu();
|
|
207
|
+
}
|
|
145
208
|
function setFocused(next) {
|
|
146
209
|
if (!panel || focusableItems.length === 0) return;
|
|
147
210
|
focusedIndex = (next % focusableItems.length + focusableItems.length) % focusableItems.length;
|
|
@@ -150,20 +213,20 @@ function setFocused(next) {
|
|
|
150
213
|
function onOutsidePointerDown(e) {
|
|
151
214
|
if (!panel) return;
|
|
152
215
|
const target = e.target;
|
|
153
|
-
if (!(target instanceof Node) || !panel.contains(target))
|
|
216
|
+
if (!(target instanceof Node) || !panel.contains(target)) closeContextMenu();
|
|
154
217
|
}
|
|
155
218
|
function onScrollSignal(e) {
|
|
156
219
|
if (panel && e.target instanceof Node && panel.contains(e.target)) return;
|
|
157
|
-
|
|
220
|
+
closeContextMenu();
|
|
158
221
|
}
|
|
159
222
|
function onCloseSignal() {
|
|
160
|
-
|
|
223
|
+
closeContextMenu();
|
|
161
224
|
}
|
|
162
225
|
function onKeyDown(e) {
|
|
163
226
|
if (!panel) return;
|
|
164
227
|
if (e.key === "Escape") {
|
|
165
228
|
e.preventDefault();
|
|
166
|
-
|
|
229
|
+
closeContextMenu();
|
|
167
230
|
return;
|
|
168
231
|
}
|
|
169
232
|
if (focusableItems.length === 0) return;
|
|
@@ -184,43 +247,64 @@ function clearLongPress() {
|
|
|
184
247
|
longPress = null;
|
|
185
248
|
}
|
|
186
249
|
function openForTarget(target, x, y) {
|
|
187
|
-
openContextMenu(
|
|
250
|
+
openContextMenu(
|
|
251
|
+
x,
|
|
252
|
+
y,
|
|
253
|
+
resolveItems(target),
|
|
254
|
+
{ sizing: readPanelSizing(target instanceof Element ? target.closest("[data-context-menu]") ?? target : target) }
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
function onContextMenu(e) {
|
|
258
|
+
const target = e.target instanceof Element ? e.target : null;
|
|
259
|
+
if (isEditable(target)) return;
|
|
260
|
+
e.preventDefault();
|
|
261
|
+
openForTarget(target, e.clientX, e.clientY);
|
|
262
|
+
}
|
|
263
|
+
function onLongPressStart(e) {
|
|
264
|
+
if (e.pointerType !== "touch") return;
|
|
265
|
+
const target = e.target instanceof Element ? e.target : null;
|
|
266
|
+
if (!target || isEditable(target)) return;
|
|
267
|
+
clearLongPress();
|
|
268
|
+
const startX = e.clientX;
|
|
269
|
+
const startY = e.clientY;
|
|
270
|
+
const timer = window.setTimeout(() => {
|
|
271
|
+
longPress = null;
|
|
272
|
+
openForTarget(target, startX, startY);
|
|
273
|
+
}, LONG_PRESS_DELAY);
|
|
274
|
+
longPress = { timer, x: startX, y: startY, target };
|
|
275
|
+
}
|
|
276
|
+
function onLongPressMove(e) {
|
|
277
|
+
if (!longPress) return;
|
|
278
|
+
if (Math.hypot(e.clientX - longPress.x, e.clientY - longPress.y) > LONG_PRESS_MOVE_LIMIT) {
|
|
279
|
+
clearLongPress();
|
|
280
|
+
}
|
|
188
281
|
}
|
|
189
282
|
function initContextMenu(opts = {}) {
|
|
190
|
-
if (typeof document === "undefined") return
|
|
283
|
+
if (typeof document === "undefined") return () => {
|
|
284
|
+
};
|
|
191
285
|
if (opts.items) fallbackItems = opts.items;
|
|
192
|
-
if (initialized) return
|
|
286
|
+
if (initialized) return () => {
|
|
287
|
+
};
|
|
193
288
|
initialized = true;
|
|
194
|
-
document.addEventListener("contextmenu",
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
e.preventDefault();
|
|
198
|
-
openForTarget(target, e.clientX, e.clientY);
|
|
199
|
-
});
|
|
200
|
-
document.addEventListener("pointerdown", (e) => {
|
|
201
|
-
if (e.pointerType !== "touch") return;
|
|
202
|
-
const target = e.target instanceof Element ? e.target : null;
|
|
203
|
-
if (!target || isEditable(target)) return;
|
|
204
|
-
clearLongPress();
|
|
205
|
-
const startX = e.clientX;
|
|
206
|
-
const startY = e.clientY;
|
|
207
|
-
const timer = window.setTimeout(() => {
|
|
208
|
-
longPress = null;
|
|
209
|
-
openForTarget(target, startX, startY);
|
|
210
|
-
}, LONG_PRESS_DELAY);
|
|
211
|
-
longPress = { timer, x: startX, y: startY, target };
|
|
212
|
-
});
|
|
213
|
-
document.addEventListener("pointermove", (e) => {
|
|
214
|
-
if (!longPress) return;
|
|
215
|
-
if (Math.hypot(e.clientX - longPress.x, e.clientY - longPress.y) > LONG_PRESS_MOVE_LIMIT) {
|
|
216
|
-
clearLongPress();
|
|
217
|
-
}
|
|
218
|
-
});
|
|
289
|
+
document.addEventListener("contextmenu", onContextMenu);
|
|
290
|
+
document.addEventListener("pointerdown", onLongPressStart);
|
|
291
|
+
document.addEventListener("pointermove", onLongPressMove);
|
|
219
292
|
document.addEventListener("pointerup", clearLongPress);
|
|
220
293
|
document.addEventListener("pointercancel", clearLongPress);
|
|
294
|
+
return () => {
|
|
295
|
+
document.removeEventListener("contextmenu", onContextMenu);
|
|
296
|
+
document.removeEventListener("pointerdown", onLongPressStart);
|
|
297
|
+
document.removeEventListener("pointermove", onLongPressMove);
|
|
298
|
+
document.removeEventListener("pointerup", clearLongPress);
|
|
299
|
+
document.removeEventListener("pointercancel", clearLongPress);
|
|
300
|
+
closeContextMenu();
|
|
301
|
+
initialized = false;
|
|
302
|
+
};
|
|
221
303
|
}
|
|
222
304
|
export {
|
|
305
|
+
closeContextMenu,
|
|
223
306
|
closeMenu,
|
|
307
|
+
emitMenuSelect,
|
|
224
308
|
initContextMenu,
|
|
225
309
|
openContextMenu,
|
|
226
310
|
registerContextMenu
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export { initInput } from './input.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 接线开关 / 勾选框 / 单选(document 级委托,页面级一次即可,重复调用幂等)。
|
|
5
|
+
* 点击 / Space / Enter 驱动 aria-checked(checkbox 三态循环含初始半选例外;
|
|
6
|
+
* radio 组内互斥),派 icen:switch-change / icen:check-change。
|
|
7
|
+
* 返回销毁函数:摘除委托并复位幂等标记,销毁后可重新 initSwitch。SSR 下返回 no-op。
|
|
8
|
+
*/
|
|
9
|
+
declare const initSwitch: () => void;
|
|
10
|
+
/**
|
|
11
|
+
* 接线数字步进器(document 级委托,重复调用幂等)。
|
|
12
|
+
* .stepper 内 .stepper-btn[data-step] 点击 → .stepper-input 数值 ±step 并 clamp 到
|
|
13
|
+
* min/max,派 icen:stepper-change { el: .stepper 根, value, delta }(触界 delta 为 0)。
|
|
14
|
+
* 返回销毁函数:摘除委托并复位幂等标记,销毁后可重新 initStepper。SSR 下返回 no-op。
|
|
15
|
+
*/
|
|
16
|
+
declare const initStepper: () => void;
|
|
17
|
+
/**
|
|
18
|
+
* 接线分段控件(document 级委托,重复调用幂等)。
|
|
19
|
+
* .segmented 内 .segmented-item 点击 → 组内 .is-active 互斥 + role="radio" 项同步
|
|
20
|
+
* aria-checked,派 icen:segmented-change { el: 容器, value: data-value ?? String(index), index }。
|
|
21
|
+
* 返回销毁函数:摘除委托并复位幂等标记,销毁后可重新 initSegmented。SSR 下返回 no-op。
|
|
22
|
+
*/
|
|
23
|
+
declare const initSegmented: () => void;
|
|
24
|
+
/**
|
|
25
|
+
* 接线可点击步骤条(document 级委托,重复调用幂等)。
|
|
26
|
+
* .steps 内 .step[role="button"] 点击(或聚焦后 Space / Enter)→ 激活点位移
|
|
27
|
+
* (目标 step--process + .is-active,之前 finish、之后 wait),派
|
|
28
|
+
* icen:step-change { step, index }。返回销毁函数:摘除委托并复位幂等标记,
|
|
29
|
+
* 销毁后可重新 initSteps。SSR 下返回 no-op。
|
|
30
|
+
*/
|
|
31
|
+
declare const initSteps: () => void;
|
|
32
|
+
/**
|
|
33
|
+
* 接线星级评分(document 级委托,重复调用幂等)。
|
|
34
|
+
* .rating 内 .rating-star 点击 → 该星及之前 .is-filled(重建选中态,清除残留
|
|
35
|
+
* is-half),.rating-value 存在时回写数值(textContent),派
|
|
36
|
+
* icen:rating-change { el: 容器, value }(1 起算);.rating--readonly 不接线。
|
|
37
|
+
* 返回销毁函数:摘除委托并复位幂等标记,销毁后可重新 initRating。SSR 下返回 no-op。
|
|
38
|
+
*/
|
|
39
|
+
declare const initRating: () => void;
|
|
40
|
+
/**
|
|
41
|
+
* 接线分页(document 级委托,重复调用幂等)。
|
|
42
|
+
* .pagination 内 .page-btn 点击 → .is-active / aria-current 位移并派
|
|
43
|
+
* icen:page-change { page };页码取 data-page > 按钮文本数字 > 序号,上下页按钮按
|
|
44
|
+
* aria-label / data-dir 推断方向(当前页 ±1,目标钮被省略号折叠时只派事件)。
|
|
45
|
+
* 总页数与省略号折叠策略归消费方。返回销毁函数:摘除委托并复位幂等标记,
|
|
46
|
+
* 销毁后可重新 initPagination。SSR 下返回 no-op。
|
|
47
|
+
*/
|
|
48
|
+
declare const initPagination: () => void;
|
|
49
|
+
/**
|
|
50
|
+
* 接线静态表排序(document 级委托,重复调用幂等)。
|
|
51
|
+
* th[data-sort] 点击 → asc→desc→无 循环(data-sort 属性即方向载体,列 key 首次
|
|
52
|
+
* 交互转存 data-sort-key,中性态还原;同表其他表头复位),派
|
|
53
|
+
* icen:sort-change { th, key, dir }。行数据重排归消费方( datatable 场景用
|
|
54
|
+
* behaviors/datatable 的 icen:table-sort-change)。返回销毁函数:摘除委托并
|
|
55
|
+
* 复位幂等标记,销毁后可重新 initTableSort。SSR 下返回 no-op。
|
|
56
|
+
*/
|
|
57
|
+
declare const initTableSort: () => void;
|
|
58
|
+
|
|
59
|
+
export { initPagination, initRating, initSegmented, initStepper, initSteps, initSwitch, initTableSort };
|