@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,469 +0,0 @@
1
- import { initVal } from "@valbuild/core";
2
- import { parseRichTextSource } from "./parseRichTextSource";
3
-
4
- const { val } = initVal();
5
-
6
- //MD to HTML
7
- describe("richtext", () => {
8
- test("basic h1", () => {
9
- const r = val.richtext`# Title 1`;
10
- expect(parseRichTextSource(r).children).toStrictEqual([
11
- { tag: "h1", children: ["Title 1"] },
12
- ]);
13
- });
14
-
15
- test("basic complete", () => {
16
- const r = val.richtext`# Title 1
17
- ## Title 2
18
-
19
- Paragraph 1 2 3 4 5. Words *italic* **bold**
20
- `;
21
- expect(parseRichTextSource(r).children).toStrictEqual([
22
- { tag: "h1", children: ["Title 1"] },
23
- { tag: "h2", children: ["Title 2"] },
24
- {
25
- tag: "p",
26
- children: [
27
- "Paragraph 1 2 3 4 5. Words ",
28
- { tag: "span", classes: ["italic"], children: ["italic"] },
29
- " ",
30
- { tag: "span", classes: ["bold"], children: ["bold"] },
31
- ],
32
- },
33
- ]);
34
- });
35
-
36
- test.skip("strong and emphasis merged spans", () => {
37
- // TODO: currently we do not merge
38
- const r = val.richtext`Which classes?
39
- ***All of them!***
40
- `;
41
- expect(parseRichTextSource(r).children).toStrictEqual([
42
- {
43
- tag: "p",
44
- children: [
45
- "Which classes?\n",
46
- {
47
- tag: "span",
48
- classes: ["italic", "bold"],
49
- children: ["All of them!"],
50
- },
51
- ],
52
- },
53
- ]);
54
- });
55
-
56
- test("line through", () => {
57
- // TODO: currently we do not merge
58
- const r = val.richtext`~~line through~~`;
59
- expect(parseRichTextSource(r).children).toStrictEqual([
60
- {
61
- tag: "p",
62
- children: [
63
- {
64
- tag: "span",
65
- classes: ["line-through"],
66
- children: ["line through"],
67
- },
68
- ],
69
- },
70
- ]);
71
- });
72
-
73
- test("2 paragraphs", () => {
74
- const r = val.richtext`# Title 1
75
-
76
- First paragraph
77
-
78
- Second paragraph
79
- `;
80
- expect(parseRichTextSource(r).children).toStrictEqual([
81
- { tag: "h1", children: ["Title 1"] },
82
- { tag: "p", children: ["First paragraph"] },
83
- { tag: "p", children: ["Second paragraph"] },
84
- ]);
85
- });
86
-
87
- test("basic lists", () => {
88
- const r = val.richtext`A bullet list:
89
-
90
- - bullet 1
91
- - bullet 2
92
- `;
93
- expect(parseRichTextSource(r).children).toStrictEqual([
94
- { tag: "p", children: ["A bullet list:"] },
95
- {
96
- tag: "ul",
97
- children: [
98
- { tag: "li", children: ["bullet 1"] },
99
- { tag: "li", children: ["bullet 2"] },
100
- ],
101
- },
102
- ]);
103
- });
104
-
105
- test("lists with line breaks", () => {
106
- const r = val.richtext`A bullet list:
107
-
108
- - bullet 1
109
- - bullet 2
110
- break this line
111
- `;
112
- expect(parseRichTextSource(r).children).toStrictEqual([
113
- { tag: "p", children: ["A bullet list:"] },
114
- {
115
- tag: "ul",
116
- children: [
117
- {
118
- tag: "li",
119
- children: ["bullet 1"],
120
- },
121
- {
122
- tag: "li",
123
- children: [
124
- "bullet 2",
125
- { tag: "br", children: [] },
126
- "break this line",
127
- ],
128
- },
129
- ],
130
- },
131
- ]);
132
- });
133
-
134
- test("special chars", () => {
135
- const r = val.richtext`# "Title 1"
136
-
137
- Beautiful "quotes" and 'single quotes'
138
-
139
- Some crocodiles: < >
140
-
141
- Ampersand: &
142
-
143
- `;
144
- expect(parseRichTextSource(r).children).toStrictEqual([
145
- { tag: "h1", children: ['"Title 1"'] },
146
- { tag: "p", children: [`Beautiful "quotes" and 'single quotes'`] },
147
- { tag: "p", children: ["Some crocodiles: < >"] },
148
- { tag: "p", children: ["Ampersand: &"] },
149
- ]);
150
- });
151
-
152
- test("lists", () => {
153
- const r = val.richtext`# Title 1
154
-
155
- A paragraph
156
-
157
- A bullet list:
158
- - bullet 1
159
- - bullet 2
160
-
161
- A numbered list:
162
- 1. number 1
163
- 2. number 2
164
-
165
- A nested list:
166
- - bullet 1:
167
- 1. number 1.1
168
- 2. number 1.2
169
- - bullet 2:
170
- - bullet 2.1
171
- - bullet 2.2
172
- `;
173
- expect(parseRichTextSource(r).children).toStrictEqual([
174
- { tag: "h1", children: ["Title 1"] },
175
- { tag: "p", children: ["A paragraph"] },
176
- { tag: "p", children: ["A bullet list:"] },
177
- {
178
- tag: "ul",
179
- children: [
180
- { tag: "li", children: ["bullet 1"] },
181
- { tag: "li", children: ["bullet 2"] },
182
- ],
183
- },
184
- { tag: "p", children: ["A numbered list:"] },
185
- {
186
- tag: "ol",
187
- children: [
188
- { tag: "li", children: ["number 1"] },
189
- { tag: "li", children: ["number 2"] },
190
- ],
191
- },
192
- { tag: "p", children: ["A nested list:"] },
193
- {
194
- tag: "ul",
195
- children: [
196
- {
197
- tag: "li",
198
- children: [
199
- "bullet 1:",
200
- {
201
- tag: "ol",
202
- children: [
203
- { tag: "li", children: ["number 1.1"] },
204
- { tag: "li", children: ["number 1.2"] },
205
- ],
206
- },
207
- ],
208
- },
209
- {
210
- tag: "li",
211
- children: [
212
- "bullet 2:",
213
- {
214
- tag: "ul",
215
- children: [
216
- { tag: "li", children: ["bullet 2.1"] },
217
- { tag: "li", children: ["bullet 2.2"] },
218
- ],
219
- },
220
- ],
221
- },
222
- ],
223
- },
224
- ]);
225
- });
226
-
227
- test("br tokens", () => {
228
- const r = val.richtext`1 år 400,- kinokveld
229
- 5 år 5000,- en kveld i tretoppene`;
230
- expect(parseRichTextSource(r).children).toStrictEqual([
231
- {
232
- tag: "p",
233
- children: [
234
- "1 år 400,- kinokveld",
235
- { tag: "br", children: [] },
236
- "5 år 5000,- en kveld i tretoppene",
237
- ],
238
- },
239
- ]);
240
- });
241
-
242
- test("multiple br tokens", () => {
243
- const r = val.richtext`1 år 400,- kinokveld
244
- 2 år 1000,- kulturell opplevelse
245
- 3 år 2000,- mat i fjeset
246
- 4 år 500,- nørding i bokhandel
247
- 5 år 5000,- en kveld i tretoppene
248
- 6 år 1200,- ta smaksløkene på trim
249
- 7 år 2500,- gjør en forskjell`;
250
- expect(parseRichTextSource(r).children).toStrictEqual([
251
- {
252
- tag: "p",
253
- children: [
254
- "1 år 400,- kinokveld",
255
- { tag: "br", children: [] },
256
- "2 år 1000,- kulturell opplevelse",
257
- { tag: "br", children: [] },
258
- "3 år 2000,- mat i fjeset",
259
- { tag: "br", children: [] },
260
- "4 år 500,- nørding i bokhandel",
261
- { tag: "br", children: [] },
262
- "5 år 5000,- en kveld i tretoppene",
263
- { tag: "br", children: [] },
264
- "6 år 1200,- ta smaksløkene på trim",
265
- { tag: "br", children: [] },
266
- "7 år 2500,- gjør en forskjell",
267
- ],
268
- },
269
- ]);
270
- });
271
-
272
- test("image", () => {
273
- const r = val.richtext`# Title 1
274
-
275
- Below we have an image block:
276
-
277
- ${val.file("/public/foo.png", {
278
- width: 100,
279
- height: 100,
280
- sha256: "123",
281
- })}`;
282
- expect(parseRichTextSource(r).children).toStrictEqual([
283
- { tag: "h1", children: ["Title 1"] },
284
- { tag: "p", children: ["Below we have an image block:"] },
285
- {
286
- tag: "p",
287
- children: [
288
- {
289
- src: "/foo.png?sha256=123",
290
- tag: "img",
291
- width: 100,
292
- height: 100,
293
- children: [],
294
- },
295
- ],
296
- },
297
- ]);
298
- });
299
-
300
- test("markdown link", () => {
301
- const r = val.richtext`# Title 1
302
-
303
- Below we have a url: [google](https://google.com)`;
304
- expect(parseRichTextSource(r).children).toStrictEqual([
305
- { tag: "h1", children: ["Title 1"] },
306
- {
307
- tag: "p",
308
- children: [
309
- "Below we have a url: ",
310
- {
311
- href: "https://google.com",
312
- tag: "a",
313
- children: ["google"],
314
- },
315
- ],
316
- },
317
- ]);
318
- });
319
-
320
- test("block link", () => {
321
- const r = val.richtext`# Title 1
322
-
323
- Below we have a url:
324
-
325
- ${val.link("google", { href: "https://google.com" })}`;
326
- expect(parseRichTextSource(r).children).toStrictEqual([
327
- { tag: "h1", children: ["Title 1"] },
328
- { tag: "p", children: ["Below we have a url:"] },
329
- {
330
- tag: "p",
331
- children: [
332
- {
333
- tag: "a",
334
- href: "https://google.com",
335
- children: ["google"],
336
- },
337
- ],
338
- },
339
- ]);
340
- });
341
-
342
- test("inline link", () => {
343
- const r = val.richtext`# Title 1
344
-
345
- Below we have a url: ${val.link("google", { href: "https://google.com" })}`;
346
- expect(parseRichTextSource(r).children).toStrictEqual([
347
- { tag: "h1", children: ["Title 1"] },
348
- {
349
- tag: "p",
350
- children: [
351
- "Below we have a url: ",
352
- {
353
- href: "https://google.com",
354
- tag: "a",
355
- children: ["google"],
356
- },
357
- ],
358
- },
359
- ]);
360
- });
361
-
362
- test("inline link with bold", () => {
363
- const r = val.richtext`# Title 1
364
-
365
- Inline link -> ${val.link("**google**", { href: "https://google.com" })}`;
366
-
367
- // source:
368
- expect(parseRichTextSource(r).children).toStrictEqual([
369
- { tag: "h1", children: ["Title 1"] },
370
- {
371
- tag: "p",
372
- children: [
373
- "Inline link -> ",
374
- {
375
- href: "https://google.com",
376
- tag: "a",
377
- children: [
378
- {
379
- tag: "span",
380
- classes: ["bold"],
381
- children: ["google"],
382
- },
383
- ],
384
- },
385
- ],
386
- },
387
- ]);
388
- });
389
-
390
- test("https:// in link description", () => {
391
- const r = val.richtext`# Title 1
392
-
393
- Inline link -> ${val.link("https://google.com", {
394
- href: "https://google.com",
395
- })}`;
396
-
397
- expect(parseRichTextSource(r).children).toStrictEqual([
398
- { tag: "h1", children: ["Title 1"] },
399
- {
400
- tag: "p",
401
- children: [
402
- "Inline link -> ",
403
- {
404
- tag: "a",
405
- href: "https://google.com",
406
- children: ["https://google.com"],
407
- },
408
- ],
409
- },
410
- ]);
411
- });
412
-
413
- test("auto link does nothing", () => {
414
- const r = val.richtext`# Title 1
415
-
416
- No transform here -> https://google.com
417
-
418
- Transform this:
419
- [https://google.com](https://google.com)
420
- `;
421
-
422
- expect(parseRichTextSource(r).children).toStrictEqual([
423
- { tag: "h1", children: ["Title 1"] },
424
- {
425
- tag: "p",
426
- children: ["No transform here -> ", "https://google.com"],
427
- },
428
- {
429
- tag: "p",
430
- children: [
431
- "Transform this:\n",
432
- {
433
- tag: "a",
434
- href: "https://google.com",
435
- children: ["https://google.com"],
436
- },
437
- ],
438
- },
439
- ]);
440
- });
441
-
442
- test("breaks", () => {
443
- const r = val.richtext`
444
- # Title 1
445
-
446
- Foo
447
-
448
- <br>
449
-
450
- Bar
451
- `;
452
- // source:
453
- expect(parseRichTextSource(r).children).toStrictEqual([
454
- { tag: "h1", children: ["Title 1"] },
455
- {
456
- tag: "p",
457
- children: ["Foo"],
458
- },
459
- {
460
- tag: "br",
461
- children: [],
462
- },
463
- {
464
- tag: "p",
465
- children: ["Bar"],
466
- },
467
- ]);
468
- });
469
- });
@@ -1,233 +0,0 @@
1
- import * as marked from "marked";
2
- import {
3
- OrderedListNode,
4
- AnyRichTextOptions,
5
- UnorderedListNode,
6
- LinkSource,
7
- RichTextNode,
8
- SpanNode,
9
- LinkNode,
10
- ListItemNode,
11
- RichTextOptions,
12
- RichTextSource,
13
- RichText,
14
- VAL_EXTENSION,
15
- FileSource,
16
- ParagraphNode,
17
- HeadingNode,
18
- Internal,
19
- } from "@valbuild/core";
20
-
21
- const VAL_START_TAG_PREFIX = '<val value="';
22
- const VAL_START_TAG_SUFFIX = '">';
23
- const VAL_END_TAG = "</val>";
24
-
25
- type AnyListChildren =
26
- | OrderedListNode<AnyRichTextOptions>["children"]
27
- | UnorderedListNode<AnyRichTextOptions>["children"];
28
-
29
- type ImageSource = FileSource<{
30
- width: number;
31
- height: number;
32
- sha256: string;
33
- }>;
34
-
35
- function parseTokens(
36
- tokens: marked.Token[],
37
- sourceNodes: (ImageSource | LinkSource)[],
38
- cursor: number,
39
- insideList = false
40
- ): { children: RichTextNode<AnyRichTextOptions>[]; cursor: number } {
41
- const children: RichTextNode<AnyRichTextOptions>[] = [];
42
- while (cursor < tokens.length) {
43
- const token = tokens[cursor];
44
- if (token.type === "heading") {
45
- children.push({
46
- tag: `h${token.depth as 1 | 2 | 3 | 4 | 5 | 6}`,
47
- children: parseTokens(token.tokens ? token.tokens : [], sourceNodes, 0)
48
- .children as HeadingNode<AnyRichTextOptions>["children"],
49
- });
50
- } else if (token.type === "paragraph") {
51
- children.push({
52
- tag: "p",
53
- children: parseTokens(token.tokens ? token.tokens : [], sourceNodes, 0)
54
- .children as ParagraphNode<AnyRichTextOptions>["children"],
55
- });
56
- } else if (token.type === "strong") {
57
- children.push({
58
- tag: "span",
59
- classes: ["bold"],
60
- children: parseTokens(token.tokens ? token.tokens : [], sourceNodes, 0)
61
- .children as SpanNode<AnyRichTextOptions>["children"],
62
- });
63
- } else if (token.type === "em") {
64
- children.push({
65
- tag: "span",
66
- classes: ["italic"],
67
- children: parseTokens(token.tokens ? token.tokens : [], sourceNodes, 0)
68
- .children as SpanNode<AnyRichTextOptions>["children"],
69
- });
70
- } else if (token.type === "del") {
71
- children.push({
72
- tag: "span",
73
- classes: ["line-through"],
74
- children: parseTokens(token.tokens ? token.tokens : [], sourceNodes, 0)
75
- .children as SpanNode<AnyRichTextOptions>["children"],
76
- });
77
- } else if (token.type === "text") {
78
- if ("tokens" in token && Array.isArray(token.tokens)) {
79
- children.push(
80
- ...parseTokens(token.tokens, sourceNodes, cursor, insideList).children
81
- );
82
- } else {
83
- if (insideList && typeof token.raw === "string") {
84
- const lines = token.raw.split("\n");
85
- const tags: RichTextNode<AnyRichTextOptions>[] = lines.flatMap(
86
- (line, i) => {
87
- if (i === lines.length - 1) return [line];
88
- return [line, { tag: "br", children: [] }];
89
- }
90
- );
91
- children.push(...tags);
92
- } else {
93
- children.push(token.raw);
94
- }
95
- }
96
- } else if (token.type === "list") {
97
- children.push({
98
- tag: token.ordered ? "ol" : "ul",
99
- children: parseTokens(token.items, sourceNodes, 0)
100
- .children as AnyListChildren,
101
- });
102
- } else if (token.type === "list_item") {
103
- children.push({
104
- tag: "li",
105
- children: parseTokens(
106
- token.tokens ? token.tokens : [],
107
- sourceNodes,
108
- 0,
109
- true
110
- ).children as ListItemNode<AnyRichTextOptions>["children"],
111
- });
112
- } else if (token.type === "space") {
113
- // do nothing
114
- } else if (token.type === "html") {
115
- if (token.text === VAL_END_TAG) {
116
- return { children, cursor };
117
- }
118
- const suffixIndex = token.text.indexOf(VAL_START_TAG_SUFFIX);
119
- if (token.text.startsWith(VAL_START_TAG_PREFIX) && suffixIndex > -1) {
120
- const number = Number(
121
- token.text.slice(VAL_START_TAG_PREFIX.length, suffixIndex)
122
- );
123
- if (Number.isNaN(number)) {
124
- throw Error(
125
- `Illegal val intermediate node: ${JSON.stringify(token)}`
126
- );
127
- }
128
- const { children: subChildren, cursor: subCursor } = parseTokens(
129
- tokens.map((token) => {
130
- if (token.type === "link" || token.type === "list") {
131
- return {
132
- type: "text",
133
- raw: token.raw,
134
- text: token.raw,
135
- };
136
- }
137
- return token;
138
- }),
139
- sourceNodes,
140
- cursor + 1
141
- );
142
- const sourceNode = sourceNodes[number];
143
- if (sourceNode._type === "link") {
144
- children.push({
145
- tag: "a",
146
- href: sourceNode.href,
147
- children: subChildren as LinkNode<AnyRichTextOptions>["children"],
148
- });
149
- } else if (sourceNode._type === "file") {
150
- children.push({
151
- tag: "img",
152
- src: Internal.convertFileSource(sourceNode).url,
153
- width: sourceNode.metadata?.width,
154
- height: sourceNode.metadata?.height,
155
- children: [],
156
- });
157
- }
158
-
159
- cursor = subCursor;
160
- }
161
- const br_html_regex = /<br\s*\/?>/gi; // matches <br>, <br/>, <br />; case insensitive
162
- if (token.text.trim().match(br_html_regex)) {
163
- children.push({
164
- tag: "br",
165
- children: [],
166
- });
167
- }
168
- } else if (token.type === "link") {
169
- if (token.raw === token.href) {
170
- // avoid auto-linking (provided by github flavoured markdown, but we want strikethrough so keep it enabled)
171
- children.push(token.raw);
172
- } else {
173
- children.push({
174
- tag: "a",
175
- href: token.href,
176
- children: parseTokens(
177
- token.tokens ? token.tokens : [],
178
- sourceNodes,
179
- 0
180
- ).children as LinkNode<AnyRichTextOptions>["children"],
181
- });
182
- }
183
- } else if (token.type === "br") {
184
- children.push({
185
- tag: "br",
186
- children: [],
187
- });
188
- } else {
189
- console.error(
190
- `Could not parse markdown: unsupported token type: ${token.type}. Found: ${token.raw}`
191
- );
192
- }
193
- cursor++;
194
- }
195
- return { children, cursor };
196
- }
197
-
198
- export function parseRichTextSource<O extends RichTextOptions>({
199
- templateStrings,
200
- exprs: nodes,
201
- }: RichTextSource<O>): RichText<O> {
202
- // TODO: validate that templateStrings does not contain VAL_NODE_PREFIX
203
- const inputText = templateStrings
204
- .flatMap((templateString, i) => {
205
- const node = nodes[i];
206
- if (node) {
207
- if (node[VAL_EXTENSION] === "link") {
208
- return templateString.concat(
209
- `${VAL_START_TAG_PREFIX}${i}${VAL_START_TAG_SUFFIX}${node.children[0]}${VAL_END_TAG}`
210
- );
211
- } else {
212
- return templateString.concat(
213
- `${VAL_START_TAG_PREFIX}${i}${VAL_START_TAG_SUFFIX}${VAL_END_TAG}`
214
- );
215
- }
216
- }
217
- return templateString;
218
- })
219
- .join("");
220
- const tokenList = marked.lexer(inputText, {
221
- gfm: true,
222
- });
223
- const { children, cursor } = parseTokens(tokenList, nodes, 0);
224
- if (cursor !== tokenList.length) {
225
- throw Error(
226
- "Unexpectedly terminated markdown parsing. Possible reason: unclosed html tag?"
227
- );
228
- }
229
- return {
230
- [VAL_EXTENSION]: "richtext",
231
- children,
232
- } as RichText<O>;
233
- }