@icen.ai/ui 0.11.0 → 0.11.2
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/README.md +2 -2
- package/dist/base.css +11 -6
- package/dist/behaviors/ai-branch.mjs +13 -0
- package/dist/behaviors/ai-chat.mjs +13 -0
- package/dist/behaviors/ai-composer.mjs +13 -0
- package/dist/behaviors/ai-core.mjs +13 -0
- package/dist/behaviors/ai-diff.mjs +13 -0
- package/dist/behaviors/ai-feedback.mjs +13 -0
- package/dist/behaviors/ai-panel.mjs +13 -0
- package/dist/behaviors/ai-provider.mjs +13 -0
- package/dist/behaviors/ai-threads.mjs +13 -0
- package/dist/behaviors/ai-tool.mjs +242 -0
- package/dist/behaviors/ai-tools.mjs +242 -0
- package/dist/behaviors/autocomplete.mjs +13 -0
- package/dist/behaviors/back-top.mjs +13 -0
- package/dist/behaviors/carousel.mjs +13 -0
- package/dist/behaviors/cascader.mjs +13 -0
- package/dist/behaviors/charts.d.mts +12 -1
- package/dist/behaviors/charts.mjs +242 -0
- package/dist/behaviors/code-block.mjs +13 -0
- package/dist/behaviors/context-menu.mjs +13 -0
- package/dist/behaviors/controls.mjs +13 -0
- package/dist/behaviors/copy.mjs +13 -0
- package/dist/behaviors/datatable.mjs +13 -0
- package/dist/behaviors/date-picker.mjs +13 -0
- package/dist/behaviors/form-validate.mjs +13 -0
- package/dist/behaviors/i18n.d.mts +13 -0
- package/dist/behaviors/i18n.mjs +26 -0
- package/dist/behaviors/input.mjs +13 -0
- package/dist/behaviors/kb-access.mjs +13 -0
- package/dist/behaviors/kb-acl.mjs +13 -0
- package/dist/behaviors/kb-answer.mjs +242 -0
- package/dist/behaviors/kb-audit.mjs +13 -0
- package/dist/behaviors/kb-canvas.mjs +13 -0
- package/dist/behaviors/kb-chain.mjs +13 -0
- package/dist/behaviors/kb-checkpoint.mjs +13 -0
- package/dist/behaviors/kb-chunks.mjs +13 -0
- package/dist/behaviors/kb-citation.mjs +13 -0
- package/dist/behaviors/kb-clarify.mjs +13 -0
- package/dist/behaviors/kb-conflict.mjs +13 -0
- package/dist/behaviors/kb-connector.mjs +13 -0
- package/dist/behaviors/kb-core.mjs +13 -0
- package/dist/behaviors/kb-eval.mjs +13 -0
- package/dist/behaviors/kb-explain.mjs +13 -0
- package/dist/behaviors/kb-filter.mjs +13 -0
- package/dist/behaviors/kb-gap.mjs +13 -0
- package/dist/behaviors/kb-hittest.mjs +13 -0
- package/dist/behaviors/kb-metadata.mjs +13 -0
- package/dist/behaviors/kb-passage.mjs +13 -0
- package/dist/behaviors/kb-pipeline.mjs +13 -0
- package/dist/behaviors/kb-qa.mjs +13 -0
- package/dist/behaviors/kb-rerank.mjs +13 -0
- package/dist/behaviors/kb-retrieval.mjs +13 -0
- package/dist/behaviors/kb-review.mjs +13 -0
- package/dist/behaviors/kb-sandbox.mjs +13 -0
- package/dist/behaviors/kb-segment.mjs +13 -0
- package/dist/behaviors/kb-select.mjs +13 -0
- package/dist/behaviors/kb-sources.mjs +13 -0
- package/dist/behaviors/kb-sql.mjs +13 -0
- package/dist/behaviors/kb-trace.mjs +13 -0
- package/dist/behaviors/kb-visibility.mjs +13 -0
- package/dist/behaviors/kb-who-can.mjs +13 -0
- package/dist/behaviors/mentions.mjs +13 -0
- package/dist/behaviors/modal.mjs +13 -0
- package/dist/behaviors/motion.d.mts +16 -0
- package/dist/behaviors/motion.mjs +39 -0
- package/dist/behaviors/notification.mjs +13 -0
- package/dist/behaviors/panel.mjs +13 -0
- package/dist/behaviors/select.mjs +13 -0
- package/dist/behaviors/suggestions.mjs +13 -0
- package/dist/behaviors/tag-input.mjs +13 -0
- package/dist/behaviors/theme-switcher.mjs +13 -0
- package/dist/behaviors/toast.mjs +13 -0
- package/dist/behaviors/tree-select.mjs +13 -0
- package/dist/behaviors/upload.mjs +13 -0
- package/dist/components/charts.css +29 -0
- package/dist/components/material.css +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +257 -1
- package/dist/react.mjs +242 -0
- package/dist/registry.json +3 -1
- package/dist/tokens/design.css +15 -9
- package/dist/tokens/dtcg.json +3594 -738
- package/dist/tokens/figma.variables.json +1705 -157
- package/dist/tokens/motion.css +51 -0
- package/dist/tokens/pixel.css +7 -0
- package/dist/tokens/tokens-studio.json +3007 -679
- package/dist/tokens/typography.css +33 -0
- package/dist/tokens.css +107 -10
- package/dist/ui.css +147 -16
- package/dist/vue.mjs +242 -0
- package/docs/spec/charts-scale-a11y.md +115 -0
- package/docs/spec/motion-typography.md +105 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://github.com/icen-ai/ui/actions/workflows/ci.yml)
|
|
5
5
|
[](./LICENSE)
|
|
6
6
|
|
|
7
|
-
icen.ai
|
|
7
|
+
icen.ai 的设计系统:<!-- meta:components -->122<!-- /meta:components --> 个组件入口、<!-- meta:charts.total -->14<!-- /meta:charts.total --> 种图表与 AI 原生组件族共用一套设计令牌——换肤不改代码,UI 可直接交给模型调用。无框架、零运行时依赖(`dependencies` 为空,可验证)、SSR 安全,MIT。
|
|
8
8
|
|
|
9
9
|
- 文档与实时演示:<https://ui.icen.ai>
|
|
10
10
|
- 安装:`bun add @icen.ai/ui`(或 `npm i`)
|
|
@@ -39,7 +39,7 @@ renderLine(el, { labels, series }); // 函数式组件:无 init,直接渲染
|
|
|
39
39
|
## 里面有什么
|
|
40
40
|
|
|
41
41
|
- **组件**:无框架组件库(表单 / 浮层 / 导航 / 数据展示 / 反馈),纯 CSS 契约 + 按需行为 JS。类名 `icen-*`、钩子 `data-icen-*`、变量 `--icen-*`,产物全部进 cascade layers,与任何第三方 CSS 共存零冲突。
|
|
42
|
-
- **图表**:一份 JSON
|
|
42
|
+
- **图表**:一份 JSON <!-- meta:charts.total -->14<!-- /meta:charts.total --> 种图,悬停/点击/图例开关内建,不依赖图表库。
|
|
43
43
|
- **AI 界面**:对话 / 推理 / 工具调用 / 审批 / 输入台 / 用量审计;兼容 OpenAI / Anthropic / MCP / AI SDK 协议;UI 能力可注册成模型直接调用的工具。
|
|
44
44
|
- **知识库**:覆盖 RAG 全链路的组件族(摄取 / 检索 / 问数 / 治理 / 权限),权限域 fail-closed。
|
|
45
45
|
- **主题**:色彩预设 × 设计原语 × 明暗,全部挂在 `<html>` data 属性上;自建品牌只需在自家 CSS 写一块 token 面。
|
package/dist/base.css
CHANGED
|
@@ -493,15 +493,20 @@ p { margin: 0 0 1em; }
|
|
|
493
493
|
动效与无障碍兜底
|
|
494
494
|
══════════════════════════════════════════════════════════════ */
|
|
495
495
|
|
|
496
|
-
/* reduced-motion
|
|
496
|
+
/* reduced-motion 与手动覆盖的行为压制(变量开关在 design.css 自持):
|
|
497
|
+
循环/环境动画单次瞬时 + 平滑滚动关闭;过渡时长经 --icen-design-motion 归零瞬时完成(状态反馈保留)。 */
|
|
497
498
|
@media (prefers-reduced-motion: reduce) {
|
|
498
|
-
*, *::before, *::after {
|
|
499
|
-
animation-duration: 0.01ms !important; /* guard:allow-important
|
|
500
|
-
animation-iteration-count: 1 !important; /* guard:allow-important
|
|
501
|
-
|
|
502
|
-
scroll-behavior: auto !important; /* guard:allow-important 动效守卫:降级媒体查询需压制组件动画 */
|
|
499
|
+
:root:not([data-icen-motion="full"]) *, :root:not([data-icen-motion="full"]) *::before, :root:not([data-icen-motion="full"]) *::after {
|
|
500
|
+
animation-duration: 0.01ms !important; /* guard:allow-important 动效守卫:降级需压制组件循环动画 */
|
|
501
|
+
animation-iteration-count: 1 !important; /* guard:allow-important 动效守卫:降级需压制组件循环动画 */
|
|
502
|
+
scroll-behavior: auto !important; /* guard:allow-important 动效守卫:降级需关闭平滑滚动 */
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
|
+
:root[data-icen-motion="reduce"] *, :root[data-icen-motion="reduce"] *::before, :root[data-icen-motion="reduce"] *::after {
|
|
506
|
+
animation-duration: 0.01ms !important; /* guard:allow-important 手动降级:与系统降级同口径 */
|
|
507
|
+
animation-iteration-count: 1 !important; /* guard:allow-important 手动降级:与系统降级同口径 */
|
|
508
|
+
scroll-behavior: auto !important; /* guard:allow-important 手动降级:与系统降级同口径 */
|
|
509
|
+
}
|
|
505
510
|
|
|
506
511
|
/* 触屏设备(无精细指针):压低 pressable 按下形变(hover 抬升已由 hover 守卫关闭) */
|
|
507
512
|
@media (pointer: coarse) {
|
|
@@ -305,6 +305,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
305
305
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
306
306
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
307
307
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
308
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
309
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
310
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
311
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
312
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
313
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
314
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
315
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
316
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
317
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
318
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
319
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
320
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
308
321
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
309
322
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
310
323
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -204,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
204
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
205
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
206
206
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
207
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
208
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
209
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
210
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
211
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
212
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
213
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
214
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
215
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
216
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
217
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
218
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
219
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
207
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
208
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
209
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -305,6 +305,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
305
305
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
306
306
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
307
307
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
308
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
309
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
310
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
311
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
312
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
313
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
314
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
315
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
316
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
317
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
318
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
319
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
320
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
308
321
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
309
322
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
310
323
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -197,6 +197,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
197
197
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
198
198
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
199
199
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
200
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
201
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
202
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
203
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
204
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
205
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
206
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
207
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
208
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
209
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
210
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
211
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
212
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
200
213
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
201
214
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
202
215
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -204,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
204
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
205
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
206
206
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
207
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
208
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
209
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
210
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
211
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
212
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
213
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
214
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
215
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
216
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
217
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
218
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
219
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
207
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
208
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
209
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -204,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
204
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
205
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
206
206
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
207
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
208
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
209
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
210
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
211
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
212
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
213
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
214
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
215
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
216
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
217
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
218
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
219
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
207
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
208
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
209
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -305,6 +305,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
305
305
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
306
306
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
307
307
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
308
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
309
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
310
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
311
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
312
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
313
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
314
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
315
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
316
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
317
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
318
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
319
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
320
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
308
321
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
309
322
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
310
323
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -204,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
204
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
205
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
206
206
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
207
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
208
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
209
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
210
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
211
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
212
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
213
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
214
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
215
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
216
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
217
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
218
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
219
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
207
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
208
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
209
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -305,6 +305,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
305
305
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
306
306
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
307
307
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
308
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
309
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
310
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
311
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
312
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
313
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
314
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
315
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
316
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
317
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
318
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
319
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
320
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
308
321
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
309
322
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
310
323
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -204,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
204
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
205
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
206
206
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
207
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
208
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
209
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
210
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
211
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
212
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
213
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
214
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
215
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
216
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
217
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
218
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
219
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
207
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
208
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
209
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -2570,6 +2583,14 @@ function normalizeChartSpec(raw) {
|
|
|
2570
2583
|
}
|
|
2571
2584
|
if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
|
|
2572
2585
|
if (typeof s.loading === "boolean") spec.loading = s.loading;
|
|
2586
|
+
if (s.a11y && typeof s.a11y === "object") {
|
|
2587
|
+
const a = s.a11y;
|
|
2588
|
+
const a11y = {};
|
|
2589
|
+
if (typeof a.summary === "boolean") a11y.summary = a.summary;
|
|
2590
|
+
if (typeof a.table === "boolean") a11y.table = a.table;
|
|
2591
|
+
if (typeof a.keyboard === "boolean") a11y.keyboard = a.keyboard;
|
|
2592
|
+
if (Object.keys(a11y).length > 0) spec.a11y = a11y;
|
|
2593
|
+
}
|
|
2573
2594
|
if (Array.isArray(s.marks)) {
|
|
2574
2595
|
const marks = [];
|
|
2575
2596
|
for (const raw2 of s.marks) {
|
|
@@ -2925,6 +2946,81 @@ function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
|
|
|
2925
2946
|
function chartAriaLabel(title, typeName) {
|
|
2926
2947
|
return title ? `${typeName}\uFF1A${title}` : typeName;
|
|
2927
2948
|
}
|
|
2949
|
+
function summarizeChart(view, type, fmt2) {
|
|
2950
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
2951
|
+
const parts = [];
|
|
2952
|
+
if (series.length > 1) parts.push(t("charts.a11y.seriesCount", { p0: series.length }));
|
|
2953
|
+
if (type === "scatter") {
|
|
2954
|
+
const pts = view.points ?? [];
|
|
2955
|
+
if (pts.length > 0) {
|
|
2956
|
+
const xs = pts.map((p) => p.x);
|
|
2957
|
+
const ys = pts.map((p) => p.y);
|
|
2958
|
+
parts.push(t("charts.a11y.scatterRange", { p0: fmt2(Math.min(...xs)), p1: fmt2(Math.max(...xs)), p2: fmt2(Math.min(...ys)), p3: fmt2(Math.max(...ys)) }));
|
|
2959
|
+
}
|
|
2960
|
+
return parts.join("\uFF1B");
|
|
2961
|
+
}
|
|
2962
|
+
const labels = view.labels ?? [];
|
|
2963
|
+
if (labels.length > 1) parts.push(t("charts.a11y.range", { p0: labels[0], p1: labels[labels.length - 1] }));
|
|
2964
|
+
let min = Infinity;
|
|
2965
|
+
let max = -Infinity;
|
|
2966
|
+
let minAt = "";
|
|
2967
|
+
let maxAt = "";
|
|
2968
|
+
for (const s of series) {
|
|
2969
|
+
s.values.forEach((v, i) => {
|
|
2970
|
+
if (v < min) {
|
|
2971
|
+
min = v;
|
|
2972
|
+
minAt = labels[i] ?? String(i + 1);
|
|
2973
|
+
}
|
|
2974
|
+
if (v > max) {
|
|
2975
|
+
max = v;
|
|
2976
|
+
maxAt = labels[i] ?? String(i + 1);
|
|
2977
|
+
}
|
|
2978
|
+
});
|
|
2979
|
+
}
|
|
2980
|
+
if (Number.isFinite(min) && Number.isFinite(max)) {
|
|
2981
|
+
parts.push(t("charts.a11y.min", { p0: fmt2(min), p1: minAt }));
|
|
2982
|
+
parts.push(t("charts.a11y.max", { p0: fmt2(max), p1: maxAt }));
|
|
2983
|
+
}
|
|
2984
|
+
const first = series[0]?.values ?? [];
|
|
2985
|
+
if (first.length > 1) {
|
|
2986
|
+
const d = first[first.length - 1] - first[0];
|
|
2987
|
+
const key = Math.abs(d) < 1e-9 ? "charts.a11y.trendFlat" : d > 0 ? "charts.a11y.trendUp" : "charts.a11y.trendDown";
|
|
2988
|
+
parts.push(t("charts.a11y.trend", { p0: t(key) }));
|
|
2989
|
+
}
|
|
2990
|
+
return parts.join("\uFF1B");
|
|
2991
|
+
}
|
|
2992
|
+
function buildChartTable(view, spec, type, fmt2) {
|
|
2993
|
+
const table = document.createElement("table");
|
|
2994
|
+
table.className = "icen-chart-table";
|
|
2995
|
+
const caption = document.createElement("caption");
|
|
2996
|
+
caption.textContent = t("charts.a11y.tableCaption", { p0: spec.title ?? String(type) });
|
|
2997
|
+
table.appendChild(caption);
|
|
2998
|
+
const addRow = (target, cells, head) => {
|
|
2999
|
+
const tr = document.createElement("tr");
|
|
3000
|
+
for (const c of cells) {
|
|
3001
|
+
const cell = document.createElement(head ? "th" : "td");
|
|
3002
|
+
if (head) cell.scope = target.tagName === "THEAD" ? "col" : "row";
|
|
3003
|
+
cell.textContent = c;
|
|
3004
|
+
tr.appendChild(cell);
|
|
3005
|
+
}
|
|
3006
|
+
target.appendChild(tr);
|
|
3007
|
+
};
|
|
3008
|
+
const thead = table.createTHead();
|
|
3009
|
+
const tbody = table.createTBody();
|
|
3010
|
+
if (type === "scatter") {
|
|
3011
|
+
addRow(thead, ["x", "y"], true);
|
|
3012
|
+
for (const p of view.points ?? []) addRow(tbody, [fmt2(p.x), fmt2(p.y)], false);
|
|
3013
|
+
return table;
|
|
3014
|
+
}
|
|
3015
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
3016
|
+
const labels = view.labels ?? [];
|
|
3017
|
+
addRow(thead, ["", ...series.map((s, i) => s.name || String(i + 1))], true);
|
|
3018
|
+
const n = Math.max(labels.length, ...series.map((s) => s.values.length));
|
|
3019
|
+
for (let i = 0; i < n; i++) {
|
|
3020
|
+
addRow(tbody, [labels[i] ?? String(i + 1), ...series.map((s) => fmt2(s.values[i] ?? 0))], false);
|
|
3021
|
+
}
|
|
3022
|
+
return table;
|
|
3023
|
+
}
|
|
2928
3024
|
function svgDimsOf(svg) {
|
|
2929
3025
|
const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
|
|
2930
3026
|
const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
|
|
@@ -3265,6 +3361,7 @@ function renderChart(el, raw) {
|
|
|
3265
3361
|
if (!isZoomableType(t2) || fullLength() < 2) return;
|
|
3266
3362
|
const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
|
|
3267
3363
|
if (!plot) return;
|
|
3364
|
+
plot.style.touchAction = current2.zoom === "x" ? "pan-y" : "none";
|
|
3268
3365
|
const on = (type, fn) => {
|
|
3269
3366
|
plot.addEventListener(type, fn);
|
|
3270
3367
|
};
|
|
@@ -3320,6 +3417,149 @@ function renderChart(el, raw) {
|
|
|
3320
3417
|
render();
|
|
3321
3418
|
});
|
|
3322
3419
|
};
|
|
3420
|
+
const KB_TYPES = /* @__PURE__ */ new Set(["line", "area", "vbar", "hbar", "scatter"]);
|
|
3421
|
+
const kbCursor = { si: 0, i: 0, active: false };
|
|
3422
|
+
let liveRegion = null;
|
|
3423
|
+
let a11ySeq = 0;
|
|
3424
|
+
const a11yOf = () => ({
|
|
3425
|
+
summary: current2.a11y?.summary !== false,
|
|
3426
|
+
table: current2.a11y?.table === true,
|
|
3427
|
+
keyboard: current2.a11y?.keyboard !== false
|
|
3428
|
+
});
|
|
3429
|
+
const seriesViewOf = (view) => view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
3430
|
+
const kbPointCount = (view) => typeOf() === "scatter" ? view.points?.length ?? 0 : Math.max(0, ...seriesViewOf(view).map((s) => s.values.length), view.labels?.length ?? 0);
|
|
3431
|
+
const kbCursorEl = () => {
|
|
3432
|
+
const t2 = typeOf();
|
|
3433
|
+
const view = viewOf();
|
|
3434
|
+
const series = seriesViewOf(view);
|
|
3435
|
+
const n = kbPointCount(view);
|
|
3436
|
+
if (n < 1) return null;
|
|
3437
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
3438
|
+
const i = clampNum(kbCursor.i, 0, n - 1);
|
|
3439
|
+
if (t2 === "line" || t2 === "area") {
|
|
3440
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
3441
|
+
if (!svg) return null;
|
|
3442
|
+
const dots = svg.querySelectorAll("circle");
|
|
3443
|
+
let base = 0;
|
|
3444
|
+
for (let k = 0; k < si; k++) base += Math.min(series[k].values.length, n);
|
|
3445
|
+
return dots.item(base + i) ?? null;
|
|
3446
|
+
}
|
|
3447
|
+
if (t2 === "scatter") return root.querySelector(".icen-chart-scatter svg")?.querySelectorAll("circle").item(i) ?? null;
|
|
3448
|
+
if (t2 === "vbar") return root.querySelectorAll(".icen-chart-vbar-bar").item(series.length > 1 ? i * series.length + si : i) ?? null;
|
|
3449
|
+
if (t2 === "hbar") return root.querySelectorAll(".icen-chart-hbar-bar").item(i) ?? null;
|
|
3450
|
+
return null;
|
|
3451
|
+
};
|
|
3452
|
+
const announceKb = (text) => {
|
|
3453
|
+
if (!liveRegion || !liveRegion.isConnected) {
|
|
3454
|
+
liveRegion = document.createElement("div");
|
|
3455
|
+
liveRegion.className = "icen-chart-live";
|
|
3456
|
+
liveRegion.setAttribute("aria-live", "polite");
|
|
3457
|
+
root.appendChild(liveRegion);
|
|
3458
|
+
}
|
|
3459
|
+
liveRegion.textContent = "";
|
|
3460
|
+
liveRegion.textContent = text;
|
|
3461
|
+
};
|
|
3462
|
+
const applyKbCursor = () => {
|
|
3463
|
+
for (const el2 of root.querySelectorAll(".icen-chart-kb-focus")) el2.classList.remove("icen-chart-kb-focus");
|
|
3464
|
+
if (!kbCursor.active) return;
|
|
3465
|
+
kbCursorEl()?.classList.add("icen-chart-kb-focus");
|
|
3466
|
+
};
|
|
3467
|
+
const announceCursor = () => {
|
|
3468
|
+
const view = viewOf();
|
|
3469
|
+
const series = seriesViewOf(view);
|
|
3470
|
+
const n = kbPointCount(view);
|
|
3471
|
+
if (n < 1) return;
|
|
3472
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
3473
|
+
const i = clampNum(kbCursor.i, 0, Math.max(0, n - 1));
|
|
3474
|
+
const fmt2 = chartFormatValue(current2.format);
|
|
3475
|
+
if (typeOf() === "scatter") {
|
|
3476
|
+
const p = view.points?.[i];
|
|
3477
|
+
if (!p) return;
|
|
3478
|
+
announceKb(t("charts.a11y.point", { p0: `x ${fmt2(p.x)}`, p1: `y ${fmt2(p.y)}`, p2: i + 1, p3: n }));
|
|
3479
|
+
return;
|
|
3480
|
+
}
|
|
3481
|
+
const label = view.labels?.[i] ?? String(i + 1);
|
|
3482
|
+
const value = series[si]?.values[i] ?? 0;
|
|
3483
|
+
if (series.length > 1) announceKb(t("charts.a11y.pointSeries", { p0: series[si].name || String(si + 1), p1: label, p2: fmt2(value), p3: i + 1, p4: n }));
|
|
3484
|
+
else announceKb(t("charts.a11y.point", { p0: label, p1: fmt2(value), p2: i + 1, p3: n }));
|
|
3485
|
+
};
|
|
3486
|
+
const onKbKeydown = (e) => {
|
|
3487
|
+
const conf = a11yOf();
|
|
3488
|
+
if (!conf.keyboard || !KB_TYPES.has(typeOf())) return;
|
|
3489
|
+
const g = root.querySelector("[data-icen-chart-kb]");
|
|
3490
|
+
if (!g || e.target !== g) return;
|
|
3491
|
+
if (e.key === "Escape") {
|
|
3492
|
+
if (zoomWindow) {
|
|
3493
|
+
zoomWindow = null;
|
|
3494
|
+
kbCursor.active = false;
|
|
3495
|
+
render();
|
|
3496
|
+
}
|
|
3497
|
+
return;
|
|
3498
|
+
}
|
|
3499
|
+
const view = viewOf();
|
|
3500
|
+
const series = seriesViewOf(view);
|
|
3501
|
+
const n = kbPointCount(view);
|
|
3502
|
+
if (n < 1) return;
|
|
3503
|
+
const siMax = Math.max(0, series.length - 1);
|
|
3504
|
+
let moved = true;
|
|
3505
|
+
switch (e.key) {
|
|
3506
|
+
case "ArrowRight":
|
|
3507
|
+
kbCursor.i = clampNum(kbCursor.i + 1, 0, n - 1);
|
|
3508
|
+
break;
|
|
3509
|
+
case "ArrowLeft":
|
|
3510
|
+
kbCursor.i = clampNum(kbCursor.i - 1, 0, n - 1);
|
|
3511
|
+
break;
|
|
3512
|
+
case "ArrowDown":
|
|
3513
|
+
kbCursor.si = clampNum(kbCursor.si + 1, 0, siMax);
|
|
3514
|
+
break;
|
|
3515
|
+
case "ArrowUp":
|
|
3516
|
+
kbCursor.si = clampNum(kbCursor.si - 1, 0, siMax);
|
|
3517
|
+
break;
|
|
3518
|
+
case "Home":
|
|
3519
|
+
kbCursor.i = 0;
|
|
3520
|
+
break;
|
|
3521
|
+
case "End":
|
|
3522
|
+
kbCursor.i = n - 1;
|
|
3523
|
+
break;
|
|
3524
|
+
default:
|
|
3525
|
+
moved = false;
|
|
3526
|
+
}
|
|
3527
|
+
if (!moved) return;
|
|
3528
|
+
e.preventDefault();
|
|
3529
|
+
kbCursor.active = true;
|
|
3530
|
+
applyKbCursor();
|
|
3531
|
+
announceCursor();
|
|
3532
|
+
};
|
|
3533
|
+
root.addEventListener("keydown", onKbKeydown);
|
|
3534
|
+
const applyChartA11yPlus = (view, spec, type, formatValue) => {
|
|
3535
|
+
const conf = a11yOf();
|
|
3536
|
+
const graphic = root.querySelector('[role="img"]');
|
|
3537
|
+
if (!graphic) return;
|
|
3538
|
+
const body = root.querySelector(".icen-chart-body") ?? graphic.parentElement ?? root;
|
|
3539
|
+
const summaryParts = [];
|
|
3540
|
+
if (conf.summary) summaryParts.push(summarizeChart(view, type, formatValue));
|
|
3541
|
+
if (conf.keyboard && KB_TYPES.has(type)) summaryParts.push(t("charts.a11y.keyboardHint"));
|
|
3542
|
+
const summaryText = summaryParts.filter(Boolean).join("\uFF1B");
|
|
3543
|
+
if (summaryText) {
|
|
3544
|
+
const p = document.createElement("p");
|
|
3545
|
+
p.className = "icen-chart-summary";
|
|
3546
|
+
p.id = `icen-chart-a11y-${++a11ySeq}`;
|
|
3547
|
+
p.textContent = summaryText;
|
|
3548
|
+
body.appendChild(p);
|
|
3549
|
+
graphic.setAttribute("aria-describedby", p.id);
|
|
3550
|
+
} else {
|
|
3551
|
+
graphic.removeAttribute("aria-describedby");
|
|
3552
|
+
}
|
|
3553
|
+
if (conf.keyboard && KB_TYPES.has(type)) {
|
|
3554
|
+
graphic.setAttribute("tabindex", "0");
|
|
3555
|
+
graphic.setAttribute("data-icen-chart-kb", "");
|
|
3556
|
+
} else {
|
|
3557
|
+
graphic.removeAttribute("tabindex");
|
|
3558
|
+
graphic.removeAttribute("data-icen-chart-kb");
|
|
3559
|
+
}
|
|
3560
|
+
if (conf.table) body.appendChild(buildChartTable(view, spec, type, formatValue));
|
|
3561
|
+
applyKbCursor();
|
|
3562
|
+
};
|
|
3323
3563
|
const render = () => {
|
|
3324
3564
|
if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
|
|
3325
3565
|
const spec = current2;
|
|
@@ -3400,6 +3640,7 @@ function renderChart(el, raw) {
|
|
|
3400
3640
|
}
|
|
3401
3641
|
}
|
|
3402
3642
|
if (loading) return;
|
|
3643
|
+
applyChartA11yPlus(view, spec, type, formatValue);
|
|
3403
3644
|
paintChartMarks(root, view, spec, formatValue, warnedMarks);
|
|
3404
3645
|
bindZoomGesture();
|
|
3405
3646
|
};
|
|
@@ -3481,6 +3722,7 @@ function renderChart(el, raw) {
|
|
|
3481
3722
|
releaseFluidWidth(root);
|
|
3482
3723
|
hiddenLegendKeys.delete(root);
|
|
3483
3724
|
zoomDragCleanup?.();
|
|
3725
|
+
root.removeEventListener("keydown", onKbKeydown);
|
|
3484
3726
|
root.textContent = "";
|
|
3485
3727
|
root.classList.remove("is-loading");
|
|
3486
3728
|
unbindEvents();
|