@blue-patterns/richtext 0.0.0-stage → 0.7.18
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 +275 -0
- package/LICENSE +22 -0
- package/README.md +88 -2
- package/astryx.integration.mjs +11 -0
- package/blocks/RichTextEditorShowcase.template.mjs +13 -0
- package/blocks/RichTextEditorShowcase.tsx +19 -0
- package/dist/RichTextEditor.d.ts +282 -0
- package/dist/RichTextEditor.d.ts.map +1 -0
- package/dist/RichTextEditor.js +657 -0
- package/dist/RichTextEditorAutoLinkPlugin.d.ts +83 -0
- package/dist/RichTextEditorAutoLinkPlugin.d.ts.map +1 -0
- package/dist/RichTextEditorAutoLinkPlugin.js +99 -0
- package/dist/RichTextEditorToolbar.d.ts +186 -0
- package/dist/RichTextEditorToolbar.d.ts.map +1 -0
- package/dist/RichTextEditorToolbar.js +688 -0
- package/dist/RichTextView.d.ts +92 -0
- package/dist/RichTextView.d.ts.map +1 -0
- package/dist/RichTextView.js +267 -0
- package/dist/codeLanguages.d.ts +14 -0
- package/dist/codeLanguages.d.ts.map +1 -0
- package/dist/codeLanguages.js +34 -0
- package/dist/codeLineTokens.d.ts +53 -0
- package/dist/codeLineTokens.d.ts.map +1 -0
- package/dist/codeLineTokens.js +188 -0
- package/dist/editorNodes.d.ts +8 -0
- package/dist/editorNodes.d.ts.map +1 -0
- package/dist/editorNodes.js +30 -0
- package/dist/editorTheme.d.ts +7 -0
- package/dist/editorTheme.d.ts.map +1 -0
- package/dist/editorTheme.js +328 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/internal/CodeBackspacePlugin.d.ts +2 -0
- package/dist/internal/CodeBackspacePlugin.d.ts.map +1 -0
- package/dist/internal/CodeBackspacePlugin.js +70 -0
- package/dist/internal/CodeBlockHeaderPlugin.d.ts +11 -0
- package/dist/internal/CodeBlockHeaderPlugin.d.ts.map +1 -0
- package/dist/internal/CodeBlockHeaderPlugin.js +204 -0
- package/dist/internal/CodePastePlugin.d.ts +5 -0
- package/dist/internal/CodePastePlugin.d.ts.map +1 -0
- package/dist/internal/CodePastePlugin.js +104 -0
- package/dist/internal/CodeSyntaxPlugin.d.ts +8 -0
- package/dist/internal/CodeSyntaxPlugin.d.ts.map +1 -0
- package/dist/internal/CodeSyntaxPlugin.js +397 -0
- package/dist/internal/CodeTabPlugin.d.ts +2 -0
- package/dist/internal/CodeTabPlugin.d.ts.map +1 -0
- package/dist/internal/CodeTabPlugin.js +256 -0
- package/dist/internal/DisabledLinkGuardPlugin.d.ts +4 -0
- package/dist/internal/DisabledLinkGuardPlugin.d.ts.map +1 -0
- package/dist/internal/DisabledLinkGuardPlugin.js +93 -0
- package/dist/internal/ImageSourceCaretPlugin.d.ts +3 -0
- package/dist/internal/ImageSourceCaretPlugin.d.ts.map +1 -0
- package/dist/internal/ImageSourceCaretPlugin.js +105 -0
- package/dist/internal/ListItemShortcutsPlugin.d.ts +6 -0
- package/dist/internal/ListItemShortcutsPlugin.d.ts.map +1 -0
- package/dist/internal/ListItemShortcutsPlugin.js +314 -0
- package/dist/internal/MarkdownExtensionsPlugin.d.ts +17 -0
- package/dist/internal/MarkdownExtensionsPlugin.d.ts.map +1 -0
- package/dist/internal/MarkdownExtensionsPlugin.js +185 -0
- package/dist/internal/SelectAllScopePlugin.d.ts +2 -0
- package/dist/internal/SelectAllScopePlugin.d.ts.map +1 -0
- package/dist/internal/SelectAllScopePlugin.js +67 -0
- package/dist/internal/TableColumnFloorPlugin.d.ts +12 -0
- package/dist/internal/TableColumnFloorPlugin.d.ts.map +1 -0
- package/dist/internal/TableColumnFloorPlugin.js +84 -0
- package/dist/internal/TablePastePlugin.d.ts +9 -0
- package/dist/internal/TablePastePlugin.d.ts.map +1 -0
- package/dist/internal/TablePastePlugin.js +183 -0
- package/dist/internal/TableScrollRegionPlugin.d.ts +9 -0
- package/dist/internal/TableScrollRegionPlugin.d.ts.map +1 -0
- package/dist/internal/TableScrollRegionPlugin.js +95 -0
- package/dist/internal/TaskCheckboxPlugin.d.ts +7 -0
- package/dist/internal/TaskCheckboxPlugin.d.ts.map +1 -0
- package/dist/internal/TaskCheckboxPlugin.js +193 -0
- package/dist/internal/ToolbarLinkPopover.d.ts +74 -0
- package/dist/internal/ToolbarLinkPopover.d.ts.map +1 -0
- package/dist/internal/ToolbarLinkPopover.js +292 -0
- package/dist/linkEditing.d.ts +6 -0
- package/dist/linkEditing.d.ts.map +1 -0
- package/dist/linkEditing.js +20 -0
- package/dist/linkForm.d.ts +28 -0
- package/dist/linkForm.d.ts.map +1 -0
- package/dist/linkForm.js +137 -0
- package/dist/linkUtils.d.ts +27 -0
- package/dist/linkUtils.d.ts.map +1 -0
- package/dist/linkUtils.js +101 -0
- package/dist/markdown.d.ts +17 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +17 -0
- package/dist/markdownCharacterReferences.d.ts +135 -0
- package/dist/markdownCharacterReferences.d.ts.map +1 -0
- package/dist/markdownCharacterReferences.js +1127 -0
- package/dist/markdownCodeFence.d.ts +4 -0
- package/dist/markdownCodeFence.d.ts.map +1 -0
- package/dist/markdownCodeFence.js +167 -0
- package/dist/markdownExtensionNode.d.ts +88 -0
- package/dist/markdownExtensionNode.d.ts.map +1 -0
- package/dist/markdownExtensionNode.js +248 -0
- package/dist/markdownExtensions.d.ts +115 -0
- package/dist/markdownExtensions.d.ts.map +1 -0
- package/dist/markdownExtensions.js +392 -0
- package/dist/markdownHardLineBreak.d.ts +25 -0
- package/dist/markdownHardLineBreak.d.ts.map +1 -0
- package/dist/markdownHardLineBreak.js +59 -0
- package/dist/markdownHeading.d.ts +20 -0
- package/dist/markdownHeading.d.ts.map +1 -0
- package/dist/markdownHeading.js +30 -0
- package/dist/markdownLink.d.ts +5 -0
- package/dist/markdownLink.d.ts.map +1 -0
- package/dist/markdownLink.js +80 -0
- package/dist/markdownListExport.d.ts +3 -0
- package/dist/markdownListExport.d.ts.map +1 -0
- package/dist/markdownListExport.js +68 -0
- package/dist/markdownListIndentation.d.ts +8 -0
- package/dist/markdownListIndentation.d.ts.map +1 -0
- package/dist/markdownListIndentation.js +101 -0
- package/dist/markdownOrderedList.d.ts +3 -0
- package/dist/markdownOrderedList.d.ts.map +1 -0
- package/dist/markdownOrderedList.js +51 -0
- package/dist/markdownQuote.d.ts +22 -0
- package/dist/markdownQuote.d.ts.map +1 -0
- package/dist/markdownQuote.js +32 -0
- package/dist/markdownSerializers.d.ts +49 -0
- package/dist/markdownSerializers.d.ts.map +1 -0
- package/dist/markdownSerializers.js +83 -0
- package/dist/markdownSource.d.ts +71 -0
- package/dist/markdownSource.d.ts.map +1 -0
- package/dist/markdownSource.js +804 -0
- package/dist/markdownSpaceRuns.d.ts +24 -0
- package/dist/markdownSpaceRuns.d.ts.map +1 -0
- package/dist/markdownSpaceRuns.js +147 -0
- package/dist/markdownTable.d.ts +35 -0
- package/dist/markdownTable.d.ts.map +1 -0
- package/dist/markdownTable.js +227 -0
- package/dist/markdownTaskList.d.ts +48 -0
- package/dist/markdownTaskList.d.ts.map +1 -0
- package/dist/markdownTaskList.js +166 -0
- package/dist/markdownThematicBreak.d.ts +3 -0
- package/dist/markdownThematicBreak.d.ts.map +1 -0
- package/dist/markdownThematicBreak.js +55 -0
- package/dist/privateAttributes/layerPortalBoundary.stylex.d.ts +12 -0
- package/dist/privateAttributes/layerPortalBoundary.stylex.d.ts.map +1 -0
- package/dist/privateAttributes/layerPortalBoundary.stylex.js +16 -0
- package/dist/richtext.css +213 -0
- package/dist/textSemantics.d.ts +3 -0
- package/dist/textSemantics.d.ts.map +1 -0
- package/dist/textSemantics.js +87 -0
- package/package.json +158 -3
- package/src/RichTextEditor.doc.mjs +308 -0
- package/src/RichTextEditor.tsx +1109 -0
- package/src/RichTextEditorAutoLinkPlugin.doc.mjs +43 -0
- package/src/RichTextEditorAutoLinkPlugin.tsx +126 -0
- package/src/RichTextEditorToolbar.doc.mjs +92 -0
- package/src/RichTextEditorToolbar.tsx +871 -0
- package/src/RichTextView.doc.mjs +101 -0
- package/src/RichTextView.tsx +351 -0
- package/src/codeLanguages.ts +42 -0
- package/src/codeLineTokens.ts +241 -0
- package/src/doc-mjs.d.ts +23 -0
- package/src/editorNodes.ts +44 -0
- package/src/editorTheme.ts +550 -0
- package/src/index.ts +59 -0
- package/src/internal/CodeBackspacePlugin.tsx +96 -0
- package/src/internal/CodeBlockHeaderPlugin.tsx +282 -0
- package/src/internal/CodePastePlugin.tsx +144 -0
- package/src/internal/CodeSyntaxPlugin.tsx +493 -0
- package/src/internal/CodeTabPlugin.tsx +298 -0
- package/src/internal/DisabledLinkGuardPlugin.tsx +93 -0
- package/src/internal/ImageSourceCaretPlugin.tsx +159 -0
- package/src/internal/ListItemShortcutsPlugin.tsx +404 -0
- package/src/internal/MarkdownExtensionsPlugin.tsx +289 -0
- package/src/internal/SelectAllScopePlugin.tsx +86 -0
- package/src/internal/TableColumnFloorPlugin.tsx +99 -0
- package/src/internal/TablePastePlugin.tsx +223 -0
- package/src/internal/TableScrollRegionPlugin.tsx +107 -0
- package/src/internal/TaskCheckboxPlugin.tsx +246 -0
- package/src/internal/ToolbarLinkPopover.tsx +392 -0
- package/src/linkEditing.ts +20 -0
- package/src/linkForm.tsx +156 -0
- package/src/linkUtils.ts +106 -0
- package/src/markdown.ts +25 -0
- package/src/markdownCharacterReferences.ts +1137 -0
- package/src/markdownCodeFence.ts +216 -0
- package/src/markdownExtensionNode.ts +339 -0
- package/src/markdownExtensions.ts +496 -0
- package/src/markdownHardLineBreak.ts +73 -0
- package/src/markdownHeading.ts +33 -0
- package/src/markdownLink.ts +86 -0
- package/src/markdownListExport.ts +85 -0
- package/src/markdownListIndentation.ts +105 -0
- package/src/markdownOrderedList.ts +60 -0
- package/src/markdownQuote.ts +35 -0
- package/src/markdownSerializers.ts +108 -0
- package/src/markdownSource.ts +1045 -0
- package/src/markdownSpaceRuns.ts +164 -0
- package/src/markdownTable.ts +309 -0
- package/src/markdownTaskList.ts +222 -0
- package/src/markdownThematicBreak.ts +66 -0
- package/src/privateAttributes/layerPortalBoundary.stylex.ts +18 -0
- package/src/textSemantics.ts +104 -0
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file editorTheme.ts
|
|
5
|
+
* @input Uses StyleX + Astryx design tokens
|
|
6
|
+
* @output Exports sharedEditorTheme(), which builds a Lexical EditorThemeClasses
|
|
7
|
+
* object mapping Lexical's theme slots to StyleX-generated class names, with
|
|
8
|
+
* document blocks styled like core Markdown (spec:AST-061 FR2–FR4).
|
|
9
|
+
* @position Shared by RichTextEditor.tsx and RichTextView.tsx so editor and
|
|
10
|
+
* read-only view render identically.
|
|
11
|
+
*
|
|
12
|
+
* SYNC: When modified, keep RichTextEditor.tsx and RichTextView.tsx in sync.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import * as stylex from '@stylexjs/stylex';
|
|
16
|
+
import {
|
|
17
|
+
colorVars,
|
|
18
|
+
spacingVars,
|
|
19
|
+
radiusVars,
|
|
20
|
+
typographyVars,
|
|
21
|
+
typeScaleVars,
|
|
22
|
+
fontWeightVars,
|
|
23
|
+
borderVars,
|
|
24
|
+
focusVars,
|
|
25
|
+
sizeVars,
|
|
26
|
+
} from '@blue-patterns/core/theme/tokens.stylex';
|
|
27
|
+
import {CODE_SYNTAX_CLASS} from './internal/CodeSyntaxPlugin';
|
|
28
|
+
import type {EditorThemeClasses} from 'lexical';
|
|
29
|
+
|
|
30
|
+
// Document blocks follow core Markdown's typography, spacing, and measure
|
|
31
|
+
// (spec:AST-061 FR2–FR4): type-scale tokens for text, one block spacing table
|
|
32
|
+
// with no margin before the first block or after the last, and prose capped
|
|
33
|
+
// at Markdown's default content width while code and tables span the editor.
|
|
34
|
+
const PROSE_MEASURE = '680px';
|
|
35
|
+
|
|
36
|
+
// Block margins wrap their spacing tokens in calc(). The value is unique to
|
|
37
|
+
// these rules, so its atomic class never matches a margin declared by other
|
|
38
|
+
// code; a stylesheet in a later cascade layer therefore cannot outrank the
|
|
39
|
+
// :first-child and :last-child rules that remove the outer margins.
|
|
40
|
+
const MAJOR_HEADING_BEFORE = `calc(${spacingVars['--spacing-6']})`;
|
|
41
|
+
const MAJOR_HEADING_AFTER = `calc(${spacingVars['--spacing-3']})`;
|
|
42
|
+
const MINOR_HEADING_BEFORE = `calc(${spacingVars['--spacing-4']})`;
|
|
43
|
+
const MINOR_HEADING_AFTER = `calc(${spacingVars['--spacing-2']})`;
|
|
44
|
+
const TEXT_BLOCK_SPACE = `calc(${spacingVars['--spacing-3']})`;
|
|
45
|
+
const WIDE_BLOCK_SPACE = `calc(${spacingVars['--spacing-4']})`;
|
|
46
|
+
const LIST_ITEM_SPACE = `calc(${spacingVars['--spacing-1']})`;
|
|
47
|
+
const TASK_BOX_SIZE = '20px';
|
|
48
|
+
const LIST_ROW_GAP = `calc(${spacingVars['--spacing-0-5']})`;
|
|
49
|
+
const LIST_ROW_FLUSH = `calc(${spacingVars['--spacing-0']})`;
|
|
50
|
+
const NESTED_LIST_SPACE = `calc(${spacingVars['--spacing-2']})`;
|
|
51
|
+
const RULE_SPACE = `calc(${spacingVars['--spacing-6']})`;
|
|
52
|
+
const CODE_SPACE = `calc(${spacingVars['--spacing-3']})`;
|
|
53
|
+
// Core CodeBlock's header (8px, a small control, 8px) overlaps the code's
|
|
54
|
+
// 12px top padding by 8px, so its code starts 8px + control + 12px down.
|
|
55
|
+
const CODE_HEADER_SPACE = `calc(${spacingVars['--spacing-2']} + ${sizeVars['--size-element-sm']} + ${spacingVars['--spacing-3']})`;
|
|
56
|
+
// A block that names no language has no header: core CodeBlock puts its copy
|
|
57
|
+
// button in a column of its own at the inline end (8px, a small control, 8px),
|
|
58
|
+
// beside the code rather than over it, so the code ends that much earlier.
|
|
59
|
+
const CODE_CORNER_SPACE = `calc(${spacingVars['--spacing-4']} + ${sizeVars['--size-element-sm']} + 2 * ${spacingVars['--spacing-2']})`;
|
|
60
|
+
|
|
61
|
+
const editorTheme = stylex.create({
|
|
62
|
+
// Lexical marks every top-level block `dir="auto"`, which picks each
|
|
63
|
+
// block's direction from its first strong character: a Hebrew paragraph in
|
|
64
|
+
// an English document flips to the right, an English one in an Arabic
|
|
65
|
+
// document to the left. Here blocks take the direction of the surface
|
|
66
|
+
// around them, and bidi inside a block still follows the Unicode
|
|
67
|
+
// algorithm. Core Markdown differs: it gives each block the direction of
|
|
68
|
+
// its own text.
|
|
69
|
+
providerDirection: {
|
|
70
|
+
direction: 'inherit',
|
|
71
|
+
},
|
|
72
|
+
paragraph: {
|
|
73
|
+
// The first block's leading margin would stack with the input inset, so
|
|
74
|
+
// the first line aligns with TextArea and the empty-editor placeholder.
|
|
75
|
+
// A Markdown plugin block takes this style and is a decorator, so at
|
|
76
|
+
// either edge of the document it sits beside Lexical's zero-size caret
|
|
77
|
+
// boundary element (see `hr`) and takes no outer margin there either.
|
|
78
|
+
marginBlockStart: {
|
|
79
|
+
default: TEXT_BLOCK_SPACE,
|
|
80
|
+
':first-child': spacingVars['--spacing-0'],
|
|
81
|
+
':is([data-lexical-decorator-boundary]:first-child + *)':
|
|
82
|
+
spacingVars['--spacing-0'],
|
|
83
|
+
},
|
|
84
|
+
marginBlockEnd: {
|
|
85
|
+
default: TEXT_BLOCK_SPACE,
|
|
86
|
+
':last-child': spacingVars['--spacing-0'],
|
|
87
|
+
':has(+ [data-lexical-decorator-boundary]:last-child)':
|
|
88
|
+
spacingVars['--spacing-0'],
|
|
89
|
+
},
|
|
90
|
+
maxWidth: PROSE_MEASURE,
|
|
91
|
+
// The base reset gives every <p> body weight and primary color; a
|
|
92
|
+
// paragraph inside a table header cell takes the cell's instead.
|
|
93
|
+
fontWeight: 'inherit',
|
|
94
|
+
color: 'inherit',
|
|
95
|
+
},
|
|
96
|
+
h1: {
|
|
97
|
+
fontFamily: typographyVars['--font-family-heading'],
|
|
98
|
+
fontSize: typeScaleVars['--text-heading-1-size'],
|
|
99
|
+
fontWeight: typeScaleVars['--text-heading-1-weight'],
|
|
100
|
+
lineHeight: typeScaleVars['--text-heading-1-leading'],
|
|
101
|
+
marginBlockStart: {
|
|
102
|
+
default: MAJOR_HEADING_BEFORE,
|
|
103
|
+
':first-child': spacingVars['--spacing-0'],
|
|
104
|
+
},
|
|
105
|
+
marginBlockEnd: {
|
|
106
|
+
default: MAJOR_HEADING_AFTER,
|
|
107
|
+
':last-child': spacingVars['--spacing-0'],
|
|
108
|
+
},
|
|
109
|
+
maxWidth: PROSE_MEASURE,
|
|
110
|
+
},
|
|
111
|
+
h2: {
|
|
112
|
+
fontFamily: typographyVars['--font-family-heading'],
|
|
113
|
+
fontSize: typeScaleVars['--text-heading-2-size'],
|
|
114
|
+
fontWeight: typeScaleVars['--text-heading-2-weight'],
|
|
115
|
+
lineHeight: typeScaleVars['--text-heading-2-leading'],
|
|
116
|
+
marginBlockStart: {
|
|
117
|
+
default: MAJOR_HEADING_BEFORE,
|
|
118
|
+
':first-child': spacingVars['--spacing-0'],
|
|
119
|
+
},
|
|
120
|
+
marginBlockEnd: {
|
|
121
|
+
default: MAJOR_HEADING_AFTER,
|
|
122
|
+
':last-child': spacingVars['--spacing-0'],
|
|
123
|
+
},
|
|
124
|
+
maxWidth: PROSE_MEASURE,
|
|
125
|
+
},
|
|
126
|
+
h3: {
|
|
127
|
+
fontFamily: typographyVars['--font-family-heading'],
|
|
128
|
+
fontSize: typeScaleVars['--text-heading-3-size'],
|
|
129
|
+
fontWeight: typeScaleVars['--text-heading-3-weight'],
|
|
130
|
+
lineHeight: typeScaleVars['--text-heading-3-leading'],
|
|
131
|
+
marginBlockStart: {
|
|
132
|
+
default: MAJOR_HEADING_BEFORE,
|
|
133
|
+
':first-child': spacingVars['--spacing-0'],
|
|
134
|
+
},
|
|
135
|
+
marginBlockEnd: {
|
|
136
|
+
default: MAJOR_HEADING_AFTER,
|
|
137
|
+
':last-child': spacingVars['--spacing-0'],
|
|
138
|
+
},
|
|
139
|
+
maxWidth: PROSE_MEASURE,
|
|
140
|
+
},
|
|
141
|
+
h4: {
|
|
142
|
+
fontFamily: typographyVars['--font-family-heading'],
|
|
143
|
+
fontSize: typeScaleVars['--text-heading-4-size'],
|
|
144
|
+
fontWeight: typeScaleVars['--text-heading-4-weight'],
|
|
145
|
+
lineHeight: typeScaleVars['--text-heading-4-leading'],
|
|
146
|
+
marginBlockStart: {
|
|
147
|
+
default: MINOR_HEADING_BEFORE,
|
|
148
|
+
':first-child': spacingVars['--spacing-0'],
|
|
149
|
+
},
|
|
150
|
+
marginBlockEnd: {
|
|
151
|
+
default: MINOR_HEADING_AFTER,
|
|
152
|
+
':last-child': spacingVars['--spacing-0'],
|
|
153
|
+
},
|
|
154
|
+
maxWidth: PROSE_MEASURE,
|
|
155
|
+
},
|
|
156
|
+
h5: {
|
|
157
|
+
fontFamily: typographyVars['--font-family-heading'],
|
|
158
|
+
fontSize: typeScaleVars['--text-heading-5-size'],
|
|
159
|
+
fontWeight: typeScaleVars['--text-heading-5-weight'],
|
|
160
|
+
lineHeight: typeScaleVars['--text-heading-5-leading'],
|
|
161
|
+
marginBlockStart: {
|
|
162
|
+
default: MINOR_HEADING_BEFORE,
|
|
163
|
+
':first-child': spacingVars['--spacing-0'],
|
|
164
|
+
},
|
|
165
|
+
marginBlockEnd: {
|
|
166
|
+
default: MINOR_HEADING_AFTER,
|
|
167
|
+
':last-child': spacingVars['--spacing-0'],
|
|
168
|
+
},
|
|
169
|
+
maxWidth: PROSE_MEASURE,
|
|
170
|
+
},
|
|
171
|
+
h6: {
|
|
172
|
+
fontFamily: typographyVars['--font-family-heading'],
|
|
173
|
+
fontSize: typeScaleVars['--text-heading-6-size'],
|
|
174
|
+
fontWeight: typeScaleVars['--text-heading-6-weight'],
|
|
175
|
+
lineHeight: typeScaleVars['--text-heading-6-leading'],
|
|
176
|
+
marginBlockStart: {
|
|
177
|
+
default: MINOR_HEADING_BEFORE,
|
|
178
|
+
':first-child': spacingVars['--spacing-0'],
|
|
179
|
+
},
|
|
180
|
+
marginBlockEnd: {
|
|
181
|
+
default: MINOR_HEADING_AFTER,
|
|
182
|
+
':last-child': spacingVars['--spacing-0'],
|
|
183
|
+
},
|
|
184
|
+
maxWidth: PROSE_MEASURE,
|
|
185
|
+
},
|
|
186
|
+
quote: {
|
|
187
|
+
marginBlockStart: {
|
|
188
|
+
default: WIDE_BLOCK_SPACE,
|
|
189
|
+
':first-child': spacingVars['--spacing-0'],
|
|
190
|
+
},
|
|
191
|
+
marginBlockEnd: {
|
|
192
|
+
default: WIDE_BLOCK_SPACE,
|
|
193
|
+
':last-child': spacingVars['--spacing-0'],
|
|
194
|
+
},
|
|
195
|
+
marginInline: 0,
|
|
196
|
+
maxWidth: PROSE_MEASURE,
|
|
197
|
+
paddingInlineStart: spacingVars['--spacing-4'],
|
|
198
|
+
borderInlineStartWidth: '2px',
|
|
199
|
+
borderInlineStartStyle: 'solid',
|
|
200
|
+
borderInlineStartColor: colorVars['--color-border-emphasized'],
|
|
201
|
+
color: colorVars['--color-text-secondary'],
|
|
202
|
+
},
|
|
203
|
+
ul: {
|
|
204
|
+
marginBlockStart: {
|
|
205
|
+
default: TEXT_BLOCK_SPACE,
|
|
206
|
+
':first-child': spacingVars['--spacing-0'],
|
|
207
|
+
},
|
|
208
|
+
marginBlockEnd: {
|
|
209
|
+
default: TEXT_BLOCK_SPACE,
|
|
210
|
+
':last-child': spacingVars['--spacing-0'],
|
|
211
|
+
},
|
|
212
|
+
maxWidth: PROSE_MEASURE,
|
|
213
|
+
paddingInlineStart: spacingVars['--spacing-6'],
|
|
214
|
+
listStylePosition: 'outside',
|
|
215
|
+
},
|
|
216
|
+
ol: {
|
|
217
|
+
marginBlockStart: {
|
|
218
|
+
default: TEXT_BLOCK_SPACE,
|
|
219
|
+
':first-child': spacingVars['--spacing-0'],
|
|
220
|
+
},
|
|
221
|
+
marginBlockEnd: {
|
|
222
|
+
default: TEXT_BLOCK_SPACE,
|
|
223
|
+
':last-child': spacingVars['--spacing-0'],
|
|
224
|
+
},
|
|
225
|
+
maxWidth: PROSE_MEASURE,
|
|
226
|
+
paddingInlineStart: spacingVars['--spacing-6'],
|
|
227
|
+
listStylePosition: 'outside',
|
|
228
|
+
},
|
|
229
|
+
// Markers by depth (spec:AST-061 DEC-6): a list nested inside n lists, of
|
|
230
|
+
// either kind, draws disc, circle, or square, or writes decimal,
|
|
231
|
+
// lower-alpha, or lower-roman numbers, for n modulo 3 = 0, 1, 2. Lexical
|
|
232
|
+
// gives every list its tag's class above and the depth class at
|
|
233
|
+
// `depth % 3`; only the depth class names a marker, so no two classes on a
|
|
234
|
+
// list compete for it. A nested list sits alone in its item, so the first-
|
|
235
|
+
// and last-child rules above already take its margins away.
|
|
236
|
+
ulMarker0: {listStyleType: 'disc'},
|
|
237
|
+
ulMarker1: {listStyleType: 'circle'},
|
|
238
|
+
ulMarker2: {listStyleType: 'square'},
|
|
239
|
+
olMarker0: {listStyleType: 'decimal'},
|
|
240
|
+
olMarker1: {listStyleType: 'lower-alpha'},
|
|
241
|
+
olMarker2: {listStyleType: 'lower-roman'},
|
|
242
|
+
// List items space like core Markdown's compact list rows: 4px padding and
|
|
243
|
+
// a 2px gap between rows. Lexical puts a nested list in an item of its own
|
|
244
|
+
// after its parent item; that wrapper adds no top padding and no marker,
|
|
245
|
+
// and its 8px top margin plus the parent row's padding give the 12px
|
|
246
|
+
// Markdown leaves between an item's text and its nested list.
|
|
247
|
+
listItem: {
|
|
248
|
+
paddingBlockStart: {
|
|
249
|
+
default: LIST_ITEM_SPACE,
|
|
250
|
+
':has(ul)': spacingVars['--spacing-0'],
|
|
251
|
+
':has(ol)': spacingVars['--spacing-0'],
|
|
252
|
+
},
|
|
253
|
+
paddingBlockEnd: LIST_ITEM_SPACE,
|
|
254
|
+
marginBlockStart: {
|
|
255
|
+
default: LIST_ROW_FLUSH,
|
|
256
|
+
':has(ul)': NESTED_LIST_SPACE,
|
|
257
|
+
':has(ol)': NESTED_LIST_SPACE,
|
|
258
|
+
},
|
|
259
|
+
marginBlockEnd: {
|
|
260
|
+
default: LIST_ROW_GAP,
|
|
261
|
+
':last-child': spacingVars['--spacing-0'],
|
|
262
|
+
},
|
|
263
|
+
// Ensure the marker is shown (some CSS resets set list-style: none on li).
|
|
264
|
+
// A task item (TaskCheckboxPlugin marks it) shows a checkbox instead.
|
|
265
|
+
listStyleType: {
|
|
266
|
+
default: 'inherit',
|
|
267
|
+
':has(ul)': 'none',
|
|
268
|
+
':has(ol)': 'none',
|
|
269
|
+
':is([data-richtext-task])': 'none',
|
|
270
|
+
},
|
|
271
|
+
// A task item's text starts 28px in from the list's edge, after core's
|
|
272
|
+
// small checkbox (20px) and its 8px gap, like core Markdown's task lists:
|
|
273
|
+
// the item cancels the list's bullet indent and pads for the checkbox.
|
|
274
|
+
marginInlineStart: {
|
|
275
|
+
default: LIST_ROW_FLUSH,
|
|
276
|
+
':is([data-richtext-task])': `calc(-1 * ${spacingVars['--spacing-6']})`,
|
|
277
|
+
},
|
|
278
|
+
paddingInlineStart: {
|
|
279
|
+
default: LIST_ROW_FLUSH,
|
|
280
|
+
':is([data-richtext-task])': `calc(${TASK_BOX_SIZE} + ${spacingVars['--spacing-2']})`,
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
link: {
|
|
284
|
+
color: colorVars['--color-text-accent'],
|
|
285
|
+
textDecoration: 'underline',
|
|
286
|
+
cursor: {
|
|
287
|
+
default: 'pointer',
|
|
288
|
+
':is(:disabled,[aria-disabled="true"])': 'default',
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
textBold: {fontWeight: fontWeightVars['--font-weight-semibold']},
|
|
292
|
+
textItalic: {fontStyle: 'italic'},
|
|
293
|
+
textUnderline: {textDecoration: 'underline'},
|
|
294
|
+
textStrikethrough: {textDecoration: 'line-through'},
|
|
295
|
+
textCode: {
|
|
296
|
+
fontFamily: typographyVars['--font-family-code'],
|
|
297
|
+
backgroundColor: colorVars['--color-background-muted'],
|
|
298
|
+
paddingInline: spacingVars['--spacing-1'],
|
|
299
|
+
borderRadius: radiusVars['--radius-inner'],
|
|
300
|
+
},
|
|
301
|
+
// GFM tables, styled like core Markdown's table: semibold secondary header
|
|
302
|
+
// text, a divider under every row but the last, and a wide table that
|
|
303
|
+
// scrolls inside its own wrapper instead of widening the editor.
|
|
304
|
+
tableScrollableWrapper: {
|
|
305
|
+
overflowX: 'auto',
|
|
306
|
+
maxWidth: '100%',
|
|
307
|
+
// One grid track that may shrink to nothing: the wrapper asks its host
|
|
308
|
+
// for no minimum width, so a grid or flex host never grows to fit a wide
|
|
309
|
+
// table and the wrapper scrolls instead, while a shrink-to-fit host still
|
|
310
|
+
// sizes to the table's natural width.
|
|
311
|
+
display: 'grid',
|
|
312
|
+
gridTemplateColumns: 'minmax(0, 1fr)',
|
|
313
|
+
marginBlockStart: {
|
|
314
|
+
default: WIDE_BLOCK_SPACE,
|
|
315
|
+
':first-child': spacingVars['--spacing-0'],
|
|
316
|
+
},
|
|
317
|
+
marginBlockEnd: {
|
|
318
|
+
default: WIDE_BLOCK_SPACE,
|
|
319
|
+
':last-child': spacingVars['--spacing-0'],
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
table: {
|
|
323
|
+
borderCollapse: 'collapse',
|
|
324
|
+
width: '100%',
|
|
325
|
+
// The grid's outer edge, matching core Markdown's table: the row and
|
|
326
|
+
// column lines stop at the table's rim, so without this the top, bottom,
|
|
327
|
+
// and sides stay open. `border-collapse: collapse` merges it with the
|
|
328
|
+
// cell lines into one 1px rule rather than doubling up at the edge.
|
|
329
|
+
borderWidth: borderVars['--border-width'],
|
|
330
|
+
borderStyle: 'solid',
|
|
331
|
+
borderColor: colorVars['--color-border'],
|
|
332
|
+
},
|
|
333
|
+
tableRow: {
|
|
334
|
+
borderBottomWidth: '1px',
|
|
335
|
+
borderBottomStyle: 'solid',
|
|
336
|
+
borderBottomColor: {
|
|
337
|
+
default: colorVars['--color-border'],
|
|
338
|
+
':last-child': 'transparent',
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
tableCell: {
|
|
342
|
+
// Column floors (TableColumnFloorPlugin) size the text box, not the
|
|
343
|
+
// padding, as in core Markdown's tables.
|
|
344
|
+
boxSizing: 'content-box',
|
|
345
|
+
paddingBlock: spacingVars['--spacing-2'],
|
|
346
|
+
paddingInline: spacingVars['--spacing-2'],
|
|
347
|
+
textAlign: 'start',
|
|
348
|
+
verticalAlign: 'middle',
|
|
349
|
+
overflowWrap: 'break-word',
|
|
350
|
+
// A line on every cell edge, as core Markdown's table draws with
|
|
351
|
+
// `dividers="grid"`. The row lines come from `tableRow`; this is the
|
|
352
|
+
// column half. The last column draws none, so the rim is the `table`
|
|
353
|
+
// rule's own border rather than two lines stacked at the edge — the
|
|
354
|
+
// same rule core `TableCell` follows (`:last-child` → 0).
|
|
355
|
+
borderInlineEndWidth: {
|
|
356
|
+
default: borderVars['--border-width'],
|
|
357
|
+
':last-child': 0,
|
|
358
|
+
},
|
|
359
|
+
borderInlineEndStyle: 'solid',
|
|
360
|
+
borderInlineEndColor: colorVars['--color-border'],
|
|
361
|
+
},
|
|
362
|
+
tableCellHeader: {
|
|
363
|
+
fontWeight: fontWeightVars['--font-weight-semibold'],
|
|
364
|
+
color: colorVars['--color-text-secondary'],
|
|
365
|
+
},
|
|
366
|
+
// Cells in a table selection — dragging across cells, Shift+arrow between
|
|
367
|
+
// them, or selecting a row or column — are ringed, for the reason
|
|
368
|
+
// `hrSelected` gives: a person has to see what the next keystroke will
|
|
369
|
+
// replace. Lexical names this class on every highlighted cell and takes it
|
|
370
|
+
// off when the selection goes; left unnamed, a cell inside the selection is
|
|
371
|
+
// painted exactly like one outside it.
|
|
372
|
+
//
|
|
373
|
+
// A ring, not a background wash. A wash sits behind the cell's text and
|
|
374
|
+
// eats into its contrast, and no one token stays clear of the field in
|
|
375
|
+
// every theme: `--color-accent-muted` resolves to the field's own colour
|
|
376
|
+
// under Neutral dark, so the selection would be invisible there, and a
|
|
377
|
+
// 10% accent tint drops Neutral dark's header text from 5.65:1 to 4.25:1.
|
|
378
|
+
// The focus ring is drawn for exactly this job — it clears the field by
|
|
379
|
+
// 5.24:1 at worst across every shipped theme and mode — and sits beside
|
|
380
|
+
// the text rather than behind it, so no cell's contrast moves at all.
|
|
381
|
+
// `outline` takes no space, so the document's geometry is untouched
|
|
382
|
+
// (spec:AST-061 FR9), and the inset offset keeps each ring inside its own
|
|
383
|
+
// cell instead of bleeding over the neighbour it is not marking.
|
|
384
|
+
//
|
|
385
|
+
// `RichTextView` and a read-only editor ring a dragged cell selection too:
|
|
386
|
+
// Lexical's table pointer handler does not ask whether the surface is
|
|
387
|
+
// editable, and a person selects cells in a read surface to copy them, so
|
|
388
|
+
// seeing the selection is as right there. Both surfaces draw the same ring
|
|
389
|
+
// and neither moves a block, so they still render the same document the
|
|
390
|
+
// same way.
|
|
391
|
+
tableCellSelected: {
|
|
392
|
+
outlineWidth: focusVars['--focus-outline-width'],
|
|
393
|
+
outlineStyle: focusVars['--focus-outline-style'],
|
|
394
|
+
outlineColor: focusVars['--focus-outline-color'],
|
|
395
|
+
outlineOffset: `calc(-1 * ${focusVars['--focus-outline-width']})`,
|
|
396
|
+
},
|
|
397
|
+
// Thematic breaks, drawn like core Markdown's rule. A rule is a decorator,
|
|
398
|
+
// and Lexical puts a zero-size caret boundary element beside a decorator at
|
|
399
|
+
// either edge of the document, so a rule there is not literally the first
|
|
400
|
+
// or last child; it still takes no outer margin.
|
|
401
|
+
hr: {
|
|
402
|
+
borderWidth: 0,
|
|
403
|
+
borderTopWidth: borderVars['--border-width'],
|
|
404
|
+
borderTopStyle: 'solid',
|
|
405
|
+
borderTopColor: colorVars['--color-border'],
|
|
406
|
+
marginBlockStart: {
|
|
407
|
+
default: RULE_SPACE,
|
|
408
|
+
':first-child': spacingVars['--spacing-0'],
|
|
409
|
+
':is([data-lexical-decorator-boundary]:first-child + *)':
|
|
410
|
+
spacingVars['--spacing-0'],
|
|
411
|
+
},
|
|
412
|
+
marginBlockEnd: {
|
|
413
|
+
default: RULE_SPACE,
|
|
414
|
+
':last-child': spacingVars['--spacing-0'],
|
|
415
|
+
':has(+ [data-lexical-decorator-boundary]:last-child)':
|
|
416
|
+
spacingVars['--spacing-0'],
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
// A selected rule (click, or arrow onto it) or Markdown plugin node (click)
|
|
420
|
+
// shows the focus ring, so users can see what Backspace will delete.
|
|
421
|
+
hrSelected: {
|
|
422
|
+
outlineWidth: focusVars['--focus-outline-width'],
|
|
423
|
+
outlineStyle: focusVars['--focus-outline-style'],
|
|
424
|
+
outlineColor: focusVars['--focus-outline-color'],
|
|
425
|
+
outlineOffset: focusVars['--focus-outline-offset'],
|
|
426
|
+
},
|
|
427
|
+
// Fenced code in core CodeBlock's frame: syntax background, a border, the
|
|
428
|
+
// code type size, and room at the top for the header that
|
|
429
|
+
// CodeBlockHeaderPlugin draws over a block that names its language. Long
|
|
430
|
+
// lines wrap rather than scroll: a scrolling region inside the editable
|
|
431
|
+
// text cannot take keyboard focus of its own, so keyboard users could not
|
|
432
|
+
// scroll it (axe scrollable-region-focusable).
|
|
433
|
+
code: {
|
|
434
|
+
display: 'block',
|
|
435
|
+
fontFamily: typographyVars['--font-family-code'],
|
|
436
|
+
fontSize: typeScaleVars['--text-code-size'],
|
|
437
|
+
lineHeight: typeScaleVars['--text-code-leading'],
|
|
438
|
+
backgroundColor: 'var(--color-syntax-background)',
|
|
439
|
+
borderWidth: borderVars['--border-width'],
|
|
440
|
+
borderStyle: 'solid',
|
|
441
|
+
borderColor: colorVars['--color-border'],
|
|
442
|
+
borderRadius: radiusVars['--radius-element'],
|
|
443
|
+
paddingBlockStart: {
|
|
444
|
+
default: CODE_SPACE,
|
|
445
|
+
// Only a block whose header names a language; `plaintext` names none,
|
|
446
|
+
// as in core CodeBlock (CodeBlockHeaderPlugin).
|
|
447
|
+
':is([data-language]:not([data-language="plaintext"]))':
|
|
448
|
+
CODE_HEADER_SPACE,
|
|
449
|
+
},
|
|
450
|
+
paddingBlockEnd: spacingVars['--spacing-3'],
|
|
451
|
+
paddingInlineStart: spacingVars['--spacing-4'],
|
|
452
|
+
paddingInlineEnd: {
|
|
453
|
+
// Room for the corner copy button CodeBlockHeaderPlugin draws over a
|
|
454
|
+
// block that names no language, so no line runs under it.
|
|
455
|
+
default: CODE_CORNER_SPACE,
|
|
456
|
+
':is([data-language]:not([data-language="plaintext"]))':
|
|
457
|
+
spacingVars['--spacing-4'],
|
|
458
|
+
},
|
|
459
|
+
// Sized like core Markdown's code frame: as wide as its longest line, at
|
|
460
|
+
// least the prose measure (or the whole width when that is narrower), and
|
|
461
|
+
// never wider than the editor, where long lines wrap.
|
|
462
|
+
boxSizing: 'border-box',
|
|
463
|
+
width: 'fit-content',
|
|
464
|
+
minWidth: `min(${PROSE_MEASURE}, 100%)`,
|
|
465
|
+
maxWidth: '100%',
|
|
466
|
+
marginBlockStart: {
|
|
467
|
+
default: WIDE_BLOCK_SPACE,
|
|
468
|
+
':first-child': spacingVars['--spacing-0'],
|
|
469
|
+
},
|
|
470
|
+
marginBlockEnd: {
|
|
471
|
+
default: WIDE_BLOCK_SPACE,
|
|
472
|
+
':last-child': spacingVars['--spacing-0'],
|
|
473
|
+
},
|
|
474
|
+
// Long lines wrap exactly as core CodeBlock's wrapped lines do, so a code
|
|
475
|
+
// block is as tall here as in core Markdown (spec:AST-061 FR5, DEC-9).
|
|
476
|
+
whiteSpace: 'pre-wrap',
|
|
477
|
+
wordBreak: 'break-all',
|
|
478
|
+
overflowWrap: 'break-word',
|
|
479
|
+
},
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Builds the Lexical EditorThemeClasses object. Lexical expects plain
|
|
484
|
+
* class-name strings, which `stylex.props(...).className` yields.
|
|
485
|
+
*/
|
|
486
|
+
export function sharedEditorTheme(): EditorThemeClasses {
|
|
487
|
+
// A class for a block Lexical may mark `dir="auto"`.
|
|
488
|
+
const block = (...styles: Array<stylex.StyleXStyles>): string =>
|
|
489
|
+
stylex.props(...styles, editorTheme.providerDirection).className ?? '';
|
|
490
|
+
const className = (style: stylex.StyleXStyles): string =>
|
|
491
|
+
stylex.props(style).className ?? '';
|
|
492
|
+
return {
|
|
493
|
+
paragraph: block(editorTheme.paragraph),
|
|
494
|
+
// A Markdown plugin's block node is spaced and measured as a paragraph,
|
|
495
|
+
// as core Markdown spaces its block (RichTextExtensionNode reads it).
|
|
496
|
+
markdownExtensionBlock: block(editorTheme.paragraph),
|
|
497
|
+
heading: {
|
|
498
|
+
h1: block(editorTheme.h1),
|
|
499
|
+
h2: block(editorTheme.h2),
|
|
500
|
+
h3: block(editorTheme.h3),
|
|
501
|
+
h4: block(editorTheme.h4),
|
|
502
|
+
h5: block(editorTheme.h5),
|
|
503
|
+
h6: block(editorTheme.h6),
|
|
504
|
+
},
|
|
505
|
+
quote: block(editorTheme.quote),
|
|
506
|
+
list: {
|
|
507
|
+
ul: block(editorTheme.ul),
|
|
508
|
+
ol: block(editorTheme.ol),
|
|
509
|
+
listitem: stylex.props(editorTheme.listItem).className,
|
|
510
|
+
nested: {
|
|
511
|
+
listitem: stylex.props(editorTheme.listItem).className,
|
|
512
|
+
},
|
|
513
|
+
// Lexical picks the class at `depth % 3` (spec:AST-061 DEC-6).
|
|
514
|
+
ulDepth: [
|
|
515
|
+
className(editorTheme.ulMarker0),
|
|
516
|
+
className(editorTheme.ulMarker1),
|
|
517
|
+
className(editorTheme.ulMarker2),
|
|
518
|
+
],
|
|
519
|
+
olDepth: [
|
|
520
|
+
className(editorTheme.olMarker0),
|
|
521
|
+
className(editorTheme.olMarker1),
|
|
522
|
+
className(editorTheme.olMarker2),
|
|
523
|
+
],
|
|
524
|
+
},
|
|
525
|
+
link: stylex.props(editorTheme.link).className,
|
|
526
|
+
text: {
|
|
527
|
+
bold: stylex.props(editorTheme.textBold).className,
|
|
528
|
+
italic: stylex.props(editorTheme.textItalic).className,
|
|
529
|
+
underline: stylex.props(editorTheme.textUnderline).className,
|
|
530
|
+
strikethrough: stylex.props(editorTheme.textStrikethrough).className,
|
|
531
|
+
code: stylex.props(editorTheme.textCode).className,
|
|
532
|
+
},
|
|
533
|
+
// The plain class lets CodeSyntaxPlugin's highlight rules find code blocks.
|
|
534
|
+
code: `${block(editorTheme.code)} ${CODE_SYNTAX_CLASS}`,
|
|
535
|
+
hr: stylex.props(editorTheme.hr).className,
|
|
536
|
+
hrSelected: stylex.props(editorTheme.hrSelected).className,
|
|
537
|
+
// MarkdownExtensionsPlugin puts it on a selected plugin node.
|
|
538
|
+
markdownExtensionSelected: stylex.props(editorTheme.hrSelected).className,
|
|
539
|
+
table: block(editorTheme.table),
|
|
540
|
+
// Lexical stamps rows and cells `dir="auto"` too, which would set a cell
|
|
541
|
+
// of English text left-to-right inside a right-to-left document.
|
|
542
|
+
tableRow: block(editorTheme.tableRow),
|
|
543
|
+
tableCell: block(editorTheme.tableCell),
|
|
544
|
+
tableCellHeader: block(editorTheme.tableCellHeader),
|
|
545
|
+
// Added on top of the cell's own class by Lexical while the cell is in a
|
|
546
|
+
// table selection, so it carries no direction of its own.
|
|
547
|
+
tableCellSelected: className(editorTheme.tableCellSelected),
|
|
548
|
+
tableScrollableWrapper: block(editorTheme.tableScrollableWrapper),
|
|
549
|
+
};
|
|
550
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
'use client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @file index.ts
|
|
7
|
+
* @input Imports RichTextEditor and RichTextView components and their types
|
|
8
|
+
* @output Public API surface for @blue-patterns/richtext
|
|
9
|
+
* @position Package entry point (barrel) for @blue-patterns/richtext — the
|
|
10
|
+
* Lexical-based rich text editor and viewer, promoted out of
|
|
11
|
+
* @blue-patterns/lab so it can be canaried independently.
|
|
12
|
+
*
|
|
13
|
+
* Exports only what a caller builds with (spec:AST-061/DEC-8): the generated
|
|
14
|
+
* editor theme classes and the autolink regular expressions stay internal,
|
|
15
|
+
* and Lexical's `Transformer` type comes from `@lexical/markdown`.
|
|
16
|
+
* `publicSurface.test.ts` holds the runtime list.
|
|
17
|
+
*
|
|
18
|
+
* SYNC: When modified, update this header, /packages/richtext/README.md,
|
|
19
|
+
* /packages/richtext/src/publicSurface.test.ts, and the editor component doc
|
|
20
|
+
* files.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export {RichTextEditor} from './RichTextEditor';
|
|
24
|
+
export type {
|
|
25
|
+
RichTextEditorProps,
|
|
26
|
+
RichTextEditorRef,
|
|
27
|
+
RichTextEditorStatus,
|
|
28
|
+
RichTextEditorStatusType,
|
|
29
|
+
RichTextEditorSize,
|
|
30
|
+
} from './RichTextEditor';
|
|
31
|
+
|
|
32
|
+
export {RichTextView} from './RichTextView';
|
|
33
|
+
export type {RichTextViewProps} from './RichTextView';
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
markdownToEditorStateJSON,
|
|
37
|
+
editorStateJSONToMarkdown,
|
|
38
|
+
} from './markdownSerializers';
|
|
39
|
+
export type {MarkdownSerializerOptions} from './markdownSerializers';
|
|
40
|
+
export {
|
|
41
|
+
createRichTextExtension,
|
|
42
|
+
RichTextExtensionError,
|
|
43
|
+
} from './markdownExtensions';
|
|
44
|
+
export type {RichTextMarkdownExtension} from './markdownExtensions';
|
|
45
|
+
|
|
46
|
+
export {
|
|
47
|
+
RichTextEditorToolbar,
|
|
48
|
+
RICHTEXT_ICON_KEYS,
|
|
49
|
+
} from './RichTextEditorToolbar';
|
|
50
|
+
export type {RichTextEditorToolbarProps} from './RichTextEditorToolbar';
|
|
51
|
+
|
|
52
|
+
export {
|
|
53
|
+
RichTextEditorAutoLinkPlugin,
|
|
54
|
+
DEFAULT_LINK_MATCHERS,
|
|
55
|
+
NEW_TAB_LINK_ATTRIBUTES,
|
|
56
|
+
} from './RichTextEditorAutoLinkPlugin';
|
|
57
|
+
export type {RichTextEditorAutoLinkPluginProps} from './RichTextEditorAutoLinkPlugin';
|
|
58
|
+
|
|
59
|
+
export {sanitizeUrl, validateUrl} from './linkUtils';
|