@astryxdesign/lab 0.1.7-canary.fb9c68c → 0.1.8-canary.0db5dfd
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/CHANGELOG.md +4 -0
- package/dist/CircularProgress/CircularProgress.d.ts +40 -11
- package/dist/CircularProgress/CircularProgress.d.ts.map +1 -1
- package/dist/CircularProgress/CircularProgress.js +66 -25
- package/dist/RichTextEditor/RichTextEditor.d.ts +145 -0
- package/dist/RichTextEditor/RichTextEditor.d.ts.map +1 -0
- package/dist/RichTextEditor/RichTextEditor.js +262 -0
- package/dist/RichTextEditor/RichTextView.d.ts +65 -0
- package/dist/RichTextEditor/RichTextView.d.ts.map +1 -0
- package/dist/RichTextEditor/RichTextView.js +122 -0
- package/dist/RichTextEditor/editorTheme.d.ts +7 -0
- package/dist/RichTextEditor/editorTheme.d.ts.map +1 -0
- package/dist/RichTextEditor/editorTheme.js +75 -0
- package/dist/RichTextEditor/index.d.ts +15 -0
- package/dist/RichTextEditor/index.d.ts.map +1 -0
- package/dist/RichTextEditor/index.js +16 -0
- package/dist/Schedule/shared.d.ts.map +1 -1
- package/dist/Stepper/Step.d.ts +12 -6
- package/dist/Stepper/Step.d.ts.map +1 -1
- package/dist/Stepper/Step.js +335 -59
- package/dist/Stepper/StepStatus.d.ts +10 -10
- package/dist/Stepper/Stepper.d.ts +14 -4
- package/dist/Stepper/Stepper.d.ts.map +1 -1
- package/dist/Stepper/Stepper.js +30 -10
- package/dist/Stepper/StepperContext.d.ts +16 -0
- package/dist/Stepper/StepperContext.d.ts.map +1 -1
- package/dist/Stepper/StepperContext.js +10 -0
- package/dist/Stepper/index.d.ts +1 -1
- package/dist/Stepper/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/lab.css +29 -1
- package/package.json +49 -6
- package/src/CircularProgress/CircularProgress.doc.mjs +88 -18
- package/src/CircularProgress/CircularProgress.test.tsx +210 -31
- package/src/CircularProgress/CircularProgress.tsx +108 -25
- package/src/RichTextEditor/RichTextEditor.doc.mjs +147 -0
- package/src/RichTextEditor/RichTextEditor.test.tsx +220 -0
- package/src/RichTextEditor/RichTextEditor.tsx +466 -0
- package/src/RichTextEditor/RichTextView.tsx +184 -0
- package/src/RichTextEditor/editorTheme.ts +120 -0
- package/src/RichTextEditor/index.ts +26 -0
- package/src/Schedule/shared.tsx +1 -3
- package/src/Stepper/Step.tsx +494 -51
- package/src/Stepper/StepStatus.ts +10 -10
- package/src/Stepper/Stepper.test.tsx +134 -0
- package/src/Stepper/Stepper.tsx +52 -14
- package/src/Stepper/StepperContext.ts +18 -3
- package/src/Stepper/index.ts +4 -1
- package/src/index.ts +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,11 +5,10 @@
|
|
|
5
5
|
* @position Core implementation; consumed by index.ts
|
|
6
6
|
*
|
|
7
7
|
* SYNC: When modified, update these files to stay in sync:
|
|
8
|
-
* - /packages/
|
|
9
|
-
* - /packages/
|
|
10
|
-
* - /packages/
|
|
8
|
+
* - /packages/lab/src/CircularProgress/CircularProgress.doc.mjs (props table, features, implementation notes)
|
|
9
|
+
* - /packages/lab/src/CircularProgress/CircularProgress.test.tsx (tests for new/changed behavior)
|
|
10
|
+
* - /packages/lab/src/CircularProgress/index.ts (exports if types change)
|
|
11
11
|
* - /apps/storybook/stories/CircularProgress.stories.tsx (storybook stories)
|
|
12
|
-
* - /packages/cli/templates/blocks/components/CircularProgress/ (showcase blocks)
|
|
13
12
|
*/
|
|
14
13
|
import { type ReactNode } from 'react';
|
|
15
14
|
import type { BaseProps } from '@astryxdesign/core';
|
|
@@ -19,7 +18,7 @@ import type { BaseProps } from '@astryxdesign/core';
|
|
|
19
18
|
* Theme packages can add custom variants via TypeScript module augmentation:
|
|
20
19
|
* @example
|
|
21
20
|
* ```
|
|
22
|
-
* declare module '@astryxdesign/
|
|
21
|
+
* declare module '@astryxdesign/lab' {
|
|
23
22
|
* interface CircularProgressVariantMap {
|
|
24
23
|
* 'brand': true;
|
|
25
24
|
* }
|
|
@@ -40,7 +39,7 @@ export interface CircularProgressProps extends BaseProps<HTMLDivElement> {
|
|
|
40
39
|
ref?: React.Ref<HTMLDivElement>;
|
|
41
40
|
/**
|
|
42
41
|
* Current value of the circular progress.
|
|
43
|
-
*
|
|
42
|
+
* Ignored when `isIndeterminate` is true.
|
|
44
43
|
*/
|
|
45
44
|
value?: number;
|
|
46
45
|
/**
|
|
@@ -57,9 +56,22 @@ export interface CircularProgressProps extends BaseProps<HTMLDivElement> {
|
|
|
57
56
|
* @default true
|
|
58
57
|
*/
|
|
59
58
|
isLabelHidden?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* When true, displays the formatted value (e.g. "75%") in the center of
|
|
61
|
+
* the ring. Ignored when `isIndeterminate` is true or when `children`
|
|
62
|
+
* provide custom center content.
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
hasValueLabel?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Custom formatter for the value label.
|
|
68
|
+
* @default (value, max) => `${Math.round((value / max) * 100)}%`
|
|
69
|
+
*/
|
|
70
|
+
formatValueLabel?: (value: number, max: number) => string;
|
|
60
71
|
/**
|
|
61
72
|
* Content displayed in the center of the ring.
|
|
62
73
|
* Typically a percentage string, icon, or custom content.
|
|
74
|
+
* Takes precedence over `hasValueLabel`.
|
|
63
75
|
*/
|
|
64
76
|
children?: ReactNode;
|
|
65
77
|
/**
|
|
@@ -75,6 +87,20 @@ export interface CircularProgressProps extends BaseProps<HTMLDivElement> {
|
|
|
75
87
|
* @default 'accent'
|
|
76
88
|
*/
|
|
77
89
|
variant?: CircularProgressVariant;
|
|
90
|
+
/**
|
|
91
|
+
* When true, renders an animated indeterminate progress indicator.
|
|
92
|
+
* Use when the progress amount is unknown (e.g. loading, processing).
|
|
93
|
+
* The `value` and `hasValueLabel` props are ignored in this mode.
|
|
94
|
+
* Respects `prefers-reduced-motion` by slowing the animation.
|
|
95
|
+
* @default false
|
|
96
|
+
*/
|
|
97
|
+
isIndeterminate?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* When true, the circular progress is visually disabled — the ring and
|
|
100
|
+
* text use disabled colors. Use for canceled or inactive operations.
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
isDisabled?: boolean;
|
|
78
104
|
/**
|
|
79
105
|
* Test ID for testing utilities.
|
|
80
106
|
*/
|
|
@@ -85,16 +111,19 @@ export interface CircularProgressProps extends BaseProps<HTMLDivElement> {
|
|
|
85
111
|
*
|
|
86
112
|
* In determinate mode, displays a known value as an arc fill.
|
|
87
113
|
* In indeterminate mode, shows an animated spinning indicator.
|
|
88
|
-
* Supports center content via children for labels, percentages, or icons
|
|
114
|
+
* Supports center content via children for labels, percentages, or icons,
|
|
115
|
+
* or an automatic formatted value label via `hasValueLabel`.
|
|
89
116
|
*
|
|
90
117
|
* @example
|
|
91
118
|
* ```
|
|
92
|
-
* <CircularProgress value={75} label="Upload progress" />
|
|
93
|
-
* <CircularProgress
|
|
94
|
-
* <CircularProgress label="
|
|
119
|
+
* <CircularProgress value={75} label="Upload progress" hasValueLabel />
|
|
120
|
+
* <CircularProgress isIndeterminate label="Loading..." />
|
|
121
|
+
* <CircularProgress value={3.2} max={5} label="Disk usage" hasValueLabel
|
|
122
|
+
* formatValueLabel={(v, m) => `${v} GB / ${m} GB`} />
|
|
123
|
+
* <CircularProgress value={30} label="Canceled" isDisabled hasValueLabel />
|
|
95
124
|
* ```
|
|
96
125
|
*/
|
|
97
|
-
export declare function CircularProgress({ value, max, label, isLabelHidden, children, size, variant, xstyle, className, style, 'data-testid': dataTestId, ref, ...rest }: CircularProgressProps): import("react").JSX.Element;
|
|
126
|
+
export declare function CircularProgress({ value, max, label, isLabelHidden, hasValueLabel, formatValueLabel, children, size, variant, isIndeterminate, isDisabled, xstyle, className, style, 'data-testid': dataTestId, ref, ...rest }: CircularProgressProps): import("react").JSX.Element;
|
|
98
127
|
export declare namespace CircularProgress {
|
|
99
128
|
var displayName: string;
|
|
100
129
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../src/CircularProgress/CircularProgress.tsx"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"CircularProgress.d.ts","sourceRoot":"","sources":["../../src/CircularProgress/CircularProgress.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAQ,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAY5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,IAAI,CAAC;IACb,OAAO,EAAE,IAAI,CAAC;IACd,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,IAAI,CAAC;CACf;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAQtD,MAAM,WAAW,qBAAsB,SAAQ,SAAS,CAAC,cAAc,CAAC;IACtE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1D;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;OAGG;IACH,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAqKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAS,EACT,GAAS,EACT,KAAK,EACL,aAAoB,EACpB,aAAqB,EACrB,gBAA0C,EAC1C,QAAQ,EACR,IAAW,EACX,OAAkB,EAClB,eAAuB,EACvB,UAAkB,EAClB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,UAAU,EACzB,GAAG,EACH,GAAG,IAAI,EACR,EAAE,qBAAqB,+BAuHvB;yBAzIe,gBAAgB"}
|
|
@@ -9,11 +9,10 @@
|
|
|
9
9
|
* @position Core implementation; consumed by index.ts
|
|
10
10
|
*
|
|
11
11
|
* SYNC: When modified, update these files to stay in sync:
|
|
12
|
-
* - /packages/
|
|
13
|
-
* - /packages/
|
|
14
|
-
* - /packages/
|
|
12
|
+
* - /packages/lab/src/CircularProgress/CircularProgress.doc.mjs (props table, features, implementation notes)
|
|
13
|
+
* - /packages/lab/src/CircularProgress/CircularProgress.test.tsx (tests for new/changed behavior)
|
|
14
|
+
* - /packages/lab/src/CircularProgress/index.ts (exports if types change)
|
|
15
15
|
* - /apps/storybook/stories/CircularProgress.stories.tsx (storybook stories)
|
|
16
|
-
* - /packages/cli/templates/blocks/components/CircularProgress/ (showcase blocks)
|
|
17
16
|
*/
|
|
18
17
|
import { useId } from 'react';
|
|
19
18
|
import * as stylex from '@stylexjs/stylex';
|
|
@@ -28,7 +27,7 @@ import { themeProps } from '@astryxdesign/core/utils';
|
|
|
28
27
|
* Theme packages can add custom variants via TypeScript module augmentation:
|
|
29
28
|
* @example
|
|
30
29
|
* ```
|
|
31
|
-
* declare module '@astryxdesign/
|
|
30
|
+
* declare module '@astryxdesign/lab' {
|
|
32
31
|
* interface CircularProgressVariantMap {
|
|
33
32
|
* 'brand': true;
|
|
34
33
|
* }
|
|
@@ -118,6 +117,10 @@ const variantStyles = {
|
|
|
118
117
|
neutral: {
|
|
119
118
|
kjVXCG: "xuxf9kk",
|
|
120
119
|
$$css: true
|
|
120
|
+
},
|
|
121
|
+
disabled: {
|
|
122
|
+
kjVXCG: "xuxf9kk",
|
|
123
|
+
$$css: true
|
|
121
124
|
}
|
|
122
125
|
};
|
|
123
126
|
const trackVariantStyles = {
|
|
@@ -142,29 +145,40 @@ const trackVariantStyles = {
|
|
|
142
145
|
$$css: true
|
|
143
146
|
}
|
|
144
147
|
};
|
|
148
|
+
function defaultFormatValueLabel(value, max) {
|
|
149
|
+
const pct = max > 0 ? Math.round(value / max * 100) : 0;
|
|
150
|
+
return `${pct}%`;
|
|
151
|
+
}
|
|
145
152
|
|
|
146
153
|
/**
|
|
147
154
|
* A circular/radial progress indicator that shows completion as a ring.
|
|
148
155
|
*
|
|
149
156
|
* In determinate mode, displays a known value as an arc fill.
|
|
150
157
|
* In indeterminate mode, shows an animated spinning indicator.
|
|
151
|
-
* Supports center content via children for labels, percentages, or icons
|
|
158
|
+
* Supports center content via children for labels, percentages, or icons,
|
|
159
|
+
* or an automatic formatted value label via `hasValueLabel`.
|
|
152
160
|
*
|
|
153
161
|
* @example
|
|
154
162
|
* ```
|
|
155
|
-
* <CircularProgress value={75} label="Upload progress" />
|
|
156
|
-
* <CircularProgress
|
|
157
|
-
* <CircularProgress label="
|
|
163
|
+
* <CircularProgress value={75} label="Upload progress" hasValueLabel />
|
|
164
|
+
* <CircularProgress isIndeterminate label="Loading..." />
|
|
165
|
+
* <CircularProgress value={3.2} max={5} label="Disk usage" hasValueLabel
|
|
166
|
+
* formatValueLabel={(v, m) => `${v} GB / ${m} GB`} />
|
|
167
|
+
* <CircularProgress value={30} label="Canceled" isDisabled hasValueLabel />
|
|
158
168
|
* ```
|
|
159
169
|
*/
|
|
160
170
|
export function CircularProgress({
|
|
161
|
-
value,
|
|
171
|
+
value = 0,
|
|
162
172
|
max = 100,
|
|
163
173
|
label,
|
|
164
174
|
isLabelHidden = true,
|
|
175
|
+
hasValueLabel = false,
|
|
176
|
+
formatValueLabel = defaultFormatValueLabel,
|
|
165
177
|
children,
|
|
166
178
|
size = 'md',
|
|
167
179
|
variant = 'accent',
|
|
180
|
+
isIndeterminate = false,
|
|
181
|
+
isDisabled = false,
|
|
168
182
|
xstyle,
|
|
169
183
|
className,
|
|
170
184
|
style,
|
|
@@ -173,19 +187,29 @@ export function CircularProgress({
|
|
|
173
187
|
...rest
|
|
174
188
|
}) {
|
|
175
189
|
const labelId = useId();
|
|
176
|
-
const isIndeterminate = value == null;
|
|
177
190
|
const {
|
|
178
191
|
diameter,
|
|
179
192
|
strokeWidth
|
|
180
193
|
} = SIZE_CONFIG[size];
|
|
181
194
|
const radius = (diameter - strokeWidth) / 2;
|
|
182
195
|
const circumference = 2 * Math.PI * radius;
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
196
|
+
|
|
197
|
+
// A non-finite value or max (e.g. a NaN from an upstream `loaded / total`
|
|
198
|
+
// with total 0) would otherwise leak into aria-valuenow, the value label,
|
|
199
|
+
// and the arc geometry as the string "NaN". Treat it as empty progress,
|
|
200
|
+
// matching the max=0 handling below.
|
|
201
|
+
const safeValue = Number.isFinite(value) ? value : 0;
|
|
202
|
+
const safeMax = Number.isFinite(max) ? max : 0;
|
|
203
|
+
const clampedValue = Math.min(Math.max(0, safeValue), safeMax);
|
|
204
|
+
const percentage = safeMax > 0 ? clampedValue / safeMax : 0;
|
|
186
205
|
const dashoffset = circumference * (1 - percentage);
|
|
206
|
+
const valueText = formatValueLabel(clampedValue, safeMax);
|
|
187
207
|
const center = diameter / 2;
|
|
188
208
|
const showLabel = !isLabelHidden;
|
|
209
|
+
const showValueLabel = hasValueLabel && !isIndeterminate;
|
|
210
|
+
const centerContent = children != null ? children : showValueLabel ? valueText : null;
|
|
211
|
+
const fillVariant = isDisabled ? 'disabled' : variant;
|
|
212
|
+
const trackVariant = isDisabled ? 'neutral' : variant;
|
|
189
213
|
return /*#__PURE__*/_jsxs("div", {
|
|
190
214
|
ref: ref,
|
|
191
215
|
...mergeProps(themeProps('circular-progress', {
|
|
@@ -200,21 +224,28 @@ export function CircularProgress({
|
|
|
200
224
|
0: {
|
|
201
225
|
className: "x10l6tqk x1i1rx1s xjm9jq1 x1717udv xkdpibf xb3r6kr xzpqnlu xuxw1ft xc342km"
|
|
202
226
|
},
|
|
203
|
-
|
|
227
|
+
2: {
|
|
204
228
|
className: "x141an7d x1ltkj2j x1e4wzip xv1l7n4"
|
|
229
|
+
},
|
|
230
|
+
1: {
|
|
231
|
+
className: "x10l6tqk x1i1rx1s xjm9jq1 x1717udv xkdpibf xb3r6kr xzpqnlu xuxw1ft xc342km xnbbluu"
|
|
232
|
+
},
|
|
233
|
+
3: {
|
|
234
|
+
className: "x141an7d x1ltkj2j x1e4wzip xnbbluu"
|
|
205
235
|
}
|
|
206
|
-
}[!!showLabel << 0],
|
|
236
|
+
}[!!showLabel << 1 | !!(showLabel && isDisabled) << 0],
|
|
207
237
|
children: label
|
|
208
238
|
}), /*#__PURE__*/_jsxs("div", {
|
|
209
239
|
...{
|
|
210
240
|
className: "x1n2onr6 x3nfvp2"
|
|
211
241
|
},
|
|
212
242
|
children: [/*#__PURE__*/_jsxs("svg", {
|
|
213
|
-
role:
|
|
243
|
+
role: "progressbar",
|
|
214
244
|
"aria-labelledby": labelId,
|
|
215
245
|
"aria-valuenow": isIndeterminate ? undefined : clampedValue,
|
|
216
246
|
"aria-valuemin": isIndeterminate ? undefined : 0,
|
|
217
|
-
"aria-valuemax": isIndeterminate ? undefined :
|
|
247
|
+
"aria-valuemax": isIndeterminate ? undefined : safeMax,
|
|
248
|
+
"aria-valuetext": isIndeterminate ? undefined : valueText,
|
|
218
249
|
width: diameter,
|
|
219
250
|
height: diameter,
|
|
220
251
|
viewBox: `0 0 ${diameter} ${diameter}`,
|
|
@@ -227,23 +258,23 @@ export function CircularProgress({
|
|
|
227
258
|
}
|
|
228
259
|
}[!!isIndeterminate << 0],
|
|
229
260
|
children: [/*#__PURE__*/_jsx("circle", {
|
|
230
|
-
...mergeProps(themeProps('circular-progress-track'), stylex.props(styles.track, trackVariantStyles[
|
|
261
|
+
...mergeProps(themeProps('circular-progress-track'), stylex.props(styles.track, trackVariantStyles[trackVariant])),
|
|
231
262
|
cx: center,
|
|
232
263
|
cy: center,
|
|
233
264
|
r: radius,
|
|
234
265
|
strokeWidth: strokeWidth
|
|
235
266
|
}), isIndeterminate ? /*#__PURE__*/_jsx("circle", {
|
|
236
267
|
...mergeProps(themeProps('circular-progress-fill', {
|
|
237
|
-
variant
|
|
238
|
-
}), stylex.props(styles.fillIndeterminate, variantStyles[
|
|
268
|
+
variant: fillVariant
|
|
269
|
+
}), stylex.props(styles.fillIndeterminate, variantStyles[fillVariant])),
|
|
239
270
|
cx: center,
|
|
240
271
|
cy: center,
|
|
241
272
|
r: radius,
|
|
242
273
|
strokeWidth: strokeWidth
|
|
243
274
|
}) : /*#__PURE__*/_jsx("circle", {
|
|
244
275
|
...mergeProps(themeProps('circular-progress-fill', {
|
|
245
|
-
variant
|
|
246
|
-
}), stylex.props(styles.fill, variantStyles[
|
|
276
|
+
variant: fillVariant
|
|
277
|
+
}), stylex.props(styles.fill, variantStyles[fillVariant])),
|
|
247
278
|
cx: center,
|
|
248
279
|
cy: center,
|
|
249
280
|
r: radius,
|
|
@@ -251,11 +282,21 @@ export function CircularProgress({
|
|
|
251
282
|
strokeDasharray: circumference,
|
|
252
283
|
strokeDashoffset: dashoffset
|
|
253
284
|
})]
|
|
254
|
-
}),
|
|
285
|
+
}), centerContent != null && /*#__PURE__*/_jsx("div", {
|
|
255
286
|
...{
|
|
256
287
|
className: "x10l6tqk x10a8y8t x78zum5 x6s0dn4 xl56j7k x47corl"
|
|
257
288
|
},
|
|
258
|
-
children: children
|
|
289
|
+
children: children != null ? children : /*#__PURE__*/_jsx("span", {
|
|
290
|
+
...{
|
|
291
|
+
0: {
|
|
292
|
+
className: "x141an7d x1ltkj2j x1sodnla xv1l7n4"
|
|
293
|
+
},
|
|
294
|
+
1: {
|
|
295
|
+
className: "x141an7d x1ltkj2j x1sodnla xnbbluu"
|
|
296
|
+
}
|
|
297
|
+
}[!!isDisabled << 0],
|
|
298
|
+
children: valueText
|
|
299
|
+
})
|
|
259
300
|
})]
|
|
260
301
|
})]
|
|
261
302
|
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file RichTextEditor.tsx
|
|
3
|
+
* @input Uses React, useId, Lexical (lexical + @lexical/react), Field, design tokens
|
|
4
|
+
* @output Exports RichTextEditor component, RichTextEditorProps, RichTextEditorStatus,
|
|
5
|
+
* RichTextEditorStatusType, RichTextEditorSize
|
|
6
|
+
* @position Experimental (lab) implementation; consumed by RichTextEditor/index.ts and
|
|
7
|
+
* re-exported from @astryxdesign/lab. Tested by RichTextEditor.test.tsx.
|
|
8
|
+
*
|
|
9
|
+
* SYNC: When modified, update these files to stay in sync:
|
|
10
|
+
* - /packages/lab/src/RichTextEditor/RichTextEditor.doc.mjs (props table, features, implementation notes)
|
|
11
|
+
* - /packages/lab/src/RichTextEditor/RichTextEditor.test.tsx (tests for new/changed behavior)
|
|
12
|
+
* - /packages/lab/src/RichTextEditor/index.ts (exports if types change)
|
|
13
|
+
* - /packages/lab/src/index.ts (barrel re-export)
|
|
14
|
+
* - /apps/storybook/stories/RichTextEditor.stories.tsx (storybook stories)
|
|
15
|
+
*
|
|
16
|
+
* NOTE: This is an EXPERIMENTAL component in @astryxdesign/lab (published only under
|
|
17
|
+
* the `@canary` dist-tag, never as stable `latest`). It is the initial landing for the
|
|
18
|
+
* OSS Lexical editor RFC; the goal is graduation to @astryxdesign/core after the
|
|
19
|
+
* Component Specification Protocol. `lexical` and `@lexical/*` are OPTIONAL peer
|
|
20
|
+
* dependencies — install them to use this component.
|
|
21
|
+
*/
|
|
22
|
+
import { type ReactNode } from 'react';
|
|
23
|
+
import type { BaseProps } from '@astryxdesign/core';
|
|
24
|
+
import type { SizeValue } from '@astryxdesign/core/utils';
|
|
25
|
+
import type { EditorState, Klass, LexicalEditor, LexicalNode } from 'lexical';
|
|
26
|
+
export type RichTextEditorStatusType = 'warning' | 'error' | 'success';
|
|
27
|
+
export type RichTextEditorSize = 'sm' | 'md' | 'lg';
|
|
28
|
+
export interface RichTextEditorStatus {
|
|
29
|
+
/** The type of status to display. */
|
|
30
|
+
type: RichTextEditorStatusType;
|
|
31
|
+
/** Optional message to display below the editor. */
|
|
32
|
+
message?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface RichTextEditorProps extends Omit<BaseProps, 'onChange' | 'defaultValue'> {
|
|
35
|
+
/** Label text for the editor (always rendered for accessibility). */
|
|
36
|
+
label: string;
|
|
37
|
+
/**
|
|
38
|
+
* Whether to visually hide the label (still accessible to screen readers).
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
isLabelHidden?: boolean;
|
|
42
|
+
/** Description text displayed between the label and editor. */
|
|
43
|
+
description?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Whether the field is optional. Mutually exclusive with isRequired.
|
|
46
|
+
* @default false
|
|
47
|
+
*/
|
|
48
|
+
isOptional?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Whether the field is required. Mutually exclusive with isOptional.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
53
|
+
isRequired?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Initial serialized editor state (a JSON string produced by
|
|
56
|
+
* `JSON.stringify(editorState.toJSON())`), used to seed the editor on mount.
|
|
57
|
+
* The editor is uncontrolled: this is read once.
|
|
58
|
+
*/
|
|
59
|
+
defaultValue?: string;
|
|
60
|
+
/**
|
|
61
|
+
* Callback fired when the editor content changes. Receives the current
|
|
62
|
+
* `EditorState` and the `LexicalEditor` instance. Serialize with
|
|
63
|
+
* `editorState.toJSON()` for persistence.
|
|
64
|
+
*/
|
|
65
|
+
onChange?: (editorState: EditorState, editor: LexicalEditor) => void;
|
|
66
|
+
/** Placeholder text shown when the editor is empty. */
|
|
67
|
+
placeholder?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Whether the editor is read-only (non-editable).
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
isReadOnly?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Whether the editor is disabled (non-editable, dimmed).
|
|
75
|
+
* @default false
|
|
76
|
+
*/
|
|
77
|
+
isDisabled?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Status indicator. When set, displays a colored border. If message is
|
|
80
|
+
* provided, displays a message box below the editor.
|
|
81
|
+
*/
|
|
82
|
+
status?: RichTextEditorStatus;
|
|
83
|
+
/**
|
|
84
|
+
* Width of the field. Numbers are treated as pixels, strings are used as-is
|
|
85
|
+
* (e.g. `'100%'`).
|
|
86
|
+
*/
|
|
87
|
+
width?: SizeValue;
|
|
88
|
+
/** Tooltip text to display in an info icon at the end of the label. */
|
|
89
|
+
labelTooltip?: string;
|
|
90
|
+
/**
|
|
91
|
+
* The size of the editor, affecting internal padding.
|
|
92
|
+
* @default 'md'
|
|
93
|
+
*/
|
|
94
|
+
size?: RichTextEditorSize;
|
|
95
|
+
/**
|
|
96
|
+
* Additional Lexical nodes to register beyond the default OSS set
|
|
97
|
+
* (Heading, Quote, List, Link, Code). Use this extension point to plug in
|
|
98
|
+
* custom nodes (e.g. mentions, images) without forking the editor.
|
|
99
|
+
*/
|
|
100
|
+
nodes?: ReadonlyArray<Klass<LexicalNode>>;
|
|
101
|
+
/**
|
|
102
|
+
* Additional Lexical plugins to render inside the composer. Use this to
|
|
103
|
+
* compose extra behaviour (toolbars, mentions, autolink, etc.) on top of the
|
|
104
|
+
* base editor. Plugins receive the editor via `useLexicalComposerContext()`.
|
|
105
|
+
*/
|
|
106
|
+
plugins?: ReactNode;
|
|
107
|
+
/**
|
|
108
|
+
* Whether to enable Markdown shortcut typing (e.g. `# ` for a heading,
|
|
109
|
+
* `- ` for a list). Uses the default `@lexical/markdown` transformers.
|
|
110
|
+
* @default true
|
|
111
|
+
*/
|
|
112
|
+
hasMarkdownShortcuts?: boolean;
|
|
113
|
+
/** Whether to automatically focus the editor on mount. @default false */
|
|
114
|
+
hasAutoFocus?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* The Lexical composer namespace, used for editor identity.
|
|
117
|
+
* @default 'astryx-editor'
|
|
118
|
+
*/
|
|
119
|
+
namespace?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A WYSIWYG rich-text editor built on Lexical, styled with Astryx design
|
|
123
|
+
* tokens. Experimental — ships from `@astryxdesign/lab` (canary). `lexical` and
|
|
124
|
+
* `@lexical/*` are optional peer dependencies — install them to use this
|
|
125
|
+
* component.
|
|
126
|
+
*
|
|
127
|
+
* The editor is intentionally minimal and extensible: pass `nodes` and
|
|
128
|
+
* `plugins` to layer richer behaviour (toolbars, mentions, hover cards) on top
|
|
129
|
+
* without forking.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```
|
|
133
|
+
* import {RichTextEditor} from '@astryxdesign/lab';
|
|
134
|
+
* <RichTextEditor
|
|
135
|
+
* label="Notes"
|
|
136
|
+
* placeholder="Write something..."
|
|
137
|
+
* onChange={state => save(JSON.stringify(state.toJSON()))}
|
|
138
|
+
* />
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function RichTextEditor({ label, isLabelHidden, description, isOptional, isRequired, defaultValue, onChange, placeholder, isReadOnly, isDisabled, status, width, labelTooltip, size: sizeProp, nodes, plugins, hasMarkdownShortcuts, hasAutoFocus, namespace, xstyle, className, style, ...rest }: RichTextEditorProps): import("react").JSX.Element;
|
|
142
|
+
export declare namespace RichTextEditor {
|
|
143
|
+
var displayName: string;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=RichTextEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/RichTextEditor.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAA2B,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAgB/D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAuBxD,OAAO,KAAK,EACV,WAAW,EACX,KAAK,EACL,aAAa,EACb,WAAW,EAEZ,MAAM,SAAS,CAAC;AAiEjB,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAEvE,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,SAAS,EACT,UAAU,GAAG,cAAc,CAC5B;IACC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACrE,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1C;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,yEAAyE;IACzE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,aAAqB,EACrB,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,MAAM,EACN,KAAK,EACL,YAAY,EACZ,IAAI,EAAE,QAAQ,EACd,KAAK,EACL,OAAO,EACP,oBAA2B,EAC3B,YAAoB,EACpB,SAA2B,EAC3B,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,mBAAmB,+BAkHrB;yBA1Ie,cAAc"}
|