@valbuild/ui 0.26.0 → 0.28.0

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.
Files changed (145) hide show
  1. package/dist/valbuild-ui.cjs.js +41 -15
  2. package/dist/valbuild-ui.esm.js +41 -15
  3. package/package.json +7 -3
  4. package/server/.tmp/assets/index-18cfa26c.css +1 -0
  5. package/server/.tmp/assets/index-513f7a9c.js +197 -0
  6. package/{index.html → server/.tmp/index.html} +3 -1
  7. package/server/dist/style.css +0 -3
  8. package/server/dist/valbuild-ui-main.cjs.js +60 -34
  9. package/server/dist/valbuild-ui-main.esm.js +60 -34
  10. package/server/dist/valbuild-ui-server.cjs.js +1 -1
  11. package/server/dist/valbuild-ui-server.esm.js +1 -1
  12. package/.babelrc.json +0 -10
  13. package/.storybook/main.js +0 -25
  14. package/.storybook/preview-head.html +0 -6
  15. package/.storybook/preview.js +0 -33
  16. package/.storybook/theme.css +0 -34
  17. package/CHANGELOG.md +0 -0
  18. package/components.json +0 -16
  19. package/fix-server-hack.js +0 -54
  20. package/fullscreen.vite.config.ts +0 -9
  21. package/jest.config.js +0 -4
  22. package/postcss.config.js +0 -6
  23. package/rollup.config.js +0 -23
  24. package/server.vite.config.ts +0 -31
  25. package/src/App.tsx +0 -73
  26. package/src/assets/icons/Bold.tsx +0 -23
  27. package/src/assets/icons/Chevron.tsx +0 -28
  28. package/src/assets/icons/FontColor.tsx +0 -30
  29. package/src/assets/icons/ImageIcon.tsx +0 -29
  30. package/src/assets/icons/Italic.tsx +0 -24
  31. package/src/assets/icons/Logo.tsx +0 -103
  32. package/src/assets/icons/Section.tsx +0 -41
  33. package/src/assets/icons/Strikethrough.tsx +0 -22
  34. package/src/assets/icons/TextIcon.tsx +0 -20
  35. package/src/assets/icons/Underline.tsx +0 -22
  36. package/src/assets/icons/Undo.tsx +0 -20
  37. package/src/components/Button.tsx +0 -68
  38. package/src/components/Checkbox.tsx +0 -51
  39. package/src/components/DraggableList.stories.tsx +0 -20
  40. package/src/components/DraggableList.tsx +0 -95
  41. package/src/components/Dropdown.tsx +0 -101
  42. package/src/components/EditButton.tsx +0 -10
  43. package/src/components/ErrorText.tsx +0 -3
  44. package/src/components/ExpandLogo.tsx +0 -72
  45. package/src/components/Grid.stories.tsx +0 -43
  46. package/src/components/Grid.tsx +0 -139
  47. package/src/components/RichTextEditor/ContentEditable.tsx +0 -117
  48. package/src/components/RichTextEditor/Nodes/ImageNode.tsx +0 -100
  49. package/src/components/RichTextEditor/Plugins/AutoFocus.tsx +0 -12
  50. package/src/components/RichTextEditor/Plugins/ImagePlugin.tsx +0 -45
  51. package/src/components/RichTextEditor/Plugins/LinkEditorPlugin.tsx +0 -58
  52. package/src/components/RichTextEditor/Plugins/Toolbar.tsx +0 -412
  53. package/src/components/RichTextEditor/RichTextEditor.tsx +0 -105
  54. package/src/components/UploadModal.tsx +0 -109
  55. package/src/components/User.tsx +0 -17
  56. package/src/components/ValFormField.tsx +0 -574
  57. package/src/components/ValFullscreen.tsx +0 -1278
  58. package/src/components/ValMenu.tsx +0 -92
  59. package/src/components/ValOverlay.tsx +0 -488
  60. package/src/components/ValOverlayContext.tsx +0 -80
  61. package/src/components/ValWindow.stories.tsx +0 -146
  62. package/src/components/ValWindow.tsx +0 -220
  63. package/src/components/dashboard/DashboardButton.tsx +0 -25
  64. package/src/components/dashboard/DashboardDropdown.tsx +0 -59
  65. package/src/components/dashboard/Dropdown.stories.tsx +0 -11
  66. package/src/components/dashboard/Dropdown.tsx +0 -70
  67. package/src/components/dashboard/FormGroup.stories.tsx +0 -37
  68. package/src/components/dashboard/FormGroup.tsx +0 -42
  69. package/src/components/dashboard/Grid2.stories.tsx +0 -56
  70. package/src/components/dashboard/Grid2.tsx +0 -72
  71. package/src/components/dashboard/Tree.stories.tsx +0 -91
  72. package/src/components/dashboard/Tree.tsx +0 -72
  73. package/src/components/dashboard/ValDashboardEditor.tsx +0 -269
  74. package/src/components/dashboard/ValDashboardGrid.tsx +0 -142
  75. package/src/components/dashboard/ValTreeNavigator.tsx +0 -253
  76. package/src/components/forms/Form.tsx +0 -126
  77. package/src/components/forms/FormContainer.tsx +0 -24
  78. package/src/components/forms/ImageForm.tsx +0 -195
  79. package/src/components/forms/TextArea.tsx +0 -24
  80. package/src/components/ui/accordion.tsx +0 -58
  81. package/src/components/ui/alert-dialog.tsx +0 -139
  82. package/src/components/ui/avatar.tsx +0 -48
  83. package/src/components/ui/button.tsx +0 -56
  84. package/src/components/ui/calendar.tsx +0 -62
  85. package/src/components/ui/card.tsx +0 -86
  86. package/src/components/ui/checkbox.tsx +0 -28
  87. package/src/components/ui/command.tsx +0 -153
  88. package/src/components/ui/dialog.tsx +0 -120
  89. package/src/components/ui/dropdown-menu.tsx +0 -198
  90. package/src/components/ui/form.tsx +0 -177
  91. package/src/components/ui/input.tsx +0 -24
  92. package/src/components/ui/label.tsx +0 -24
  93. package/src/components/ui/popover.tsx +0 -29
  94. package/src/components/ui/progress.tsx +0 -26
  95. package/src/components/ui/radio-group.tsx +0 -42
  96. package/src/components/ui/scroll-area.tsx +0 -51
  97. package/src/components/ui/select.tsx +0 -119
  98. package/src/components/ui/switch.tsx +0 -27
  99. package/src/components/ui/tabs.tsx +0 -53
  100. package/src/components/ui/toggle.tsx +0 -43
  101. package/src/components/ui/tooltip.tsx +0 -28
  102. package/src/components/usePatch.ts +0 -86
  103. package/src/components/useTheme.ts +0 -45
  104. package/src/dto/SerializedSchema.ts +0 -69
  105. package/src/dto/Session.ts +0 -12
  106. package/src/dto/SessionMode.ts +0 -5
  107. package/src/dto/Tree.ts +0 -18
  108. package/src/exports.ts +0 -6
  109. package/src/index.css +0 -115
  110. package/src/index.tsx +0 -14
  111. package/src/lib/IValStore.ts +0 -6
  112. package/src/lib/utils.ts +0 -6
  113. package/src/main.jsx +0 -10
  114. package/src/richtext/conversion/conversion.test.ts +0 -146
  115. package/src/richtext/conversion/lexicalToRichTextSource.test.ts +0 -89
  116. package/src/richtext/conversion/lexicalToRichTextSource.ts +0 -285
  117. package/src/richtext/conversion/parseRichTextSource.test.ts +0 -469
  118. package/src/richtext/conversion/parseRichTextSource.ts +0 -233
  119. package/src/richtext/conversion/richTextSourceToLexical.test.ts +0 -381
  120. package/src/richtext/conversion/richTextSourceToLexical.ts +0 -293
  121. package/src/richtext/shadowRootPolyFill.js +0 -115
  122. package/src/server.ts +0 -70
  123. package/src/stories/Button.stories.tsx +0 -20
  124. package/src/stories/Checkbox.stories.tsx +0 -14
  125. package/src/stories/Dropdown.stories.tsx +0 -23
  126. package/src/stories/Introduction.mdx +0 -221
  127. package/src/stories/RichTextEditor.stories.tsx +0 -24
  128. package/src/stories/assets/code-brackets.svg +0 -1
  129. package/src/stories/assets/colors.svg +0 -1
  130. package/src/stories/assets/comments.svg +0 -1
  131. package/src/stories/assets/direction.svg +0 -1
  132. package/src/stories/assets/flow.svg +0 -1
  133. package/src/stories/assets/plugin.svg +0 -1
  134. package/src/stories/assets/repo.svg +0 -1
  135. package/src/stories/assets/stackalt.svg +0 -1
  136. package/src/utils/Remote.ts +0 -15
  137. package/src/utils/imageMimeType.ts +0 -23
  138. package/src/utils/readImage.ts +0 -54
  139. package/src/utils/resolvePath.ts +0 -32
  140. package/src/vite-env.d.ts +0 -1
  141. package/src/vite-index.tsx +0 -7
  142. package/src/vite-server.ts +0 -42
  143. package/tailwind.config.js +0 -83
  144. package/tsconfig.json +0 -19
  145. package/vite.config.ts +0 -43
@@ -1,381 +0,0 @@
1
- import { RichText, AnyRichTextOptions } from "@valbuild/core";
2
- import {
3
- toLexicalFormat,
4
- fromLexicalFormat,
5
- richTextSourceToLexical,
6
- LexicalRootNode,
7
- } from "./richTextSourceToLexical";
8
-
9
- describe("richtext conversion", () => {
10
- test("format conversion", () => {
11
- //
12
- expect(toLexicalFormat([])).toStrictEqual(0);
13
- expect(toLexicalFormat(["bold"])).toStrictEqual(1);
14
- expect(toLexicalFormat(["italic"])).toStrictEqual(2);
15
- expect(toLexicalFormat(["bold", "italic"])).toStrictEqual(3);
16
- expect(toLexicalFormat(["line-through"])).toStrictEqual(4);
17
- expect(toLexicalFormat(["bold", "line-through"])).toStrictEqual(5);
18
- expect(toLexicalFormat(["italic", "line-through"])).toStrictEqual(6);
19
- expect(toLexicalFormat(["bold", "italic", "line-through"])).toStrictEqual(
20
- 7
21
- );
22
- //
23
- expect(fromLexicalFormat(0)).toStrictEqual([]);
24
- expect(fromLexicalFormat(1)).toStrictEqual(["bold"]);
25
- expect(fromLexicalFormat(2)).toStrictEqual(["italic"]);
26
- expect(fromLexicalFormat(3)).toStrictEqual(["bold", "italic"]);
27
- expect(fromLexicalFormat(4)).toStrictEqual(["line-through"]);
28
- expect(fromLexicalFormat(5)).toStrictEqual(["bold", "line-through"]);
29
- expect(fromLexicalFormat(6)).toStrictEqual(["italic", "line-through"]);
30
- expect(fromLexicalFormat(7)).toStrictEqual([
31
- "bold",
32
- "italic",
33
- "line-through",
34
- ]);
35
- });
36
-
37
- test("basic toLexical", () => {
38
- const input: RichText<AnyRichTextOptions> = {
39
- _type: "richtext",
40
- children: [
41
- { tag: "h1", children: ["Title 1"] },
42
- { tag: "h2", children: ["Title 2"] },
43
- { tag: "h3", children: ["Title 3"] },
44
- { tag: "h4", children: ["Title 4"] },
45
- { tag: "h5", children: ["Title 5"] },
46
- { tag: "h6", children: ["Title 6"] },
47
- {
48
- tag: "p",
49
- children: [
50
- {
51
- tag: "span",
52
- classes: ["bold", "italic", "line-through"],
53
- children: ["Formatted span"],
54
- },
55
- ],
56
- },
57
- {
58
- tag: "p",
59
- children: ["Inline line break", { tag: "br", children: [] }],
60
- },
61
- { tag: "br", children: [] },
62
- { tag: "br", children: [] },
63
- {
64
- tag: "p",
65
- children: [
66
- { tag: "a", href: "https://example.com", children: ["Link"] },
67
- ],
68
- },
69
- {
70
- tag: "ul",
71
- children: [
72
- {
73
- tag: "li",
74
- children: [
75
- {
76
- tag: "ol",
77
- dir: "rtl",
78
- children: [
79
- {
80
- tag: "li",
81
- children: [
82
- {
83
- tag: "span",
84
- classes: ["italic"],
85
- children: ["number 1.1. breaking lines: "],
86
- },
87
- { tag: "br", children: [] },
88
- "after line break",
89
- ],
90
- },
91
- { tag: "li", children: ["number 1.2"] },
92
- ],
93
- },
94
- ],
95
- },
96
- ],
97
- },
98
- ],
99
- };
100
- const output: LexicalRootNode = {
101
- version: 1,
102
- format: "",
103
- indent: 0,
104
- direction: null,
105
- type: "root",
106
- children: [
107
- {
108
- version: 1,
109
- format: "",
110
- indent: 0,
111
- direction: null,
112
- type: "heading",
113
- tag: "h1",
114
- children: [
115
- {
116
- version: 1,
117
- format: "",
118
- indent: 0,
119
- direction: null,
120
- type: "text",
121
- text: "Title 1",
122
- },
123
- ],
124
- },
125
- {
126
- version: 1,
127
- format: "",
128
- indent: 0,
129
- direction: null,
130
- type: "heading",
131
- tag: "h2",
132
- children: [
133
- {
134
- version: 1,
135
- format: "",
136
- indent: 0,
137
- direction: null,
138
- type: "text",
139
- text: "Title 2",
140
- },
141
- ],
142
- },
143
- {
144
- version: 1,
145
- format: "",
146
- indent: 0,
147
- direction: null,
148
- type: "heading",
149
- tag: "h3",
150
- children: [
151
- {
152
- version: 1,
153
- format: "",
154
- indent: 0,
155
- direction: null,
156
- type: "text",
157
- text: "Title 3",
158
- },
159
- ],
160
- },
161
- {
162
- version: 1,
163
- format: "",
164
- indent: 0,
165
- direction: null,
166
- type: "heading",
167
- tag: "h4",
168
- children: [
169
- {
170
- version: 1,
171
- format: "",
172
- indent: 0,
173
- direction: null,
174
- type: "text",
175
- text: "Title 4",
176
- },
177
- ],
178
- },
179
- {
180
- version: 1,
181
- format: "",
182
- indent: 0,
183
- direction: null,
184
- type: "heading",
185
- tag: "h5",
186
- children: [
187
- {
188
- version: 1,
189
- format: "",
190
- indent: 0,
191
- direction: null,
192
- type: "text",
193
- text: "Title 5",
194
- },
195
- ],
196
- },
197
- {
198
- version: 1,
199
- format: "",
200
- indent: 0,
201
- direction: null,
202
- type: "heading",
203
- tag: "h6",
204
- children: [
205
- {
206
- version: 1,
207
- format: "",
208
- indent: 0,
209
- direction: null,
210
- type: "text",
211
- text: "Title 6",
212
- },
213
- ],
214
- },
215
- {
216
- version: 1,
217
- format: "",
218
- indent: 0,
219
- direction: null,
220
- type: "paragraph",
221
- children: [
222
- {
223
- version: 1,
224
- format: 7,
225
- indent: 0,
226
- direction: null,
227
- type: "text",
228
- text: "Formatted span",
229
- },
230
- ],
231
- },
232
- {
233
- version: 1,
234
- format: "",
235
- indent: 0,
236
- direction: null,
237
- type: "paragraph",
238
- children: [
239
- {
240
- version: 1,
241
- format: "",
242
- indent: 0,
243
- direction: null,
244
- type: "text",
245
- text: "Inline line break",
246
- },
247
- {
248
- version: 1,
249
- format: "",
250
- indent: 0,
251
- direction: null,
252
- type: "linebreak",
253
- },
254
- ],
255
- },
256
- {
257
- version: 1,
258
- format: "",
259
- indent: 0,
260
- direction: null,
261
- type: "paragraph",
262
- children: [],
263
- },
264
- {
265
- version: 1,
266
- format: "",
267
- indent: 0,
268
- direction: null,
269
- type: "paragraph",
270
- children: [],
271
- },
272
- {
273
- version: 1,
274
- format: "",
275
- indent: 0,
276
- direction: null,
277
- type: "paragraph",
278
- children: [
279
- {
280
- version: 1,
281
- format: "",
282
- indent: 0,
283
- direction: null,
284
- type: "link",
285
- url: "https://example.com",
286
- children: [
287
- {
288
- version: 1,
289
- format: "",
290
- indent: 0,
291
- direction: null,
292
- type: "text",
293
- text: "Link",
294
- },
295
- ],
296
- },
297
- ],
298
- },
299
- {
300
- version: 1,
301
- format: "",
302
- indent: 0,
303
- direction: null,
304
- type: "list",
305
- listType: "bullet",
306
- children: [
307
- {
308
- version: 1,
309
- format: "",
310
- indent: 0,
311
- direction: null,
312
- type: "listitem",
313
- children: [
314
- {
315
- version: 1,
316
- format: "",
317
- indent: 0,
318
- direction: "rtl",
319
- type: "list",
320
- listType: "number",
321
- children: [
322
- {
323
- version: 1,
324
- format: "",
325
- indent: 0,
326
- direction: null,
327
- type: "listitem",
328
- children: [
329
- {
330
- version: 1,
331
- format: 2,
332
- indent: 0,
333
- direction: null,
334
- type: "text",
335
- text: "number 1.1. breaking lines: ",
336
- },
337
- {
338
- version: 1,
339
- format: "",
340
- indent: 0,
341
- direction: null,
342
- type: "linebreak",
343
- },
344
- {
345
- version: 1,
346
- format: "",
347
- indent: 0,
348
- direction: null,
349
- type: "text",
350
- text: "after line break",
351
- },
352
- ],
353
- },
354
- {
355
- version: 1,
356
- format: "",
357
- indent: 0,
358
- direction: null,
359
- type: "listitem",
360
- children: [
361
- {
362
- version: 1,
363
- format: "",
364
- indent: 0,
365
- direction: null,
366
- type: "text",
367
- text: "number 1.2",
368
- },
369
- ],
370
- },
371
- ],
372
- },
373
- ],
374
- },
375
- ],
376
- },
377
- ],
378
- };
379
- expect(richTextSourceToLexical(input)).toStrictEqual(output);
380
- });
381
- });
@@ -1,293 +0,0 @@
1
- import {
2
- AnyRichTextOptions,
3
- HeadingNode as ValHeadingNode,
4
- ListItemNode as ValListItemNode,
5
- SpanNode as ValSpanNode,
6
- UnorderedListNode as ValUnorderedListNode,
7
- OrderedListNode as ValOrderedListNode,
8
- ParagraphNode as ValParagraphNode,
9
- RichTextNode as ValRichTextNode,
10
- LinkNode as ValLinkNode,
11
- ImageNode as ValImageNode,
12
- RichText,
13
- } from "@valbuild/core";
14
- import { ImagePayload } from "../../components/RichTextEditor/Nodes/ImageNode";
15
-
16
- /// Serialized Lexical Nodes:
17
- // TODO: replace with Lexical libs types - not currently exported?
18
-
19
- export type LexicalTextNode = CommonLexicalProps & {
20
- type: "text";
21
- text: string;
22
- format: "" | number;
23
- };
24
-
25
- type InlineNode = LexicalTextNode | LexicalLinkNode;
26
-
27
- export type LexicalParagraphNode = CommonLexicalProps & {
28
- type: "paragraph";
29
- children: (InlineNode | LexicalLineBreakNode)[];
30
- };
31
-
32
- export type LexicalHeadingNode = CommonLexicalProps & {
33
- type: "heading";
34
- tag: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
35
- children: InlineNode[];
36
- };
37
-
38
- export type LexicalListItemNode = CommonLexicalProps & {
39
- type: "listitem";
40
- children: (InlineNode | LexicalListNode | LexicalLineBreakNode)[];
41
- };
42
-
43
- export type LexicalListNode = CommonLexicalProps & {
44
- type: "list";
45
- listType: "bullet" | "number" | "checked";
46
- direction: "ltr" | "rtl" | null;
47
- children: LexicalListItemNode[];
48
- };
49
-
50
- export type LexicalImageNode = CommonLexicalProps & {
51
- type: "image";
52
- } & ImagePayload;
53
-
54
- export type LexicalLinkNode = CommonLexicalProps & {
55
- type: "link";
56
- url: string;
57
- children: LexicalTextNode[];
58
- };
59
-
60
- export type LexicalLineBreakNode = CommonLexicalProps & {
61
- type: "linebreak";
62
- };
63
-
64
- export type LexicalNode =
65
- | LexicalTextNode
66
- | LexicalParagraphNode
67
- | LexicalHeadingNode
68
- | LexicalListItemNode
69
- | LexicalListNode
70
- | LexicalImageNode
71
- | LexicalLineBreakNode
72
- | LexicalLinkNode;
73
-
74
- export type LexicalRootNode = {
75
- type: "root";
76
- children: (LexicalHeadingNode | LexicalParagraphNode | LexicalListNode)[];
77
- version: 1;
78
- format: "left" | "start" | "center" | "right" | "end" | "justify" | "";
79
- direction: null | "ltr" | "rtl";
80
- } & CommonLexicalProps;
81
-
82
- export const COMMON_LEXICAL_PROPS = {
83
- version: 1,
84
- format: "" as number | "",
85
- indent: 0,
86
- direction: null as null | "ltr" | "rtl",
87
- } as const;
88
-
89
- type CommonLexicalProps = typeof COMMON_LEXICAL_PROPS;
90
-
91
- export function toLexicalNode(
92
- node: ValRichTextNode<AnyRichTextOptions>,
93
- useBreakNode = false
94
- ): LexicalNode {
95
- if (typeof node === "string") {
96
- return {
97
- ...COMMON_LEXICAL_PROPS,
98
- type: "text",
99
- format: "",
100
- text: node,
101
- };
102
- }
103
- if ("tag" in node) {
104
- switch (node.tag) {
105
- case "h1":
106
- return toLexicalHeadingNode(node);
107
- case "h2":
108
- return toLexicalHeadingNode(node);
109
- case "h3":
110
- return toLexicalHeadingNode(node);
111
- case "h4":
112
- return toLexicalHeadingNode(node);
113
- case "h5":
114
- return toLexicalHeadingNode(node);
115
- case "h6":
116
- return toLexicalHeadingNode(node);
117
- case "li":
118
- return toLexicalListItemNode(node);
119
- case "p":
120
- return toLexicalParagraphNode(node);
121
- case "ul":
122
- return toLexicalListNode(node);
123
- case "ol":
124
- return toLexicalListNode(node);
125
- case "span":
126
- return toLexicalTextNode(node);
127
- case "a":
128
- return toLexicalLinkNode(node);
129
- case "img":
130
- return toLexicalImageNode(node);
131
- case "br":
132
- if (useBreakNode) {
133
- return {
134
- ...COMMON_LEXICAL_PROPS,
135
- type: "linebreak",
136
- };
137
- }
138
- return toLexicalPseudoLineBreakNode();
139
- default:
140
- throw Error("Unexpected node tag: " + JSON.stringify(node, null, 2));
141
- }
142
- } else {
143
- throw Error("Unexpected node: " + JSON.stringify(node, null, 2));
144
- }
145
- }
146
-
147
- function toLexicalImageNode(
148
- node: ValImageNode<AnyRichTextOptions>
149
- ): LexicalImageNode {
150
- const url = node.src;
151
- return {
152
- ...COMMON_LEXICAL_PROPS,
153
- type: "image",
154
- src: url,
155
- width: node.width,
156
- height: node.height,
157
- // TODO: altText
158
- };
159
- }
160
-
161
- function toLexicalLinkNode(
162
- link: ValLinkNode<AnyRichTextOptions>
163
- ): LexicalLinkNode {
164
- return {
165
- ...COMMON_LEXICAL_PROPS,
166
- type: "link",
167
- url: link.href,
168
- children: link.children.map((child) =>
169
- toLexicalNode(child)
170
- ) as LexicalLinkNode["children"],
171
- };
172
- }
173
- export function richTextSourceToLexical(
174
- richtext: RichText<AnyRichTextOptions>
175
- ): LexicalRootNode {
176
- return {
177
- ...COMMON_LEXICAL_PROPS,
178
- format: "",
179
- type: "root",
180
- children: richtext.children.map((child) =>
181
- toLexicalNode(child)
182
- ) as LexicalRootNode["children"],
183
- };
184
- }
185
-
186
- function toLexicalHeadingNode(
187
- heading: ValHeadingNode<AnyRichTextOptions>
188
- ): LexicalHeadingNode {
189
- return {
190
- ...COMMON_LEXICAL_PROPS,
191
- type: "heading",
192
- tag: heading.tag,
193
- children: heading.children.map((child) =>
194
- toLexicalNode(child)
195
- ) as LexicalHeadingNode["children"],
196
- };
197
- }
198
-
199
- function toLexicalParagraphNode(
200
- paragraph: ValParagraphNode<AnyRichTextOptions>
201
- ): LexicalParagraphNode {
202
- return {
203
- ...COMMON_LEXICAL_PROPS,
204
- type: "paragraph",
205
- children: paragraph.children.map((child) =>
206
- toLexicalNode(child, true)
207
- ) as LexicalParagraphNode["children"],
208
- };
209
- }
210
-
211
- // Lexical does not support line breaks, so we convert them to empty paragraphs
212
- function toLexicalPseudoLineBreakNode(): LexicalParagraphNode {
213
- return {
214
- ...COMMON_LEXICAL_PROPS,
215
- type: "paragraph",
216
- children: [] as LexicalParagraphNode["children"],
217
- };
218
- }
219
-
220
- function toLexicalListItemNode(
221
- listItem: ValListItemNode<AnyRichTextOptions>
222
- ): LexicalListItemNode {
223
- return {
224
- ...COMMON_LEXICAL_PROPS,
225
- type: "listitem",
226
- children: listItem.children.map((child) =>
227
- toLexicalNode(child, true)
228
- ) as LexicalListItemNode["children"],
229
- };
230
- }
231
-
232
- function toLexicalListNode(
233
- list:
234
- | ValUnorderedListNode<AnyRichTextOptions>
235
- | ValOrderedListNode<AnyRichTextOptions>
236
- ): LexicalListNode {
237
- return {
238
- ...COMMON_LEXICAL_PROPS,
239
- type: "list",
240
- listType: list.tag === "ol" ? "number" : "bullet",
241
- children: list.children.map((child) =>
242
- toLexicalNode(child)
243
- ) as LexicalListNode["children"],
244
- ...(list.dir ? { direction: list.dir } : { direction: null }),
245
- };
246
- }
247
-
248
- const FORMAT_MAPPING = {
249
- bold: 1, // 0001
250
- italic: 2, // 0010
251
- "line-through": 4, // 0100
252
- // underline: 8, // 1000
253
- };
254
-
255
- export function toLexicalFormat(
256
- classes: (keyof typeof FORMAT_MAPPING)[]
257
- ): number {
258
- return classes.reduce(
259
- (prev, curr) => prev | /* bitwise or */ FORMAT_MAPPING[curr],
260
- 0
261
- );
262
- }
263
-
264
- export function fromLexicalFormat(
265
- format: number
266
- ): (keyof typeof FORMAT_MAPPING)[] {
267
- return Object.entries(FORMAT_MAPPING).flatMap(([key, value]) => {
268
- if ((value & /* bitwise and */ format) === value) {
269
- return [key as keyof typeof FORMAT_MAPPING];
270
- }
271
- return [];
272
- });
273
- }
274
-
275
- function toLexicalTextNode(
276
- spanNode: ValSpanNode<AnyRichTextOptions>
277
- ): LexicalTextNode {
278
- const child = spanNode.children[0];
279
- if (typeof child === "string") {
280
- return {
281
- ...COMMON_LEXICAL_PROPS,
282
- type: "text",
283
- text: child,
284
- format: toLexicalFormat(spanNode.classes),
285
- };
286
- } else {
287
- // recurse the spans and merge their classes
288
- return toLexicalTextNode({
289
- ...child,
290
- classes: spanNode.classes.concat(child.classes),
291
- });
292
- }
293
- }