@valbuild/ui 0.26.0 → 0.27.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 (138) hide show
  1. package/package.json +7 -3
  2. package/server/.tmp/assets/index-082e6676.css +1 -0
  3. package/server/.tmp/assets/index-3108ab2a.js +197 -0
  4. package/{index.html → server/.tmp/index.html} +3 -1
  5. package/.babelrc.json +0 -10
  6. package/.storybook/main.js +0 -25
  7. package/.storybook/preview-head.html +0 -6
  8. package/.storybook/preview.js +0 -33
  9. package/.storybook/theme.css +0 -34
  10. package/CHANGELOG.md +0 -0
  11. package/components.json +0 -16
  12. package/fix-server-hack.js +0 -54
  13. package/fullscreen.vite.config.ts +0 -9
  14. package/jest.config.js +0 -4
  15. package/postcss.config.js +0 -6
  16. package/rollup.config.js +0 -23
  17. package/server.vite.config.ts +0 -31
  18. package/src/App.tsx +0 -73
  19. package/src/assets/icons/Bold.tsx +0 -23
  20. package/src/assets/icons/Chevron.tsx +0 -28
  21. package/src/assets/icons/FontColor.tsx +0 -30
  22. package/src/assets/icons/ImageIcon.tsx +0 -29
  23. package/src/assets/icons/Italic.tsx +0 -24
  24. package/src/assets/icons/Logo.tsx +0 -103
  25. package/src/assets/icons/Section.tsx +0 -41
  26. package/src/assets/icons/Strikethrough.tsx +0 -22
  27. package/src/assets/icons/TextIcon.tsx +0 -20
  28. package/src/assets/icons/Underline.tsx +0 -22
  29. package/src/assets/icons/Undo.tsx +0 -20
  30. package/src/components/Button.tsx +0 -68
  31. package/src/components/Checkbox.tsx +0 -51
  32. package/src/components/DraggableList.stories.tsx +0 -20
  33. package/src/components/DraggableList.tsx +0 -95
  34. package/src/components/Dropdown.tsx +0 -101
  35. package/src/components/EditButton.tsx +0 -10
  36. package/src/components/ErrorText.tsx +0 -3
  37. package/src/components/ExpandLogo.tsx +0 -72
  38. package/src/components/Grid.stories.tsx +0 -43
  39. package/src/components/Grid.tsx +0 -139
  40. package/src/components/RichTextEditor/ContentEditable.tsx +0 -117
  41. package/src/components/RichTextEditor/Nodes/ImageNode.tsx +0 -100
  42. package/src/components/RichTextEditor/Plugins/AutoFocus.tsx +0 -12
  43. package/src/components/RichTextEditor/Plugins/ImagePlugin.tsx +0 -45
  44. package/src/components/RichTextEditor/Plugins/LinkEditorPlugin.tsx +0 -58
  45. package/src/components/RichTextEditor/Plugins/Toolbar.tsx +0 -412
  46. package/src/components/RichTextEditor/RichTextEditor.tsx +0 -105
  47. package/src/components/UploadModal.tsx +0 -109
  48. package/src/components/User.tsx +0 -17
  49. package/src/components/ValFormField.tsx +0 -574
  50. package/src/components/ValFullscreen.tsx +0 -1278
  51. package/src/components/ValMenu.tsx +0 -92
  52. package/src/components/ValOverlay.tsx +0 -488
  53. package/src/components/ValOverlayContext.tsx +0 -80
  54. package/src/components/ValWindow.stories.tsx +0 -146
  55. package/src/components/ValWindow.tsx +0 -220
  56. package/src/components/dashboard/DashboardButton.tsx +0 -25
  57. package/src/components/dashboard/DashboardDropdown.tsx +0 -59
  58. package/src/components/dashboard/Dropdown.stories.tsx +0 -11
  59. package/src/components/dashboard/Dropdown.tsx +0 -70
  60. package/src/components/dashboard/FormGroup.stories.tsx +0 -37
  61. package/src/components/dashboard/FormGroup.tsx +0 -42
  62. package/src/components/dashboard/Grid2.stories.tsx +0 -56
  63. package/src/components/dashboard/Grid2.tsx +0 -72
  64. package/src/components/dashboard/Tree.stories.tsx +0 -91
  65. package/src/components/dashboard/Tree.tsx +0 -72
  66. package/src/components/dashboard/ValDashboardEditor.tsx +0 -269
  67. package/src/components/dashboard/ValDashboardGrid.tsx +0 -142
  68. package/src/components/dashboard/ValTreeNavigator.tsx +0 -253
  69. package/src/components/forms/Form.tsx +0 -126
  70. package/src/components/forms/FormContainer.tsx +0 -24
  71. package/src/components/forms/ImageForm.tsx +0 -195
  72. package/src/components/forms/TextArea.tsx +0 -24
  73. package/src/components/ui/accordion.tsx +0 -58
  74. package/src/components/ui/alert-dialog.tsx +0 -139
  75. package/src/components/ui/avatar.tsx +0 -48
  76. package/src/components/ui/button.tsx +0 -56
  77. package/src/components/ui/calendar.tsx +0 -62
  78. package/src/components/ui/card.tsx +0 -86
  79. package/src/components/ui/checkbox.tsx +0 -28
  80. package/src/components/ui/command.tsx +0 -153
  81. package/src/components/ui/dialog.tsx +0 -120
  82. package/src/components/ui/dropdown-menu.tsx +0 -198
  83. package/src/components/ui/form.tsx +0 -177
  84. package/src/components/ui/input.tsx +0 -24
  85. package/src/components/ui/label.tsx +0 -24
  86. package/src/components/ui/popover.tsx +0 -29
  87. package/src/components/ui/progress.tsx +0 -26
  88. package/src/components/ui/radio-group.tsx +0 -42
  89. package/src/components/ui/scroll-area.tsx +0 -51
  90. package/src/components/ui/select.tsx +0 -119
  91. package/src/components/ui/switch.tsx +0 -27
  92. package/src/components/ui/tabs.tsx +0 -53
  93. package/src/components/ui/toggle.tsx +0 -43
  94. package/src/components/ui/tooltip.tsx +0 -28
  95. package/src/components/usePatch.ts +0 -86
  96. package/src/components/useTheme.ts +0 -45
  97. package/src/dto/SerializedSchema.ts +0 -69
  98. package/src/dto/Session.ts +0 -12
  99. package/src/dto/SessionMode.ts +0 -5
  100. package/src/dto/Tree.ts +0 -18
  101. package/src/exports.ts +0 -6
  102. package/src/index.css +0 -115
  103. package/src/index.tsx +0 -14
  104. package/src/lib/IValStore.ts +0 -6
  105. package/src/lib/utils.ts +0 -6
  106. package/src/main.jsx +0 -10
  107. package/src/richtext/conversion/conversion.test.ts +0 -146
  108. package/src/richtext/conversion/lexicalToRichTextSource.test.ts +0 -89
  109. package/src/richtext/conversion/lexicalToRichTextSource.ts +0 -285
  110. package/src/richtext/conversion/parseRichTextSource.test.ts +0 -469
  111. package/src/richtext/conversion/parseRichTextSource.ts +0 -233
  112. package/src/richtext/conversion/richTextSourceToLexical.test.ts +0 -381
  113. package/src/richtext/conversion/richTextSourceToLexical.ts +0 -293
  114. package/src/richtext/shadowRootPolyFill.js +0 -115
  115. package/src/server.ts +0 -70
  116. package/src/stories/Button.stories.tsx +0 -20
  117. package/src/stories/Checkbox.stories.tsx +0 -14
  118. package/src/stories/Dropdown.stories.tsx +0 -23
  119. package/src/stories/Introduction.mdx +0 -221
  120. package/src/stories/RichTextEditor.stories.tsx +0 -24
  121. package/src/stories/assets/code-brackets.svg +0 -1
  122. package/src/stories/assets/colors.svg +0 -1
  123. package/src/stories/assets/comments.svg +0 -1
  124. package/src/stories/assets/direction.svg +0 -1
  125. package/src/stories/assets/flow.svg +0 -1
  126. package/src/stories/assets/plugin.svg +0 -1
  127. package/src/stories/assets/repo.svg +0 -1
  128. package/src/stories/assets/stackalt.svg +0 -1
  129. package/src/utils/Remote.ts +0 -15
  130. package/src/utils/imageMimeType.ts +0 -23
  131. package/src/utils/readImage.ts +0 -54
  132. package/src/utils/resolvePath.ts +0 -32
  133. package/src/vite-env.d.ts +0 -1
  134. package/src/vite-index.tsx +0 -7
  135. package/src/vite-server.ts +0 -42
  136. package/tailwind.config.js +0 -83
  137. package/tsconfig.json +0 -19
  138. 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
- }