@astryxdesign/lab 0.1.9-canary.ae1eaed → 0.1.9-canary.b7d7f4b
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/RichTextEditor/RichTextEditor.d.ts +23 -2
- package/dist/RichTextEditor/RichTextEditor.d.ts.map +1 -1
- package/dist/RichTextEditor/RichTextEditor.js +9 -2
- package/dist/RichTextEditor/editorTheme.d.ts.map +1 -1
- package/dist/RichTextEditor/editorTheme.js +33 -7
- package/dist/RichTextEditor/index.d.ts +1 -1
- package/dist/RichTextEditor/index.d.ts.map +1 -1
- package/dist/Stepper/Step.js +1 -1
- package/dist/Stepper/Stepper.d.ts +1 -1
- package/dist/Stepper/StepperContext.d.ts +1 -1
- package/dist/Stepper/StepperContext.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lab.css +10 -0
- package/package.json +3 -2
- package/src/Chart/ChartArea.doc.mjs +1 -1
- package/src/Chart/ChartBar.doc.mjs +1 -1
- package/src/Chart/ChartCandlestick.doc.mjs +1 -1
- package/src/Chart/ChartDot.doc.mjs +1 -1
- package/src/Chart/ChartDotGL.doc.mjs +1 -1
- package/src/Chart/ChartDotGLInteractive.doc.mjs +1 -1
- package/src/Chart/ChartHeatmapGL.doc.mjs +1 -1
- package/src/Chart/ChartLine.doc.mjs +1 -1
- package/src/Chart/ChartStreamGL.doc.mjs +1 -1
- package/src/Chat/ChatEmojiPicker.doc.mjs +1 -1
- package/src/Chat/ChatReactionBar.doc.mjs +1 -1
- package/src/Chat/ChatTypingIndicator.doc.mjs +1 -1
- package/src/Chat/ChatUnreadDivider.doc.mjs +1 -1
- package/src/ChatReasoning/ChatReasoning.doc.mjs +1 -1
- package/src/CodeEditor/CodeEditor.doc.mjs +1 -1
- package/src/Drawer/Drawer.doc.mjs +3 -3
- package/src/InfoTip/InfoTip.doc.mjs +3 -3
- package/src/LogStream/LogStream.doc.mjs +1 -1
- package/src/Radial/RadialChart.doc.mjs +1 -1
- package/src/RichTextEditor/RichTextEditor.doc.mjs +9 -2
- package/src/RichTextEditor/RichTextEditor.test.tsx +228 -8
- package/src/RichTextEditor/RichTextEditor.tsx +31 -4
- package/src/RichTextEditor/editorTheme.ts +63 -3
- package/src/RichTextEditor/index.ts +1 -0
- package/src/SVGIcon/SVGIcon.doc.mjs +1 -1
- package/src/Sankey/SankeyChart.doc.mjs +1 -1
- package/src/Schedule/Schedule.doc.mjs +1 -1
- package/src/Stat/Stat.doc.mjs +3 -3
- package/src/Stepper/Step.doc.mjs +1 -1
- package/src/Stepper/Step.tsx +1 -1
- package/src/Stepper/Stepper.doc.mjs +3 -3
- package/src/Stepper/Stepper.tsx +1 -1
- package/src/Stepper/StepperContext.ts +1 -1
- package/src/ThreeD/3DBar.doc.mjs +1 -1
- package/src/ThreeD/3DChart.doc.mjs +1 -1
- package/src/ThreeD/3DScatter.doc.mjs +1 -1
- package/src/ThreeD/3DScatterGL.doc.mjs +1 -1
- package/src/ThreeD/3DSurface.doc.mjs +1 -1
- package/src/index.ts +1 -0
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
import { type ReactNode } from 'react';
|
|
23
23
|
import type { BaseProps } from '@astryxdesign/core';
|
|
24
24
|
import type { SizeValue } from '@astryxdesign/core/utils';
|
|
25
|
+
import { type Transformer } from '@lexical/markdown';
|
|
26
|
+
export type { Transformer } from '@lexical/markdown';
|
|
25
27
|
import type { EditorState, Klass, LexicalEditor, LexicalNode } from 'lexical';
|
|
26
28
|
export type RichTextEditorStatusType = 'warning' | 'error' | 'success';
|
|
27
29
|
export type RichTextEditorSize = 'sm' | 'md' | 'lg';
|
|
@@ -106,10 +108,29 @@ export interface RichTextEditorProps extends Omit<BaseProps, 'onChange' | 'defau
|
|
|
106
108
|
plugins?: ReactNode;
|
|
107
109
|
/**
|
|
108
110
|
* Whether to enable Markdown shortcut typing (e.g. `# ` for a heading,
|
|
109
|
-
* `- ` for a list). Uses the
|
|
111
|
+
* `- ` for a list). Uses the `transformers` prop (defaults to the standard
|
|
112
|
+
* `@lexical/markdown` transformers).
|
|
110
113
|
* @default true
|
|
111
114
|
*/
|
|
112
115
|
hasMarkdownShortcuts?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Markdown transformers — the single source of truth for markdown behaviour.
|
|
118
|
+
* Defaults to the standard `@lexical/markdown` `TRANSFORMERS`.
|
|
119
|
+
*
|
|
120
|
+
* The same array drives all three markdown operations in Lexical (see the
|
|
121
|
+
* lexical-playground reference, where one `PLAYGROUND_TRANSFORMERS` array
|
|
122
|
+
* feeds each):
|
|
123
|
+
* - shortcut typing — `registerMarkdownShortcuts` (wired here today)
|
|
124
|
+
* - markdown -> state — `$convertFromMarkdownString` (future import API)
|
|
125
|
+
* - state -> markdown — `$convertToMarkdownString` (future `getMarkdown`)
|
|
126
|
+
*
|
|
127
|
+
* Pass a custom array to support additional node types (e.g. custom
|
|
128
|
+
* transformers layered in via the `nodes` extension point) consistently
|
|
129
|
+
* across all three. Shortcut typing is only applied when
|
|
130
|
+
* `hasMarkdownShortcuts` is true; the array is still the intended input for
|
|
131
|
+
* the serialization APIs added in later phases.
|
|
132
|
+
*/
|
|
133
|
+
transformers?: ReadonlyArray<Transformer>;
|
|
113
134
|
/** Whether to automatically focus the editor on mount. @default false */
|
|
114
135
|
hasAutoFocus?: boolean;
|
|
115
136
|
/**
|
|
@@ -138,7 +159,7 @@ export interface RichTextEditorProps extends Omit<BaseProps, 'onChange' | 'defau
|
|
|
138
159
|
* />
|
|
139
160
|
* ```
|
|
140
161
|
*/
|
|
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;
|
|
162
|
+
export declare function RichTextEditor({ label, isLabelHidden, description, isOptional, isRequired, defaultValue, onChange, placeholder, isReadOnly, isDisabled, status, width, labelTooltip, size: sizeProp, nodes, plugins, hasMarkdownShortcuts, transformers, hasAutoFocus, namespace, xstyle, className, style, ...rest }: RichTextEditorProps): import("react").JSX.Element;
|
|
142
163
|
export declare namespace RichTextEditor {
|
|
143
164
|
var displayName: string;
|
|
144
165
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/RichTextEditor.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/RichTextEditor.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAoC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAgBxE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAkBxD,OAAO,EAAe,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACjE,YAAY,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAKnD,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;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,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,YAA2B,EAC3B,YAAoB,EACpB,SAA2B,EAC3B,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,IAAI,EACR,EAAE,mBAAmB,+BAwHrB;yBAjJe,cAAc"}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* Component Specification Protocol. `lexical` and `@lexical/*` are OPTIONAL peer
|
|
24
24
|
* dependencies — install them to use this component.
|
|
25
25
|
*/
|
|
26
|
-
import { useEffect, useId, useRef } from 'react';
|
|
26
|
+
import { useEffect, useId, useMemo, useRef } from 'react';
|
|
27
27
|
import * as stylex from '@stylexjs/stylex';
|
|
28
28
|
import '@astryxdesign/core/theme/tokens.stylex';
|
|
29
29
|
import { colorVars, spacingVars, typographyVars, typeScaleVars } from '@astryxdesign/core/theme/tokens.stylex';
|
|
@@ -114,6 +114,7 @@ export function RichTextEditor({
|
|
|
114
114
|
nodes,
|
|
115
115
|
plugins,
|
|
116
116
|
hasMarkdownShortcuts = true,
|
|
117
|
+
transformers = TRANSFORMERS,
|
|
117
118
|
hasAutoFocus = false,
|
|
118
119
|
namespace = 'astryx-editor',
|
|
119
120
|
xstyle,
|
|
@@ -133,6 +134,12 @@ export function RichTextEditor({
|
|
|
133
134
|
themeRef.current = sharedEditorTheme();
|
|
134
135
|
}
|
|
135
136
|
const editable = !isReadOnly && !isDisabled;
|
|
137
|
+
|
|
138
|
+
// Stabilize the transformers array so MarkdownShortcutPlugin doesn't
|
|
139
|
+
// re-register on every render. `[...transformers]` would allocate a new
|
|
140
|
+
// array each time; memoize on the prop identity instead. (React Compiler
|
|
141
|
+
// isn't running the transform in this repo, so this isn't auto-memoized.)
|
|
142
|
+
const markdownTransformers = useMemo(() => [...transformers], [transformers]);
|
|
136
143
|
const initialConfig = {
|
|
137
144
|
namespace,
|
|
138
145
|
theme: themeRef.current,
|
|
@@ -189,7 +196,7 @@ export function RichTextEditor({
|
|
|
189
196
|
placeholder: null,
|
|
190
197
|
ErrorBoundary: LexicalErrorBoundary
|
|
191
198
|
}), /*#__PURE__*/_jsx(HistoryPlugin, {}), /*#__PURE__*/_jsx(ListPlugin, {}), /*#__PURE__*/_jsx(LinkPlugin, {}), /*#__PURE__*/_jsx(TabIndentationPlugin, {}), hasMarkdownShortcuts && /*#__PURE__*/_jsx(MarkdownShortcutPlugin, {
|
|
192
|
-
transformers:
|
|
199
|
+
transformers: markdownTransformers
|
|
193
200
|
}), hasAutoFocus && /*#__PURE__*/_jsx(AutoFocusOnMount, {}), onChange && /*#__PURE__*/_jsx(OnChangePlugin, {
|
|
194
201
|
onChange: onChange,
|
|
195
202
|
ignoreHistoryMergeTagChange: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/editorTheme.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"editorTheme.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/editorTheme.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,SAAS,CAAC;AA2GhD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,kBAAkB,CA8CtD"}
|
|
@@ -19,6 +19,24 @@ import { colorVars, spacingVars, radiusVars, typographyVars, typeScaleVars, font
|
|
|
19
19
|
* class-name strings, which `stylex.props(...).className` yields.
|
|
20
20
|
*/
|
|
21
21
|
export function sharedEditorTheme() {
|
|
22
|
+
const ulClass = {
|
|
23
|
+
className: "xsq74q5 x31w388 xtaz4m5 x43c9pm"
|
|
24
|
+
}.className ?? '';
|
|
25
|
+
const olClass = {
|
|
26
|
+
className: "xsq74q5 x31w388 x3yw8vx x43c9pm"
|
|
27
|
+
}.className ?? '';
|
|
28
|
+
const ulDepth2Class = {
|
|
29
|
+
className: "x31w388 x43c9pm x10im51j xrylv2j"
|
|
30
|
+
}.className ?? '';
|
|
31
|
+
const ulDepth3Class = {
|
|
32
|
+
className: "x31w388 x43c9pm x10im51j x152237o"
|
|
33
|
+
}.className ?? '';
|
|
34
|
+
const olDepth2Class = {
|
|
35
|
+
className: "x31w388 x43c9pm x10im51j x1rrqm6h"
|
|
36
|
+
}.className ?? '';
|
|
37
|
+
const olDepth3Class = {
|
|
38
|
+
className: "x31w388 x43c9pm x10im51j x19k9dhg"
|
|
39
|
+
}.className ?? '';
|
|
22
40
|
return {
|
|
23
41
|
paragraph: {
|
|
24
42
|
className: "xsq74q5"
|
|
@@ -38,15 +56,23 @@ export function sharedEditorTheme() {
|
|
|
38
56
|
className: "x1g06x3t xrxpjvj x126nfab xct1zlm x1t7ytsu x14ydlgx xv1l7n4"
|
|
39
57
|
}.className,
|
|
40
58
|
list: {
|
|
41
|
-
ul:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
className: "xsq74q5 x31w388"
|
|
59
|
+
ul: ulClass,
|
|
60
|
+
ol: olClass,
|
|
61
|
+
checklist: {
|
|
62
|
+
className: "xsq74q5 x43c9pm x3ct3a4 x12gdq22"
|
|
46
63
|
}.className,
|
|
47
64
|
listitem: {
|
|
48
|
-
className: "x1yqqeh1"
|
|
49
|
-
}.className
|
|
65
|
+
className: "x1yqqeh1 x1sle589"
|
|
66
|
+
}.className,
|
|
67
|
+
nested: {
|
|
68
|
+
listitem: {
|
|
69
|
+
className: "x1yqqeh1 x1sle589"
|
|
70
|
+
}.className
|
|
71
|
+
},
|
|
72
|
+
// Depth arrays cycle via `depth % length`, so three entries give three
|
|
73
|
+
// distinct nesting levels before repeating (disc→circle→square, etc.).
|
|
74
|
+
ulDepth: [ulClass, ulDepth2Class, ulDepth3Class],
|
|
75
|
+
olDepth: [olClass, olDepth2Class, olDepth3Class]
|
|
50
76
|
},
|
|
51
77
|
link: {
|
|
52
78
|
className: "xjse4m1 x1bvjpef x1ypdohk"
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* SYNC: When modified, update this header and the editor component doc files.
|
|
9
9
|
*/
|
|
10
10
|
export { RichTextEditor } from './RichTextEditor';
|
|
11
|
-
export type { RichTextEditorProps, RichTextEditorStatus, RichTextEditorStatusType, RichTextEditorSize, } from './RichTextEditor';
|
|
11
|
+
export type { RichTextEditorProps, RichTextEditorStatus, RichTextEditorStatusType, RichTextEditorSize, Transformer, } from './RichTextEditor';
|
|
12
12
|
export { RichTextView } from './RichTextView';
|
|
13
13
|
export type { RichTextViewProps } from './RichTextView';
|
|
14
14
|
export { sharedEditorTheme } from './editorTheme';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAChD,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAC,iBAAiB,EAAC,MAAM,eAAe,CAAC"}
|
package/dist/Stepper/Step.js
CHANGED
|
@@ -553,7 +553,7 @@ export function Step({
|
|
|
553
553
|
status: status ?? undefined
|
|
554
554
|
});
|
|
555
555
|
|
|
556
|
-
// ======= ON-TRACK
|
|
556
|
+
// ======= ON-TRACK: indicator is a node on the connector =======
|
|
557
557
|
if (indicatorPosition === 'on-track') {
|
|
558
558
|
// Connector fill is purely progress-based (matches the separated bar):
|
|
559
559
|
// the segment before the indicator is "reached" once we're at/past this
|
|
@@ -50,7 +50,7 @@ export interface StepperProps extends BaseProps<HTMLOListElement> {
|
|
|
50
50
|
* - 'separated': indicator lives in the label row, distinct from the progress
|
|
51
51
|
* bar (the original Astryx layout).
|
|
52
52
|
* - 'on-track': indicator is slotted into the connector line as a node on the
|
|
53
|
-
* track (
|
|
53
|
+
* track (the on-track indicator design).
|
|
54
54
|
* @default 'separated'
|
|
55
55
|
*/
|
|
56
56
|
indicatorPosition?: StepperIndicatorPosition;
|
|
@@ -6,7 +6,7 @@ export type StepperDensity = 'compact' | 'balanced' | 'spacious';
|
|
|
6
6
|
* bar (Astryx's original layout).
|
|
7
7
|
* - 'on-track': indicator is slotted *into* the connector line as a node on the
|
|
8
8
|
* track, with the label beside (vertical) or below (horizontal). Aligns with
|
|
9
|
-
* the
|
|
9
|
+
* the on-track stepper design.
|
|
10
10
|
*/
|
|
11
11
|
export type StepperIndicatorPosition = 'separated' | 'on-track';
|
|
12
12
|
export interface StepperContextValue {
|
|
@@ -20,7 +20,7 @@ import { createContext, use } from 'react';
|
|
|
20
20
|
* bar (Astryx's original layout).
|
|
21
21
|
* - 'on-track': indicator is slotted *into* the connector line as a node on the
|
|
22
22
|
* track, with the label beside (vertical) or below (horizontal). Aligns with
|
|
23
|
-
* the
|
|
23
|
+
* the on-track stepper design.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
export const StepperContext = /*#__PURE__*/createContext(null);
|
package/dist/index.d.ts
CHANGED
|
@@ -27,5 +27,5 @@ export { SankeyChart, type SankeyChartProps, SankeyLink, type SankeyLinkProps, S
|
|
|
27
27
|
export * from './Stepper';
|
|
28
28
|
export * from './CircularProgress';
|
|
29
29
|
export { LogStream, type LogStreamProps, type LogEntry, type LogStreamLevel, } from './LogStream';
|
|
30
|
-
export { RichTextEditor, type RichTextEditorProps, type RichTextEditorStatus, type RichTextEditorStatusType, type RichTextEditorSize, RichTextView, type RichTextViewProps, sharedEditorTheme, } from './RichTextEditor';
|
|
30
|
+
export { RichTextEditor, type RichTextEditorProps, type RichTextEditorStatus, type RichTextEditorStatusType, type RichTextEditorSize, type Transformer, RichTextView, type RichTextViewProps, sharedEditorTheme, } from './RichTextEditor';
|
|
31
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lab.css
CHANGED
|
@@ -111,6 +111,7 @@
|
|
|
111
111
|
.xz51j44:not(#\#):not(#\#){grid-row:3}
|
|
112
112
|
.x33j1x8:not(#\#):not(#\#){grid-row:var(--x-gridRow)}
|
|
113
113
|
.x17y0mx6:not(#\#):not(#\#){inset-inline:0}
|
|
114
|
+
.x10im51j:not(#\#):not(#\#){margin-block:0}
|
|
114
115
|
.x1yqqeh1:not(#\#):not(#\#){margin-block:var(--spacing-0-5)}
|
|
115
116
|
.xsq74q5:not(#\#):not(#\#){margin-block:var(--spacing-1)}
|
|
116
117
|
.x1g06x3t:not(#\#):not(#\#){margin-block:var(--spacing-2)}
|
|
@@ -370,7 +371,15 @@
|
|
|
370
371
|
.x1cpk1wn:not(#\#):not(#\#):not(#\#){line-height:var(--text-heading-2-leading)}
|
|
371
372
|
.x1kq96og:not(#\#):not(#\#):not(#\#){line-height:var(--text-label-leading)}
|
|
372
373
|
.x1ltkj2j:not(#\#):not(#\#):not(#\#){line-height:var(--text-supporting-leading)}
|
|
374
|
+
.x43c9pm:not(#\#):not(#\#):not(#\#){list-style-position:outside}
|
|
375
|
+
.xrylv2j:not(#\#):not(#\#):not(#\#){list-style-type:circle}
|
|
376
|
+
.x3yw8vx:not(#\#):not(#\#):not(#\#){list-style-type:decimal}
|
|
377
|
+
.xtaz4m5:not(#\#):not(#\#):not(#\#){list-style-type:disc}
|
|
378
|
+
.x1sle589:not(#\#):not(#\#):not(#\#){list-style-type:inherit}
|
|
379
|
+
.x1rrqm6h:not(#\#):not(#\#):not(#\#){list-style-type:lower-alpha}
|
|
380
|
+
.x19k9dhg:not(#\#):not(#\#):not(#\#){list-style-type:lower-roman}
|
|
373
381
|
.x3ct3a4:not(#\#):not(#\#):not(#\#){list-style-type:none}
|
|
382
|
+
.x152237o:not(#\#):not(#\#):not(#\#){list-style-type:square}
|
|
374
383
|
.x1h1dc9q:not(#\#):not(#\#):not(#\#){margin-inline-end:calc(var(--spacing-0-5) + var(--border-width))}
|
|
375
384
|
.xhi58n4:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(var(--spacing-1) * -1)}
|
|
376
385
|
.xladpz9:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--spacing-0-5)}
|
|
@@ -389,6 +398,7 @@
|
|
|
389
398
|
.xmarwi5:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--icon-inline-offset)}
|
|
390
399
|
.x18gyask:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-0)}
|
|
391
400
|
.x1vsv5vr:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-1)}
|
|
401
|
+
.x12gdq22:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-2)}
|
|
392
402
|
.x126nfab:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-3)}
|
|
393
403
|
.x1rey3nv:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-4)}
|
|
394
404
|
.x31w388:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-6)}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/lab",
|
|
3
|
-
"version": "0.1.9-canary.
|
|
3
|
+
"version": "0.1.9-canary.b7d7f4b",
|
|
4
4
|
"description": "Experimental Astryx components — published to npm only under the @canary dist-tag for early testing; never released as a stable (latest) version.",
|
|
5
5
|
"author": "Meta Open Source",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@stylexjs/stylex": ">=0.10.0",
|
|
48
|
-
"@astryxdesign/core": "0.1.9-canary.
|
|
48
|
+
"@astryxdesign/core": "0.1.9-canary.b7d7f4b",
|
|
49
49
|
"react": ">=19.0.0",
|
|
50
50
|
"react-dom": ">=19.0.0",
|
|
51
51
|
"lexical": "^0.46.0",
|
|
@@ -109,6 +109,7 @@
|
|
|
109
109
|
"test": "vitest run --root ../..",
|
|
110
110
|
"test:watch": "vitest --root ../..",
|
|
111
111
|
"lint": "eslint src",
|
|
112
|
+
"typecheck:docs": "tsc --project tsconfig.docs.json",
|
|
112
113
|
"typecheck": "tsc --project tsconfig.json --noEmit"
|
|
113
114
|
}
|
|
114
115
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
/** @type {import('
|
|
2
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
3
3
|
|
|
4
4
|
export const docs = {
|
|
5
5
|
name: 'Drawer',
|
|
@@ -123,7 +123,7 @@ const [lineItem, setLineItem] = useState(null);
|
|
|
123
123
|
],
|
|
124
124
|
};
|
|
125
125
|
|
|
126
|
-
/** @type {import('
|
|
126
|
+
/** @type {import('../../../core/src/docs-types').TranslationDoc} */
|
|
127
127
|
export const docsZh = {
|
|
128
128
|
usage: {
|
|
129
129
|
description: '用于检查器、详情视图和面板的边缘浮层——"点击表格行查看详情"的模式。按 Escape 关闭抽屉,焦点返回到打开它的元素。滑入/滑出动画遵循 prefers-reduced-motion。堆叠约定:同级抽屉后开的在上层,Escape 只关闭最上层的,关闭顺序由内向外——请以同级方式渲染,切勿嵌套。',
|
|
@@ -139,7 +139,7 @@ export const docsZh = {
|
|
|
139
139
|
},
|
|
140
140
|
};
|
|
141
141
|
|
|
142
|
-
/** @type {import('
|
|
142
|
+
/** @type {import('../../../core/src/docs-types').TranslationDoc} */
|
|
143
143
|
export const docsDense = {
|
|
144
144
|
description: 'edge-anchored overlay (native <dialog>): start/end side panel or top/bottom sheet',
|
|
145
145
|
usage: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
/** @type {import('
|
|
3
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
4
4
|
|
|
5
5
|
export const docs = {
|
|
6
6
|
name: 'InfoTip',
|
|
@@ -39,7 +39,7 @@ export const docs = {
|
|
|
39
39
|
},
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
/** @type {import('
|
|
42
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
43
43
|
export const docsZh = {
|
|
44
44
|
name: 'InfoTip',
|
|
45
45
|
displayName: 'Info Tip',
|
|
@@ -75,7 +75,7 @@ export const docsZh = {
|
|
|
75
75
|
},
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
/** @type {import('
|
|
78
|
+
/** @type {import('../../../core/src/docs-types').TranslationDoc} */
|
|
79
79
|
export const docsDense = {
|
|
80
80
|
description:
|
|
81
81
|
'Inline info-icon help affordance: accessible "i" button trigger pre-wired into a Tooltip.',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
/** @type {import('
|
|
3
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
4
4
|
|
|
5
5
|
export const docs = {
|
|
6
6
|
name: 'RichTextEditor',
|
|
@@ -93,9 +93,16 @@ export const docs = {
|
|
|
93
93
|
name: 'hasMarkdownShortcuts',
|
|
94
94
|
type: 'boolean',
|
|
95
95
|
description:
|
|
96
|
-
'Enable Markdown shortcut typing (e.g. "# " for a heading). Uses
|
|
96
|
+
'Enable Markdown shortcut typing (e.g. "# " for a heading). Uses the transformers prop (defaults to the standard @lexical/markdown transformers).',
|
|
97
97
|
default: 'true',
|
|
98
98
|
},
|
|
99
|
+
{
|
|
100
|
+
name: 'transformers',
|
|
101
|
+
type: 'ReadonlyArray<Transformer>',
|
|
102
|
+
description:
|
|
103
|
+
'Markdown transformers — the single source of truth for markdown behaviour. Defaults to the standard @lexical/markdown TRANSFORMERS. In Lexical the same array drives all three markdown operations (shortcut typing, markdown->state import, state->markdown export); this prop wires shortcut typing today and is the intended input for the serialization APIs added in later phases. Pass a custom array to support additional node types (e.g. transformers layered in via the nodes extension point) consistently across all three. Shortcut typing is only applied when hasMarkdownShortcuts is true.',
|
|
104
|
+
default: 'TRANSFORMERS',
|
|
105
|
+
},
|
|
99
106
|
{
|
|
100
107
|
name: 'hasAutoFocus',
|
|
101
108
|
type: 'boolean',
|
|
@@ -16,11 +16,132 @@ import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
|
|
|
16
16
|
import type {LexicalEditor} from 'lexical';
|
|
17
17
|
import {$getRoot, $createParagraphNode, $createTextNode} from 'lexical';
|
|
18
18
|
import {HeadingNode} from '@lexical/rich-text';
|
|
19
|
+
import {
|
|
20
|
+
TRANSFORMERS,
|
|
21
|
+
$convertFromMarkdownString,
|
|
22
|
+
} from '@lexical/markdown';
|
|
19
23
|
import {RichTextEditor} from './RichTextEditor';
|
|
20
24
|
import {RichTextView} from './RichTextView';
|
|
21
25
|
|
|
26
|
+
// Small plugin that captures the editor instance so tests can drive real
|
|
27
|
+
// Lexical updates (jsdom does not implement contenteditable editing).
|
|
28
|
+
function CaptureEditor({
|
|
29
|
+
onReady,
|
|
30
|
+
}: {
|
|
31
|
+
onReady: (editor: LexicalEditor) => void;
|
|
32
|
+
}) {
|
|
33
|
+
const [editor] = useLexicalComposerContext();
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
onReady(editor);
|
|
36
|
+
}, [editor, onReady]);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
22
40
|
// A minimal valid serialized Lexical editor state containing a single
|
|
23
41
|
// paragraph with the text "Hello world".
|
|
42
|
+
// Builds a serialized Lexical state containing a list. `listType` is
|
|
43
|
+
// 'bullet' (renders <ul>) or 'number' (renders <ol>). Used to verify that the
|
|
44
|
+
// editor theme applies visible list markers rather than bare indentation.
|
|
45
|
+
function makeListState(listType: 'bullet' | 'number'): string {
|
|
46
|
+
const tag = listType === 'number' ? 'ol' : 'ul';
|
|
47
|
+
return JSON.stringify({
|
|
48
|
+
root: {
|
|
49
|
+
children: [
|
|
50
|
+
{
|
|
51
|
+
children: [
|
|
52
|
+
{
|
|
53
|
+
children: [
|
|
54
|
+
{
|
|
55
|
+
detail: 0,
|
|
56
|
+
format: 0,
|
|
57
|
+
mode: 'normal',
|
|
58
|
+
style: '',
|
|
59
|
+
text: 'Item one',
|
|
60
|
+
type: 'text',
|
|
61
|
+
version: 1,
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
direction: 'ltr',
|
|
65
|
+
format: '',
|
|
66
|
+
indent: 0,
|
|
67
|
+
type: 'listitem',
|
|
68
|
+
version: 1,
|
|
69
|
+
value: 1,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
direction: 'ltr',
|
|
73
|
+
format: '',
|
|
74
|
+
indent: 0,
|
|
75
|
+
type: 'list',
|
|
76
|
+
version: 1,
|
|
77
|
+
listType,
|
|
78
|
+
start: 1,
|
|
79
|
+
tag,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
direction: 'ltr',
|
|
83
|
+
format: '',
|
|
84
|
+
indent: 0,
|
|
85
|
+
type: 'root',
|
|
86
|
+
version: 1,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Builds a serialized Lexical state with a two-level nested bullet list:
|
|
92
|
+
// • Item one
|
|
93
|
+
// ◦ Nested item
|
|
94
|
+
// Lexical models nesting as a child `list` node inside a `listitem`. Used to
|
|
95
|
+
// verify that depth-2 markers differ from depth-1 (disc → circle) rather than
|
|
96
|
+
// falling back to bare indentation.
|
|
97
|
+
function makeNestedBulletState(): string {
|
|
98
|
+
const textNode = (text: string) => ({
|
|
99
|
+
detail: 0,
|
|
100
|
+
format: 0,
|
|
101
|
+
mode: 'normal',
|
|
102
|
+
style: '',
|
|
103
|
+
text,
|
|
104
|
+
type: 'text',
|
|
105
|
+
version: 1,
|
|
106
|
+
});
|
|
107
|
+
const listItem = (children: unknown[], value: number) => ({
|
|
108
|
+
children,
|
|
109
|
+
direction: 'ltr',
|
|
110
|
+
format: '',
|
|
111
|
+
indent: 0,
|
|
112
|
+
type: 'listitem',
|
|
113
|
+
version: 1,
|
|
114
|
+
value,
|
|
115
|
+
});
|
|
116
|
+
const bulletList = (children: unknown[]) => ({
|
|
117
|
+
children,
|
|
118
|
+
direction: 'ltr',
|
|
119
|
+
format: '',
|
|
120
|
+
indent: 0,
|
|
121
|
+
type: 'list',
|
|
122
|
+
version: 1,
|
|
123
|
+
listType: 'bullet',
|
|
124
|
+
start: 1,
|
|
125
|
+
tag: 'ul',
|
|
126
|
+
});
|
|
127
|
+
return JSON.stringify({
|
|
128
|
+
root: {
|
|
129
|
+
children: [
|
|
130
|
+
bulletList([
|
|
131
|
+
listItem([textNode('Item one')], 1),
|
|
132
|
+
// A nested list lives inside its own list item wrapper.
|
|
133
|
+
listItem([bulletList([listItem([textNode('Nested item')], 1)])], 2),
|
|
134
|
+
]),
|
|
135
|
+
],
|
|
136
|
+
direction: 'ltr',
|
|
137
|
+
format: '',
|
|
138
|
+
indent: 0,
|
|
139
|
+
type: 'root',
|
|
140
|
+
version: 1,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
24
145
|
const HELLO_STATE = JSON.stringify({
|
|
25
146
|
root: {
|
|
26
147
|
children: [
|
|
@@ -112,19 +233,12 @@ describe('RichTextEditor', () => {
|
|
|
112
233
|
// instance via a small capture plugin and drive a real Lexical update,
|
|
113
234
|
// then assert onChange fires.
|
|
114
235
|
let editorRef: LexicalEditor | undefined;
|
|
115
|
-
function CaptureEditor() {
|
|
116
|
-
const [editor] = useLexicalComposerContext();
|
|
117
|
-
useEffect(() => {
|
|
118
|
-
editorRef = editor;
|
|
119
|
-
}, [editor]);
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
236
|
const onChange = vi.fn();
|
|
123
237
|
render(
|
|
124
238
|
<RichTextEditor
|
|
125
239
|
label="Notes"
|
|
126
240
|
onChange={onChange}
|
|
127
|
-
plugins={<CaptureEditor />}
|
|
241
|
+
plugins={<CaptureEditor onReady={e => (editorRef = e)} />}
|
|
128
242
|
/>,
|
|
129
243
|
);
|
|
130
244
|
await waitFor(() => expect(editorRef).toBeDefined());
|
|
@@ -155,6 +269,70 @@ describe('RichTextEditor', () => {
|
|
|
155
269
|
);
|
|
156
270
|
expect(screen.getByTestId('custom-plugin')).toBeInTheDocument();
|
|
157
271
|
});
|
|
272
|
+
|
|
273
|
+
it('accepts a custom transformers array without throwing', () => {
|
|
274
|
+
// Empty transformer set is a valid custom configuration (disables all
|
|
275
|
+
// markdown shortcuts while keeping the plugin mounted).
|
|
276
|
+
render(<RichTextEditor label="Notes" transformers={[]} />);
|
|
277
|
+
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('renders when markdown shortcuts are disabled', () => {
|
|
281
|
+
render(<RichTextEditor label="Notes" hasMarkdownShortcuts={false} />);
|
|
282
|
+
expect(screen.getByRole('textbox')).toBeInTheDocument();
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it('applies the default transformers to convert markdown to a heading', async () => {
|
|
286
|
+
// jsdom can't dispatch the keystrokes that trigger registerMarkdownShortcuts
|
|
287
|
+
// live, so we drive $convertFromMarkdownString with the same TRANSFORMERS
|
|
288
|
+
// the component registers by default. This proves the default transformer
|
|
289
|
+
// set actually produces the expected node structure (a heading), rather
|
|
290
|
+
// than only asserting the editor mounts.
|
|
291
|
+
let editorRef: LexicalEditor | undefined;
|
|
292
|
+
render(
|
|
293
|
+
<RichTextEditor
|
|
294
|
+
label="Notes"
|
|
295
|
+
plugins={<CaptureEditor onReady={e => (editorRef = e)} />}
|
|
296
|
+
/>,
|
|
297
|
+
);
|
|
298
|
+
await waitFor(() => expect(editorRef).toBeDefined());
|
|
299
|
+
editorRef!.update(() => {
|
|
300
|
+
$convertFromMarkdownString('# Title', TRANSFORMERS);
|
|
301
|
+
});
|
|
302
|
+
await waitFor(() => {
|
|
303
|
+
editorRef!.getEditorState().read(() => {
|
|
304
|
+
const first = $getRoot().getFirstChild();
|
|
305
|
+
expect(first?.getType()).toBe('heading');
|
|
306
|
+
expect(first?.getTextContent()).toBe('Title');
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('leaves markdown untransformed when given an empty transformers array', async () => {
|
|
312
|
+
// With no transformers, the same markdown text stays a plain paragraph —
|
|
313
|
+
// demonstrating the transformers prop is the effective source of truth for
|
|
314
|
+
// markdown behaviour, not a fixed internal default.
|
|
315
|
+
let editorRef: LexicalEditor | undefined;
|
|
316
|
+
render(
|
|
317
|
+
<RichTextEditor
|
|
318
|
+
label="Notes"
|
|
319
|
+
transformers={[]}
|
|
320
|
+
plugins={<CaptureEditor onReady={e => (editorRef = e)} />}
|
|
321
|
+
/>,
|
|
322
|
+
);
|
|
323
|
+
await waitFor(() => expect(editorRef).toBeDefined());
|
|
324
|
+
editorRef!.update(() => {
|
|
325
|
+
// Empty transformer set: markdown syntax is preserved verbatim.
|
|
326
|
+
$convertFromMarkdownString('# Title', []);
|
|
327
|
+
});
|
|
328
|
+
await waitFor(() => {
|
|
329
|
+
editorRef!.getEditorState().read(() => {
|
|
330
|
+
const first = $getRoot().getFirstChild();
|
|
331
|
+
expect(first?.getType()).toBe('paragraph');
|
|
332
|
+
expect(first?.getTextContent()).toBe('# Title');
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
});
|
|
158
336
|
});
|
|
159
337
|
|
|
160
338
|
describe('RichTextView', () => {
|
|
@@ -213,6 +391,48 @@ describe('RichTextView', () => {
|
|
|
213
391
|
expect(screen.queryByRole('textbox')).not.toBeInTheDocument();
|
|
214
392
|
});
|
|
215
393
|
|
|
394
|
+
it('renders bullet lists with a disc marker (not bare indentation)', async () => {
|
|
395
|
+
const {container} = render(<RichTextView value={makeListState('bullet')} />);
|
|
396
|
+
await waitFor(() =>
|
|
397
|
+
expect(screen.getByText('Item one')).toBeInTheDocument(),
|
|
398
|
+
);
|
|
399
|
+
const ul = container.querySelector('ul');
|
|
400
|
+
expect(ul).not.toBeNull();
|
|
401
|
+
// The theme must give the <ul> a marker class so the browser draws a
|
|
402
|
+
// bullet. A bare list with only padding would show indentation only —
|
|
403
|
+
// the exact bug this guards against.
|
|
404
|
+
expect(ul?.className.trim()).not.toBe('');
|
|
405
|
+
expect(getComputedStyle(ul as Element).listStyleType).toBe('disc');
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('renders numbered lists with a decimal marker (not bare indentation)', async () => {
|
|
409
|
+
const {container} = render(<RichTextView value={makeListState('number')} />);
|
|
410
|
+
await waitFor(() =>
|
|
411
|
+
expect(screen.getByText('Item one')).toBeInTheDocument(),
|
|
412
|
+
);
|
|
413
|
+
const ol = container.querySelector('ol');
|
|
414
|
+
expect(ol).not.toBeNull();
|
|
415
|
+
expect(ol?.className.trim()).not.toBe('');
|
|
416
|
+
expect(getComputedStyle(ol as Element).listStyleType).toBe('decimal');
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it('renders nested bullet lists with a distinct depth-2 marker (circle)', async () => {
|
|
420
|
+
const {container} = render(
|
|
421
|
+
<RichTextView value={makeNestedBulletState()} />,
|
|
422
|
+
);
|
|
423
|
+
await waitFor(() =>
|
|
424
|
+
expect(screen.getByText('Nested item')).toBeInTheDocument(),
|
|
425
|
+
);
|
|
426
|
+
const lists = container.querySelectorAll('ul');
|
|
427
|
+
// Outer <ul> plus the nested <ul>.
|
|
428
|
+
expect(lists.length).toBe(2);
|
|
429
|
+
const [outer, nested] = lists;
|
|
430
|
+
expect(getComputedStyle(outer).listStyleType).toBe('disc');
|
|
431
|
+
// Depth-2 must cycle to a different marker so nesting is visually legible,
|
|
432
|
+
// matching the native browser disc → circle progression.
|
|
433
|
+
expect(getComputedStyle(nested).listStyleType).toBe('circle');
|
|
434
|
+
});
|
|
435
|
+
|
|
216
436
|
it('renders nothing (no crash) on malformed JSON with no fallback', () => {
|
|
217
437
|
expect(() => render(<RichTextView value={'garbage'} />)).not.toThrow();
|
|
218
438
|
expect(screen.queryByRole('textbox')).not.toBeInTheDocument();
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* dependencies — install them to use this component.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import {useEffect, useId, useRef, type ReactNode} from 'react';
|
|
27
|
+
import {useEffect, useId, useMemo, useRef, type ReactNode} from 'react';
|
|
28
28
|
import * as stylex from '@stylexjs/stylex';
|
|
29
29
|
import {
|
|
30
30
|
colorVars,
|
|
@@ -59,7 +59,8 @@ import {LinkPlugin} from '@lexical/react/LexicalLinkPlugin';
|
|
|
59
59
|
import {TabIndentationPlugin} from '@lexical/react/LexicalTabIndentationPlugin';
|
|
60
60
|
import {MarkdownShortcutPlugin} from '@lexical/react/LexicalMarkdownShortcutPlugin';
|
|
61
61
|
import {OnChangePlugin} from '@lexical/react/LexicalOnChangePlugin';
|
|
62
|
-
import {TRANSFORMERS} from '@lexical/markdown';
|
|
62
|
+
import {TRANSFORMERS, type Transformer} from '@lexical/markdown';
|
|
63
|
+
export type {Transformer} from '@lexical/markdown';
|
|
63
64
|
import {ListNode, ListItemNode} from '@lexical/list';
|
|
64
65
|
import {HeadingNode, QuoteNode} from '@lexical/rich-text';
|
|
65
66
|
import {LinkNode, AutoLinkNode} from '@lexical/link';
|
|
@@ -224,10 +225,29 @@ export interface RichTextEditorProps extends Omit<
|
|
|
224
225
|
plugins?: ReactNode;
|
|
225
226
|
/**
|
|
226
227
|
* Whether to enable Markdown shortcut typing (e.g. `# ` for a heading,
|
|
227
|
-
* `- ` for a list). Uses the
|
|
228
|
+
* `- ` for a list). Uses the `transformers` prop (defaults to the standard
|
|
229
|
+
* `@lexical/markdown` transformers).
|
|
228
230
|
* @default true
|
|
229
231
|
*/
|
|
230
232
|
hasMarkdownShortcuts?: boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Markdown transformers — the single source of truth for markdown behaviour.
|
|
235
|
+
* Defaults to the standard `@lexical/markdown` `TRANSFORMERS`.
|
|
236
|
+
*
|
|
237
|
+
* The same array drives all three markdown operations in Lexical (see the
|
|
238
|
+
* lexical-playground reference, where one `PLAYGROUND_TRANSFORMERS` array
|
|
239
|
+
* feeds each):
|
|
240
|
+
* - shortcut typing — `registerMarkdownShortcuts` (wired here today)
|
|
241
|
+
* - markdown -> state — `$convertFromMarkdownString` (future import API)
|
|
242
|
+
* - state -> markdown — `$convertToMarkdownString` (future `getMarkdown`)
|
|
243
|
+
*
|
|
244
|
+
* Pass a custom array to support additional node types (e.g. custom
|
|
245
|
+
* transformers layered in via the `nodes` extension point) consistently
|
|
246
|
+
* across all three. Shortcut typing is only applied when
|
|
247
|
+
* `hasMarkdownShortcuts` is true; the array is still the intended input for
|
|
248
|
+
* the serialization APIs added in later phases.
|
|
249
|
+
*/
|
|
250
|
+
transformers?: ReadonlyArray<Transformer>;
|
|
231
251
|
/** Whether to automatically focus the editor on mount. @default false */
|
|
232
252
|
hasAutoFocus?: boolean;
|
|
233
253
|
/**
|
|
@@ -275,6 +295,7 @@ export function RichTextEditor({
|
|
|
275
295
|
nodes,
|
|
276
296
|
plugins,
|
|
277
297
|
hasMarkdownShortcuts = true,
|
|
298
|
+
transformers = TRANSFORMERS,
|
|
278
299
|
hasAutoFocus = false,
|
|
279
300
|
namespace = 'astryx-editor',
|
|
280
301
|
xstyle,
|
|
@@ -296,6 +317,12 @@ export function RichTextEditor({
|
|
|
296
317
|
|
|
297
318
|
const editable = !isReadOnly && !isDisabled;
|
|
298
319
|
|
|
320
|
+
// Stabilize the transformers array so MarkdownShortcutPlugin doesn't
|
|
321
|
+
// re-register on every render. `[...transformers]` would allocate a new
|
|
322
|
+
// array each time; memoize on the prop identity instead. (React Compiler
|
|
323
|
+
// isn't running the transform in this repo, so this isn't auto-memoized.)
|
|
324
|
+
const markdownTransformers = useMemo(() => [...transformers], [transformers]);
|
|
325
|
+
|
|
299
326
|
const initialConfig: InitialConfigType = {
|
|
300
327
|
namespace,
|
|
301
328
|
theme: themeRef.current,
|
|
@@ -379,7 +406,7 @@ export function RichTextEditor({
|
|
|
379
406
|
<LinkPlugin />
|
|
380
407
|
<TabIndentationPlugin />
|
|
381
408
|
{hasMarkdownShortcuts && (
|
|
382
|
-
<MarkdownShortcutPlugin transformers={
|
|
409
|
+
<MarkdownShortcutPlugin transformers={markdownTransformers} />
|
|
383
410
|
)}
|
|
384
411
|
{hasAutoFocus && <AutoFocusOnMount />}
|
|
385
412
|
{onChange && (
|
|
@@ -53,12 +53,50 @@ const editorTheme = stylex.create({
|
|
|
53
53
|
borderInlineStartColor: colorVars['--color-border-emphasized'],
|
|
54
54
|
color: colorVars['--color-text-secondary'],
|
|
55
55
|
},
|
|
56
|
-
|
|
56
|
+
ul: {
|
|
57
57
|
marginBlock: spacingVars['--spacing-1'],
|
|
58
58
|
paddingInlineStart: spacingVars['--spacing-6'],
|
|
59
|
+
listStyleType: 'disc',
|
|
60
|
+
listStylePosition: 'outside',
|
|
61
|
+
},
|
|
62
|
+
ol: {
|
|
63
|
+
marginBlock: spacingVars['--spacing-1'],
|
|
64
|
+
paddingInlineStart: spacingVars['--spacing-6'],
|
|
65
|
+
listStyleType: 'decimal',
|
|
66
|
+
listStylePosition: 'outside',
|
|
67
|
+
},
|
|
68
|
+
// Nested lists: no extra vertical margin, and cycle marker styles per depth
|
|
69
|
+
// to match native browser list nesting. Lexical indexes ulDepth/olDepth by
|
|
70
|
+
// `depth % array.length`, so three entries give three distinct levels that
|
|
71
|
+
// then repeat — matching the browser default disc → circle → square cycle.
|
|
72
|
+
ulNested: {
|
|
73
|
+
marginBlock: 0,
|
|
74
|
+
},
|
|
75
|
+
ulDepth2: {
|
|
76
|
+
listStyleType: 'circle',
|
|
77
|
+
},
|
|
78
|
+
ulDepth3: {
|
|
79
|
+
listStyleType: 'square',
|
|
80
|
+
},
|
|
81
|
+
olNested: {
|
|
82
|
+
marginBlock: 0,
|
|
83
|
+
},
|
|
84
|
+
olDepth2: {
|
|
85
|
+
listStyleType: 'lower-alpha',
|
|
86
|
+
},
|
|
87
|
+
olDepth3: {
|
|
88
|
+
listStyleType: 'lower-roman',
|
|
89
|
+
},
|
|
90
|
+
// Checklists render as a <ul listtype="check">; Lexical draws checkbox
|
|
91
|
+
// affordances on the list items, so suppress the disc marker here.
|
|
92
|
+
checklist: {
|
|
93
|
+
listStyleType: 'none',
|
|
94
|
+
paddingInlineStart: spacingVars['--spacing-2'],
|
|
59
95
|
},
|
|
60
96
|
listItem: {
|
|
61
97
|
marginBlock: spacingVars['--spacing-0-5'],
|
|
98
|
+
// Ensure the marker is shown (some CSS resets set list-style: none on li).
|
|
99
|
+
listStyleType: 'inherit',
|
|
62
100
|
},
|
|
63
101
|
link: {
|
|
64
102
|
color: colorVars['--color-text-accent'],
|
|
@@ -94,6 +132,20 @@ const editorTheme = stylex.create({
|
|
|
94
132
|
* class-name strings, which `stylex.props(...).className` yields.
|
|
95
133
|
*/
|
|
96
134
|
export function sharedEditorTheme(): EditorThemeClasses {
|
|
135
|
+
const ulClass = stylex.props(editorTheme.ul).className ?? '';
|
|
136
|
+
const olClass = stylex.props(editorTheme.ol).className ?? '';
|
|
137
|
+
const ulDepth2Class =
|
|
138
|
+
stylex.props(editorTheme.ul, editorTheme.ulNested, editorTheme.ulDepth2)
|
|
139
|
+
.className ?? '';
|
|
140
|
+
const ulDepth3Class =
|
|
141
|
+
stylex.props(editorTheme.ul, editorTheme.ulNested, editorTheme.ulDepth3)
|
|
142
|
+
.className ?? '';
|
|
143
|
+
const olDepth2Class =
|
|
144
|
+
stylex.props(editorTheme.ol, editorTheme.olNested, editorTheme.olDepth2)
|
|
145
|
+
.className ?? '';
|
|
146
|
+
const olDepth3Class =
|
|
147
|
+
stylex.props(editorTheme.ol, editorTheme.olNested, editorTheme.olDepth3)
|
|
148
|
+
.className ?? '';
|
|
97
149
|
return {
|
|
98
150
|
paragraph: stylex.props(editorTheme.paragraph).className,
|
|
99
151
|
heading: {
|
|
@@ -103,9 +155,17 @@ export function sharedEditorTheme(): EditorThemeClasses {
|
|
|
103
155
|
},
|
|
104
156
|
quote: stylex.props(editorTheme.quote).className,
|
|
105
157
|
list: {
|
|
106
|
-
ul:
|
|
107
|
-
ol:
|
|
158
|
+
ul: ulClass,
|
|
159
|
+
ol: olClass,
|
|
160
|
+
checklist: stylex.props(editorTheme.ul, editorTheme.checklist).className,
|
|
108
161
|
listitem: stylex.props(editorTheme.listItem).className,
|
|
162
|
+
nested: {
|
|
163
|
+
listitem: stylex.props(editorTheme.listItem).className,
|
|
164
|
+
},
|
|
165
|
+
// Depth arrays cycle via `depth % length`, so three entries give three
|
|
166
|
+
// distinct nesting levels before repeating (disc→circle→square, etc.).
|
|
167
|
+
ulDepth: [ulClass, ulDepth2Class, ulDepth3Class],
|
|
168
|
+
olDepth: [olClass, olDepth2Class, olDepth3Class],
|
|
109
169
|
},
|
|
110
170
|
link: stylex.props(editorTheme.link).className,
|
|
111
171
|
text: {
|
package/src/Stat/Stat.doc.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
/** @type {import('
|
|
3
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
4
4
|
|
|
5
5
|
export const docs = {
|
|
6
6
|
name: 'Stat',
|
|
@@ -70,7 +70,7 @@ export const docs = {
|
|
|
70
70
|
},
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
/** @type {import('
|
|
73
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
74
74
|
export const docsZh = {
|
|
75
75
|
name: 'Stat',
|
|
76
76
|
displayName: 'Stat',
|
|
@@ -136,7 +136,7 @@ export const docsZh = {
|
|
|
136
136
|
},
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
-
/** @type {import('
|
|
139
|
+
/** @type {import('../../../core/src/docs-types').TranslationDoc} */
|
|
140
140
|
export const docsDense = {
|
|
141
141
|
description: 'KPI/metric display: label, large tabular-nums value, sentiment-aware delta, and trend media slot.',
|
|
142
142
|
usage: {
|
package/src/Stepper/Step.doc.mjs
CHANGED
package/src/Stepper/Step.tsx
CHANGED
|
@@ -871,7 +871,7 @@ export function Step({
|
|
|
871
871
|
status: status ?? undefined,
|
|
872
872
|
});
|
|
873
873
|
|
|
874
|
-
// ======= ON-TRACK
|
|
874
|
+
// ======= ON-TRACK: indicator is a node on the connector =======
|
|
875
875
|
if (indicatorPosition === 'on-track') {
|
|
876
876
|
// Connector fill is purely progress-based (matches the separated bar):
|
|
877
877
|
// the segment before the indicator is "reached" once we're at/past this
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
/** @type {import('
|
|
3
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
4
4
|
|
|
5
5
|
export const docs = {
|
|
6
6
|
name: 'Stepper',
|
|
@@ -159,7 +159,7 @@ export const docs = {
|
|
|
159
159
|
},
|
|
160
160
|
};
|
|
161
161
|
|
|
162
|
-
/** @type {import('
|
|
162
|
+
/** @type {import('../../../core/src/docs-types').TranslationDoc} */
|
|
163
163
|
export const docsDense = {
|
|
164
164
|
description: 'numbered step sequence for multi-step workflows',
|
|
165
165
|
usage: {
|
|
@@ -206,7 +206,7 @@ export const docsDense = {
|
|
|
206
206
|
],
|
|
207
207
|
};
|
|
208
208
|
|
|
209
|
-
/** @type {import('
|
|
209
|
+
/** @type {import('../../../core/src/docs-types').ComponentDoc} */
|
|
210
210
|
export const docsZh = {
|
|
211
211
|
name: 'Stepper',
|
|
212
212
|
displayName: 'Stepper',
|
package/src/Stepper/Stepper.tsx
CHANGED
|
@@ -66,7 +66,7 @@ export interface StepperProps extends BaseProps<HTMLOListElement> {
|
|
|
66
66
|
* - 'separated': indicator lives in the label row, distinct from the progress
|
|
67
67
|
* bar (the original Astryx layout).
|
|
68
68
|
* - 'on-track': indicator is slotted into the connector line as a node on the
|
|
69
|
-
* track (
|
|
69
|
+
* track (the on-track indicator design).
|
|
70
70
|
* @default 'separated'
|
|
71
71
|
*/
|
|
72
72
|
indicatorPosition?: StepperIndicatorPosition;
|
|
@@ -24,7 +24,7 @@ export type StepperDensity = 'compact' | 'balanced' | 'spacious';
|
|
|
24
24
|
* bar (Astryx's original layout).
|
|
25
25
|
* - 'on-track': indicator is slotted *into* the connector line as a node on the
|
|
26
26
|
* track, with the label beside (vertical) or below (horizontal). Aligns with
|
|
27
|
-
* the
|
|
27
|
+
* the on-track stepper design.
|
|
28
28
|
*/
|
|
29
29
|
export type StepperIndicatorPosition = 'separated' | 'on-track';
|
|
30
30
|
|
package/src/ThreeD/3DBar.doc.mjs
CHANGED