@astryxdesign/lab 0.2.0-canary.ea693ac → 0.2.0-canary.f306f13

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.
@@ -5,10 +5,6 @@
5
5
  *
6
6
  * Handles the d3 margin convention: outer SVG at full size, inner <g> translated
7
7
  * by margins. Children receive scales and dimensions via context.
8
- *
9
- * Accessibility: the svg is exposed as a named image (role="img" + aria-label,
10
- * overridable via `label`), and small datasets are mirrored in a visually
11
- * hidden data table so screen reader users can read the underlying values.
12
8
  */
13
9
  import { type ReactNode } from 'react';
14
10
  import type { ChartMargin } from './types';
@@ -62,13 +58,6 @@ export interface ChartProps {
62
58
  * interference on mobile.
63
59
  */
64
60
  interactive?: boolean;
65
- /**
66
- * Accessible name for the chart, announced by screen readers (the svg is
67
- * exposed as `role="img"`). Defaults to an English description derived from
68
- * the keys (e.g. "Chart of revenue by month") — pass a localized string to
69
- * override.
70
- */
71
- label?: string;
72
61
  /** Chart contents — axes, marks, tooltips */
73
62
  children: ReactNode;
74
63
  }
@@ -84,5 +73,5 @@ export interface ChartProps {
84
73
  * </Chart>
85
74
  * ```
86
75
  */
87
- export declare function Chart({ data, xKey, yKeys, height, margin: marginOverride, yBaseline, yDomain: yDomainProp, xDomain: xDomainProp, interactive, label, children, }: ChartProps): import("react").JSX.Element;
76
+ export declare function Chart({ data, xKey, yKeys, height, margin: marginOverride, yBaseline, yDomain: yDomainProp, xDomain: xDomainProp, interactive, children, }: ChartProps): import("react").JSX.Element;
88
77
  //# sourceMappingURL=Chart.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../../src/Chart/Chart.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EAEL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAC,WAAW,EAAa,MAAM,SAAS,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAgBD;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAY,EACZ,MAAM,EAAE,cAAc,EACtB,SAAkB,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,WAAW,EACpB,WAAmB,EACnB,KAAK,EACL,QAAQ,GACT,EAAE,UAAU,+BA+OZ"}
1
+ {"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../../src/Chart/Chart.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EAEL,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAC,WAAW,EAAa,MAAM,SAAS,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,EACpB,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,MAAY,EACZ,MAAM,EAAE,cAAc,EACtB,SAAkB,EAClB,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,WAAW,EACpB,WAAmB,EACnB,QAAQ,GACT,EAAE,UAAU,+BA6MZ"}
@@ -7,15 +7,10 @@
7
7
  *
8
8
  * Handles the d3 margin convention: outer SVG at full size, inner <g> translated
9
9
  * by margins. Children receive scales and dimensions via context.
10
- *
11
- * Accessibility: the svg is exposed as a named image (role="img" + aria-label,
12
- * overridable via `label`), and small datasets are mirrored in a visually
13
- * hidden data table so screen reader users can read the underlying values.
14
10
  */
15
11
 
16
12
  import { useMemo, useRef, useState, useCallback, useLayoutEffect } from 'react';
17
13
  import { scaleLinear, scaleBand } from 'd3-scale';
18
- import { VisuallyHidden } from '@astryxdesign/core/VisuallyHidden';
19
14
  import { isBandScale } from "./utils.js";
20
15
  import { ChartProvider } from "./ChartContext.js";
21
16
 
@@ -33,18 +28,6 @@ const DEFAULT_MARGIN = {
33
28
  left: 48
34
29
  };
35
30
 
36
- /**
37
- * Maximum number of data points (rows × series) for which the visually hidden
38
- * data-table fallback is rendered. Beyond this a table is more noise than
39
- * signal for screen reader users, so larger charts are name-only.
40
- */
41
- const MAX_TABLE_POINTS = 100;
42
-
43
- /** Stringify a cell value for the hidden data table. */
44
- function tableCell(value) {
45
- return value == null ? '' : String(value);
46
- }
47
-
48
31
  /**
49
32
  * Root chart container. Computes scales from data and provides them to children.
50
33
  *
@@ -67,7 +50,6 @@ export function Chart({
67
50
  yDomain: yDomainProp,
68
51
  xDomain: xDomainProp,
69
52
  interactive = false,
70
- label,
71
53
  children
72
54
  }) {
73
55
  const containerRef = useRef(null);
@@ -233,15 +215,11 @@ export function Chart({
233
215
  touchAction: interactive ? 'none' : undefined,
234
216
  userSelect: interactive ? 'none' : undefined
235
217
  };
236
- const accessibleLabel = label ?? `Chart of ${yKeys.join(', ')} by ${xKey}`;
237
- const showDataTable = data.length > 0 && data.length * Math.max(yKeys.length, 1) <= MAX_TABLE_POINTS;
238
- return /*#__PURE__*/_jsxs("div", {
218
+ return /*#__PURE__*/_jsx("div", {
239
219
  ref: containerRef,
240
220
  style: containerStyle,
241
- children: [containerWidth > 0 && /*#__PURE__*/_jsxs("svg", {
221
+ children: containerWidth > 0 && /*#__PURE__*/_jsxs("svg", {
242
222
  ref: svgRef,
243
- role: "img",
244
- "aria-label": accessibleLabel,
245
223
  width: containerWidth,
246
224
  height: height,
247
225
  style: interactive ? {
@@ -264,32 +242,6 @@ export function Chart({
264
242
  children: children
265
243
  })
266
244
  })]
267
- }), showDataTable && /*#__PURE__*/_jsx(VisuallyHidden, {
268
- as: "div",
269
- children: /*#__PURE__*/_jsxs("table", {
270
- children: [/*#__PURE__*/_jsx("caption", {
271
- children: `${accessibleLabel} data`
272
- }), /*#__PURE__*/_jsx("thead", {
273
- children: /*#__PURE__*/_jsxs("tr", {
274
- children: [/*#__PURE__*/_jsx("th", {
275
- scope: "col",
276
- children: xKey
277
- }), yKeys.map(key => /*#__PURE__*/_jsx("th", {
278
- scope: "col",
279
- children: key
280
- }, key))]
281
- })
282
- }), /*#__PURE__*/_jsx("tbody", {
283
- children: data.map((d, i) => /*#__PURE__*/_jsxs("tr", {
284
- children: [/*#__PURE__*/_jsx("th", {
285
- scope: "row",
286
- children: tableCell(d[xKey])
287
- }), yKeys.map(key => /*#__PURE__*/_jsx("td", {
288
- children: tableCell(d[key])
289
- }, key))]
290
- }, i))
291
- })]
292
- })
293
- })]
245
+ })
294
246
  });
295
247
  }
@@ -23,24 +23,12 @@ export interface CodeEditorProps extends Omit<BaseProps<HTMLDivElement>, 'onChan
23
23
  size?: 'sm' | 'md';
24
24
  /** Custom tokenizer */
25
25
  tokenizer?: (code: string, language: string) => TokenLine[];
26
- /**
27
- * Hint exposed to assistive technology (via aria-describedby) explaining
28
- * how to move focus out of the editor. English default — the lab package
29
- * has no i18n catalog yet, so override this prop to localize.
30
- * @default 'Press Escape then Tab to move focus out of the editor.'
31
- */
32
- escapeHint?: string;
33
26
  }
34
27
  /**
35
28
  * An editable code input using contentEditable="plaintext-only".
36
29
  *
37
30
  * Uses CSS Custom Highlight API for syntax coloring. Supports
38
- * auto-indent, tab insertion, Shift+Tab outdent, and bracket auto-closing.
39
- *
40
- * Because Tab is captured for indentation, pressing Escape arms a one-shot
41
- * "tab moves focus" mode so keyboard users can leave the editor (WCAG 2.1.2).
42
- * The escape is advertised to assistive technology via a visually hidden
43
- * aria-describedby hint (see `escapeHint`).
31
+ * auto-indent, tab insertion, and bracket auto-closing.
44
32
  *
45
33
  * @example
46
34
  * ```
@@ -54,7 +42,7 @@ export interface CodeEditorProps extends Omit<BaseProps<HTMLDivElement>, 'onChan
54
42
  * />
55
43
  * ```
56
44
  */
57
- export declare function CodeEditor({ value, onChange, language, hasLineNumbers, isReadOnly, placeholder, maxHeight, size, tokenizer: customTokenizer, label, escapeHint, xstyle, className, style, ref, ...props }: CodeEditorProps): import("react").JSX.Element;
45
+ export declare function CodeEditor({ value, onChange, language, hasLineNumbers, isReadOnly, placeholder, maxHeight, size, tokenizer: customTokenizer, label, xstyle, className, style, ref, ...props }: CodeEditorProps): import("react").JSX.Element;
58
46
  export declare namespace CodeEditor {
59
47
  var displayName: string;
60
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor.d.ts","sourceRoot":"","sources":["../../src/CodeEditor/CodeEditor.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAkBlD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,8BAA8B,CAAC;AAuF5D,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,+BAA+B;IAC/B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,uBAAuB;IACvB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;IAC5D;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAsED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,QAAsB,EACtB,cAAsB,EACtB,UAAkB,EAClB,WAAW,EACX,SAAS,EACT,IAAW,EACX,SAAS,EAAE,eAAe,EAC1B,KAAK,EACL,UAAqE,EACrE,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,eAAe,+BAwUjB;yBAzVe,UAAU"}
1
+ {"version":3,"file":"CodeEditor.d.ts","sourceRoot":"","sources":["../../src/CodeEditor/CodeEditor.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAiBlD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,8BAA8B,CAAC;AAuF5D,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,+BAA+B;IAC/B,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,uBAAuB;IACvB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;CAC7D;AA6BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,QAAsB,EACtB,cAAsB,EACtB,UAAkB,EAClB,WAAW,EACX,SAAS,EACT,IAAW,EACX,SAAS,EAAE,eAAe,EAC1B,KAAK,EACL,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,eAAe,+BAkQjB;yBAlRe,UAAU"}
@@ -2,8 +2,7 @@
2
2
 
3
3
  /**
4
4
  * @file CodeEditor.tsx
5
- * @input Uses React, StyleX, theme tokens, CSS Custom Highlight API,
6
- * VisuallyHidden (core)
5
+ * @input Uses React, StyleX, theme tokens, CSS Custom Highlight API
7
6
  * @output Exports CodeEditor component and CodeEditorProps
8
7
  * @position Core implementation; editable code input (lab/experimental)
9
8
  *
@@ -15,8 +14,7 @@
15
14
 
16
15
  'use client';
17
16
 
18
- import { useEffect, useId, useLayoutEffect, useRef, useCallback, useState } from 'react';
19
- import { VisuallyHidden } from '@astryxdesign/core/VisuallyHidden';
17
+ import { useEffect, useLayoutEffect, useRef, useCallback, useState } from 'react';
20
18
  import * as stylex from '@stylexjs/stylex';
21
19
  import '@astryxdesign/core/theme/tokens.stylex';
22
20
  import { colorVars, spacingVars, radiusVars, textSizeVars, typographyVars, typeScaleVars, borderVars } from '@astryxdesign/core/theme/tokens.stylex';
@@ -118,41 +116,6 @@ const AUTO_CLOSE_PAIRS = {
118
116
  "'": "'",
119
117
  '`': '`'
120
118
  };
121
-
122
- /**
123
- * Modifier keys that must NOT re-arm Tab indentation after Escape has armed
124
- * "tab moves focus" mode — otherwise the Shift keydown that precedes
125
- * Shift+Tab would cancel the mode before Tab arrives.
126
- */
127
- const MODE_NEUTRAL_KEYS = new Set(['Shift', 'Control', 'Alt', 'Meta', 'CapsLock']);
128
-
129
- /** Place a collapsed caret at a character offset within an element's text. */
130
- function setCaretAtTextOffset(el, offset) {
131
- const sel = window.getSelection();
132
- if (!sel) {
133
- return;
134
- }
135
- const range = document.createRange();
136
- let remaining = offset;
137
- const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
138
- let node = walker.nextNode();
139
- while (node) {
140
- const length = node.textContent?.length ?? 0;
141
- if (remaining <= length) {
142
- range.setStart(node, remaining);
143
- range.collapse(true);
144
- sel.removeAllRanges();
145
- sel.addRange(range);
146
- return;
147
- }
148
- remaining -= length;
149
- node = walker.nextNode();
150
- }
151
- range.selectNodeContents(el);
152
- range.collapse(false);
153
- sel.removeAllRanges();
154
- sel.addRange(range);
155
- }
156
119
  let editorInstanceCounter = 0;
157
120
 
158
121
  // ---------------------------------------------------------------------------
@@ -163,12 +126,7 @@ let editorInstanceCounter = 0;
163
126
  * An editable code input using contentEditable="plaintext-only".
164
127
  *
165
128
  * Uses CSS Custom Highlight API for syntax coloring. Supports
166
- * auto-indent, tab insertion, Shift+Tab outdent, and bracket auto-closing.
167
- *
168
- * Because Tab is captured for indentation, pressing Escape arms a one-shot
169
- * "tab moves focus" mode so keyboard users can leave the editor (WCAG 2.1.2).
170
- * The escape is advertised to assistive technology via a visually hidden
171
- * aria-describedby hint (see `escapeHint`).
129
+ * auto-indent, tab insertion, and bracket auto-closing.
172
130
  *
173
131
  * @example
174
132
  * ```
@@ -193,7 +151,6 @@ export function CodeEditor({
193
151
  size = 'md',
194
152
  tokenizer: customTokenizer,
195
153
  label,
196
- escapeHint = 'Press Escape then Tab to move focus out of the editor.',
197
154
  xstyle,
198
155
  className,
199
156
  style,
@@ -204,10 +161,6 @@ export function CodeEditor({
204
161
  const [instanceId] = useState(() => ++editorInstanceCounter);
205
162
  const [focused, setFocused] = useState(false);
206
163
  const isComposingRef = useRef(false);
207
- // One-shot "tab moves focus" mode, armed by Escape (WCAG 2.1.2 — the
208
- // standard escape from a code editor's Tab-to-indent keyboard trap).
209
- const tabMovesFocusRef = useRef(false);
210
- const hintId = useId();
211
164
  const lines = value.split('\n');
212
165
 
213
166
  // Sync textContent with controlled value
@@ -290,56 +243,13 @@ export function CodeEditor({
290
243
  return;
291
244
  }
292
245
 
293
- // Escape arms one-shot "tab moves focus" mode so keyboard users can
294
- // leave the editor. Only engage when nothing inside the editor (e.g.
295
- // an embedded popover/autocomplete) already consumed the Escape.
296
- if (e.key === 'Escape') {
297
- if (!e.defaultPrevented) {
298
- tabMovesFocusRef.current = true;
299
- }
300
- return;
301
- }
246
+ // Tab key: insert 2 spaces
302
247
  if (e.key === 'Tab') {
303
- // Tab-moves-focus mode: let the browser handle Tab / Shift+Tab
304
- // natively so focus leaves the editor. One-shot — disarm.
305
- if (tabMovesFocusRef.current) {
306
- tabMovesFocusRef.current = false;
307
- return;
308
- }
309
248
  e.preventDefault();
310
249
  const sel = window.getSelection();
311
250
  if (!sel || sel.rangeCount === 0) {
312
251
  return;
313
252
  }
314
- const el = editorRef.current;
315
- if (!el) {
316
- return;
317
- }
318
-
319
- // Shift+Tab: outdent — remove up to two leading spaces on the
320
- // current line.
321
- if (e.shiftKey) {
322
- const range = sel.getRangeAt(0);
323
- const preCaretRange = range.cloneRange();
324
- preCaretRange.selectNodeContents(el);
325
- preCaretRange.setEnd(range.startContainer, range.startOffset);
326
- const cursorOffset = preCaretRange.toString().length;
327
- const fullText = el.textContent ?? '';
328
- const lineStart = fullText.lastIndexOf('\n', cursorOffset - 1) + 1;
329
- const line = fullText.slice(lineStart);
330
- const removeCount = line.startsWith(' ') ? 2 : line.startsWith(' ') ? 1 : 0;
331
- if (removeCount === 0) {
332
- return;
333
- }
334
- const newText = fullText.slice(0, lineStart) + fullText.slice(lineStart + removeCount);
335
- el.textContent = newText;
336
- const removedBeforeCursor = Math.min(removeCount, Math.max(0, cursorOffset - lineStart));
337
- setCaretAtTextOffset(el, cursorOffset - removedBeforeCursor);
338
- onChange(newText);
339
- return;
340
- }
341
-
342
- // Tab: insert 2 spaces
343
253
  const range = sel.getRangeAt(0);
344
254
  range.deleteContents();
345
255
  const textNode = document.createTextNode(' ');
@@ -348,17 +258,13 @@ export function CodeEditor({
348
258
  range.setEndAfter(textNode);
349
259
  sel.removeAllRanges();
350
260
  sel.addRange(range);
351
- onChange(el.textContent ?? '');
261
+ const el = editorRef.current;
262
+ if (el) {
263
+ onChange(el.textContent ?? '');
264
+ }
352
265
  return;
353
266
  }
354
267
 
355
- // Any other non-modifier key re-arms Tab indentation. Modifiers are
356
- // excluded so Escape → Shift+Tab still moves focus backward (the
357
- // Shift keydown fires before the Tab keydown).
358
- if (!MODE_NEUTRAL_KEYS.has(e.key)) {
359
- tabMovesFocusRef.current = false;
360
- }
361
-
362
268
  // Enter key: preserve indentation
363
269
  if (e.key === 'Enter') {
364
270
  e.preventDefault();
@@ -477,21 +383,14 @@ export function CodeEditor({
477
383
  "aria-multiline": "true",
478
384
  "aria-label": label,
479
385
  "aria-readonly": isReadOnly,
480
- "aria-describedby": isReadOnly ? undefined : hintId,
481
386
  spellCheck: false,
482
387
  onInput: handleInput,
483
388
  onKeyDown: handleKeyDown,
484
389
  onFocus: () => setFocused(true),
485
- onBlur: () => {
486
- setFocused(false);
487
- tabMovesFocusRef.current = false;
488
- },
390
+ onBlur: () => setFocused(false),
489
391
  onCompositionStart: handleCompositionStart,
490
392
  onCompositionEnd: handleCompositionEnd,
491
393
  ...stylex.props(styles.editor, sizeStyle)
492
- }), !isReadOnly && /*#__PURE__*/_jsx(VisuallyHidden, {
493
- id: hintId,
494
- children: escapeHint
495
394
  })]
496
395
  })]
497
396
  })
@@ -5,10 +5,6 @@
5
5
  *
6
6
  * Owns the radial coordinate space: center, radius, angle/radius scales.
7
7
  * Same Tier 1 guarantee as Chart — all children map through the same context.
8
- *
9
- * Accessibility: the svg is exposed as a named image (role="img" + aria-label,
10
- * overridable via `label`), and small datasets are mirrored in a visually
11
- * hidden data table (slices in pie mode, axis values in spider mode).
12
8
  */
13
9
  import { type ReactNode } from 'react';
14
10
  export interface RadialChartProps {
@@ -44,13 +40,6 @@ export interface RadialChartProps {
44
40
  * Enable touch interaction mode — blocks scroll on mobile.
45
41
  */
46
42
  interactive?: boolean;
47
- /**
48
- * Accessible name for the chart, announced by screen readers (the svg is
49
- * exposed as `role="img"`). Defaults to an English description derived from
50
- * the mode and keys (e.g. "Radar chart of speed, handling" or
51
- * "Pie chart of revenue") — pass a localized string to override.
52
- */
53
- label?: string;
54
43
  children: ReactNode;
55
44
  }
56
45
  /**
@@ -72,5 +61,5 @@ export interface RadialChartProps {
72
61
  * </RadialChart>
73
62
  * ```
74
63
  */
75
- export declare function RadialChart({ data, height, axes, valueKey, labelKey, innerRadius: innerRadiusFraction, padAngle, label, children, }: RadialChartProps): import("react").JSX.Element;
64
+ export declare function RadialChart({ data, height, axes, valueKey, labelKey, innerRadius: innerRadiusFraction, padAngle, children, }: RadialChartProps): import("react").JSX.Element;
76
65
  //# sourceMappingURL=RadialChart.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RadialChart.d.ts","sourceRoot":"","sources":["../../src/Radial/RadialChart.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAKf,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;CACrB;AAkBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,MAAY,EACZ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,WAAW,EAAE,mBAAuB,EACpC,QAAe,EACf,KAAK,EACL,QAAQ,GACT,EAAE,gBAAgB,+BAwMlB"}
1
+ {"version":3,"file":"RadialChart.d.ts","sourceRoot":"","sources":["../../src/Radial/RadialChart.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAIf,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,MAAY,EACZ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,WAAW,EAAE,mBAAuB,EACpC,QAAe,EACf,QAAQ,GACT,EAAE,gBAAgB,+BAgIlB"}
@@ -7,32 +7,11 @@
7
7
  *
8
8
  * Owns the radial coordinate space: center, radius, angle/radius scales.
9
9
  * Same Tier 1 guarantee as Chart — all children map through the same context.
10
- *
11
- * Accessibility: the svg is exposed as a named image (role="img" + aria-label,
12
- * overridable via `label`), and small datasets are mirrored in a visually
13
- * hidden data table (slices in pie mode, axis values in spider mode).
14
10
  */
15
11
 
16
12
  import { useMemo, useRef, useState, useLayoutEffect } from 'react';
17
- import { VisuallyHidden } from '@astryxdesign/core/VisuallyHidden';
18
13
  import { RadialProvider } from "./RadialContext.js";
19
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
- /**
21
- * Maximum number of data points (rows × axes in spider mode, slices in pie
22
- * mode) for which the visually hidden data-table fallback is rendered. Beyond
23
- * this a table is more noise than signal, so larger charts are name-only.
24
- */
25
- const MAX_TABLE_POINTS = 100;
26
-
27
- /**
28
- * Row header for a spider-mode table row: the first string field in the row
29
- * (the same heuristic RadialArea uses to match its `dataKey`), else the index.
30
- */
31
- function spiderRowHeader(row, index) {
32
- const name = Object.values(row).find(v => typeof v === 'string');
33
- return typeof name === 'string' ? name : `Series ${index + 1}`;
34
- }
35
-
14
+ import { jsx as _jsx } from "react/jsx-runtime";
36
15
  /**
37
16
  * Root radial chart container. Computes angular/radial scales and provides
38
17
  * them to children via context.
@@ -60,7 +39,6 @@ export function RadialChart({
60
39
  labelKey,
61
40
  innerRadius: innerRadiusFraction = 0,
62
41
  padAngle = 0.02,
63
- label,
64
42
  children
65
43
  }) {
66
44
  const containerRef = useRef(null);
@@ -174,81 +152,18 @@ export function RadialChart({
174
152
  ...spiderCtx,
175
153
  ...pieCtx
176
154
  }), [cx, cy, outerRadius, innerRadiusPx, data, mode, spiderCtx, pieCtx]);
177
- const accessibleLabel = label ?? (mode === 'spider' ? `Radar chart of ${(axes ?? []).join(', ')}` : `Pie chart of ${valueKey ?? 'values'}`);
178
- const slices = pieCtx.slices ?? [];
179
- const showPieTable = mode === 'pie' && slices.length > 0 && slices.length <= MAX_TABLE_POINTS;
180
- const showSpiderTable = mode === 'spider' && axes != null && axes.length > 0 && data.length > 0 && data.length * axes.length <= MAX_TABLE_POINTS;
181
- return /*#__PURE__*/_jsxs("div", {
155
+ return /*#__PURE__*/_jsx("div", {
182
156
  ref: containerRef,
183
157
  style: {
184
158
  width: '100%'
185
159
  },
186
- children: [containerWidth > 0 && /*#__PURE__*/_jsx("svg", {
187
- role: "img",
188
- "aria-label": accessibleLabel,
160
+ children: containerWidth > 0 && /*#__PURE__*/_jsx("svg", {
189
161
  width: containerWidth,
190
162
  height: height,
191
163
  children: /*#__PURE__*/_jsx(RadialProvider, {
192
164
  value: ctx,
193
165
  children: children
194
166
  })
195
- }), showPieTable && /*#__PURE__*/_jsx(VisuallyHidden, {
196
- as: "div",
197
- children: /*#__PURE__*/_jsxs("table", {
198
- children: [/*#__PURE__*/_jsx("caption", {
199
- children: `${accessibleLabel} data`
200
- }), /*#__PURE__*/_jsx("thead", {
201
- children: /*#__PURE__*/_jsxs("tr", {
202
- children: [/*#__PURE__*/_jsx("th", {
203
- scope: "col",
204
- children: labelKey ?? 'Label'
205
- }), /*#__PURE__*/_jsx("th", {
206
- scope: "col",
207
- children: valueKey
208
- }), /*#__PURE__*/_jsx("th", {
209
- scope: "col",
210
- children: "Percentage"
211
- })]
212
- })
213
- }), /*#__PURE__*/_jsx("tbody", {
214
- children: slices.map((slice, i) => /*#__PURE__*/_jsxs("tr", {
215
- children: [/*#__PURE__*/_jsx("th", {
216
- scope: "row",
217
- children: slice.key
218
- }), /*#__PURE__*/_jsx("td", {
219
- children: String(slice.value)
220
- }), /*#__PURE__*/_jsx("td", {
221
- children: `${(slice.percentage * 100).toFixed(1)}%`
222
- })]
223
- }, i))
224
- })]
225
- })
226
- }), showSpiderTable && /*#__PURE__*/_jsx(VisuallyHidden, {
227
- as: "div",
228
- children: /*#__PURE__*/_jsxs("table", {
229
- children: [/*#__PURE__*/_jsx("caption", {
230
- children: `${accessibleLabel} data`
231
- }), /*#__PURE__*/_jsx("thead", {
232
- children: /*#__PURE__*/_jsxs("tr", {
233
- children: [/*#__PURE__*/_jsx("th", {
234
- scope: "col",
235
- children: "Series"
236
- }), axes.map(key => /*#__PURE__*/_jsx("th", {
237
- scope: "col",
238
- children: key
239
- }, key))]
240
- })
241
- }), /*#__PURE__*/_jsx("tbody", {
242
- children: data.map((row, i) => /*#__PURE__*/_jsxs("tr", {
243
- children: [/*#__PURE__*/_jsx("th", {
244
- scope: "row",
245
- children: spiderRowHeader(row, i)
246
- }), axes.map(key => /*#__PURE__*/_jsx("td", {
247
- children: row[key] == null ? '' : String(row[key])
248
- }, key))]
249
- }, i))
250
- })]
251
- })
252
- })]
167
+ })
253
168
  });
254
169
  }
@@ -5,10 +5,6 @@
5
5
  *
6
6
  * When columns × minColumnWidth exceeds the container, the chart
7
7
  * scrolls horizontally rather than squishing columns together.
8
- *
9
- * Accessibility: the svg is exposed as a named image (role="img" + aria-label,
10
- * overridable via `label`) in both the scrolling and non-scrolling paths, and
11
- * small graphs are mirrored in a visually hidden From/To/Value table.
12
8
  */
13
9
  import { type ReactNode } from 'react';
14
10
  import type { SankeyNodeDatum, SankeyLinkDatum, SankeyColumn } from './types';
@@ -43,14 +39,6 @@ export interface SankeyChartProps {
43
39
  * When total min width exceeds the container, horizontal scrolling activates.
44
40
  */
45
41
  minColumnWidth?: number;
46
- /**
47
- * Accessible name for the chart, announced by screen readers. Applied to the
48
- * svg (`role="img"`) and, when the chart scrolls, to the focusable scroll
49
- * region. Pass a localized string to override the English default.
50
- *
51
- * @default 'Sankey chart'
52
- */
53
- label?: string;
54
42
  /** Chart contents */
55
43
  children: ReactNode;
56
44
  }
@@ -76,7 +64,7 @@ export interface SankeyChartProps {
76
64
  * </SankeyChart>
77
65
  * ```
78
66
  */
79
- export declare function SankeyChart({ nodes, links, columns, height, nodeWidth, nodeGap, nodeColor, minColumnWidth, label, children, }: SankeyChartProps): import("react").JSX.Element;
67
+ export declare function SankeyChart({ nodes, links, columns, height, nodeWidth, nodeGap, nodeColor, minColumnWidth, children, }: SankeyChartProps): import("react").JSX.Element;
80
68
  export declare namespace SankeyChart {
81
69
  var displayName: string;
82
70
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SankeyChart.d.ts","sourceRoot":"","sources":["../../src/Sankey/SankeyChart.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAC,eAAe,EAAE,eAAe,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,uBAAuB;IACvB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAsDD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,KAAK,EACL,OAAO,EACP,MAAY,EACZ,SAAc,EACd,OAAY,EACZ,SAAS,EACT,cAAoB,EACpB,KAAsB,EACtB,QAAQ,GACT,EAAE,gBAAgB,+BAsHlB;yBAjIe,WAAW"}
1
+ {"version":3,"file":"SankeyChart.d.ts","sourceRoot":"","sources":["../../src/Sankey/SankeyChart.tsx"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAC,eAAe,EAAE,eAAe,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,uBAAuB;IACvB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB;IACrB,QAAQ,EAAE,SAAS,CAAC;CACrB;AA+CD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,KAAK,EACL,OAAO,EACP,MAAY,EACZ,SAAc,EACd,OAAY,EACZ,SAAS,EACT,cAAoB,EACpB,QAAQ,GACT,EAAE,gBAAgB,+BAqFlB;yBA/Fe,WAAW"}