@astryxdesign/lab 0.2.0-canary.90ae6c6 → 0.2.0-canary.bdc7cde
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/dist/Chart/Chart.d.ts +1 -12
- package/dist/Chart/Chart.d.ts.map +1 -1
- package/dist/Chart/Chart.js +3 -51
- package/dist/CodeEditor/CodeEditor.d.ts +2 -14
- package/dist/CodeEditor/CodeEditor.d.ts.map +1 -1
- package/dist/CodeEditor/CodeEditor.js +9 -110
- package/dist/Radial/RadialChart.d.ts +1 -12
- package/dist/Radial/RadialChart.d.ts.map +1 -1
- package/dist/Radial/RadialChart.js +4 -89
- package/dist/Sankey/SankeyChart.d.ts +1 -13
- package/dist/Sankey/SankeyChart.d.ts.map +1 -1
- package/dist/Sankey/SankeyChart.js +5 -53
- package/dist/ThreeD/ThreeDChart.d.ts +3 -16
- package/dist/ThreeD/ThreeDChart.d.ts.map +1 -1
- package/dist/ThreeD/ThreeDChart.js +5 -63
- package/package.json +2 -2
- package/src/Chart/Chart.tsx +0 -59
- package/src/CodeEditor/CodeEditor.test.tsx +2 -172
- package/src/CodeEditor/CodeEditor.tsx +9 -142
- package/src/Radial/RadialChart.tsx +1 -102
- package/src/Sankey/SankeyChart.test.tsx +0 -95
- package/src/Sankey/SankeyChart.tsx +1 -55
- package/src/ThreeD/ThreeDChart.tsx +6 -84
- package/src/Chart/Chart.test.tsx +0 -126
- package/src/Radial/RadialChart.test.tsx +0 -157
- package/src/ThreeD/ThreeDChart.test.tsx +0 -251
package/dist/Chart/Chart.d.ts
CHANGED
|
@@ -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,
|
|
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
|
|
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"}
|
package/dist/Chart/Chart.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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
|
-
})
|
|
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,
|
|
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,
|
|
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":"
|
|
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,
|
|
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,
|
|
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
|
-
//
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
-
})
|
|
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,
|
|
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
|
|
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"}
|