@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
package/AGENTS.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# 第一段 · 消费方速查(在用户项目里用 @icen.ai/ui)
|
|
8
8
|
|
|
9
|
-
完整类型签名看包内 `dist/*.d.ts`;交互式文档 <https://ui.icen.ai>;AI 能力规格 `docs/spec/ai-native.md
|
|
9
|
+
完整类型签名看包内 `dist/*.d.ts`;交互式文档 <https://ui.icen.ai>;AI 能力规格 `docs/spec/ai-native.md`;知识库族规格 `docs/spec/kb-family.md`;最佳实践成品页 <https://ui.icen.ai/kb/>;文档全文(喂模型)<https://ui.icen.ai/llms-full.txt>。
|
|
10
10
|
|
|
11
11
|
## 形态约束(先读,避免生成跑不通的代码)
|
|
12
12
|
|
|
@@ -50,7 +50,7 @@ c.destroy();
|
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
- 省略 `type` 时 `inferChartType` 自动选型(ISO 日期/年月/周几/版本号 v0.8/纯年份等时序标签 → line)。
|
|
53
|
-
- 事件:`icen:chart-
|
|
53
|
+
- 事件:`icen:chart-hover`(detail.phase ∈ enter/move/leave)/ `-click / -dblclick / -contextmenu / -legend-toggle / -legend-visibility`;内置 tooltip 门户(`tooltip:false` 关闭只派事件),tooltip 最大宽吃图表根 `data-panel-max`;图表头统一带**图例眼睛**(隐藏/显示全部指标)。直调底层渲染器同样有交互委托(`bindChartEvents`)。
|
|
54
54
|
- 底层渲染器(同 chrome,非 AI 场景直用):`renderVBar/renderHBar/renderStack/renderDonut/renderLine/renderArea/renderRadar/renderHeatmap/renderCalendar/renderSparkline/renderGauge/renderScatter`。
|
|
55
55
|
|
|
56
56
|
## AI 原生族 — 7 态状态机 + kind 注册表
|
|
@@ -131,13 +131,44 @@ parseAiToolArgs('render_chart', raw); // 模型回包解析(容错 JSON 字
|
|
|
131
131
|
|
|
132
132
|
自定义工具:`registerAiTool({ name, description, inputSchema, onCall })`;内置 `render_chart`。挂载区条目可折叠/移除,超限 LRU 自动回收。
|
|
133
133
|
|
|
134
|
+
## 知识库族(kb-*)— 证据层组件
|
|
135
|
+
|
|
136
|
+
**ai 族描述思考(过程),kb 族呈现证据(知识从哪来 / 可信吗 / 怎么用);权限域呈现边界(谁能看到什么,以及为什么)**。32 个 slug 七域,CSS 根类 `.kb-*`,事件统一 `icen:kb-*`(56 个全类型登记)。规格唯一事实源 `docs/spec/kb-family.md`(§9 为权限域);最佳实践成品页 <https://ui.icen.ai/kb/>(八标签工作台 + 参考文献锚点)。
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { renderKbCitations, parseInlineCitations } from '@icen.ai/ui/behaviors/kb-citation';
|
|
140
|
+
import { createKbRetrieval, scorePercent } from '@icen.ai/ui/behaviors/kb-retrieval';
|
|
141
|
+
import { createKbFilter } from '@icen.ai/ui/behaviors/kb-filter';
|
|
142
|
+
|
|
143
|
+
// 角标:文本里的 [1][2] → parseInlineCitations → renderKbCitations(el, citations, opts)
|
|
144
|
+
// 引用三型定位(Anthropic 同款):location: {type:'char',start,end,unit:'char'} | {type:'page',page} | {type:'block',blockId}——unit 写死不猜
|
|
145
|
+
// 检索 playground:混合权重 / 阈值 / topK 即调即得,事件 icen:kb-retrieval-run
|
|
146
|
+
// 过滤器:树形规则 → serialize('mongo'|'odata') 双 DSL;无效规则不镜像(诚实纪律)
|
|
147
|
+
const filter = createKbFilter(el, { node, fields, onChange: (node, valid) => {...} });
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
- **分数纪律(全族统一)**:score 必带 metric 与 higherIsBetter(l2 距离自动反转);null / 缺失渲染「—」不猜;条形轨道定宽,长度严格按 scorePercent 比例。
|
|
151
|
+
- **诚实呈现**:行数截断要声明、权限缺失打码并给「申请访问」、重排关闭后列压淡不隐藏、检查点回滚范围显式(只回滚文件保留对话)。
|
|
152
|
+
- 契约层 `kb-core.ts`(`import ... from '@icen.ai/ui/behaviors/kb-core'`):KbCitation / KbChunk / KbRunStatus / KbConnector / KbRetrievalParams / KbFilterNode / KbEvalRow 等 40+ normalize 与格式化函数,业务数据一律先过 normalize 再喂组件。
|
|
153
|
+
- 域文件映射:证据 kb-citation·kb-sources·kb-passage·kb-conflict → kb-ground.css;摄取 kb-pipeline·kb-chunks·kb-segment·kb-connector·kb-metadata·kb-qa → kb-ingest.css;检索 kb-retrieval·kb-filter·kb-rerank·kb-hittest → kb-search.css;问数 kb-sql·kb-answer·kb-clarify → kb-data.css;治理 kb-explain·kb-trace·kb-review·kb-gap·kb-eval → kb-ops.css;工作台 kb-canvas·kb-checkpoint·kb-sandbox·kb-chain → kb-agent.css;**权限 kb-acl·kb-who-can·kb-access·kb-audit·kb-visibility → kb-perm.css**;全部组件 kit 自动带 kb.css 基座。
|
|
154
|
+
|
|
155
|
+
**权限域安全纪律(spec §9.0,评审必查)**:
|
|
156
|
+
|
|
157
|
+
- 检索期隔离唯一安全基线 = **query-time pre-filter**(ANN 与 BM25 两侧);post-filter / generation / presentation 都不是边界。
|
|
158
|
+
- **对授权侧诚实,对受限侧沉默**:被裁条数 / 标题 / 分数 / 「若权限不同」对照不出现在普通用户视图(kb-visibility 的 admin 对照是唯一例外,组件自带警示条)。
|
|
159
|
+
- 「不知道」与「不能说」不可区分:无权限文档在检索/列表/计数/引用中 = 不存在;唯一允许的裁剪提示是与命中无关的恒定文案。
|
|
160
|
+
- 求值语义:`evaluateAcl(entries, identity)` 纯函数 = **先显式 deny → allow 并集 → 默认拒绝(fail-closed)**;身份来自服务端固定身份集,不接受自由输入。
|
|
161
|
+
- 引用白名单:citation 只能生成自过滤后集合;revoked 历史引用呈中性 `.is-revoked`;每条 grant 可带 `expiresAt`(到期三态:永不过期 / 倒计时+续期 / 已过期+重交)。
|
|
162
|
+
- 组件速用:`renderKbAcl(el, model)`(继承四件套 + Direct/Links 双区 + deny 置顶);`renderKbWhoCan(el, {identities, entries})`(view-as 原因链,业界唯一全实现是 SharePoint Check Permissions——差异化件);`createKbAccess(el, {request, mode})`(被拒五件套 + 九态状态机 + 路由明示);`renderKbAudit(el, {entries, hygiene})` + `initKbAudit()`(三通道 + break-glass 警示 + 六类异味);`renderKbVisibility(el, opts)`(admin 对照器 + 过滤层三态徽标 `.kb-layer-chip` pre✓/post⚠/none✕)。
|
|
163
|
+
|
|
134
164
|
## 深挖索引(复杂模块不设单独 AGENTS.md,类型真相在 .d.mts)
|
|
135
165
|
|
|
136
166
|
每个 behavior 的完整接口/类型/字段约束都随包发布在 `dist/behaviors/<模块>.d.mts`(JSDoc 注释含行为约束,如「el 传容器或内部任意元素,就近解析 `[data-ai-composer]`」)。**不建议也不需要按组件再写深层 AGENTS.md**——复制必漂移;读类型面即读文档:
|
|
137
167
|
|
|
138
168
|
| 深挖什么 | 去哪读 |
|
|
139
169
|
| --- | --- |
|
|
140
|
-
| AI 族全部签名与字段约束 | 包内 `dist/behaviors/ai-{core,chat,composer,tool,panel,diff,provider,tools}.d.mts` |
|
|
170
|
+
| AI 族全部签名与字段约束 | 包内 `dist/behaviors/ai-{core,chat,composer,tool,panel,diff,provider,tools,threads,feedback,branch}.d.mts` |
|
|
171
|
+
| 知识库族全部签名与字段约束 | 包内 `dist/behaviors/kb-*.d.mts`(契约层 `kb-core.d.mts`) |
|
|
141
172
|
| 图表 ChartSpec 全字段 + 各类型 options | `dist/behaviors/charts.d.mts` |
|
|
142
173
|
| 上述类型面 + JSDoc 的纯文本快照 | <https://ui.icen.ai/llms-full.txt>(「API 类型面」节,构建期自动内嵌) |
|
|
143
174
|
| 设计动机 / 状态机语义 / 口径取舍 | `docs/spec/ai-native.md`(包内随发) |
|
|
@@ -173,9 +204,9 @@ bun run build # tsup(src/behaviors/*.ts → dist/behaviors/*.mjs + index.m
|
|
|
173
204
|
|
|
174
205
|
## 规模
|
|
175
206
|
|
|
176
|
-
- **
|
|
177
|
-
- **
|
|
178
|
-
- **
|
|
207
|
+
- **65 个组件 CSS**(charts 基座 + 13 个细分图表 CSS(+v0.9 chart-graph/map)+ 10 个 v0.5 新增:copy/tag/badge/scroll-area/notification/back-top/command-palette/date-picker/toolbar/split-pane + 4 个 v0.7 AI 族合并文件:ai-chat/ai-tool/ai-diff/ai-panel + v0.9:kb.css 基座 + 7 个 kb 域文件(ground/ingest/search/data/ops/agent/perm))
|
|
208
|
+
- **70 个 behaviors TS**(v0.9:+ai-threads/ai-feedback/ai-branch +kb-core 契约层 +31 个 kb-*——含权限域 kb-acl/kb-who-can/kb-access/kb-audit/kb-visibility)
|
|
209
|
+
- **114 个组件 slug**(kit 一行入口 / CLI / 文档站侧栏共用 SLUGS 清单;v0.9 新增 37:kb 总集 + 31 kb-* + ai-threads/ai-feedback/ai-branch + chart-graph/chart-map)
|
|
179
210
|
- **4 个 token 文件**:colors.css(6 预设 × 明暗)、style-profiles.css(modern/retro/terminal)、typography.css、retro-effects.css(可选)
|
|
180
211
|
|
|
181
212
|
## 发布(OIDC Trusted Publishing,已配好)
|
|
@@ -197,22 +228,28 @@ bun run build # tsup(src/behaviors/*.ts → dist/behaviors/*.mjs + index.m
|
|
|
197
228
|
- **交互基元**:`base.css` 提供 6 个组件地基 `.pressable` / `.control` / `.field` / `.lift` / `.surface-elevated` / `.focus-ring`。`style-profiles.css` 的 `.style-retro` 段选择器引用这 6 个类名——改名必须同步修 style-profiles.css,否则 retro 风格失效。共享 keyframes(`icen-pop-in` / `icen-spin` / `icen-skeleton-pulse`)也在 base.css,组件动画复用、不各自重定义。
|
|
198
229
|
- **z-index 标尺**:浮层一律 portal 到 body,z-index 取 `--z-base/raised/sticky/chrome/toast/banner/dialog/popover/tooltip/fx`(0.6.0 新增 `--z-fx`,retro-effects 特效层用)。
|
|
199
230
|
- **浮层 portal 家族**:popover / dropdown / context-menu / command-palette / date-picker / **select**(0.6.0 起 panel 也 portal 到 body,与 popover 共用定位模式)。
|
|
231
|
+
- **凹槽 × 尺寸 × 事件三契约(全库统一心智模型,v0.8 收敛)**:
|
|
232
|
+
- **凹槽(内容)**:标记驱动组件 = 任意 HTML 凹槽(契约在各组件 CSS 头注释,如 modal 的 `.modal-body`、select 的 `.select-option` 内可写色卡/图标/多行);函数渲染组件 = 类型化 model(一律 `textContent` 防 XSS)+ 指定挂载点(`renderAiMessage` 的 `handle.body`、datatable 的 `columns.render → Node`)。toast / notification 保持纯文本是安全纪律,不开 HTML 口子。
|
|
233
|
+
- **尺寸(PanelSizing)**:所有浮层面板共享 `behaviors/popover.ts` 的 `PanelSizing` 类型(`width 固定(最高优先)/ minWidth / maxWidth / maxHeight`)与同名 data 属性 `data-panel-width / data-panel-min / data-panel-max / data-panel-max-height`(挂组件根;context-menu 等无宿主面板的走 `opts.sizing` 程序面,datatable 右键自动从宿主读)。共享解析 `readPanelSizing(el)` / `resolvePanelSizing(el, overrides)`(程序面 > 属性面)+ `sizingToLayout`(锚定布局)/ `applyPanelSizing(panel, sizing | null)`(自建面板内联;固定宽连带盖掉 CSS 侧 max-width;**带视口夹取**——宽一律夹到视口 −24px;**传 null 复位全部内联尺寸**,单例面板跨实例复用防串味,date-picker 即此用法)。布局侧 `side` 支持 `top/bottom/left/right`(左右侧自动翻转)。已接入:select / popover(openPopover) / dropdown / context-menu / date-picker / command-palette / modal / ai-composer 三弹层(`popoverSizing` opts > composer 根 data-panel-* > 内置默认)/ datatable 筛选与列显隐面板。新增浮层组件必须走此契约,禁止再写死宽高。
|
|
234
|
+
- **事件(三层体系,`behaviors/events.ts`)**:①手势层——任意容器挂 `data-gestures="click dblclick contextmenu longpress text-select"`(空格分隔)即开通归一化 `icen:` 手势事件(click 与 dblclick 同开时单击延迟 220ms,双击到达即取消;位移 >5px 视为拖拽不派发);②协议层——全部 CustomEvent,`bubbles + composed + cancelable`;detail 契约全量登记在 `IcenEventMap`(onIcen 推断 / emitIcen 校验双侧同表,新增事件必须登记,拼错或 detail 不符编译期报错);从 document 派发(如 `icen:ai-done`/`icen:ai-usage`)= 全局广播——传播路径只经 [document, window],只有全局形态能收到(`within` 为普通元素时路径不经过它,收不到,要收广播用全局形态);③策略层——`setEventPolicy(type, fn|null)` 只收五种手势事件(编译期收死),给事件注册全站默认行为,一处赋予/覆盖/禁用,`getEventPolicy`/`resetEventPolicies` 为对称读取/清空口(调试与热重载)。绑定层 `onIcen`:类型推断 + 选择器委托 + `{ within, signal, once }`,返回解绑函数;派生口 `emitIcen`(勿裸写 new CustomEvent);`initGestures()` 幂等并返回销毁函数(`destroyGestures()` 同效),组件作者派发领域事件同样必须先在 `IcenEventMap` 登记。拖拽不在手势层(文件走 upload,排序/分割走组件自带)。
|
|
235
|
+
- **控件族(`behaviors/controls.ts`)**:纯 CSS 控件的行为承载统一在此(switch/checkbox/radio 三态、stepper、segmented、steps、rating、pagination、静态表 th[data-sort] 排序),七 init 全部「document 委托 + 幂等 + 返回销毁」同款骨架;事件 `icen:switch-change / check-change / stepper-change / segmented-change / step-change / rating-change / page-change / sort-change`。slugs 映射走 SLUG_BEHAVIOR(segmented 同时带 input 的 initInput,kit 由 SLUG_EXPORTS 三项并存解决;controls 内转发 initInput 仅为 kit 服务,**根入口 index.ts 对 controls 用具名导出**——export * 会与 input 的 initInput 构成 ESM 歧义名被静默剔除)。
|
|
200
236
|
- **事件前缀纪律**:behavior 派发的自定义事件统一 `icen:` 前缀(如 tabs 的 `icen:tab-change`、upload 的 `icen:upload`)。otp 为兼容双发 `icen:otp-complete`(新)与 `otp:complete`(deprecated,下个大版本删)。
|
|
201
237
|
- **a11y**:所有可聚焦元素必须有 `:focus-visible` 环;状态变化必须同步 `aria-*`;modal/dialog 必须有 focus trap + ESC 关闭 + 焦点还原。
|
|
202
238
|
- **动效守卫**:所有动画/过渡在 `@media (prefers-reduced-motion: reduce)` 下压缩为 ~0ms;触屏(`pointer: coarse`)关闭 `:hover` 抬升;高对比度模式(`forced-colors: active`)保留焦点环。
|
|
203
239
|
- 新组件 = `src/components/<name>.css` 一个文件 + 文档站 components 页加一节;交互行为放 `src/behaviors/<name>.ts` 并配套 CSS 类契约。每个 CSS 头注释必须列出完整 DOM 契约。
|
|
204
240
|
- behaviors 全部 SSR 守卫(`typeof document === 'undefined'`),文本赋值用 `textContent`(禁 innerHTML),init 函数全部幂等(重复调用安全,通过 WeakSet/MarkedElement.__icen*Init 标记)。initTabs/initNav/initBackTop 等返回**销毁函数**(移除监听 + 复位幂等标记,销毁后可重新 init)。
|
|
205
|
-
- 函数式组件族(charts / datatable
|
|
206
|
-
- **图表按需安装**:charts 细分为 11 个独立可安装的 kit 入口(`chart-line` / `chart-bar` / `chart-pie` / `chart-radar` / `chart-heatmap` / `chart-area` / `chart-stack` / `chart-gauge` / `chart-sparkline` / `chart-scatter` / `chart-calendar`)+ umbrella `charts`(一条 import 全拿)。**通用层(v0.8)**:`renderChart(el, spec)` 单一入口吃纯 JSON ChartSpec(type 别名归一 `normalizeChartSpec` / 自动选型 `inferChartType` / `data[]+dims` 任意维度 pivot / `format` 描述符替代回调——AI 调用层的直接底座);交互委托 `icen:chart-hover(enter/move/leave)/click/dblclick/contextmenu`(detail 含 index/seriesIndex/seriesName/label/value/指针坐标,右键默认 preventDefault)+ 内置 tooltip(portal,`tooltip:false` 关)+ 图例点击切换系列(`icen:chart-legend-toggle`);图例可见性统一由 renderChart 头部行(.chart-head = 标题 + 小眼睛)控制——根 `data-legend-hidden` 容器级 CSS 隐藏全部图型图例(`spec.legend=false` 定初值,事件 `icen:chart-legend-visibility`),图表体渲染进内层 .chart-body(底层渲染器按契约清空传入 el,头部不能同层);多系列 line(调色盘)/ vbar(分组 `stacked` 堆叠)已内建,标记统一 `data-chart-mark` + `data-chart-*` 数据位。共享基座在 `charts.css`(.chart / .chart-legend / .chart-labels / 调色盘),各类型专属样式在独立 `chart-<type>.css`;所有渲染函数仍在 `behaviors/charts.ts` 一个文件(tree-shake
|
|
241
|
+
- 函数式组件族(charts / datatable / ai 族 render*):不写类契约,导出 `createX(el, opts) → handle`;render* 一律返回挂载元素(有生命周期的图表返回 ChartHandle)——「有生命周期返 handle、静态返容器元素」,写文档示例时勿再写 void。同样一文件 CSS + 文档页一节 + slugs.mjs 登记。datatable 右键菜单复用 context-menu,其依赖的额外 CSS 走 slugs.mjs 的 EXTRA_CSS(kit 入口自动带上)。
|
|
242
|
+
- **图表按需安装**:charts 细分为 11 个独立可安装的 kit 入口(`chart-line` / `chart-bar` / `chart-pie` / `chart-radar` / `chart-heatmap` / `chart-area` / `chart-stack` / `chart-gauge` / `chart-sparkline` / `chart-scatter` / `chart-calendar`)+ umbrella `charts`(一条 import 全拿)。**通用层(v0.8)**:`renderChart(el, spec)` 单一入口吃纯 JSON ChartSpec(type 别名归一 `normalizeChartSpec` / 自动选型 `inferChartType` / `data[]+dims` 任意维度 pivot / `format` 描述符替代回调——AI 调用层的直接底座);交互委托 `icen:chart-hover(enter/move/leave)/click/dblclick/contextmenu`(detail 含 index/seriesIndex/seriesName/label/value/指针坐标,右键默认 preventDefault)+ 内置 tooltip(portal,`tooltip:false` 关)+ 图例点击切换系列(`icen:chart-legend-toggle`);图例可见性统一由 renderChart 头部行(.chart-head = 标题 + 小眼睛)控制——根 `data-legend-hidden` 容器级 CSS 隐藏全部图型图例(`spec.legend=false` 定初值,事件 `icen:chart-legend-visibility`),图表体渲染进内层 .chart-body(底层渲染器按契约清空传入 el,头部不能同层);多系列 line(调色盘)/ vbar(分组 `stacked` 堆叠)已内建,标记统一 `data-chart-mark` + `data-chart-*` 数据位。共享基座在 `charts.css`(.chart / .chart-legend / .chart-labels / 调色盘),各类型专属样式在独立 `chart-<type>.css`;所有渲染函数仍在 `behaviors/charts.ts` 一个文件(tree-shake 友好);调色盘扩展口 `registerChartTone(name, cssVar)`(注册第 7+ 档自定义 tone,主题层/消费方用,内置六档之外时必走它)。子类型 slug → charts 行为模块的映射走 slugs.mjs 的 **`SLUG_BEHAVIOR`**(key=子类型 slug,value='charts'),kit 入口按 `SLUG_EXPORTS` 只 re-export 该类型的渲染函数。
|
|
207
243
|
- 组件 slug 映射(css 合并文件 / init 函数名 / behavior 模块名)的单一事实源是 `scripts/slugs.mjs`——新组件必须在此登记;`scripts/build-css.ts` 据此生成 kit 一行入口(`dist/components/<slug>.mjs` = import css + re-export behavior,消费侧 `@icen.ai/ui/kit/<slug>`)与 registry.json 的 slugs 面,CLI(`dist/cli.mjs`,`bunx @icen.ai/ui add <slug>` 打印引入行,不拷贝源码)与文档站都消费它。`slugs.mjs` 的类型声明在 `slugs.d.mts`,加导出成员时两处同步改。behavior 与 slug 不同名的(如 segmented 的 OTP 由 input.ts 的 initInput 提供)在 `SLUG_BEHAVIOR` 登记映射、在 `SLUG_EXPORTS` 登记 re-export,kit 入口才能正确带出。
|
|
208
244
|
- **kit 的 Astro 陷阱**:kit 入口里的 css import 在 Astro 页面 `<script>`(client bundle)里会被摇掉——Astro 项目必须在布局 frontmatter 里引组件 CSS(accounts 已踩过);Vite SPA / webpack 无此问题。文档站安装段已带此提示。
|
|
209
|
-
-
|
|
245
|
+
- **文档站客户端换页(ClientRouter)**:Docs 布局挂 `<ClientRouter prefetch />`,组件↔原语↔色彩↔各组件页之间为客户端换页(首页走 Base 布局,进出仍整页加载)。两条硬约定:① 页头/页脚 `transition:persist` 常驻,页头脚本经 `astro:after-swap` 对齐新页 active 并滑移导航墨条;② **页面级模块脚本(同 src 只评估一次)一律 `astro:page-load` 驱动**(首载 + 每次换页都触发),全局监听(onIcen 等)重入前先退订上一代;Docs 侧栏内联脚本用 `data-astro-rerun` 强制重跑(组开合记忆存 window 内存——客户端换页保留手动展开、真刷新归零回「全收 + 深链开组」)。新增页面脚本必须遵守,否则换页后接线断线。
|
|
246
|
+
- 文档站(`site/`):站壳/代码块样式集中在 `site/src/styles/site.css`;可复用展示件在 `site/src/components/`(SiteHeader / SiteFooter / CodeBlock / PmInstall / ThemeRestore 防闪烁);轻量语法高亮在 `site/src/lib/highlight.ts`(单行 token 化,`.tok-*` 颜色消费语义 token)。站顶 ⌘K 全站搜索 = 自家 command-palette 组件直出(条目由 `COMPONENTS` 生成),既是功能也是门面条 demo。
|
|
210
247
|
- **skill `icen-ui` 源在本仓库**(`skill/icen-ui/`,SKILL.md + 中英产品页):只写 WHEN/WHICH 场景配方,不抄 API 签名(事实层在 AGENTS.md/.d.mts)。改完跑 `bun scripts/sync-skill.mjs` 单向同步到兄弟仓库 `../skill/skills/icen-ui/`(skill 仓库那份是产物,勿手改),在该仓库提交 push 后 CI 自动上 skill.icen.ai;`--check` 可挂 CI 防漂移。
|
|
211
248
|
- 文档站字体体系(site.css 顶部):prose/站壳 = `--site-font-sans`(系统无衬线),demo 区 = `--site-font-mono`(Plex Mono + CJK 无衬线回退),展示级大标题才用 `--font-heading` 宋体——小字号中文一律不走宋体/通用 monospace 回退。
|
|
212
249
|
- CSS 产物由 `scripts/build-css.ts` 生成,**不要手改 dist/**。`tokensExtras`(如 retro-effects.css)单独拷贝、暴露 exports,**不**进 `tokens.css`/`ui.css` 默认拼合。
|
|
213
250
|
- clay 的 12 基值 token 改动属于品牌级变更;新增色彩预设 = 在 colors.css 加 `.<name>` + `.<name>.dark` 两块完整 token 面(仿照现有 6 套),并注册到 `src/behaviors/theme.ts` 的 PRESETS 与文档站。
|
|
214
|
-
- 文档分组(`site/src/lib/components.ts` 的 `GROUPS`)= 侧栏顺序 = 索引页分组顺序:基础 / AI 原生 / 表单 / 数据展示 / 图表 / 浮层 / 反馈 / 导航(v0.8
|
|
215
|
-
- **反馈三件正交**:`toast`(瞬时 2.6s 右下角)/ `alert`(内嵌页面流)/ `notification`(持久右上角栈,工程级——进度通知/confirm Promise/多按钮/hover 暂停/倒计时/优先级置顶/已读未读/持久化/多容器 createNotificationCenter)——三者各司其职不互相替代;`copy` 是原地按钮反馈(区别于 toast 的全局通知)。
|
|
251
|
+
- 文档分组(`site/src/lib/components.ts` 的 `GROUPS`)= 侧栏顺序 = 索引页分组顺序:基础 / AI 原生 / 知识库 / 表单 / 数据展示 / 图表 / 浮层 / 反馈 / 导航(v0.9 调整:知识库上移第三位;v0.8:AI 上移第二位做拉新门面;「表格」并入数据展示;AI 组更名「AI 原生」)。侧栏分组为 `<details>` 折叠(可多开,首访全开,localStorage `icen.docs.nav.groups` 记忆,深链自动展开当前组)。kb 族文档数据在 `site/src/lib/kb-docs-{ground-ingest,search-data,ops-agent,perm}.ts` 四片段(避免巨文件冲突),`components.ts` 统一 push 进 COMPONENTS;`/kb` 的参考标签数据在 `site/src/lib/kb-references.ts`(32 条文献锚点 + 发表时间——设计决策可回溯,升级时先回源头)。
|
|
252
|
+
- **反馈三件正交**:`toast`(瞬时 2.6s 右下角)/ `alert`(内嵌页面流)/ `notification`(持久右上角栈,工程级——进度通知/confirm Promise/多按钮/hover 暂停/倒计时/优先级置顶/已读未读/持久化/多容器 createNotificationCenter)——三者各司其职不互相替代;`copy` 是原地按钮反馈(区别于 toast 的全局通知)。JS 词表已统一为 `toast.success/error`(ok/err 为 deprecated 别名,下大版本删)
|
|
216
253
|
- **徽章三件正交**:`pill`(行内状态徽章,语义色)/ `tag`(中性展示标签,可选关闭按钮与选中态)/ `badge`(角标式数字/圆点,挂外层元素角上,外层需 `position: relative`)。
|
|
217
254
|
- **组件 v2 增强(0.5.0 全量升级)**:所有基础组件已达到工程级深度——
|
|
218
255
|
- **select**:`data-select-search` 可搜索过滤(支持 `data-keywords` 辅助关键字 + 分组自动隐藏)、`data-select-multiple` 多选(chips 显示 + `data-select-max` 上限 + `.select-clear` 清除钮)、`.select-group` / `.select-group-label` 分组、`.select-empty` 无结果态。
|
|
@@ -229,7 +266,7 @@ bun run build # tsup(src/behaviors/*.ts → dist/behaviors/*.mjs + index.m
|
|
|
229
266
|
- **tabs**:可关闭 tab(`.page-tab-close`)、徽标(`.page-tab-badge`)、图标(`.page-tab-icon`)、分段式(`--segment`)、垂直(`--vertical`)、尺寸(`--sm/lg`)。
|
|
230
267
|
- **nav**:搜索槽(`.nav-search`)、通知徽标(`.nav-btn-badge`)、链接式(`.nav-link`)、用户区(`.nav-user`)。
|
|
231
268
|
- **sidebar**:头部/底部槽(`.sidebar-header` / `.sidebar-footer`)、折叠/轨道模式(`--collapsed`)、激活指示条、分隔线、徽章变体色。
|
|
232
|
-
- **content**:列表增强(`.list-item-leading/meta/trailing` + 选中/斑马)、时间线变体(右侧/交替/自定义尺寸/扩展内容槽)、描述列表变体(行内/垂直/可复制)、树增强(连接线 `.tree--lined` +
|
|
269
|
+
- **content**:列表增强(`.list-item-leading/meta/trailing` + 选中/斑马)、时间线变体(右侧/交替/自定义尺寸/扩展内容槽)、描述列表变体(行内/垂直/可复制)、树增强(连接线 `.tree--lined` + 搜索高亮)、代码块(`.code-block`)、kbd 大号/按下态。
|
|
233
270
|
- **media**:头像变体(语义色/渐变/方形/通知环)、头像组溢出计数、评分只读/清除/计数/摘要、轮播缩略图/索引/渐入。
|
|
234
271
|
- **toast**:语义图标、关闭钮、富内容(标题+正文)、超时进度条、6 种容器定位。
|
|
235
272
|
- **pill**:可关闭(`.pill-close`)、图标、实时脉冲(`--live`)、纯数字(`--count`)、渐变(`--gradient`)。
|
|
@@ -250,7 +287,19 @@ bun run build # tsup(src/behaviors/*.ts → dist/behaviors/*.mjs + index.m
|
|
|
250
287
|
- **ai-usage 双形态**:分段条 `renderAiUsage` + 上下文窗口环形指示器 `renderAiUsageRing`(点击弹出完整分解,弹层复用 popover;状态档 <60% accent / 60–85% warning / >85% error+脉冲)。配套 `renderAiAudit` 审计面板(totals + byModel + 最近条目,清除钮派 `icen:ai-audit-clear`);`ai-context` 抽屉的 `model.audit` 自动渲染审计节(紧凑形态)。
|
|
251
288
|
- **ai-composer v2**(业界集大成):底部工具条 = 模型切换(多 provider 分组 + 搜索 + 缓存失效提示,选中模型 context 自动喂给环的 total;无 context 显式清除不留陈旧值)+ 上下文环挂载点 + 附件 + 发送/停止;`/` 命令弹层(拦截执行不进消息流);`@` 引用弹层(chip 分离渲染,textarea 不嵌 chip);空输入 `↑` 取回历史,运行中 `↑` 取回排队消息。附件三入口:钮选 / textarea 粘贴文件 / box 拖放(`.is-dragover` 高亮)。API:setComposerModels / setComposerCommands / setComposerRefs / setComposerUsage / bindComposer。
|
|
252
289
|
- **绑定层 `bindComposer`**(v0.7.1,spec §11,「零接线全链路」):事件驱动把 composer ↔ 消息区(renderAiMessage)↔ client(stream + 停止 + 排队自动续发 + 错误 → setError/fail)↔ 用量环(`usage.from: 'context'` 默认正确口径 | `'billing'` | AiAuditor)接成闭环;运行态自动管理(send→running / icen:ai-done→解除);不传 client 为纯状态绑定(渐进采用);重复绑定 WeakSet 防护,unbind 解绑。
|
|
253
|
-
- **ai-provider 适配层**(`src/behaviors/ai-provider.ts`,无 UI 不占 slug):注册表内置 openai/claude/deepseek/glm/kimi
|
|
254
|
-
- **AI 工具体系(v0.8,`src/behaviors/ai-tools.ts`,不绑定 slug)**:UI 能力注册为模型可调用的 AiToolDef(内置 render_chart,inputSchema=ChartSpec);createAiToolArea 挂载区三层控制(不 import=无 / 白名单+max
|
|
290
|
+
- **ai-provider 适配层**(`src/behaviors/ai-provider.ts`,无 UI 不占 slug):注册表内置 openai/claude/deepseek/glm/kimi 五家(`registerAiProvider`/`getAiProvider` 注册与读取第三方/自建网关;baseURL 可自定义,models 携带定价表——`estimateCost` 未命中返回 undefined 不猜价),`createAiClient` 填 key 即用(chat + stream 双族线协议,多模态 parts 传输:openai 族 image_url/input_audio/file_id、anthropic 族 image/audio/document(pdf) + `cacheControl` 断点 + role 'tool' 的 tool_result 回灌;video 两族诚实报 unsupported),usage 走 normalizeUsage 归一(含各家缓存字段),`createAiAuditor` 环形审计(条目含 cost 定价估算 + ttftMs 首 token 延迟;`summary()` 喂环 / `totals()` 喂审计面板 / `byModel()` 分组),每次请求派 `icen:ai-usage` 与 `icen:ai-done` 事件。浏览器直连:claude 官方支持(自动带直连头),openai 官方禁止,其余三家建议代理(browserDirect 字段诚实标注)。
|
|
291
|
+
- **AI 工具体系(v0.8,`src/behaviors/ai-tools.ts`,不绑定 slug)**:UI 能力注册为模型可调用的 AiToolDef(内置 render_chart,inputSchema=ChartSpec);createAiToolArea 挂载区三层控制(不 import=无 / 白名单+max FIFO 淘汰最旧挂载 / 运行时 setTools·setMax·clear);`AiToolDef.present: 'mount'|'data'`(data=不占挂载位,记录与事件照常,run 返回值即结果);注册面 `registerAiTool`·`unregisterAiTool`(联动摘除各区域已挂载卡)·`getAiTool`·`listAiTools`;模型侧导出 aiToolsToOpenAI/aiToolsToMcp/aiToolsManifest + parseAiToolArgs;工具回执内嵌图(**仅 output**;input 是机器参数保持 JSON)→ renderAiToolCall IO 区直接 renderChart;待办业界模式:TodoWrite 折叠卡(todo kind summarize x/y)+ `setComposerTodo` 输入区实时 chip(全完成/有失败图标反馈,点击弹层看清单);事件 icen:ai-tool-call/-result/-evict。规格 §13。
|
|
255
292
|
- **ai-core 不绑定任何 slug**:demo/消费方要用 `normalizeToolCall` 等时,在该页 behaviors 数组里显式加 `'ai-core'`(boot 的 glob 会加载并注入 `aiCoreMod` 参数)。
|
|
256
293
|
- **宽度自稳定契约**:所有 AI 输出容器根(`.ai-chat/.ai-reasoning/.ai-composer/.ai-item/.ai-tool/.ai-subagent/.ai-diff/.ai-files/.ai-todo/.ai-usage`)声明 `align-self: stretch`——在 flex/grid 居中宿主(shrink-wrap 上下文,如文档站 `.demo-stage`)里不随内容多少改变宽度,流式内容只允许纵向生长。**禁用 `width: 100%`** 做这件事(在 shrink-wrap 父级下会塌成 min-content)。消费方给组件包一层自己的布局 wrapper 时,wrapper 的宽度由消费方负责(demo 里直接 `style="width:100%"`)。
|
|
294
|
+
|
|
295
|
+
## 知识库族(v0.9 新增)
|
|
296
|
+
|
|
297
|
+
规格唯一事实源:`docs/spec/kb-family.md`(顶层设计 / 类名 / 导出签名 / 事件名以它为准;调研底稿 `docs/research/2026-10-03-ai-kb-components.md` + `2026-10-03-kb-permissions.md`)。32 个 slug 在文档站侧栏「知识库」分组(第三位);旗舰成品页 `/kb`(八标签工作台全真接线 + 参考文献锚点)。
|
|
298
|
+
|
|
299
|
+
- **心法**:ai 族描述思考(过程),kb 族呈现证据(知识从哪来 / 可信吗 / 怎么用)。CSS 根类 `.kb-*`,行为文件 `kb-*.ts`,事件 `icen:kb-*`(45 个全量登记 `IcenEventMap`,detail 契约编译期校验)。
|
|
300
|
+
- **契约层 `kb-core.ts`(无 UI 不占 slug)**:KbCitation(三型定位 char/page/block,unit 写死)/ KB_SCORE_KINDS + scoreHigherIsBetter + scorePercent(l2 自动反转,null→「—」)/ KbChunk / KbRunStatus 管线五态 / normalizeConnector + connectorHealth(4 离散信号,enabled≠healthy)/ segmentText + segmentStats / normalizeRetrievalParams / KbFilterNode + filterToMongo/filterToOData / KbEvalRow + evalGrade(improvement/regression/tradeoff/tie)/ KbCheckpoint + scope / KbSandboxMessage 等 40+ normalize 与格式化函数。**业务数据一律先过 normalize 再喂组件**;demo / 消费方要用契约时在该页 behaviors 数组显式加 `'kb-core'`。
|
|
301
|
+
- **CSS 布局**:共享基座 `kb.css`(.kb-row 28/24 双密度、.kb-num/.kb-meta、.kb-dot 四态、.kb-score bar、.kb-quote 证据线 + mark 分色 data-hit 0/1/2、.kb-badge 族、.kb-chip、.kb-fold、.kb-key、.kb-empty、.kb-notice、.kb-layer-chip 过滤层徽标三态)+ 七域文件 kb-{ground,ingest,search,data,ops,agent,perm}.css。slugs.mjs 的 EXTRA_CSS 把每个 kb-* slug 映射到 `['kb.css', '<域>.css']`(kit 入口自动带上);`kb` 总集 slug 带全部七域。新组件先进规格冻结 DOM 骨架再动手(权限域冻结在 §9)。
|
|
302
|
+
- **诚实呈现纪律(kb 族特有,评审必查)**:分数 null →「—」不猜;行数截断必须声明(「前 200 行」);权限缺失打码 + 「申请访问」入口;重排关闭后列压淡不隐藏(显式禁用 > 静默消失);检查点回滚范围显式(只回滚文件保留对话);DSL 镜像只镜像可发送规则(无效规则不进 DSL);`仅本次会话生效 / 入库` 二选一显式承诺。
|
|
303
|
+
- **分数条纪律**:`.kb-score-bar` 是定宽轨道(域 CSS 内 `flex: 0 0 64px` 量级)+ `i` inline width 百分比——禁止让轨道随数值文本伸缩(曾导致 0.49 与 0.13 等长的失真)。
|
|
304
|
+
- **DOM 骨架与事件**:每个组件的冻结骨架与函数名在规格 §4/§5;`createX(el, opts) → handle`(含 destroy)、`renderX(el, data)` 快照渲染、`initX(root?)` document 委托幂等——与全库三契约(凹槽/尺寸/事件)同一心智。
|
|
305
|
+
- **/kb 工作台**(`site/src/pages/kb.astro` + `site/src/lib/kb-showcase.ts`):mock 数据与接线全在 showcase 模块;八标签 = 问答 / 摄取 / 检索 / 问数 / 观测 / 权限 / Agent / 参考(参考为静态 SSR,数据在 kb-references.ts)。改 mock 数据只动 kb-showcase.ts;页面脚本遵守 `astro:page-load` 驱动约定。
|
package/README.md
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
# @icen.ai/ui — Icen Design System
|
|
2
2
|
|
|
3
|
-
icen.ai 全生态的统一设计系统:**设计 tokens(6 色彩预设 × 明暗双模 × 3 风格 profile)+ 无框架组件 CSS(
|
|
3
|
+
icen.ai 全生态的统一设计系统:**设计 tokens(6 色彩预设 × 明暗双模 × 3 风格 profile)+ 无框架组件 CSS(65 组件)+ 行为 JS(70 behaviors)+ 统一事件体系 + AI 原生组件族 + 知识库组件族 + 图表通用层 + AI 工具体系**。工程形态与 `@icen.ai/cli` 一致(Bun + TS + tsup + ESM + MIT)。
|
|
4
4
|
|
|
5
5
|
- 色彩预设:`clay`(默认,陶土橙 × 纸白 = icen 品牌)/ `piano` / `art` / `vangogh` / `ink` / `retro`,各含 `.dark` 变体
|
|
6
6
|
- 风格配置:`.style-modern` / `.style-retro` / `.style-terminal`(几何 / 密度 / 动效 / 字体 token,与色彩正交)
|
|
7
7
|
- 可选效果层:`retro-effects.css`(CRT 扫描线 / 颗粒 / 像素边框 / 打字机光标 —— 仅 `.style-retro` 激活时生效,按需 import)
|
|
8
|
-
- 组件:btn / form / input / select / slider / switch / tag-input / upload / modal / popover / tooltip / menu(含 dropdown + context-menu)/ tabs / nav / sidebar / breadcrumb / pagination / steps / segmented / accordion / tree / carousel / charts / table / stat / card / panel / pill / tag / badge / empty / feedback / content / media / toolbar / split-pane / date-picker / command-palette / notification / copy / scroll-area / back-top / datatable / layout(
|
|
8
|
+
- 组件:btn / form / input / select / slider / switch / tag-input / upload / modal / popover / tooltip / menu(含 dropdown + context-menu)/ tabs / nav / sidebar / breadcrumb / pagination / steps / segmented / accordion / tree / carousel / charts / table / stat / card / panel / pill / tag / badge / empty / feedback / content / media / toolbar / split-pane / date-picker / command-palette / notification / copy / scroll-area / back-top / datatable / layout(65 个组件 CSS:charts 基座 + 13 个细分图表 kit + kb.css 基座 + 7 个 kb 域文件 + 4 个 AI 族合并文件);浮层尺寸统一 PanelSizing 契约(`data-panel-width/-min/-max/-min-height/-max-height` 属性面 + 程序面对象,含视口夹取)
|
|
9
9
|
- 图表通用层(v0.8):`renderChart(el, spec)` 统一入口——纯 JSON 规格(type 缺省自动推断;data[] + dims 任意维度透视)、多系列折线/分组堆叠柱、内置 tooltip、`icen:chart-hover/click/dblclick/contextmenu` 交互事件族、图例点击切换系列;新增贡献日历 renderCalendar(GitHub 同款)与散点气泡 renderScatter
|
|
10
|
-
- AI 原生组件族(v0.7,
|
|
10
|
+
- AI 原生组件族(v0.7,14 个 slug):ai-chat(会话容器)/ ai-message(消息行)/ ai-reasoning(推理块,流式展开完成后自动折叠一次)/ ai-composer(输入台)/ ai-tool-call(工具调用卡)/ ai-subagent(子智能体卡)/ ai-diff(差异审阅)/ ai-files(文件标签)/ ai-todo(任务清单)/ ai-context(上下文抽屉)/ ai-usage(用量条)/ ai-threads(会话线程树)/ ai-feedback(👍👎 + 理由)/ ai-branch(消息分支切换)——共享 7 态状态机与 kind 注册表,事件统一 `icen:ai-*` 前缀
|
|
11
|
+
- 知识库组件族(v0.9,32 个 slug,规格 `docs/spec/kb-family.md`):**ai 族描述思考(过程),kb 族呈现证据(知识从哪来 / 可信吗 / 怎么用);权限域呈现边界(谁能看到什么,以及为什么)**。七域——证据(kb-citation 角标三型定位 / kb-sources / kb-passage 高亮回看 / kb-conflict)、摄取(kb-pipeline / kb-chunks 分块审阅 / kb-segment / kb-connector 连接器健康 / kb-metadata / kb-qa 问答对)、检索(kb-retrieval playground / kb-filter → Mongo·OData 双 DSL / kb-rerank A/B 对比 / kb-hittest 召回测试)、问数(kb-sql / kb-answer / kb-clarify)、治理(kb-explain / kb-trace / kb-review / kb-gap / kb-eval 四级评测)、工作台(kb-canvas / kb-checkpoint 范围显式回滚 / kb-sandbox MCP 沙箱 / kb-chain)、**权限(kb-acl 继承四件套+双区 / kb-who-can view-as 原因链 / kb-access 九态申请流 / kb-audit 审计+异味 / kb-visibility admin 可见性对照器)**;契约层 `kb-core.ts`(60+ normalize,`evaluateAcl` 纯函数:先 deny→并集→默认拒绝;分数纪律与**安全呈现纪律**全族统一——对授权侧诚实、对受限侧沉默),事件统一 `icen:kb-*`
|
|
11
12
|
- 标准化内容模型 `AiContent`(v0.7.1,对标 AI SDK v5 parts / MCP / OpenAI / Anthropic,2026-10 调研):一套 `AiContentPart[]`(text / image / audio / video / file / resource-link)表达任意输入——消息渲染(renderAiMessage 多模态 + 错误变体)、工具回执(MCP content 数组零改动进卡片)、传输层(parts → 两族 wire,含 anthropic `cache_control` 与 tool_result 回灌)全部只认这一套;`normalizeContentParts` 一函数归一四族来源,`estimateTokens` / `contextEstimate` 提供粗估与上下文口径
|
|
12
13
|
- ai-provider 适配层(v0.7.1 增强):五家厂商注册表(含定价表,`estimateCost` 未命中不猜价)、chat + stream 双族线协议多模态传输、审计闭环(`createAiAuditor` 条目含 cost 定价估算与 ttftMs 首 token 延迟,`renderAiAudit` 面板 + `ai-context` 抽屉审计节)、请求收尾派 `icen:ai-done`(status/usage/cost/error/durationMs/ttftMs)
|
|
13
14
|
- 绑定层 `bindComposer`(v0.7.1,「零接线全链路」):一行把 composer ↔ 消息区(renderAiMessage)↔ client(stream + 停止 + 排队续发 + 错误路径)↔ 上下文环(`usage.from: 'context'` 正确口径 / `'billing'` 计费口径 / auditor)接成闭环;不传 client 为纯状态绑定(渐进采用);附件三入口(钮选 / 粘贴 / 拖放)
|
|
14
15
|
- AI 工具体系(v0.8,`ai-tools`):UI 能力注册为模型可调用的工具(内置 `render_chart` 吃 ChartSpec 纯 JSON);`createAiToolArea` 挂载区三层控制(白名单 / max LRU / 运行时调节);模型侧 `aiToolsToOpenAI()` 直接给 tools 参数、`aiToolsManifest()` 贴 system prompt;工具回执内嵌图(output 为 chart spec → 工具卡展开区直接渲染)
|
|
15
|
-
-
|
|
16
|
+
- 事件体系(events):`onIcen` 一个入口(类型化 `IcenEventMap` + 选择器委托 + `{ within, signal, once }`)+ `emitIcen` 唯一派生口 + `setEventPolicy` 手势默认行为 + `data-gestures` 声明式手势(click/dblclick/contextmenu/longpress/text-select,位移守卫与消歧内建)
|
|
17
|
+
- 控件族(controls):`initSwitch`(开关/三态勾选/单选组)/ `initStepper` / `initSegmented` / `initSteps` / `initRating` / `initPagination` / `initTableSort`——纯 CSS 控件的行为承载与 `icen:*-change` 事件
|
|
18
|
+
- 行为:theme / tabs / toast / copy / input / select / slider / tag-input / upload / modal / dropdown / popover / context-menu / accordion / tree / carousel / charts / nav / sidebar / datatable / notification / back-top / command-palette / date-picker / split-pane / events / controls / ai-core / ai-chat / ai-composer / ai-tool / ai-provider / ai-diff / ai-panel / ai-tools / ai-threads / ai-feedback / ai-branch / kb-core + 31 个 kb-*(70 个,全部 SSR 守卫 + 幂等 init + 返回销毁函数 + textContent-only)
|
|
16
19
|
|
|
17
20
|
## 使用
|
|
18
21
|
|
|
@@ -43,6 +46,9 @@ import {
|
|
|
43
46
|
} from '@icen.ai/ui';
|
|
44
47
|
|
|
45
48
|
initTheme(); // 尽早调用(或内联同步脚本防闪烁,见 accounts Base.astro)
|
|
49
|
+
setStyle('retro'); // 切风格画像(modern/retro),与主题正交
|
|
50
|
+
registerThemePreset('brand'); // 登记自建预设(宿主 CSS 先写好 .brand/.brand.dark token 面)
|
|
51
|
+
listThemePresets(); // 枚举全部预设(含注册的),UI 切换器用
|
|
46
52
|
initTabs(); // [data-tabs] > [data-tab] + [data-tab-panel] 契约;切换派发 icen:tab-change
|
|
47
53
|
initCopy(); // .copy-btn[data-copy] 委托
|
|
48
54
|
toast.ok('已保存'); // 或 toast.action('已删除', '撤销', undo);类名 .toast--success 等
|
|
@@ -71,7 +77,7 @@ const binding = bindComposer(composer, {
|
|
|
71
77
|
|
|
72
78
|
## 文档站(已上线 <https://ui.icen.ai>)
|
|
73
79
|
|
|
74
|
-
`site/` 是公开文档站(首页 / 色彩预设色板 /
|
|
80
|
+
`site/` 是公开文档站(首页 / 色彩预设色板 / 组件演示 / **[知识库工作台](https://ui.icen.ai/kb/)**——六标签全真接线的最佳实践成品页,导航栏实时换肤换明暗)。部署:
|
|
75
81
|
|
|
76
82
|
```bash
|
|
77
83
|
cd site && bun install && bun run build
|
|
@@ -87,7 +93,7 @@ bun install
|
|
|
87
93
|
bun run build # tsup(behaviors → dist/*.mjs + .d.mts 类型面)+ scripts/dts-ext.mjs + scripts/build-css.ts(css → dist/)
|
|
88
94
|
```
|
|
89
95
|
|
|
90
|
-
产物:`dist/tokens.css`(colors + style-profiles + typography 拼合)、`dist/ui.css`(tokens+base+组件)、`dist/base.css`、`dist/retro-effects.css`(按需)、`dist/tokens/*`、`dist/components/*`、`dist/behaviors/*.mjs` + `.d.mts`(
|
|
96
|
+
产物:`dist/tokens.css`(colors + style-profiles + typography 拼合)、`dist/ui.css`(tokens+base+组件)、`dist/base.css`、`dist/retro-effects.css`(按需)、`dist/tokens/*`、`dist/components/*`、`dist/behaviors/*.mjs` + `.d.mts`(66 个声明,JSDoc 约束注释存活)、`dist/index.mjs`、`dist/registry.json`(含 tokens/tokensExtras/base/components/behaviors 清单)。
|
|
91
97
|
|
|
92
98
|
## 目录
|
|
93
99
|
|
|
@@ -100,10 +106,12 @@ src/tokens/retro-effects.css # 可选效果层:CRT/扫描线/像素工具类
|
|
|
100
106
|
src/base.css # 元素基线 + 滚动条 + z-index 标尺 + 6 个交互基元
|
|
101
107
|
# .pressable / .control / .field / .lift / .surface-elevated / .focus-ring
|
|
102
108
|
# + a11y 工具类 .sr-only / .skip-link + 工具类 .mono/.dim/.faint/.numeric
|
|
103
|
-
src/components/*.css #
|
|
104
|
-
src/behaviors/*.ts
|
|
109
|
+
src/components/*.css # 65 个无框架组件 CSS(4 个 AI 族合并文件 + kb.css 基座 + 7 个 kb 域文件 + chart-graph)
|
|
110
|
+
src/behaviors/*.ts # 70 个 behaviors(AI 族 11 个 + kb 族 32 个)
|
|
111
|
+
docs/spec/kb-family.md # 知识库族规格(顶层设计唯一事实源,§9 权限域)
|
|
112
|
+
docs/research/ # 两轮调研归档(组件选型 + 权限安全,100+ 来源查证)
|
|
105
113
|
scripts/build-css.ts # CSS 产物构建(拼合 + registry.json)
|
|
106
|
-
site/ # 文档站骨架(ui.icen.ai,独立 Astro
|
|
114
|
+
site/ # 文档站骨架(ui.icen.ai,独立 Astro 应用,含 /kb 工作台)
|
|
107
115
|
```
|
|
108
116
|
|
|
109
117
|
## 消费方接入
|
package/dist/base.css
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* ════════════════════════════════════════════════════════════════════════
|
|
8
8
|
* icen 组件契约(统一抽象)
|
|
9
9
|
* ════════════════════════════════════════════════════════════════════════
|
|
10
|
-
* 所有
|
|
10
|
+
* 所有 56 个组件遵循同一套抽象,由两层共同支撑:
|
|
11
11
|
*
|
|
12
12
|
* ── 层 1:--icen-* 原语 token(所有组件自洽消费)
|
|
13
13
|
* --icen-ring / --icen-ring-soft / --icen-ring-error /
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
* 暴露的契约:
|
|
56
56
|
* - 元素基线:box-sizing / body / a / code / pre / img / ::selection
|
|
57
57
|
* - 滚动条:贴 --token-scrollbar-*(retro profile 另有硬覆盖)
|
|
58
|
-
* - 工具类:.mono / .dim / .faint / .sr-only / .skip-link
|
|
58
|
+
* - 工具类:.mono / .serif / .dim / .faint / .numeric / .sr-only / .skip-link
|
|
59
59
|
* - z-index 标尺:--z-* (浮层一律 portal 到 body)
|
|
60
60
|
* - 共享 keyframes:icen-pop-in(弹层进场)/ icen-spin(旋转)/ icen-skeleton-pulse(骨架脉冲)
|
|
61
61
|
* - 交互基元 class:.pressable / .control / .field / .lift / .surface-elevated / .focus-ring / .motion
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
───────────────────────────────────────────────────────────────
|
|
68
68
|
所有组件消费的"原语级"变量:聚焦环、悬停、按下、禁用、过渡。
|
|
69
69
|
风格 profile(如 .style-retro)只需覆盖这里的少数变量,
|
|
70
|
-
即可让
|
|
70
|
+
即可让 56 个组件整体换肤;组件自身无需感知风格切换。
|
|
71
71
|
══════════════════════════════════════════════════════════════ */
|
|
72
72
|
:root {
|
|
73
73
|
/* ── 聚焦环(focus-visible) ── */
|
|
@@ -391,6 +391,7 @@ html {
|
|
|
391
391
|
<span class="field-label">姓名</span>
|
|
392
392
|
<span class="control"><input /></span>
|
|
393
393
|
<span class="field-hint">必填</span>
|
|
394
|
+
<span class="field-error">错误</span>
|
|
394
395
|
</label> */
|
|
395
396
|
.field {
|
|
396
397
|
display: flex;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* 为 root 下每个 .accordion 容器初始化(root 自身是 .accordion 也算)。
|
|
3
|
+
* 返回销毁函数:移除本次挂上的容器监听并复位幂等标记(销毁后可重新 init)。SSR 下返回 no-op。
|
|
4
|
+
*/
|
|
5
|
+
declare function initAccordion(root?: ParentNode): () => void;
|
|
3
6
|
|
|
4
7
|
export { initAccordion };
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
// src/behaviors/events.ts
|
|
2
|
+
function emitIcen(source, type, detail) {
|
|
3
|
+
return source.dispatchEvent(
|
|
4
|
+
new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable: true })
|
|
5
|
+
);
|
|
6
|
+
}
|
|
7
|
+
|
|
1
8
|
// src/behaviors/accordion.ts
|
|
2
9
|
function setup(container) {
|
|
3
10
|
const el = container;
|
|
4
|
-
if (el.__icenAccordionInit) return;
|
|
11
|
+
if (el.__icenAccordionInit) return void 0;
|
|
5
12
|
el.__icenAccordionInit = true;
|
|
6
13
|
const single = container.hasAttribute("data-single");
|
|
7
|
-
|
|
14
|
+
const onClick = (ev) => {
|
|
8
15
|
const target = ev.target;
|
|
9
16
|
if (!(target instanceof Element)) return;
|
|
10
17
|
const trigger = target.closest(".accordion-trigger");
|
|
@@ -14,6 +21,8 @@ function setup(container) {
|
|
|
14
21
|
if (item.classList.contains("is-disabled")) return;
|
|
15
22
|
const open = item.classList.toggle("is-open");
|
|
16
23
|
trigger.setAttribute("aria-expanded", String(open));
|
|
24
|
+
const index = Array.from(container.querySelectorAll(".accordion-item")).indexOf(item);
|
|
25
|
+
emitIcen(container, "icen:accordion-toggle", { item, index, open });
|
|
17
26
|
if (single && open) {
|
|
18
27
|
container.querySelectorAll(".accordion-item.is-open").forEach((other) => {
|
|
19
28
|
if (other === item) return;
|
|
@@ -21,8 +30,8 @@ function setup(container) {
|
|
|
21
30
|
other.querySelector(".accordion-trigger")?.setAttribute("aria-expanded", "false");
|
|
22
31
|
});
|
|
23
32
|
}
|
|
24
|
-
}
|
|
25
|
-
|
|
33
|
+
};
|
|
34
|
+
const onKeyDown = (ev) => {
|
|
26
35
|
const kev = ev;
|
|
27
36
|
const target = kev.target;
|
|
28
37
|
if (!(target instanceof Element)) return;
|
|
@@ -40,15 +49,31 @@ function setup(container) {
|
|
|
40
49
|
kev.preventDefault();
|
|
41
50
|
triggers[triggers.length - 1]?.focus();
|
|
42
51
|
}
|
|
43
|
-
}
|
|
52
|
+
};
|
|
53
|
+
container.addEventListener("click", onClick);
|
|
54
|
+
container.addEventListener("keydown", onKeyDown);
|
|
55
|
+
return () => {
|
|
56
|
+
container.removeEventListener("click", onClick);
|
|
57
|
+
container.removeEventListener("keydown", onKeyDown);
|
|
58
|
+
el.__icenAccordionInit = false;
|
|
59
|
+
};
|
|
44
60
|
}
|
|
45
61
|
function initAccordion(root) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
const cleanups = [];
|
|
63
|
+
if (typeof document !== "undefined") {
|
|
64
|
+
const scope = root ?? document;
|
|
65
|
+
const containers = [];
|
|
66
|
+
if (scope instanceof Element && scope.matches(".accordion")) containers.push(scope);
|
|
67
|
+
containers.push(...Array.from(scope.querySelectorAll(".accordion")));
|
|
68
|
+
for (const c of containers) {
|
|
69
|
+
const cleanup = setup(c);
|
|
70
|
+
if (cleanup) cleanups.push(cleanup);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return () => {
|
|
74
|
+
for (const fn of cleanups) fn();
|
|
75
|
+
cleanups.length = 0;
|
|
76
|
+
};
|
|
52
77
|
}
|
|
53
78
|
export {
|
|
54
79
|
initAccordion
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface AiBranchModel {
|
|
2
|
+
/** 当前分支(0 起;渲染时钳制到 [0, count-1]) */
|
|
3
|
+
index: number;
|
|
4
|
+
/** 分支总数;≤1 时渲染为空(aria-hidden) */
|
|
5
|
+
count: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* 渲染 ‹ index+1/count › 分支切换器:count ≤ 1 时挂载容器清空并置 hidden + aria-hidden;
|
|
9
|
+
* 边界(首/末)对应方向钮禁用。返回挂载容器 el(render* 返回挂载元素约定,SSR 原样返回)。
|
|
10
|
+
*/
|
|
11
|
+
declare function renderAiBranch(el: HTMLElement, model: AiBranchModel): HTMLElement;
|
|
12
|
+
/**
|
|
13
|
+
* 分支切换委托初始化:prev/next 点击 → icen:ai-branch-change {index, count}
|
|
14
|
+
* (index 为钳制后的 index±1);同时同步 data-index / 页码 / 边界禁用态(宿主不重渲染也可用,
|
|
15
|
+
* 重渲染覆盖亦安全)。幂等(scope 挂 __icenAiBranchInit);返回销毁函数。SSR 下为 no-op。
|
|
16
|
+
*/
|
|
17
|
+
declare function initAiBranch(root?: ParentNode): () => void;
|
|
18
|
+
|
|
19
|
+
export { type AiBranchModel, initAiBranch, renderAiBranch };
|