@icen.ai/ui 0.11.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/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/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 +106 -9
- package/dist/ui.css +146 -15
- 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/dist/index.d.mts
CHANGED
|
@@ -23,7 +23,7 @@ export { OpenPopoverOptions, PanelSizing, PopoverAlign, PopoverLayout, PopoverLa
|
|
|
23
23
|
export { initAccordion } from './behaviors/accordion.mjs';
|
|
24
24
|
export { initTree } from './behaviors/tree.mjs';
|
|
25
25
|
export { initCarousel } from './behaviors/carousel.mjs';
|
|
26
|
-
export { ChartCalendarOptions, ChartChromeOptions, ChartDatum, ChartDatumDetail, ChartDims, ChartEventDetail, ChartEventName, ChartGaugeOptions, ChartHandle, ChartHeatmapOptions, ChartI18nLabels, ChartLineOptions, ChartMark, ChartMarkData, ChartMarkTone, ChartPointSpec, ChartRadarOptions, ChartScatterOptions, ChartSegment, ChartSegmentsOptions, ChartSeriesOptions, ChartSeriesSpec, ChartSpec, ChartTone, ChartType, ChartVBarOptions, ChartValueFormat, DatumChartHandle, GraphEdgeSpec, GraphLayoutOptions, GraphNodeSpec, GraphSpec, HeatmapDatum, MapPointSpec, MapSpec, RadarSeries, bindChartEvents, chartFormatValue, inferChartType, layoutGraph, lttb, normalizeChartSpec, registerChartTone, renderArea, renderCalendar, renderChart, renderDonut, renderGauge, renderGraph, renderHBar, renderHeatmap, renderLine, renderMap, renderRadar, renderScatter, renderSparkline, renderStack, renderVBar } from './behaviors/charts.mjs';
|
|
26
|
+
export { ChartA11ySpec, ChartCalendarOptions, ChartChromeOptions, ChartDatum, ChartDatumDetail, ChartDims, ChartEventDetail, ChartEventName, ChartGaugeOptions, ChartHandle, ChartHeatmapOptions, ChartI18nLabels, ChartLineOptions, ChartMark, ChartMarkData, ChartMarkTone, ChartPointSpec, ChartRadarOptions, ChartScatterOptions, ChartSegment, ChartSegmentsOptions, ChartSeriesOptions, ChartSeriesSpec, ChartSpec, ChartTone, ChartType, ChartVBarOptions, ChartValueFormat, DatumChartHandle, GraphEdgeSpec, GraphLayoutOptions, GraphNodeSpec, GraphSpec, HeatmapDatum, MapPointSpec, MapSpec, RadarSeries, bindChartEvents, chartFormatValue, inferChartType, layoutGraph, lttb, normalizeChartSpec, registerChartTone, renderArea, renderCalendar, renderChart, renderDonut, renderGauge, renderGraph, renderHBar, renderHeatmap, renderLine, renderMap, renderRadar, renderScatter, renderSparkline, renderStack, renderVBar } from './behaviors/charts.mjs';
|
|
27
27
|
export { initNav } from './behaviors/nav.mjs';
|
|
28
28
|
export { initSidebar } from './behaviors/sidebar.mjs';
|
|
29
29
|
export { NotificationAction, NotificationCenterHandle, NotificationConfig, NotificationConfirmOptions, NotificationHandle, NotificationKind, NotificationOptions, NotificationPushInput, NotificationRecord, NotificationUpdatePatch, createNotificationCenter, initNotification, notify } from './behaviors/notification.mjs';
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@icen.ai/ui",
|
|
4
|
-
version: "0.11.
|
|
4
|
+
version: "0.11.1",
|
|
5
5
|
description: "Icen Design System \u2014 \u8BBE\u8BA1 tokens\uFF086 \u4E3B\u9898 \xD7 4 \u539F\u8BED \xD7 \u660E\u6697\uFF09+ \u65E0\u6846\u67B6\u7EC4\u4EF6 CSS/\u884C\u4E3A JS + AI \u539F\u751F\u7EC4\u4EF6\u65CF\uFF087 \u6001\u72B6\u6001\u673A/\u591A\u6A21\u6001/\u5B9A\u4EF7\u5BA1\u8BA1\uFF09+ \u56FE\u8868\u901A\u7528\u5C42\uFF08ChartSpec \u7EAF JSON\uFF09+ AI \u5DE5\u5177\u4F53\u7CFB",
|
|
6
6
|
repository: {
|
|
7
7
|
type: "git",
|
|
@@ -63,6 +63,7 @@ var package_default = {
|
|
|
63
63
|
dtcg: "bun scripts/dtcg.mjs",
|
|
64
64
|
"design-tokens": "bun scripts/design-tokens.mjs",
|
|
65
65
|
guard: "bun scripts/guard/index.ts",
|
|
66
|
+
meta: "bun scripts/meta.mjs",
|
|
66
67
|
contracts: "bun scripts/contracts.ts --check",
|
|
67
68
|
"contracts:update": "bun scripts/contracts.ts --write",
|
|
68
69
|
"contracts:diff": "bun scripts/contracts.ts --diff",
|
|
@@ -1148,6 +1149,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
1148
1149
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
1149
1150
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
1150
1151
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
1152
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
1153
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
1154
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
1155
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
1156
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
1157
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
1158
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
1159
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
1160
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
1161
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
1162
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
1163
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
1164
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
1151
1165
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
1152
1166
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
1153
1167
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -1984,6 +1998,19 @@ var ICEN_LOCALE_EN_US = {
|
|
|
1984
1998
|
"charts.noData": "No data",
|
|
1985
1999
|
"charts.resetZoom": "Reset zoom",
|
|
1986
2000
|
"charts.sampled": "Sampled \u2192 {p0} points",
|
|
2001
|
+
"charts.a11y.keyboardHint": "Arrow keys browse points, Home/End jump to ends, Esc resets zoom",
|
|
2002
|
+
"charts.a11y.max": "max {p0} ({p1})",
|
|
2003
|
+
"charts.a11y.min": "min {p0} ({p1})",
|
|
2004
|
+
"charts.a11y.point": "{p0}: {p1}, point {p2} of {p3}",
|
|
2005
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}: {p2}, point {p3} of {p4}",
|
|
2006
|
+
"charts.a11y.range": "categories {p0} to {p1}",
|
|
2007
|
+
"charts.a11y.scatterRange": "x {p0}\u2013{p1}, y {p2}\u2013{p3}",
|
|
2008
|
+
"charts.a11y.seriesCount": "{p0} series",
|
|
2009
|
+
"charts.a11y.tableCaption": "{p0} data table",
|
|
2010
|
+
"charts.a11y.trend": "first-series trend: {p0}",
|
|
2011
|
+
"charts.a11y.trendDown": "down",
|
|
2012
|
+
"charts.a11y.trendFlat": "flat",
|
|
2013
|
+
"charts.a11y.trendUp": "up",
|
|
1987
2014
|
"charts.type.area": "Area chart",
|
|
1988
2015
|
"charts.type.donut": "Donut chart",
|
|
1989
2016
|
"charts.type.gauge": "Gauge",
|
|
@@ -13070,6 +13097,14 @@ function normalizeChartSpec(raw) {
|
|
|
13070
13097
|
}
|
|
13071
13098
|
if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
|
|
13072
13099
|
if (typeof s.loading === "boolean") spec.loading = s.loading;
|
|
13100
|
+
if (s.a11y && typeof s.a11y === "object") {
|
|
13101
|
+
const a = s.a11y;
|
|
13102
|
+
const a11y = {};
|
|
13103
|
+
if (typeof a.summary === "boolean") a11y.summary = a.summary;
|
|
13104
|
+
if (typeof a.table === "boolean") a11y.table = a.table;
|
|
13105
|
+
if (typeof a.keyboard === "boolean") a11y.keyboard = a.keyboard;
|
|
13106
|
+
if (Object.keys(a11y).length > 0) spec.a11y = a11y;
|
|
13107
|
+
}
|
|
13073
13108
|
if (Array.isArray(s.marks)) {
|
|
13074
13109
|
const marks = [];
|
|
13075
13110
|
for (const raw2 of s.marks) {
|
|
@@ -13425,6 +13460,81 @@ function paintVBarChartMarks(root, view, spec, marks, formatValue2, warned) {
|
|
|
13425
13460
|
function chartAriaLabel(title, typeName) {
|
|
13426
13461
|
return title ? `${typeName}\uFF1A${title}` : typeName;
|
|
13427
13462
|
}
|
|
13463
|
+
function summarizeChart(view, type, fmt2) {
|
|
13464
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
13465
|
+
const parts = [];
|
|
13466
|
+
if (series.length > 1) parts.push(t("charts.a11y.seriesCount", { p0: series.length }));
|
|
13467
|
+
if (type === "scatter") {
|
|
13468
|
+
const pts = view.points ?? [];
|
|
13469
|
+
if (pts.length > 0) {
|
|
13470
|
+
const xs = pts.map((p) => p.x);
|
|
13471
|
+
const ys = pts.map((p) => p.y);
|
|
13472
|
+
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)) }));
|
|
13473
|
+
}
|
|
13474
|
+
return parts.join("\uFF1B");
|
|
13475
|
+
}
|
|
13476
|
+
const labels = view.labels ?? [];
|
|
13477
|
+
if (labels.length > 1) parts.push(t("charts.a11y.range", { p0: labels[0], p1: labels[labels.length - 1] }));
|
|
13478
|
+
let min = Infinity;
|
|
13479
|
+
let max = -Infinity;
|
|
13480
|
+
let minAt = "";
|
|
13481
|
+
let maxAt = "";
|
|
13482
|
+
for (const s of series) {
|
|
13483
|
+
s.values.forEach((v, i) => {
|
|
13484
|
+
if (v < min) {
|
|
13485
|
+
min = v;
|
|
13486
|
+
minAt = labels[i] ?? String(i + 1);
|
|
13487
|
+
}
|
|
13488
|
+
if (v > max) {
|
|
13489
|
+
max = v;
|
|
13490
|
+
maxAt = labels[i] ?? String(i + 1);
|
|
13491
|
+
}
|
|
13492
|
+
});
|
|
13493
|
+
}
|
|
13494
|
+
if (Number.isFinite(min) && Number.isFinite(max)) {
|
|
13495
|
+
parts.push(t("charts.a11y.min", { p0: fmt2(min), p1: minAt }));
|
|
13496
|
+
parts.push(t("charts.a11y.max", { p0: fmt2(max), p1: maxAt }));
|
|
13497
|
+
}
|
|
13498
|
+
const first = series[0]?.values ?? [];
|
|
13499
|
+
if (first.length > 1) {
|
|
13500
|
+
const d = first[first.length - 1] - first[0];
|
|
13501
|
+
const key = Math.abs(d) < 1e-9 ? "charts.a11y.trendFlat" : d > 0 ? "charts.a11y.trendUp" : "charts.a11y.trendDown";
|
|
13502
|
+
parts.push(t("charts.a11y.trend", { p0: t(key) }));
|
|
13503
|
+
}
|
|
13504
|
+
return parts.join("\uFF1B");
|
|
13505
|
+
}
|
|
13506
|
+
function buildChartTable(view, spec, type, fmt2) {
|
|
13507
|
+
const table = document.createElement("table");
|
|
13508
|
+
table.className = "icen-chart-table";
|
|
13509
|
+
const caption = document.createElement("caption");
|
|
13510
|
+
caption.textContent = t("charts.a11y.tableCaption", { p0: spec.title ?? String(type) });
|
|
13511
|
+
table.appendChild(caption);
|
|
13512
|
+
const addRow = (target, cells, head) => {
|
|
13513
|
+
const tr = document.createElement("tr");
|
|
13514
|
+
for (const c of cells) {
|
|
13515
|
+
const cell = document.createElement(head ? "th" : "td");
|
|
13516
|
+
if (head) cell.scope = target.tagName === "THEAD" ? "col" : "row";
|
|
13517
|
+
cell.textContent = c;
|
|
13518
|
+
tr.appendChild(cell);
|
|
13519
|
+
}
|
|
13520
|
+
target.appendChild(tr);
|
|
13521
|
+
};
|
|
13522
|
+
const thead = table.createTHead();
|
|
13523
|
+
const tbody = table.createTBody();
|
|
13524
|
+
if (type === "scatter") {
|
|
13525
|
+
addRow(thead, ["x", "y"], true);
|
|
13526
|
+
for (const p of view.points ?? []) addRow(tbody, [fmt2(p.x), fmt2(p.y)], false);
|
|
13527
|
+
return table;
|
|
13528
|
+
}
|
|
13529
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
13530
|
+
const labels = view.labels ?? [];
|
|
13531
|
+
addRow(thead, ["", ...series.map((s, i) => s.name || String(i + 1))], true);
|
|
13532
|
+
const n = Math.max(labels.length, ...series.map((s) => s.values.length));
|
|
13533
|
+
for (let i = 0; i < n; i++) {
|
|
13534
|
+
addRow(tbody, [labels[i] ?? String(i + 1), ...series.map((s) => fmt2(s.values[i] ?? 0))], false);
|
|
13535
|
+
}
|
|
13536
|
+
return table;
|
|
13537
|
+
}
|
|
13428
13538
|
function svgDimsOf(svg6) {
|
|
13429
13539
|
const vb = (svg6.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
|
|
13430
13540
|
const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
|
|
@@ -13765,6 +13875,7 @@ function renderChart(el2, raw) {
|
|
|
13765
13875
|
if (!isZoomableType(t2) || fullLength() < 2) return;
|
|
13766
13876
|
const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
|
|
13767
13877
|
if (!plot) return;
|
|
13878
|
+
plot.style.touchAction = current2.zoom === "x" ? "pan-y" : "none";
|
|
13768
13879
|
const on = (type, fn) => {
|
|
13769
13880
|
plot.addEventListener(type, fn);
|
|
13770
13881
|
};
|
|
@@ -13820,6 +13931,149 @@ function renderChart(el2, raw) {
|
|
|
13820
13931
|
render();
|
|
13821
13932
|
});
|
|
13822
13933
|
};
|
|
13934
|
+
const KB_TYPES = /* @__PURE__ */ new Set(["line", "area", "vbar", "hbar", "scatter"]);
|
|
13935
|
+
const kbCursor = { si: 0, i: 0, active: false };
|
|
13936
|
+
let liveRegion = null;
|
|
13937
|
+
let a11ySeq = 0;
|
|
13938
|
+
const a11yOf = () => ({
|
|
13939
|
+
summary: current2.a11y?.summary !== false,
|
|
13940
|
+
table: current2.a11y?.table === true,
|
|
13941
|
+
keyboard: current2.a11y?.keyboard !== false
|
|
13942
|
+
});
|
|
13943
|
+
const seriesViewOf = (view) => view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
13944
|
+
const kbPointCount = (view) => typeOf() === "scatter" ? view.points?.length ?? 0 : Math.max(0, ...seriesViewOf(view).map((s) => s.values.length), view.labels?.length ?? 0);
|
|
13945
|
+
const kbCursorEl = () => {
|
|
13946
|
+
const t2 = typeOf();
|
|
13947
|
+
const view = viewOf();
|
|
13948
|
+
const series = seriesViewOf(view);
|
|
13949
|
+
const n = kbPointCount(view);
|
|
13950
|
+
if (n < 1) return null;
|
|
13951
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
13952
|
+
const i = clampNum(kbCursor.i, 0, n - 1);
|
|
13953
|
+
if (t2 === "line" || t2 === "area") {
|
|
13954
|
+
const svg6 = root.querySelector(".icen-chart-line svg");
|
|
13955
|
+
if (!svg6) return null;
|
|
13956
|
+
const dots = svg6.querySelectorAll("circle");
|
|
13957
|
+
let base = 0;
|
|
13958
|
+
for (let k = 0; k < si; k++) base += Math.min(series[k].values.length, n);
|
|
13959
|
+
return dots.item(base + i) ?? null;
|
|
13960
|
+
}
|
|
13961
|
+
if (t2 === "scatter") return root.querySelector(".icen-chart-scatter svg")?.querySelectorAll("circle").item(i) ?? null;
|
|
13962
|
+
if (t2 === "vbar") return root.querySelectorAll(".icen-chart-vbar-bar").item(series.length > 1 ? i * series.length + si : i) ?? null;
|
|
13963
|
+
if (t2 === "hbar") return root.querySelectorAll(".icen-chart-hbar-bar").item(i) ?? null;
|
|
13964
|
+
return null;
|
|
13965
|
+
};
|
|
13966
|
+
const announceKb = (text) => {
|
|
13967
|
+
if (!liveRegion || !liveRegion.isConnected) {
|
|
13968
|
+
liveRegion = document.createElement("div");
|
|
13969
|
+
liveRegion.className = "icen-chart-live";
|
|
13970
|
+
liveRegion.setAttribute("aria-live", "polite");
|
|
13971
|
+
root.appendChild(liveRegion);
|
|
13972
|
+
}
|
|
13973
|
+
liveRegion.textContent = "";
|
|
13974
|
+
liveRegion.textContent = text;
|
|
13975
|
+
};
|
|
13976
|
+
const applyKbCursor = () => {
|
|
13977
|
+
for (const el3 of root.querySelectorAll(".icen-chart-kb-focus")) el3.classList.remove("icen-chart-kb-focus");
|
|
13978
|
+
if (!kbCursor.active) return;
|
|
13979
|
+
kbCursorEl()?.classList.add("icen-chart-kb-focus");
|
|
13980
|
+
};
|
|
13981
|
+
const announceCursor = () => {
|
|
13982
|
+
const view = viewOf();
|
|
13983
|
+
const series = seriesViewOf(view);
|
|
13984
|
+
const n = kbPointCount(view);
|
|
13985
|
+
if (n < 1) return;
|
|
13986
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
13987
|
+
const i = clampNum(kbCursor.i, 0, Math.max(0, n - 1));
|
|
13988
|
+
const fmt2 = chartFormatValue(current2.format);
|
|
13989
|
+
if (typeOf() === "scatter") {
|
|
13990
|
+
const p = view.points?.[i];
|
|
13991
|
+
if (!p) return;
|
|
13992
|
+
announceKb(t("charts.a11y.point", { p0: `x ${fmt2(p.x)}`, p1: `y ${fmt2(p.y)}`, p2: i + 1, p3: n }));
|
|
13993
|
+
return;
|
|
13994
|
+
}
|
|
13995
|
+
const label = view.labels?.[i] ?? String(i + 1);
|
|
13996
|
+
const value = series[si]?.values[i] ?? 0;
|
|
13997
|
+
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 }));
|
|
13998
|
+
else announceKb(t("charts.a11y.point", { p0: label, p1: fmt2(value), p2: i + 1, p3: n }));
|
|
13999
|
+
};
|
|
14000
|
+
const onKbKeydown = (e) => {
|
|
14001
|
+
const conf = a11yOf();
|
|
14002
|
+
if (!conf.keyboard || !KB_TYPES.has(typeOf())) return;
|
|
14003
|
+
const g = root.querySelector("[data-icen-chart-kb]");
|
|
14004
|
+
if (!g || e.target !== g) return;
|
|
14005
|
+
if (e.key === "Escape") {
|
|
14006
|
+
if (zoomWindow) {
|
|
14007
|
+
zoomWindow = null;
|
|
14008
|
+
kbCursor.active = false;
|
|
14009
|
+
render();
|
|
14010
|
+
}
|
|
14011
|
+
return;
|
|
14012
|
+
}
|
|
14013
|
+
const view = viewOf();
|
|
14014
|
+
const series = seriesViewOf(view);
|
|
14015
|
+
const n = kbPointCount(view);
|
|
14016
|
+
if (n < 1) return;
|
|
14017
|
+
const siMax = Math.max(0, series.length - 1);
|
|
14018
|
+
let moved = true;
|
|
14019
|
+
switch (e.key) {
|
|
14020
|
+
case "ArrowRight":
|
|
14021
|
+
kbCursor.i = clampNum(kbCursor.i + 1, 0, n - 1);
|
|
14022
|
+
break;
|
|
14023
|
+
case "ArrowLeft":
|
|
14024
|
+
kbCursor.i = clampNum(kbCursor.i - 1, 0, n - 1);
|
|
14025
|
+
break;
|
|
14026
|
+
case "ArrowDown":
|
|
14027
|
+
kbCursor.si = clampNum(kbCursor.si + 1, 0, siMax);
|
|
14028
|
+
break;
|
|
14029
|
+
case "ArrowUp":
|
|
14030
|
+
kbCursor.si = clampNum(kbCursor.si - 1, 0, siMax);
|
|
14031
|
+
break;
|
|
14032
|
+
case "Home":
|
|
14033
|
+
kbCursor.i = 0;
|
|
14034
|
+
break;
|
|
14035
|
+
case "End":
|
|
14036
|
+
kbCursor.i = n - 1;
|
|
14037
|
+
break;
|
|
14038
|
+
default:
|
|
14039
|
+
moved = false;
|
|
14040
|
+
}
|
|
14041
|
+
if (!moved) return;
|
|
14042
|
+
e.preventDefault();
|
|
14043
|
+
kbCursor.active = true;
|
|
14044
|
+
applyKbCursor();
|
|
14045
|
+
announceCursor();
|
|
14046
|
+
};
|
|
14047
|
+
root.addEventListener("keydown", onKbKeydown);
|
|
14048
|
+
const applyChartA11yPlus = (view, spec, type, formatValue2) => {
|
|
14049
|
+
const conf = a11yOf();
|
|
14050
|
+
const graphic = root.querySelector('[role="img"]');
|
|
14051
|
+
if (!graphic) return;
|
|
14052
|
+
const body = root.querySelector(".icen-chart-body") ?? graphic.parentElement ?? root;
|
|
14053
|
+
const summaryParts = [];
|
|
14054
|
+
if (conf.summary) summaryParts.push(summarizeChart(view, type, formatValue2));
|
|
14055
|
+
if (conf.keyboard && KB_TYPES.has(type)) summaryParts.push(t("charts.a11y.keyboardHint"));
|
|
14056
|
+
const summaryText = summaryParts.filter(Boolean).join("\uFF1B");
|
|
14057
|
+
if (summaryText) {
|
|
14058
|
+
const p = document.createElement("p");
|
|
14059
|
+
p.className = "icen-chart-summary";
|
|
14060
|
+
p.id = `icen-chart-a11y-${++a11ySeq}`;
|
|
14061
|
+
p.textContent = summaryText;
|
|
14062
|
+
body.appendChild(p);
|
|
14063
|
+
graphic.setAttribute("aria-describedby", p.id);
|
|
14064
|
+
} else {
|
|
14065
|
+
graphic.removeAttribute("aria-describedby");
|
|
14066
|
+
}
|
|
14067
|
+
if (conf.keyboard && KB_TYPES.has(type)) {
|
|
14068
|
+
graphic.setAttribute("tabindex", "0");
|
|
14069
|
+
graphic.setAttribute("data-icen-chart-kb", "");
|
|
14070
|
+
} else {
|
|
14071
|
+
graphic.removeAttribute("tabindex");
|
|
14072
|
+
graphic.removeAttribute("data-icen-chart-kb");
|
|
14073
|
+
}
|
|
14074
|
+
if (conf.table) body.appendChild(buildChartTable(view, spec, type, formatValue2));
|
|
14075
|
+
applyKbCursor();
|
|
14076
|
+
};
|
|
13823
14077
|
const render = () => {
|
|
13824
14078
|
if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
|
|
13825
14079
|
const spec = current2;
|
|
@@ -13900,6 +14154,7 @@ function renderChart(el2, raw) {
|
|
|
13900
14154
|
}
|
|
13901
14155
|
}
|
|
13902
14156
|
if (loading) return;
|
|
14157
|
+
applyChartA11yPlus(view, spec, type, formatValue2);
|
|
13903
14158
|
paintChartMarks(root, view, spec, formatValue2, warnedMarks);
|
|
13904
14159
|
bindZoomGesture();
|
|
13905
14160
|
};
|
|
@@ -13981,6 +14236,7 @@ function renderChart(el2, raw) {
|
|
|
13981
14236
|
releaseFluidWidth(root);
|
|
13982
14237
|
hiddenLegendKeys.delete(root);
|
|
13983
14238
|
zoomDragCleanup?.();
|
|
14239
|
+
root.removeEventListener("keydown", onKbKeydown);
|
|
13984
14240
|
root.textContent = "";
|
|
13985
14241
|
root.classList.remove("is-loading");
|
|
13986
14242
|
unbindEvents();
|
package/dist/react.mjs
CHANGED
|
@@ -349,6 +349,19 @@ var ICEN_LOCALE_ZH_CN = {
|
|
|
349
349
|
"charts.noData": "\u6682\u65E0\u6570\u636E",
|
|
350
350
|
"charts.resetZoom": "\u91CD\u7F6E\u7F29\u653E",
|
|
351
351
|
"charts.sampled": "\u5DF2\u62BD\u6837 {p0}\u2192{p1} \u70B9",
|
|
352
|
+
"charts.a11y.keyboardHint": "\u65B9\u5411\u952E\u9010\u70B9\u6D4F\u89C8\uFF0CHome/End \u8DF3\u9996\u5C3E\uFF0CEsc \u91CD\u7F6E\u7F29\u653E",
|
|
353
|
+
"charts.a11y.max": "\u6700\u5927 {p0}\uFF08{p1}\uFF09",
|
|
354
|
+
"charts.a11y.min": "\u6700\u5C0F {p0}\uFF08{p1}\uFF09",
|
|
355
|
+
"charts.a11y.point": "{p0}\uFF1A{p1}\uFF0C\u7B2C {p2}/{p3} \u70B9",
|
|
356
|
+
"charts.a11y.pointSeries": "{p0} \xB7 {p1}\uFF1A{p2}\uFF0C\u7B2C {p3}/{p4} \u70B9",
|
|
357
|
+
"charts.a11y.range": "\u7C7B\u76EE {p0} \u81F3 {p1}",
|
|
358
|
+
"charts.a11y.scatterRange": "x \u8303\u56F4 {p0}\u2013{p1}\uFF0Cy \u8303\u56F4 {p2}\u2013{p3}",
|
|
359
|
+
"charts.a11y.seriesCount": "{p0} \u4E2A\u7CFB\u5217",
|
|
360
|
+
"charts.a11y.tableCaption": "{p0} \u6570\u636E\u8868",
|
|
361
|
+
"charts.a11y.trend": "\u9996\u7CFB\u5217\u8D8B\u52BF{p0}",
|
|
362
|
+
"charts.a11y.trendDown": "\u4E0B\u964D",
|
|
363
|
+
"charts.a11y.trendFlat": "\u6301\u5E73",
|
|
364
|
+
"charts.a11y.trendUp": "\u4E0A\u5347",
|
|
352
365
|
"charts.type.area": "\u9762\u79EF\u56FE",
|
|
353
366
|
"charts.type.donut": "\u73AF\u5F62\u56FE",
|
|
354
367
|
"charts.type.gauge": "\u4EEA\u8868\u76D8",
|
|
@@ -2241,6 +2254,14 @@ function normalizeChartSpec(raw) {
|
|
|
2241
2254
|
}
|
|
2242
2255
|
if (s.zoom === "x" || s.zoom === "brush") spec.zoom = s.zoom;
|
|
2243
2256
|
if (typeof s.loading === "boolean") spec.loading = s.loading;
|
|
2257
|
+
if (s.a11y && typeof s.a11y === "object") {
|
|
2258
|
+
const a = s.a11y;
|
|
2259
|
+
const a11y = {};
|
|
2260
|
+
if (typeof a.summary === "boolean") a11y.summary = a.summary;
|
|
2261
|
+
if (typeof a.table === "boolean") a11y.table = a.table;
|
|
2262
|
+
if (typeof a.keyboard === "boolean") a11y.keyboard = a.keyboard;
|
|
2263
|
+
if (Object.keys(a11y).length > 0) spec.a11y = a11y;
|
|
2264
|
+
}
|
|
2244
2265
|
if (Array.isArray(s.marks)) {
|
|
2245
2266
|
const marks = [];
|
|
2246
2267
|
for (const raw2 of s.marks) {
|
|
@@ -2596,6 +2617,81 @@ function paintVBarChartMarks(root, view, spec, marks, formatValue, warned) {
|
|
|
2596
2617
|
function chartAriaLabel(title, typeName) {
|
|
2597
2618
|
return title ? `${typeName}\uFF1A${title}` : typeName;
|
|
2598
2619
|
}
|
|
2620
|
+
function summarizeChart(view, type, fmt2) {
|
|
2621
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
2622
|
+
const parts = [];
|
|
2623
|
+
if (series.length > 1) parts.push(t("charts.a11y.seriesCount", { p0: series.length }));
|
|
2624
|
+
if (type === "scatter") {
|
|
2625
|
+
const pts = view.points ?? [];
|
|
2626
|
+
if (pts.length > 0) {
|
|
2627
|
+
const xs = pts.map((p) => p.x);
|
|
2628
|
+
const ys = pts.map((p) => p.y);
|
|
2629
|
+
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)) }));
|
|
2630
|
+
}
|
|
2631
|
+
return parts.join("\uFF1B");
|
|
2632
|
+
}
|
|
2633
|
+
const labels = view.labels ?? [];
|
|
2634
|
+
if (labels.length > 1) parts.push(t("charts.a11y.range", { p0: labels[0], p1: labels[labels.length - 1] }));
|
|
2635
|
+
let min = Infinity;
|
|
2636
|
+
let max = -Infinity;
|
|
2637
|
+
let minAt = "";
|
|
2638
|
+
let maxAt = "";
|
|
2639
|
+
for (const s of series) {
|
|
2640
|
+
s.values.forEach((v, i) => {
|
|
2641
|
+
if (v < min) {
|
|
2642
|
+
min = v;
|
|
2643
|
+
minAt = labels[i] ?? String(i + 1);
|
|
2644
|
+
}
|
|
2645
|
+
if (v > max) {
|
|
2646
|
+
max = v;
|
|
2647
|
+
maxAt = labels[i] ?? String(i + 1);
|
|
2648
|
+
}
|
|
2649
|
+
});
|
|
2650
|
+
}
|
|
2651
|
+
if (Number.isFinite(min) && Number.isFinite(max)) {
|
|
2652
|
+
parts.push(t("charts.a11y.min", { p0: fmt2(min), p1: minAt }));
|
|
2653
|
+
parts.push(t("charts.a11y.max", { p0: fmt2(max), p1: maxAt }));
|
|
2654
|
+
}
|
|
2655
|
+
const first = series[0]?.values ?? [];
|
|
2656
|
+
if (first.length > 1) {
|
|
2657
|
+
const d = first[first.length - 1] - first[0];
|
|
2658
|
+
const key = Math.abs(d) < 1e-9 ? "charts.a11y.trendFlat" : d > 0 ? "charts.a11y.trendUp" : "charts.a11y.trendDown";
|
|
2659
|
+
parts.push(t("charts.a11y.trend", { p0: t(key) }));
|
|
2660
|
+
}
|
|
2661
|
+
return parts.join("\uFF1B");
|
|
2662
|
+
}
|
|
2663
|
+
function buildChartTable(view, spec, type, fmt2) {
|
|
2664
|
+
const table = document.createElement("table");
|
|
2665
|
+
table.className = "icen-chart-table";
|
|
2666
|
+
const caption = document.createElement("caption");
|
|
2667
|
+
caption.textContent = t("charts.a11y.tableCaption", { p0: spec.title ?? String(type) });
|
|
2668
|
+
table.appendChild(caption);
|
|
2669
|
+
const addRow = (target, cells, head) => {
|
|
2670
|
+
const tr = document.createElement("tr");
|
|
2671
|
+
for (const c of cells) {
|
|
2672
|
+
const cell = document.createElement(head ? "th" : "td");
|
|
2673
|
+
if (head) cell.scope = target.tagName === "THEAD" ? "col" : "row";
|
|
2674
|
+
cell.textContent = c;
|
|
2675
|
+
tr.appendChild(cell);
|
|
2676
|
+
}
|
|
2677
|
+
target.appendChild(tr);
|
|
2678
|
+
};
|
|
2679
|
+
const thead = table.createTHead();
|
|
2680
|
+
const tbody = table.createTBody();
|
|
2681
|
+
if (type === "scatter") {
|
|
2682
|
+
addRow(thead, ["x", "y"], true);
|
|
2683
|
+
for (const p of view.points ?? []) addRow(tbody, [fmt2(p.x), fmt2(p.y)], false);
|
|
2684
|
+
return table;
|
|
2685
|
+
}
|
|
2686
|
+
const series = view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
2687
|
+
const labels = view.labels ?? [];
|
|
2688
|
+
addRow(thead, ["", ...series.map((s, i) => s.name || String(i + 1))], true);
|
|
2689
|
+
const n = Math.max(labels.length, ...series.map((s) => s.values.length));
|
|
2690
|
+
for (let i = 0; i < n; i++) {
|
|
2691
|
+
addRow(tbody, [labels[i] ?? String(i + 1), ...series.map((s) => fmt2(s.values[i] ?? 0))], false);
|
|
2692
|
+
}
|
|
2693
|
+
return table;
|
|
2694
|
+
}
|
|
2599
2695
|
function svgDimsOf(svg) {
|
|
2600
2696
|
const vb = (svg.getAttribute("viewBox") ?? "").split(/\s+/).map(Number);
|
|
2601
2697
|
const w = Number.isFinite(vb[2]) && (vb[2] ?? 0) > 0 ? vb[2] : CHART_LINE_W;
|
|
@@ -2936,6 +3032,7 @@ function renderChart(el, raw) {
|
|
|
2936
3032
|
if (!isZoomableType(t2) || fullLength() < 2) return;
|
|
2937
3033
|
const plot = t2 === "vbar" ? root.querySelector(".icen-chart-vbar") : root.querySelector(".icen-chart-line svg");
|
|
2938
3034
|
if (!plot) return;
|
|
3035
|
+
plot.style.touchAction = current2.zoom === "x" ? "pan-y" : "none";
|
|
2939
3036
|
const on = (type, fn) => {
|
|
2940
3037
|
plot.addEventListener(type, fn);
|
|
2941
3038
|
};
|
|
@@ -2991,6 +3088,149 @@ function renderChart(el, raw) {
|
|
|
2991
3088
|
render();
|
|
2992
3089
|
});
|
|
2993
3090
|
};
|
|
3091
|
+
const KB_TYPES = /* @__PURE__ */ new Set(["line", "area", "vbar", "hbar", "scatter"]);
|
|
3092
|
+
const kbCursor = { si: 0, i: 0, active: false };
|
|
3093
|
+
let liveRegion = null;
|
|
3094
|
+
let a11ySeq = 0;
|
|
3095
|
+
const a11yOf = () => ({
|
|
3096
|
+
summary: current2.a11y?.summary !== false,
|
|
3097
|
+
table: current2.a11y?.table === true,
|
|
3098
|
+
keyboard: current2.a11y?.keyboard !== false
|
|
3099
|
+
});
|
|
3100
|
+
const seriesViewOf = (view) => view.series && view.series.length > 0 ? view.series : [{ name: "", values: view.values ?? [] }];
|
|
3101
|
+
const kbPointCount = (view) => typeOf() === "scatter" ? view.points?.length ?? 0 : Math.max(0, ...seriesViewOf(view).map((s) => s.values.length), view.labels?.length ?? 0);
|
|
3102
|
+
const kbCursorEl = () => {
|
|
3103
|
+
const t2 = typeOf();
|
|
3104
|
+
const view = viewOf();
|
|
3105
|
+
const series = seriesViewOf(view);
|
|
3106
|
+
const n = kbPointCount(view);
|
|
3107
|
+
if (n < 1) return null;
|
|
3108
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
3109
|
+
const i = clampNum(kbCursor.i, 0, n - 1);
|
|
3110
|
+
if (t2 === "line" || t2 === "area") {
|
|
3111
|
+
const svg = root.querySelector(".icen-chart-line svg");
|
|
3112
|
+
if (!svg) return null;
|
|
3113
|
+
const dots = svg.querySelectorAll("circle");
|
|
3114
|
+
let base = 0;
|
|
3115
|
+
for (let k = 0; k < si; k++) base += Math.min(series[k].values.length, n);
|
|
3116
|
+
return dots.item(base + i) ?? null;
|
|
3117
|
+
}
|
|
3118
|
+
if (t2 === "scatter") return root.querySelector(".icen-chart-scatter svg")?.querySelectorAll("circle").item(i) ?? null;
|
|
3119
|
+
if (t2 === "vbar") return root.querySelectorAll(".icen-chart-vbar-bar").item(series.length > 1 ? i * series.length + si : i) ?? null;
|
|
3120
|
+
if (t2 === "hbar") return root.querySelectorAll(".icen-chart-hbar-bar").item(i) ?? null;
|
|
3121
|
+
return null;
|
|
3122
|
+
};
|
|
3123
|
+
const announceKb = (text) => {
|
|
3124
|
+
if (!liveRegion || !liveRegion.isConnected) {
|
|
3125
|
+
liveRegion = document.createElement("div");
|
|
3126
|
+
liveRegion.className = "icen-chart-live";
|
|
3127
|
+
liveRegion.setAttribute("aria-live", "polite");
|
|
3128
|
+
root.appendChild(liveRegion);
|
|
3129
|
+
}
|
|
3130
|
+
liveRegion.textContent = "";
|
|
3131
|
+
liveRegion.textContent = text;
|
|
3132
|
+
};
|
|
3133
|
+
const applyKbCursor = () => {
|
|
3134
|
+
for (const el2 of root.querySelectorAll(".icen-chart-kb-focus")) el2.classList.remove("icen-chart-kb-focus");
|
|
3135
|
+
if (!kbCursor.active) return;
|
|
3136
|
+
kbCursorEl()?.classList.add("icen-chart-kb-focus");
|
|
3137
|
+
};
|
|
3138
|
+
const announceCursor = () => {
|
|
3139
|
+
const view = viewOf();
|
|
3140
|
+
const series = seriesViewOf(view);
|
|
3141
|
+
const n = kbPointCount(view);
|
|
3142
|
+
if (n < 1) return;
|
|
3143
|
+
const si = clampNum(kbCursor.si, 0, Math.max(0, series.length - 1));
|
|
3144
|
+
const i = clampNum(kbCursor.i, 0, Math.max(0, n - 1));
|
|
3145
|
+
const fmt2 = chartFormatValue(current2.format);
|
|
3146
|
+
if (typeOf() === "scatter") {
|
|
3147
|
+
const p = view.points?.[i];
|
|
3148
|
+
if (!p) return;
|
|
3149
|
+
announceKb(t("charts.a11y.point", { p0: `x ${fmt2(p.x)}`, p1: `y ${fmt2(p.y)}`, p2: i + 1, p3: n }));
|
|
3150
|
+
return;
|
|
3151
|
+
}
|
|
3152
|
+
const label = view.labels?.[i] ?? String(i + 1);
|
|
3153
|
+
const value = series[si]?.values[i] ?? 0;
|
|
3154
|
+
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 }));
|
|
3155
|
+
else announceKb(t("charts.a11y.point", { p0: label, p1: fmt2(value), p2: i + 1, p3: n }));
|
|
3156
|
+
};
|
|
3157
|
+
const onKbKeydown = (e) => {
|
|
3158
|
+
const conf = a11yOf();
|
|
3159
|
+
if (!conf.keyboard || !KB_TYPES.has(typeOf())) return;
|
|
3160
|
+
const g = root.querySelector("[data-icen-chart-kb]");
|
|
3161
|
+
if (!g || e.target !== g) return;
|
|
3162
|
+
if (e.key === "Escape") {
|
|
3163
|
+
if (zoomWindow) {
|
|
3164
|
+
zoomWindow = null;
|
|
3165
|
+
kbCursor.active = false;
|
|
3166
|
+
render();
|
|
3167
|
+
}
|
|
3168
|
+
return;
|
|
3169
|
+
}
|
|
3170
|
+
const view = viewOf();
|
|
3171
|
+
const series = seriesViewOf(view);
|
|
3172
|
+
const n = kbPointCount(view);
|
|
3173
|
+
if (n < 1) return;
|
|
3174
|
+
const siMax = Math.max(0, series.length - 1);
|
|
3175
|
+
let moved = true;
|
|
3176
|
+
switch (e.key) {
|
|
3177
|
+
case "ArrowRight":
|
|
3178
|
+
kbCursor.i = clampNum(kbCursor.i + 1, 0, n - 1);
|
|
3179
|
+
break;
|
|
3180
|
+
case "ArrowLeft":
|
|
3181
|
+
kbCursor.i = clampNum(kbCursor.i - 1, 0, n - 1);
|
|
3182
|
+
break;
|
|
3183
|
+
case "ArrowDown":
|
|
3184
|
+
kbCursor.si = clampNum(kbCursor.si + 1, 0, siMax);
|
|
3185
|
+
break;
|
|
3186
|
+
case "ArrowUp":
|
|
3187
|
+
kbCursor.si = clampNum(kbCursor.si - 1, 0, siMax);
|
|
3188
|
+
break;
|
|
3189
|
+
case "Home":
|
|
3190
|
+
kbCursor.i = 0;
|
|
3191
|
+
break;
|
|
3192
|
+
case "End":
|
|
3193
|
+
kbCursor.i = n - 1;
|
|
3194
|
+
break;
|
|
3195
|
+
default:
|
|
3196
|
+
moved = false;
|
|
3197
|
+
}
|
|
3198
|
+
if (!moved) return;
|
|
3199
|
+
e.preventDefault();
|
|
3200
|
+
kbCursor.active = true;
|
|
3201
|
+
applyKbCursor();
|
|
3202
|
+
announceCursor();
|
|
3203
|
+
};
|
|
3204
|
+
root.addEventListener("keydown", onKbKeydown);
|
|
3205
|
+
const applyChartA11yPlus = (view, spec, type, formatValue) => {
|
|
3206
|
+
const conf = a11yOf();
|
|
3207
|
+
const graphic = root.querySelector('[role="img"]');
|
|
3208
|
+
if (!graphic) return;
|
|
3209
|
+
const body = root.querySelector(".icen-chart-body") ?? graphic.parentElement ?? root;
|
|
3210
|
+
const summaryParts = [];
|
|
3211
|
+
if (conf.summary) summaryParts.push(summarizeChart(view, type, formatValue));
|
|
3212
|
+
if (conf.keyboard && KB_TYPES.has(type)) summaryParts.push(t("charts.a11y.keyboardHint"));
|
|
3213
|
+
const summaryText = summaryParts.filter(Boolean).join("\uFF1B");
|
|
3214
|
+
if (summaryText) {
|
|
3215
|
+
const p = document.createElement("p");
|
|
3216
|
+
p.className = "icen-chart-summary";
|
|
3217
|
+
p.id = `icen-chart-a11y-${++a11ySeq}`;
|
|
3218
|
+
p.textContent = summaryText;
|
|
3219
|
+
body.appendChild(p);
|
|
3220
|
+
graphic.setAttribute("aria-describedby", p.id);
|
|
3221
|
+
} else {
|
|
3222
|
+
graphic.removeAttribute("aria-describedby");
|
|
3223
|
+
}
|
|
3224
|
+
if (conf.keyboard && KB_TYPES.has(type)) {
|
|
3225
|
+
graphic.setAttribute("tabindex", "0");
|
|
3226
|
+
graphic.setAttribute("data-icen-chart-kb", "");
|
|
3227
|
+
} else {
|
|
3228
|
+
graphic.removeAttribute("tabindex");
|
|
3229
|
+
graphic.removeAttribute("data-icen-chart-kb");
|
|
3230
|
+
}
|
|
3231
|
+
if (conf.table) body.appendChild(buildChartTable(view, spec, type, formatValue));
|
|
3232
|
+
applyKbCursor();
|
|
3233
|
+
};
|
|
2994
3234
|
const render = () => {
|
|
2995
3235
|
if (!current2.type) current2 = { ...current2, type: inferChartType(current2) };
|
|
2996
3236
|
const spec = current2;
|
|
@@ -3071,6 +3311,7 @@ function renderChart(el, raw) {
|
|
|
3071
3311
|
}
|
|
3072
3312
|
}
|
|
3073
3313
|
if (loading) return;
|
|
3314
|
+
applyChartA11yPlus(view, spec, type, formatValue);
|
|
3074
3315
|
paintChartMarks(root, view, spec, formatValue, warnedMarks);
|
|
3075
3316
|
bindZoomGesture();
|
|
3076
3317
|
};
|
|
@@ -3152,6 +3393,7 @@ function renderChart(el, raw) {
|
|
|
3152
3393
|
releaseFluidWidth(root);
|
|
3153
3394
|
hiddenLegendKeys.delete(root);
|
|
3154
3395
|
zoomDragCleanup?.();
|
|
3396
|
+
root.removeEventListener("keydown", onKbKeydown);
|
|
3155
3397
|
root.textContent = "";
|
|
3156
3398
|
root.classList.remove("is-loading");
|
|
3157
3399
|
unbindEvents();
|
package/dist/registry.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@icen.ai/ui",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"tokens": [
|
|
5
5
|
"colors.css",
|
|
6
6
|
"scrollbars.css",
|
|
7
7
|
"style-profiles.css",
|
|
8
8
|
"typography.css",
|
|
9
|
+
"motion.css",
|
|
9
10
|
"design.css",
|
|
10
11
|
"chinese.css",
|
|
11
12
|
"soviet.css",
|
|
@@ -239,6 +240,7 @@
|
|
|
239
240
|
"kb-who-can",
|
|
240
241
|
"mentions",
|
|
241
242
|
"modal",
|
|
243
|
+
"motion",
|
|
242
244
|
"nav",
|
|
243
245
|
"notification",
|
|
244
246
|
"panel",
|