@icen.ai/ui 0.10.0 → 0.11.1
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 +79 -309
- package/LICENSE +21 -0
- package/README.md +43 -54
- package/dist/base.css +68 -22
- package/dist/behaviors/accordion.mjs +1 -1
- package/dist/behaviors/ai-branch.mjs +14 -0
- package/dist/behaviors/ai-chat.d.mts +2 -2
- package/dist/behaviors/ai-chat.mjs +66 -10
- package/dist/behaviors/ai-composer.d.mts +5 -5
- package/dist/behaviors/ai-composer.mjs +34 -10
- package/dist/behaviors/ai-core.mjs +14 -0
- package/dist/behaviors/ai-diff.mjs +14 -0
- package/dist/behaviors/ai-feedback.mjs +14 -0
- package/dist/behaviors/ai-panel.d.mts +2 -2
- package/dist/behaviors/ai-panel.mjs +14 -0
- package/dist/behaviors/ai-provider.d.mts +1 -1
- package/dist/behaviors/ai-provider.mjs +14 -0
- package/dist/behaviors/ai-threads.mjs +14 -0
- package/dist/behaviors/ai-tool.d.mts +1 -1
- package/dist/behaviors/ai-tool.mjs +299 -24
- package/dist/behaviors/ai-tools.mjs +1179 -28
- package/dist/behaviors/autocomplete.d.mts +1 -1
- package/dist/behaviors/autocomplete.mjs +14 -0
- package/dist/behaviors/back-top.mjs +14 -0
- package/dist/behaviors/carousel.mjs +21 -1
- package/dist/behaviors/cascader.mjs +27 -0
- package/dist/behaviors/charts.d.mts +12 -1
- package/dist/behaviors/charts.mjs +298 -20
- package/dist/behaviors/code-block.mjs +22 -1
- package/dist/behaviors/command-palette.mjs +3 -3
- package/dist/behaviors/context-menu.d.mts +2 -2
- package/dist/behaviors/context-menu.mjs +14 -0
- package/dist/behaviors/controls.d.mts +8 -8
- package/dist/behaviors/controls.mjs +50 -6
- package/dist/behaviors/copy.mjs +14 -0
- package/dist/behaviors/datatable.d.mts +3 -3
- package/dist/behaviors/datatable.mjs +89 -11
- package/dist/behaviors/date-picker.mjs +14 -0
- package/dist/behaviors/events.d.mts +10 -10
- package/dist/behaviors/events.mjs +11 -1
- package/dist/behaviors/form-validate.d.mts +10 -1
- package/dist/behaviors/form-validate.mjs +279 -4611
- package/dist/behaviors/i18n.d.mts +14 -0
- package/dist/behaviors/i18n.mjs +28 -0
- package/dist/behaviors/input.mjs +16 -0
- package/dist/behaviors/kb-access.d.mts +2 -2
- package/dist/behaviors/kb-access.mjs +21 -2
- package/dist/behaviors/kb-acl.d.mts +2 -2
- package/dist/behaviors/kb-acl.mjs +14 -0
- package/dist/behaviors/kb-answer.d.mts +2 -2
- package/dist/behaviors/kb-answer.mjs +298 -23
- package/dist/behaviors/kb-audit.d.mts +2 -2
- package/dist/behaviors/kb-audit.mjs +14 -0
- package/dist/behaviors/kb-canvas.d.mts +3 -3
- package/dist/behaviors/kb-canvas.mjs +14 -0
- package/dist/behaviors/kb-chain.d.mts +2 -2
- package/dist/behaviors/kb-chain.mjs +14 -0
- package/dist/behaviors/kb-checkpoint.d.mts +2 -2
- package/dist/behaviors/kb-checkpoint.mjs +14 -0
- package/dist/behaviors/kb-chunks.d.mts +2 -2
- package/dist/behaviors/kb-chunks.mjs +14 -0
- package/dist/behaviors/kb-citation.d.mts +2 -2
- package/dist/behaviors/kb-citation.mjs +33 -6
- package/dist/behaviors/kb-clarify.d.mts +2 -2
- package/dist/behaviors/kb-clarify.mjs +14 -0
- package/dist/behaviors/kb-conflict.d.mts +2 -2
- package/dist/behaviors/kb-conflict.mjs +14 -0
- package/dist/behaviors/kb-connector.d.mts +2 -2
- package/dist/behaviors/kb-connector.mjs +14 -0
- package/dist/behaviors/kb-core.d.mts +1 -1
- package/dist/behaviors/kb-core.mjs +14 -0
- package/dist/behaviors/kb-eval.d.mts +2 -2
- package/dist/behaviors/kb-eval.mjs +21 -2
- package/dist/behaviors/kb-explain.d.mts +2 -2
- package/dist/behaviors/kb-explain.mjs +26 -2
- package/dist/behaviors/kb-filter.d.mts +2 -2
- package/dist/behaviors/kb-filter.mjs +21 -2
- package/dist/behaviors/kb-gap.d.mts +2 -2
- package/dist/behaviors/kb-gap.mjs +14 -0
- package/dist/behaviors/kb-hittest.d.mts +2 -2
- package/dist/behaviors/kb-hittest.mjs +15 -1
- package/dist/behaviors/kb-metadata.mjs +19 -0
- package/dist/behaviors/kb-passage.d.mts +2 -2
- package/dist/behaviors/kb-passage.mjs +14 -0
- package/dist/behaviors/kb-pipeline.d.mts +2 -2
- package/dist/behaviors/kb-pipeline.mjs +14 -0
- package/dist/behaviors/kb-qa.mjs +14 -0
- package/dist/behaviors/kb-rerank.d.mts +2 -2
- package/dist/behaviors/kb-rerank.mjs +14 -0
- package/dist/behaviors/kb-retrieval.d.mts +2 -2
- package/dist/behaviors/kb-retrieval.mjs +31 -4
- package/dist/behaviors/kb-review.d.mts +2 -2
- package/dist/behaviors/kb-review.mjs +21 -2
- package/dist/behaviors/kb-sandbox.d.mts +2 -2
- package/dist/behaviors/kb-sandbox.mjs +20 -1
- package/dist/behaviors/kb-segment.d.mts +2 -2
- package/dist/behaviors/kb-segment.mjs +15 -1
- package/dist/behaviors/kb-select.mjs +21 -2
- package/dist/behaviors/kb-sources.d.mts +2 -2
- package/dist/behaviors/kb-sources.mjs +14 -0
- package/dist/behaviors/kb-sql.d.mts +2 -2
- package/dist/behaviors/kb-sql.mjs +14 -0
- package/dist/behaviors/kb-trace.d.mts +2 -2
- package/dist/behaviors/kb-trace.mjs +22 -3
- package/dist/behaviors/kb-visibility.d.mts +2 -2
- package/dist/behaviors/kb-visibility.mjs +14 -0
- package/dist/behaviors/kb-who-can.d.mts +2 -2
- package/dist/behaviors/kb-who-can.mjs +21 -2
- package/dist/behaviors/mentions.d.mts +1 -1
- package/dist/behaviors/mentions.mjs +14 -0
- package/dist/behaviors/modal.d.mts +1 -1
- package/dist/behaviors/modal.mjs +14 -0
- package/dist/behaviors/motion.d.mts +16 -0
- package/dist/behaviors/motion.mjs +39 -0
- package/dist/behaviors/notification.d.mts +2 -2
- package/dist/behaviors/notification.mjs +27 -3
- package/dist/behaviors/panel.mjs +14 -0
- package/dist/behaviors/scroll-area.d.mts +17 -0
- package/dist/behaviors/scroll-area.mjs +59 -0
- package/dist/behaviors/select.mjs +21 -2
- package/dist/behaviors/slider.mjs +3 -3
- package/dist/behaviors/split-pane.mjs +2 -0
- package/dist/behaviors/suggestions.mjs +14 -0
- package/dist/behaviors/tabs.mjs +10 -0
- package/dist/behaviors/tag-input.mjs +14 -0
- package/dist/behaviors/theme-switcher.d.mts +2 -2
- package/dist/behaviors/theme-switcher.mjs +30 -2
- package/dist/behaviors/theme.mjs +16 -2
- package/dist/behaviors/toast.d.mts +2 -2
- package/dist/behaviors/toast.mjs +14 -0
- package/dist/behaviors/tree-select.mjs +27 -0
- package/dist/behaviors/tree.mjs +4 -4
- package/dist/behaviors/upload.mjs +14 -0
- package/dist/behaviors/url-safety.d.mts +8 -0
- package/dist/behaviors/url-safety.mjs +11 -0
- package/dist/components/accordion.d.mts +2 -0
- package/dist/components/ai-branch.d.mts +2 -0
- package/dist/components/ai-chat.css +40 -33
- package/dist/components/ai-chat.d.mts +2 -0
- package/dist/components/ai-composer.d.mts +2 -0
- package/dist/components/ai-context.d.mts +2 -0
- package/dist/components/ai-context.mjs +1 -0
- package/dist/components/ai-diff.css +6 -6
- package/dist/components/ai-diff.d.mts +2 -0
- package/dist/components/ai-feedback.d.mts +2 -0
- package/dist/components/ai-files.d.mts +2 -0
- package/dist/components/ai-message.d.mts +2 -0
- package/dist/components/ai-panel.css +12 -10
- package/dist/components/ai-reasoning.d.mts +2 -0
- package/dist/components/ai-subagent.d.mts +2 -0
- package/dist/components/ai-subagent.mjs +1 -0
- package/dist/components/ai-threads.d.mts +2 -0
- package/dist/components/ai-todo.d.mts +2 -0
- package/dist/components/ai-todo.mjs +1 -0
- package/dist/components/ai-tool-call.d.mts +2 -0
- package/dist/components/ai-tool-call.mjs +1 -0
- package/dist/components/ai-tool.css +16 -16
- package/dist/components/ai-usage.d.mts +2 -0
- package/dist/components/alert.d.mts +2 -0
- package/dist/components/autocomplete.css +12 -12
- package/dist/components/autocomplete.d.mts +2 -0
- package/dist/components/avatar.d.mts +2 -0
- package/dist/components/back-top.css +47 -16
- package/dist/components/back-top.d.mts +2 -0
- package/dist/components/badge.css +1 -1
- package/dist/components/badge.d.mts +2 -0
- package/dist/components/breadcrumb.css +26 -8
- package/dist/components/breadcrumb.d.mts +2 -0
- package/dist/components/btn.css +67 -62
- package/dist/components/btn.d.mts +2 -0
- package/dist/components/card.css +22 -22
- package/dist/components/card.d.mts +2 -0
- package/dist/components/carousel.d.mts +2 -0
- package/dist/components/cascader.css +56 -35
- package/dist/components/cascader.d.mts +2 -0
- package/dist/components/chart-area.css +46 -0
- package/dist/components/chart-area.d.mts +2 -0
- package/dist/components/chart-bar.css +66 -19
- package/dist/components/chart-bar.d.mts +2 -0
- package/dist/components/chart-calendar.d.mts +2 -0
- package/dist/components/chart-gauge.css +23 -3
- package/dist/components/chart-gauge.d.mts +2 -0
- package/dist/components/chart-graph.css +15 -3
- package/dist/components/chart-graph.d.mts +2 -0
- package/dist/components/chart-heatmap.css +117 -95
- package/dist/components/chart-heatmap.d.mts +2 -0
- package/dist/components/chart-line.css +54 -0
- package/dist/components/chart-line.d.mts +2 -0
- package/dist/components/chart-map.d.mts +2 -0
- package/dist/components/chart-pie.css +29 -0
- package/dist/components/chart-pie.d.mts +2 -0
- package/dist/components/chart-radar.css +50 -1
- package/dist/components/chart-radar.d.mts +2 -0
- package/dist/components/chart-scatter.css +39 -2
- package/dist/components/chart-scatter.d.mts +2 -0
- package/dist/components/chart-sparkline.css +20 -0
- package/dist/components/chart-sparkline.d.mts +2 -0
- package/dist/components/chart-stack.css +16 -5
- package/dist/components/chart-stack.d.mts +2 -0
- package/dist/components/charts.css +109 -35
- package/dist/components/charts.d.mts +2 -0
- package/dist/components/code-block.css +10 -8
- package/dist/components/code-block.d.mts +2 -0
- package/dist/components/command-palette.css +45 -38
- package/dist/components/command-palette.d.mts +2 -0
- package/dist/components/content.css +62 -57
- package/dist/components/context-menu.d.mts +2 -0
- package/dist/components/copy.css +10 -10
- package/dist/components/copy.d.mts +2 -0
- package/dist/components/datatable.css +72 -59
- package/dist/components/datatable.d.mts +2 -0
- package/dist/components/date-picker.css +26 -26
- package/dist/components/date-picker.d.mts +2 -0
- package/dist/components/desc.d.mts +2 -0
- package/dist/components/dropdown.d.mts +2 -0
- package/dist/components/empty.css +16 -16
- package/dist/components/empty.d.mts +2 -0
- package/dist/components/feedback.css +31 -29
- package/dist/components/form-validate.css +20 -6
- package/dist/components/form-validate.d.mts +2 -0
- package/dist/components/form.css +17 -14
- package/dist/components/form.d.mts +2 -0
- package/dist/components/icon.css +21 -10
- package/dist/components/icon.d.mts +2 -0
- package/dist/components/input.css +22 -22
- package/dist/components/input.d.mts +2 -0
- package/dist/components/kb-access.d.mts +2 -0
- package/dist/components/kb-acl.d.mts +2 -0
- package/dist/components/kb-agent.css +134 -55
- package/dist/components/kb-answer.d.mts +2 -0
- package/dist/components/kb-audit.d.mts +2 -0
- package/dist/components/kb-canvas.d.mts +2 -0
- package/dist/components/kb-chain.d.mts +2 -0
- package/dist/components/kb-checkpoint.d.mts +2 -0
- package/dist/components/kb-chunks.d.mts +2 -0
- package/dist/components/kb-citation.d.mts +2 -0
- package/dist/components/kb-clarify.d.mts +2 -0
- package/dist/components/kb-conflict.d.mts +2 -0
- package/dist/components/kb-connector.d.mts +2 -0
- package/dist/components/kb-data.css +192 -80
- package/dist/components/kb-eval.d.mts +2 -0
- package/dist/components/kb-explain.d.mts +2 -0
- package/dist/components/kb-filter.d.mts +2 -0
- package/dist/components/kb-gap.d.mts +2 -0
- package/dist/components/kb-ground.css +165 -73
- package/dist/components/kb-hittest.d.mts +2 -0
- package/dist/components/kb-ingest.css +308 -113
- package/dist/components/kb-metadata.d.mts +2 -0
- package/dist/components/kb-ops.css +189 -75
- package/dist/components/kb-passage.d.mts +2 -0
- package/dist/components/kb-perm.css +158 -87
- package/dist/components/kb-pipeline.d.mts +2 -0
- package/dist/components/kb-qa.d.mts +2 -0
- package/dist/components/kb-rerank.d.mts +2 -0
- package/dist/components/kb-retrieval.d.mts +2 -0
- package/dist/components/kb-review.d.mts +2 -0
- package/dist/components/kb-sandbox.d.mts +2 -0
- package/dist/components/kb-search.css +353 -116
- package/dist/components/kb-segment.d.mts +2 -0
- package/dist/components/kb-sources.d.mts +2 -0
- package/dist/components/kb-sql.d.mts +2 -0
- package/dist/components/kb-trace.d.mts +2 -0
- package/dist/components/kb-visibility.d.mts +2 -0
- package/dist/components/kb-who-can.d.mts +2 -0
- package/dist/components/kb.css +60 -36
- package/dist/components/kb.d.mts +2 -0
- package/dist/components/kbd.d.mts +2 -0
- package/dist/components/layout.css +10 -10
- package/dist/components/layout.d.mts +2 -0
- package/dist/components/list.d.mts +2 -0
- package/dist/components/material-chinese.css +10 -0
- package/dist/components/material-soviet.css +10 -0
- package/dist/components/material.css +61 -18
- package/dist/components/media-card.d.mts +2 -0
- package/dist/components/media.css +22 -27
- package/dist/components/mentions.css +18 -17
- package/dist/components/mentions.d.mts +2 -0
- package/dist/components/menu.css +32 -28
- package/dist/components/modal.css +30 -27
- package/dist/components/modal.d.mts +2 -0
- package/dist/components/nav.css +48 -44
- package/dist/components/nav.d.mts +2 -0
- package/dist/components/notification.css +31 -25
- package/dist/components/notification.d.mts +2 -0
- package/dist/components/pagination.css +15 -13
- package/dist/components/pagination.d.mts +2 -0
- package/dist/components/panel.css +19 -20
- package/dist/components/panel.d.mts +2 -0
- package/dist/components/pill.css +8 -7
- package/dist/components/pill.d.mts +2 -0
- package/dist/components/popover.css +32 -23
- package/dist/components/popover.d.mts +2 -0
- package/dist/components/progress.d.mts +2 -0
- package/dist/components/rating.d.mts +2 -0
- package/dist/components/result.d.mts +2 -0
- package/dist/components/scroll-area.css +84 -112
- package/dist/components/scroll-area.d.mts +2 -0
- package/dist/components/scroll-area.mjs +1 -0
- package/dist/components/segmented.css +47 -29
- package/dist/components/segmented.d.mts +2 -0
- package/dist/components/select.css +80 -41
- package/dist/components/select.d.mts +2 -0
- package/dist/components/sidebar.css +42 -38
- package/dist/components/sidebar.d.mts +2 -0
- package/dist/components/skeleton.d.mts +2 -0
- package/dist/components/slider.css +26 -22
- package/dist/components/slider.d.mts +2 -0
- package/dist/components/spinner.d.mts +2 -0
- package/dist/components/split-pane.css +16 -7
- package/dist/components/split-pane.d.mts +2 -0
- package/dist/components/stat.css +17 -16
- package/dist/components/stat.d.mts +2 -0
- package/dist/components/steps.css +26 -26
- package/dist/components/steps.d.mts +2 -0
- package/dist/components/switch.css +78 -39
- package/dist/components/switch.d.mts +2 -0
- package/dist/components/table.css +54 -32
- package/dist/components/table.d.mts +2 -0
- package/dist/components/tabs.css +53 -32
- package/dist/components/tabs.d.mts +2 -0
- package/dist/components/tag-input.css +12 -8
- package/dist/components/tag-input.d.mts +2 -0
- package/dist/components/tag.css +20 -12
- package/dist/components/tag.d.mts +2 -0
- package/dist/components/theme-switcher.css +7 -7
- package/dist/components/theme-switcher.d.mts +2 -0
- package/dist/components/timeline.d.mts +2 -0
- package/dist/components/toast.css +34 -30
- package/dist/components/toast.d.mts +2 -0
- package/dist/components/toolbar.css +19 -18
- package/dist/components/toolbar.d.mts +2 -0
- package/dist/components/tooltip.css +9 -8
- package/dist/components/tooltip.d.mts +2 -0
- package/dist/components/tree-select.css +63 -40
- package/dist/components/tree-select.d.mts +2 -0
- package/dist/components/tree.d.mts +2 -0
- package/dist/components/upload.css +9 -11
- package/dist/components/upload.d.mts +2 -0
- package/dist/index.d.mts +85 -84
- package/dist/index.mjs +14644 -13935
- package/dist/react.d.mts +18 -18
- package/dist/react.mjs +377 -36
- package/dist/registry.json +797 -64
- package/dist/tokens/colors.css +6 -0
- package/dist/tokens/design.css +137 -31
- package/dist/tokens/dtcg.json +9592 -2008
- package/dist/tokens/figma.variables.json +7451 -2141
- package/dist/tokens/motion.css +51 -0
- package/dist/tokens/pixel.css +10 -0
- package/dist/tokens/scrollbars.css +40 -0
- package/dist/tokens/tokens-studio.json +8390 -1142
- package/dist/tokens/typography.css +33 -0
- package/dist/tokens.css +402 -82
- package/dist/ui.css +4196 -2163
- package/dist/vue.d.mts +17 -17
- package/dist/vue.mjs +371 -34
- package/docs/spec/charts-scale-a11y.md +115 -0
- package/docs/spec/design-philosophy.md +5 -5
- package/docs/spec/design-primitives.md +10 -10
- package/docs/spec/motion-typography.md +105 -0
- package/docs/spec/scrollbars.md +46 -0
- package/package.json +17 -3
|
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
21
21
|
"aiChat.roleTool": "\u5DE5",
|
|
22
22
|
"aiChat.roleUser": "\u6211",
|
|
23
23
|
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
24
|
+
"aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
|
|
24
25
|
/* ── aiComposer ── */
|
|
25
26
|
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
26
27
|
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
203
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
204
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
205
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",
|
|
206
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
207
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
208
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -1216,6 +1230,15 @@ function renderKbClarify(el, c, opts) {
|
|
|
1216
1230
|
return el;
|
|
1217
1231
|
}
|
|
1218
1232
|
|
|
1233
|
+
// src/behaviors/url-safety.ts
|
|
1234
|
+
function safeUrl(uri) {
|
|
1235
|
+
const s = uri.replace(/[\t\n\r\0-\x1f\x7f]/g, "").trim().toLowerCase();
|
|
1236
|
+
if (!s) return void 0;
|
|
1237
|
+
if (s.startsWith("javascript:") || s.startsWith("vbscript:")) return void 0;
|
|
1238
|
+
if (/^data:\s*text\/html/.test(s)) return void 0;
|
|
1239
|
+
return uri;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1219
1242
|
// src/behaviors/kb-explain.ts
|
|
1220
1243
|
function toExplainFact(raw) {
|
|
1221
1244
|
const r = raw ?? {};
|
|
@@ -1276,9 +1299,10 @@ function renderKbExplain(el, fact) {
|
|
|
1276
1299
|
const row = h("div", "icen-kb-explain-metric");
|
|
1277
1300
|
row.appendChild(h("span", "icen-kb-explain-metric-name", m.name));
|
|
1278
1301
|
if (m.ref) {
|
|
1279
|
-
|
|
1302
|
+
const href = safeUrl(m.ref);
|
|
1303
|
+
if (href) {
|
|
1280
1304
|
const a = h("a", "icen-kb-explain-metric-ref", t("kbExplain.viewDefinition"));
|
|
1281
|
-
a.href =
|
|
1305
|
+
a.href = href;
|
|
1282
1306
|
a.rel = "noopener";
|
|
1283
1307
|
row.appendChild(a);
|
|
1284
1308
|
}
|
|
@@ -1521,7 +1545,8 @@ function withChrome(el, opts, hasLegend, paint, state, extras) {
|
|
|
1521
1545
|
emitIcen(el, "icen:chart-legend-visibility", { visible: hidden ? false : true });
|
|
1522
1546
|
});
|
|
1523
1547
|
syncEye();
|
|
1524
|
-
head.append(title, eye);
|
|
1548
|
+
if (hasLegend) head.append(title, eye);
|
|
1549
|
+
else head.append(title);
|
|
1525
1550
|
el.append(head, body);
|
|
1526
1551
|
paint(body);
|
|
1527
1552
|
}
|
|
@@ -1622,7 +1647,7 @@ function renderVBar(el, opts) {
|
|
|
1622
1647
|
wrap.appendChild(track);
|
|
1623
1648
|
}
|
|
1624
1649
|
body.append(wrap, labelsRow(labelsUsed));
|
|
1625
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name
|
|
1650
|
+
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
|
|
1626
1651
|
});
|
|
1627
1652
|
attachChartInteraction(el, "vbar");
|
|
1628
1653
|
return el;
|
|
@@ -1717,8 +1742,10 @@ function renderDonut(el, opts) {
|
|
|
1717
1742
|
"stroke-width": "14"
|
|
1718
1743
|
}));
|
|
1719
1744
|
let offset = 0;
|
|
1745
|
+
const gap = opts.segments.length > 1 ? 2.5 : 0;
|
|
1720
1746
|
opts.segments.forEach((seg, segIndex) => {
|
|
1721
|
-
const
|
|
1747
|
+
const arcLength = Math.max(0, seg.value / total * circumference);
|
|
1748
|
+
const dash = arcLength - Math.min(gap, arcLength * 0.1);
|
|
1722
1749
|
const arc = svgEl("circle", {
|
|
1723
1750
|
cx: "60",
|
|
1724
1751
|
cy: "60",
|
|
@@ -1732,7 +1759,7 @@ function renderDonut(el, opts) {
|
|
|
1732
1759
|
});
|
|
1733
1760
|
setMarkData(arc, { index: segIndex, label: seg.label, value: seg.value });
|
|
1734
1761
|
svg.appendChild(arc);
|
|
1735
|
-
offset +=
|
|
1762
|
+
offset += arcLength;
|
|
1736
1763
|
});
|
|
1737
1764
|
const legend = document.createElement("div");
|
|
1738
1765
|
legend.className = "icen-chart-legend";
|
|
@@ -1767,8 +1794,9 @@ function renderLine(el, opts) {
|
|
|
1767
1794
|
const svg = svgEl("svg", { viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": chartAriaLabel(opts.title, t("charts.type.line")) });
|
|
1768
1795
|
const defs = svgEl("defs", {});
|
|
1769
1796
|
for (let i = 0; i < 4; i++) {
|
|
1770
|
-
const y = pad + i * (height - pad * 2) / 3;
|
|
1797
|
+
const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
|
|
1771
1798
|
svg.appendChild(svgEl("line", {
|
|
1799
|
+
class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
|
|
1772
1800
|
x1: String(pad),
|
|
1773
1801
|
x2: String(width - pad),
|
|
1774
1802
|
y1: String(y),
|
|
@@ -1852,7 +1880,7 @@ function renderLine(el, opts) {
|
|
|
1852
1880
|
if (defs.firstChild) svg.insertBefore(defs, svg.firstChild);
|
|
1853
1881
|
wrap.append(svg, pointLabelsRow(labelsUsed, width, pad));
|
|
1854
1882
|
body.appendChild(wrap);
|
|
1855
|
-
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: s.name
|
|
1883
|
+
if (seriesList.length > 1) body.appendChild(toggleLegend(seriesList.map((s, si) => ({ key: `${si}:${s.name}`, label: s.name, tone: s.tone ?? (si === 0 ? opts.tone : void 0), si })), wrap));
|
|
1856
1884
|
});
|
|
1857
1885
|
if (el.dataset.icenChartBody == null) observeFluidWidth(el, () => renderLine(el, opts));
|
|
1858
1886
|
attachChartInteraction(el, "line");
|
|
@@ -1959,7 +1987,7 @@ function renderRadar(el, opts) {
|
|
|
1959
1987
|
setMarkData(dot, { index: i, seriesIndex: si, seriesName: s.name || void 0, label: axes[i] ?? "", value: s.values[i] ?? 0 });
|
|
1960
1988
|
svg.appendChild(dot);
|
|
1961
1989
|
}
|
|
1962
|
-
legendItems.push({ key: s.name || t("charts.seriesName", { p0: si + 1 })
|
|
1990
|
+
legendItems.push({ key: `${si}:${s.name || t("charts.seriesName", { p0: si + 1 })}`, label: s.name || t("charts.seriesName", { p0: si + 1 }), tone: s.tone, si });
|
|
1963
1991
|
});
|
|
1964
1992
|
wrap.appendChild(svg);
|
|
1965
1993
|
body.appendChild(wrap);
|
|
@@ -1981,6 +2009,11 @@ function niceCeil(v) {
|
|
|
1981
2009
|
else nice = 10;
|
|
1982
2010
|
return nice * base;
|
|
1983
2011
|
}
|
|
2012
|
+
function tickPrecision(min, max, steps) {
|
|
2013
|
+
const span = Math.abs(max - min);
|
|
2014
|
+
if (!Number.isFinite(span) || span <= 0) return 0;
|
|
2015
|
+
return Math.max(0, Math.ceil(-Math.log10(span / steps)));
|
|
2016
|
+
}
|
|
1984
2017
|
function isoDate(d) {
|
|
1985
2018
|
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
1986
2019
|
const day = String(d.getDate()).padStart(2, "0");
|
|
@@ -2076,7 +2109,8 @@ function renderSparkline(el, opts) {
|
|
|
2076
2109
|
const tone = toneVar(opts.tone);
|
|
2077
2110
|
const points = values.map((value, i) => ({
|
|
2078
2111
|
x: values.length <= 1 ? width / 2 : pad + i / (values.length - 1) * (width - pad * 2),
|
|
2079
|
-
|
|
2112
|
+
/* 负值钳到基线(与折线图同口径):viewBox 仅 28 高,反向射出更刺眼 */
|
|
2113
|
+
y: height - pad - Math.max(0, value) / max * (height - pad * 2),
|
|
2080
2114
|
value
|
|
2081
2115
|
}));
|
|
2082
2116
|
const line = points.map((p, i) => `${i === 0 ? "M" : "L"}${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
|
|
@@ -2201,6 +2235,7 @@ function renderCalendar(el, opts) {
|
|
|
2201
2235
|
weekdayRow.appendChild(s);
|
|
2202
2236
|
});
|
|
2203
2237
|
const max = maxOf(entries.map((e) => e.value));
|
|
2238
|
+
entries.sort((a, b) => a.date.localeCompare(b.date));
|
|
2204
2239
|
const pad = padFirstWeek(grid, entries[0].date, weekStart);
|
|
2205
2240
|
let lastMonth = -1;
|
|
2206
2241
|
entries.forEach((entry, i) => {
|
|
@@ -2259,8 +2294,9 @@ function renderScatter(el, opts) {
|
|
|
2259
2294
|
const xAt = (x) => pad + (x - xMin) / (xMax - xMin) * (width - pad * 2);
|
|
2260
2295
|
const yAt = (y) => height - pad - (y - yMin) / (yMax - yMin) * (height - pad * 2);
|
|
2261
2296
|
for (let i = 0; i <= 3; i++) {
|
|
2262
|
-
const y = pad + i * (height - pad * 2) / 3;
|
|
2297
|
+
const y = Math.round(pad + i * (height - pad * 2) / 3) + 0.5;
|
|
2263
2298
|
svg.appendChild(svgEl("line", {
|
|
2299
|
+
class: i === 3 ? "icen-chart-grid icen-chart-baseline" : "icen-chart-grid",
|
|
2264
2300
|
x1: String(pad),
|
|
2265
2301
|
x2: String(width - pad),
|
|
2266
2302
|
y1: String(y),
|
|
@@ -2276,12 +2312,13 @@ function renderScatter(el, opts) {
|
|
|
2276
2312
|
"font-size": "8",
|
|
2277
2313
|
fill: "var(--icen-token-text-faint)"
|
|
2278
2314
|
});
|
|
2279
|
-
txt.textContent = fmt(opts,
|
|
2315
|
+
txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(yMin, yMax, 3)));
|
|
2280
2316
|
svg.appendChild(txt);
|
|
2281
2317
|
}
|
|
2282
2318
|
for (let i = 0; i <= 4; i++) {
|
|
2283
|
-
const x = pad + i * (width - pad * 2) / 4;
|
|
2319
|
+
const x = Math.round(pad + i * (width - pad * 2) / 4) + 0.5;
|
|
2284
2320
|
svg.appendChild(svgEl("line", {
|
|
2321
|
+
class: i === 0 ? "icen-chart-grid icen-chart-grid--v icen-chart-axis" : "icen-chart-grid icen-chart-grid--v",
|
|
2285
2322
|
x1: String(x),
|
|
2286
2323
|
x2: String(x),
|
|
2287
2324
|
y1: String(pad),
|
|
@@ -2298,7 +2335,7 @@ function renderScatter(el, opts) {
|
|
|
2298
2335
|
"font-size": "8",
|
|
2299
2336
|
fill: "var(--icen-token-text-faint)"
|
|
2300
2337
|
});
|
|
2301
|
-
txt.textContent = fmt(opts,
|
|
2338
|
+
txt.textContent = fmt(opts, +tv.toFixed(tickPrecision(xMin, xMax, 4)));
|
|
2302
2339
|
svg.appendChild(txt);
|
|
2303
2340
|
}
|
|
2304
2341
|
if (opts.yLabel) {
|
|
@@ -2535,6 +2572,14 @@ function normalizeChartSpec(raw) {
|
|
|
2535
2572
|
}
|
|
2536
2573
|
if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
|
|
2537
2574
|
if (typeof s.loading === "boolean") spec.loading = s.loading;
|
|
2575
|
+
if (s.a11y && typeof s.a11y === "object") {
|
|
2576
|
+
const a = s.a11y;
|
|
2577
|
+
const a11y = {};
|
|
2578
|
+
if (typeof a.summary === "boolean") a11y.summary = a.summary;
|
|
2579
|
+
if (typeof a.table === "boolean") a11y.table = a.table;
|
|
2580
|
+
if (typeof a.keyboard === "boolean") a11y.keyboard = a.keyboard;
|
|
2581
|
+
if (Object.keys(a11y).length > 0) spec.a11y = a11y;
|
|
2582
|
+
}
|
|
2538
2583
|
if (Array.isArray(s.marks)) {
|
|
2539
2584
|
const marks = [];
|
|
2540
2585
|
for (const raw2 of s.marks) {
|
|
@@ -2662,6 +2707,7 @@ function renderChartSkeleton(body) {
|
|
|
2662
2707
|
body.appendChild(box);
|
|
2663
2708
|
}
|
|
2664
2709
|
var CHART_MARK_ACCENT = "var(--icen-token-accent)";
|
|
2710
|
+
var CHART_MARK_ACCENT_TEXT = "var(--icen-token-accent-text)";
|
|
2665
2711
|
function markToneVar(tone) {
|
|
2666
2712
|
switch (tone) {
|
|
2667
2713
|
case "success":
|
|
@@ -2797,7 +2843,7 @@ function paintSvgChartMarks(root, view, marks, formatValue, warned) {
|
|
|
2797
2843
|
y: String(clampNum(y - 10, 8, CHART_LINE_H - 4)),
|
|
2798
2844
|
"text-anchor": "middle",
|
|
2799
2845
|
"font-size": "8",
|
|
2800
|
-
fill:
|
|
2846
|
+
fill: CHART_MARK_ACCENT_TEXT
|
|
2801
2847
|
});
|
|
2802
2848
|
label.textContent = mark.text ?? mark.label;
|
|
2803
2849
|
g.appendChild(label);
|
|
@@ -2889,6 +2935,81 @@ function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
|
|
|
2889
2935
|
function chartAriaLabel(title, typeName) {
|
|
2890
2936
|
return title ? `${typeName}\uFF1A${title}` : typeName;
|
|
2891
2937
|
}
|
|
2938
|
+
function summarizeChart(view, type, fmt2) {
|
|
2939
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
2940
|
+
const parts = [];
|
|
2941
|
+
if (series.length > 1) parts.push(t("charts.a11y.seriesCount", { p0: series.length }));
|
|
2942
|
+
if (type === "scatter") {
|
|
2943
|
+
const pts = view.points ?? [];
|
|
2944
|
+
if (pts.length > 0) {
|
|
2945
|
+
const xs = pts.map((p) => p.x);
|
|
2946
|
+
const ys = pts.map((p) => p.y);
|
|
2947
|
+
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)) }));
|
|
2948
|
+
}
|
|
2949
|
+
return parts.join("\uFF1B");
|
|
2950
|
+
}
|
|
2951
|
+
const labels = view.labels ?? [];
|
|
2952
|
+
if (labels.length > 1) parts.push(t("charts.a11y.range", { p0: labels[0], p1: labels[labels.length - 1] }));
|
|
2953
|
+
let min = Infinity;
|
|
2954
|
+
let max = -Infinity;
|
|
2955
|
+
let minAt = "";
|
|
2956
|
+
let maxAt = "";
|
|
2957
|
+
for (const s of series) {
|
|
2958
|
+
s.values.forEach((v, i) => {
|
|
2959
|
+
if (v < min) {
|
|
2960
|
+
min = v;
|
|
2961
|
+
minAt = labels[i] ?? String(i + 1);
|
|
2962
|
+
}
|
|
2963
|
+
if (v > max) {
|
|
2964
|
+
max = v;
|
|
2965
|
+
maxAt = labels[i] ?? String(i + 1);
|
|
2966
|
+
}
|
|
2967
|
+
});
|
|
2968
|
+
}
|
|
2969
|
+
if (Number.isFinite(min) && Number.isFinite(max)) {
|
|
2970
|
+
parts.push(t("charts.a11y.min", { p0: fmt2(min), p1: minAt }));
|
|
2971
|
+
parts.push(t("charts.a11y.max", { p0: fmt2(max), p1: maxAt }));
|
|
2972
|
+
}
|
|
2973
|
+
const first = series[0]?.values ?? [];
|
|
2974
|
+
if (first.length > 1) {
|
|
2975
|
+
const d = first[first.length - 1] - first[0];
|
|
2976
|
+
const key = Math.abs(d) < 1e-9 ? "charts.a11y.trendFlat" : d > 0 ? "charts.a11y.trendUp" : "charts.a11y.trendDown";
|
|
2977
|
+
parts.push(t("charts.a11y.trend", { p0: t(key) }));
|
|
2978
|
+
}
|
|
2979
|
+
return parts.join("\uFF1B");
|
|
2980
|
+
}
|
|
2981
|
+
function buildChartTable(view, spec, type, fmt2) {
|
|
2982
|
+
const table = document.createElement("table");
|
|
2983
|
+
table.className = "icen-chart-table";
|
|
2984
|
+
const caption = document.createElement("caption");
|
|
2985
|
+
caption.textContent = t("charts.a11y.tableCaption", { p0: spec.title ?? String(type) });
|
|
2986
|
+
table.appendChild(caption);
|
|
2987
|
+
const addRow = (target, cells, head) => {
|
|
2988
|
+
const tr = document.createElement("tr");
|
|
2989
|
+
for (const c of cells) {
|
|
2990
|
+
const cell = document.createElement(head ? "th" : "td");
|
|
2991
|
+
if (head) cell.scope = target.tagName === "THEAD" ? "col" : "row";
|
|
2992
|
+
cell.textContent = c;
|
|
2993
|
+
tr.appendChild(cell);
|
|
2994
|
+
}
|
|
2995
|
+
target.appendChild(tr);
|
|
2996
|
+
};
|
|
2997
|
+
const thead = table.createTHead();
|
|
2998
|
+
const tbody = table.createTBody();
|
|
2999
|
+
if (type === "scatter") {
|
|
3000
|
+
addRow(thead, ["x", "y"], true);
|
|
3001
|
+
for (const p of view.points ?? []) addRow(tbody, [fmt2(p.x), fmt2(p.y)], false);
|
|
3002
|
+
return table;
|
|
3003
|
+
}
|
|
3004
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
3005
|
+
const labels = view.labels ?? [];
|
|
3006
|
+
addRow(thead, ["", ...series.map((s, i) => s.name || String(i + 1))], true);
|
|
3007
|
+
const n = Math.max(labels.length, ...series.map((s) => s.values.length));
|
|
3008
|
+
for (let i = 0; i < n; i++) {
|
|
3009
|
+
addRow(tbody, [labels[i] ?? String(i + 1), ...series.map((s) => fmt2(s.values[i] ?? 0))], false);
|
|
3010
|
+
}
|
|
3011
|
+
return table;
|
|
3012
|
+
}
|
|
2892
3013
|
function svgDimsOf(svg) {
|
|
2893
3014
|
const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
|
|
2894
3015
|
const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
|
|
@@ -3229,6 +3350,7 @@ function renderChart(el, raw) {
|
|
|
3229
3350
|
if (!isZoomableType(t2) || fullLength() < 2) return;
|
|
3230
3351
|
const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
|
|
3231
3352
|
if (!plot) return;
|
|
3353
|
+
plot.style.touchAction = current2.zoom === "x" ? "pan-y" : "none";
|
|
3232
3354
|
const on = (type, fn) => {
|
|
3233
3355
|
plot.addEventListener(type, fn);
|
|
3234
3356
|
};
|
|
@@ -3284,6 +3406,149 @@ function renderChart(el, raw) {
|
|
|
3284
3406
|
render();
|
|
3285
3407
|
});
|
|
3286
3408
|
};
|
|
3409
|
+
const KB_TYPES = /* @__PURE__ */ new Set(["line", "area", "vbar", "hbar", "scatter"]);
|
|
3410
|
+
const kbCursor = { si: 0, i: 0, active: false };
|
|
3411
|
+
let liveRegion = null;
|
|
3412
|
+
let a11ySeq = 0;
|
|
3413
|
+
const a11yOf = () => ({
|
|
3414
|
+
summary: current2.a11y?.summary !== false,
|
|
3415
|
+
table: current2.a11y?.table === true,
|
|
3416
|
+
keyboard: current2.a11y?.keyboard !== false
|
|
3417
|
+
});
|
|
3418
|
+
const seriesViewOf = (view) => view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
3419
|
+
const kbPointCount = (view) => typeOf() === "scatter" ? view.points?.length ?? 0 : Math.max(0, ...seriesViewOf(view).map((s) => s.values.length), view.labels?.length ?? 0);
|
|
3420
|
+
const kbCursorEl = () => {
|
|
3421
|
+
const t2 = typeOf();
|
|
3422
|
+
const view = viewOf();
|
|
3423
|
+
const series = seriesViewOf(view);
|
|
3424
|
+
const n = kbPointCount(view);
|
|
3425
|
+
if (n < 1) return null;
|
|
3426
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
3427
|
+
const i = clampNum(kbCursor.i, 0, n - 1);
|
|
3428
|
+
if (t2 === "line" || t2 === "area") {
|
|
3429
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
3430
|
+
if (!svg) return null;
|
|
3431
|
+
const dots = svg.querySelectorAll("circle");
|
|
3432
|
+
let base = 0;
|
|
3433
|
+
for (let k = 0; k < si; k++) base += Math.min(series[k].values.length, n);
|
|
3434
|
+
return dots.item(base + i) ?? null;
|
|
3435
|
+
}
|
|
3436
|
+
if (t2 === "scatter") return root.querySelector(".icen-chart-scatter svg")?.querySelectorAll("circle").item(i) ?? null;
|
|
3437
|
+
if (t2 === "vbar") return root.querySelectorAll(".icen-chart-vbar-bar").item(series.length > 1 ? i * series.length + si : i) ?? null;
|
|
3438
|
+
if (t2 === "hbar") return root.querySelectorAll(".icen-chart-hbar-bar").item(i) ?? null;
|
|
3439
|
+
return null;
|
|
3440
|
+
};
|
|
3441
|
+
const announceKb = (text) => {
|
|
3442
|
+
if (!liveRegion || !liveRegion.isConnected) {
|
|
3443
|
+
liveRegion = document.createElement("div");
|
|
3444
|
+
liveRegion.className = "icen-chart-live";
|
|
3445
|
+
liveRegion.setAttribute("aria-live", "polite");
|
|
3446
|
+
root.appendChild(liveRegion);
|
|
3447
|
+
}
|
|
3448
|
+
liveRegion.textContent = "";
|
|
3449
|
+
liveRegion.textContent = text;
|
|
3450
|
+
};
|
|
3451
|
+
const applyKbCursor = () => {
|
|
3452
|
+
for (const el2 of root.querySelectorAll(".icen-chart-kb-focus")) el2.classList.remove("icen-chart-kb-focus");
|
|
3453
|
+
if (!kbCursor.active) return;
|
|
3454
|
+
kbCursorEl()?.classList.add("icen-chart-kb-focus");
|
|
3455
|
+
};
|
|
3456
|
+
const announceCursor = () => {
|
|
3457
|
+
const view = viewOf();
|
|
3458
|
+
const series = seriesViewOf(view);
|
|
3459
|
+
const n = kbPointCount(view);
|
|
3460
|
+
if (n < 1) return;
|
|
3461
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
3462
|
+
const i = clampNum(kbCursor.i, 0, Math.max(0, n - 1));
|
|
3463
|
+
const fmt2 = chartFormatValue(current2.format);
|
|
3464
|
+
if (typeOf() === "scatter") {
|
|
3465
|
+
const p = view.points?.[i];
|
|
3466
|
+
if (!p) return;
|
|
3467
|
+
announceKb(t("charts.a11y.point", { p0: `x ${fmt2(p.x)}`, p1: `y ${fmt2(p.y)}`, p2: i + 1, p3: n }));
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
const label = view.labels?.[i] ?? String(i + 1);
|
|
3471
|
+
const value = series[si]?.values[i] ?? 0;
|
|
3472
|
+
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 }));
|
|
3473
|
+
else announceKb(t("charts.a11y.point", { p0: label, p1: fmt2(value), p2: i + 1, p3: n }));
|
|
3474
|
+
};
|
|
3475
|
+
const onKbKeydown = (e) => {
|
|
3476
|
+
const conf = a11yOf();
|
|
3477
|
+
if (!conf.keyboard || !KB_TYPES.has(typeOf())) return;
|
|
3478
|
+
const g = root.querySelector("[data-icen-chart-kb]");
|
|
3479
|
+
if (!g || e.target !== g) return;
|
|
3480
|
+
if (e.key === "Escape") {
|
|
3481
|
+
if (zoomWindow) {
|
|
3482
|
+
zoomWindow = null;
|
|
3483
|
+
kbCursor.active = false;
|
|
3484
|
+
render();
|
|
3485
|
+
}
|
|
3486
|
+
return;
|
|
3487
|
+
}
|
|
3488
|
+
const view = viewOf();
|
|
3489
|
+
const series = seriesViewOf(view);
|
|
3490
|
+
const n = kbPointCount(view);
|
|
3491
|
+
if (n < 1) return;
|
|
3492
|
+
const siMax = Math.max(0, series.length - 1);
|
|
3493
|
+
let moved = true;
|
|
3494
|
+
switch (e.key) {
|
|
3495
|
+
case "ArrowRight":
|
|
3496
|
+
kbCursor.i = clampNum(kbCursor.i + 1, 0, n - 1);
|
|
3497
|
+
break;
|
|
3498
|
+
case "ArrowLeft":
|
|
3499
|
+
kbCursor.i = clampNum(kbCursor.i - 1, 0, n - 1);
|
|
3500
|
+
break;
|
|
3501
|
+
case "ArrowDown":
|
|
3502
|
+
kbCursor.si = clampNum(kbCursor.si + 1, 0, siMax);
|
|
3503
|
+
break;
|
|
3504
|
+
case "ArrowUp":
|
|
3505
|
+
kbCursor.si = clampNum(kbCursor.si - 1, 0, siMax);
|
|
3506
|
+
break;
|
|
3507
|
+
case "Home":
|
|
3508
|
+
kbCursor.i = 0;
|
|
3509
|
+
break;
|
|
3510
|
+
case "End":
|
|
3511
|
+
kbCursor.i = n - 1;
|
|
3512
|
+
break;
|
|
3513
|
+
default:
|
|
3514
|
+
moved = false;
|
|
3515
|
+
}
|
|
3516
|
+
if (!moved) return;
|
|
3517
|
+
e.preventDefault();
|
|
3518
|
+
kbCursor.active = true;
|
|
3519
|
+
applyKbCursor();
|
|
3520
|
+
announceCursor();
|
|
3521
|
+
};
|
|
3522
|
+
root.addEventListener("keydown", onKbKeydown);
|
|
3523
|
+
const applyChartA11yPlus = (view, spec, type, formatValue) => {
|
|
3524
|
+
const conf = a11yOf();
|
|
3525
|
+
const graphic = root.querySelector('[role="img"]');
|
|
3526
|
+
if (!graphic) return;
|
|
3527
|
+
const body = root.querySelector(".icen-chart-body") ?? graphic.parentElement ?? root;
|
|
3528
|
+
const summaryParts = [];
|
|
3529
|
+
if (conf.summary) summaryParts.push(summarizeChart(view, type, formatValue));
|
|
3530
|
+
if (conf.keyboard && KB_TYPES.has(type)) summaryParts.push(t("charts.a11y.keyboardHint"));
|
|
3531
|
+
const summaryText = summaryParts.filter(Boolean).join("\uFF1B");
|
|
3532
|
+
if (summaryText) {
|
|
3533
|
+
const p = document.createElement("p");
|
|
3534
|
+
p.className = "icen-chart-summary";
|
|
3535
|
+
p.id = `icen-chart-a11y-${++a11ySeq}`;
|
|
3536
|
+
p.textContent = summaryText;
|
|
3537
|
+
body.appendChild(p);
|
|
3538
|
+
graphic.setAttribute("aria-describedby", p.id);
|
|
3539
|
+
} else {
|
|
3540
|
+
graphic.removeAttribute("aria-describedby");
|
|
3541
|
+
}
|
|
3542
|
+
if (conf.keyboard && KB_TYPES.has(type)) {
|
|
3543
|
+
graphic.setAttribute("tabindex", "0");
|
|
3544
|
+
graphic.setAttribute("data-icen-chart-kb", "");
|
|
3545
|
+
} else {
|
|
3546
|
+
graphic.removeAttribute("tabindex");
|
|
3547
|
+
graphic.removeAttribute("data-icen-chart-kb");
|
|
3548
|
+
}
|
|
3549
|
+
if (conf.table) body.appendChild(buildChartTable(view, spec, type, formatValue));
|
|
3550
|
+
applyKbCursor();
|
|
3551
|
+
};
|
|
3287
3552
|
const render = () => {
|
|
3288
3553
|
if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
|
|
3289
3554
|
const spec = current2;
|
|
@@ -3355,9 +3620,16 @@ function renderChart(el, raw) {
|
|
|
3355
3620
|
const graphic = root.querySelector('[role="img"]');
|
|
3356
3621
|
if (graphic && !graphic.getAttribute("aria-label")) {
|
|
3357
3622
|
graphic.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
|
|
3623
|
+
} else if (!graphic) {
|
|
3624
|
+
const dom = root.querySelector(".icen-chart-vbar, .icen-chart-hbar");
|
|
3625
|
+
if (dom) {
|
|
3626
|
+
dom.setAttribute("role", "img");
|
|
3627
|
+
dom.setAttribute("aria-label", spec.title ? `${spec.title}\uFF08${type}\uFF09` : type);
|
|
3628
|
+
}
|
|
3358
3629
|
}
|
|
3359
3630
|
}
|
|
3360
3631
|
if (loading) return;
|
|
3632
|
+
applyChartA11yPlus(view, spec, type, formatValue);
|
|
3361
3633
|
paintChartMarks(root, view, spec, formatValue, warnedMarks);
|
|
3362
3634
|
bindZoomGesture();
|
|
3363
3635
|
};
|
|
@@ -3439,6 +3711,7 @@ function renderChart(el, raw) {
|
|
|
3439
3711
|
releaseFluidWidth(root);
|
|
3440
3712
|
hiddenLegendKeys.delete(root);
|
|
3441
3713
|
zoomDragCleanup?.();
|
|
3714
|
+
root.removeEventListener("keydown", onKbKeydown);
|
|
3442
3715
|
root.textContent = "";
|
|
3443
3716
|
root.classList.remove("is-loading");
|
|
3444
3717
|
unbindEvents();
|
|
@@ -3507,15 +3780,17 @@ function renderPermissionNotice(p) {
|
|
|
3507
3780
|
function renderBody(text, citations) {
|
|
3508
3781
|
const box = h("div", "icen-kb-answer-body");
|
|
3509
3782
|
for (const seg of parseInlineCitations(text)) {
|
|
3510
|
-
if (typeof seg.n === "number" && citations
|
|
3511
|
-
const
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3783
|
+
if (typeof seg.n === "number" && citations) {
|
|
3784
|
+
const c = citations.find((x) => x.index === seg.n) ?? (seg.n >= 1 && seg.n <= citations.length ? citations[seg.n - 1] : void 0);
|
|
3785
|
+
if (c) {
|
|
3786
|
+
const sup = h("sup", "icen-kb-citation", `[${seg.n}]`);
|
|
3787
|
+
sup.dataset.icenCite = String(seg.n);
|
|
3788
|
+
if (c.title) sup.title = c.title;
|
|
3789
|
+
box.appendChild(sup);
|
|
3790
|
+
continue;
|
|
3791
|
+
}
|
|
3518
3792
|
}
|
|
3793
|
+
box.appendChild(document.createTextNode(seg.text));
|
|
3519
3794
|
}
|
|
3520
3795
|
return box;
|
|
3521
3796
|
}
|
|
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
21
21
|
"aiChat.roleTool": "\u5DE5",
|
|
22
22
|
"aiChat.roleUser": "\u6211",
|
|
23
23
|
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
24
|
+
"aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
|
|
24
25
|
/* ── aiComposer ── */
|
|
25
26
|
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
26
27
|
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
203
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
204
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
205
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",
|
|
206
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
207
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
208
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { KbCanvasVersion } from './kb-core.
|
|
2
|
-
import { renderAiDiff } from './ai-diff.
|
|
3
|
-
import './ai-core.
|
|
1
|
+
import { KbCanvasVersion } from './kb-core.mjs';
|
|
2
|
+
import { renderAiDiff } from './ai-diff.mjs';
|
|
3
|
+
import './ai-core.mjs';
|
|
4
4
|
|
|
5
5
|
interface KbCanvasOptions {
|
|
6
6
|
/** 左栏最小占比(同时约束右栏 1-minRatio);默认 0.2,钳制到 [0.05, 0.5] */
|
|
@@ -57,6 +57,7 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
57
57
|
"aiChat.roleTool": "\u5DE5",
|
|
58
58
|
"aiChat.roleUser": "\u6211",
|
|
59
59
|
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
60
|
+
"aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
|
|
60
61
|
/* ── aiComposer ── */
|
|
61
62
|
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
62
63
|
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
@@ -239,6 +240,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
239
240
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
240
241
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
241
242
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
243
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
244
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
245
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
246
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
247
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
248
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
249
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
250
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
251
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
252
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
253
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
254
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
255
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
242
256
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
243
257
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
244
258
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
21
21
|
"aiChat.roleTool": "\u5DE5",
|
|
22
22
|
"aiChat.roleUser": "\u6211",
|
|
23
23
|
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
24
|
+
"aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
|
|
24
25
|
/* ── aiComposer ── */
|
|
25
26
|
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
26
27
|
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
203
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
204
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
205
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",
|
|
206
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
207
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
208
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -21,6 +21,7 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
21
21
|
"aiChat.roleTool": "\u5DE5",
|
|
22
22
|
"aiChat.roleUser": "\u6211",
|
|
23
23
|
"aiChat.thinking": "\u601D\u8003 {p0}",
|
|
24
|
+
"aiChat.thinkingNow": "\u6B63\u5728\u601D\u8003\u2026",
|
|
24
25
|
/* ── aiComposer ── */
|
|
25
26
|
"aiComposer.attachAgent": "\u4EE3\u7406",
|
|
26
27
|
"aiComposer.library": "\u6DFB\u52A0\u4E0A\u4E0B\u6587\u4E0E\u547D\u4EE4",
|
|
@@ -203,6 +204,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
203
204
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
204
205
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
205
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",
|
|
206
220
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
207
221
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
208
222
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|