@blocknote/core 0.41.1 → 0.42.1

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 (81) hide show
  1. package/dist/BlockNoteSchema-Bi-eeHal.js +3288 -0
  2. package/dist/BlockNoteSchema-Bi-eeHal.js.map +1 -0
  3. package/dist/BlockNoteSchema-DjDaA2C3.cjs +6 -0
  4. package/dist/BlockNoteSchema-DjDaA2C3.cjs.map +1 -0
  5. package/dist/blockToNode-DIfPWLH8.js +1140 -0
  6. package/dist/blockToNode-DIfPWLH8.js.map +1 -0
  7. package/dist/blockToNode-w7H99R6p.cjs +7 -0
  8. package/dist/blockToNode-w7H99R6p.cjs.map +1 -0
  9. package/dist/blocknote.cjs +4 -4
  10. package/dist/blocknote.cjs.map +1 -1
  11. package/dist/blocknote.js +1413 -1366
  12. package/dist/blocknote.js.map +1 -1
  13. package/dist/blocks.cjs +1 -1
  14. package/dist/blocks.js +1 -1
  15. package/dist/comments.cjs +1 -1
  16. package/dist/comments.cjs.map +1 -1
  17. package/dist/comments.js +49 -49
  18. package/dist/comments.js.map +1 -1
  19. package/dist/en-Cl87Uuyf.cjs.map +1 -1
  20. package/dist/en-njEqD7AG.js.map +1 -1
  21. package/dist/locales.cjs.map +1 -1
  22. package/dist/locales.js.map +1 -1
  23. package/dist/tsconfig.tsbuildinfo +1 -0
  24. package/dist/webpack-stats.json +1 -1
  25. package/dist/yjs.cjs +2 -0
  26. package/dist/yjs.cjs.map +1 -0
  27. package/dist/yjs.js +44 -0
  28. package/dist/yjs.js.map +1 -0
  29. package/package.json +30 -25
  30. package/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.ts +19 -6
  31. package/src/api/blockManipulation/commands/replaceBlocks/util/fixColumnList.ts +173 -0
  32. package/src/api/nodeConversions/nodeToBlock.ts +17 -14
  33. package/src/blocks/Code/block.ts +1 -0
  34. package/src/blocks/ListItem/NumberedListItem/IndexingPlugin.ts +2 -1
  35. package/src/blocks/defaultBlockTypeGuards.ts +7 -18
  36. package/src/comments/threadstore/yjs/YjsThreadStoreBase.ts +3 -1
  37. package/src/editor/BlockNoteEditor.test.ts +70 -1
  38. package/src/editor/BlockNoteEditor.ts +55 -4
  39. package/src/editor/managers/ExportManager.ts +1 -1
  40. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor-forked.json +2 -2
  41. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-editor.json +2 -2
  42. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap-forked.html +1 -1
  43. package/src/extensions/Collaboration/__snapshots__/fork-yjs-snap.html +1 -1
  44. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +10 -3
  45. package/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.test.ts +130 -0
  46. package/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.ts +34 -21
  47. package/src/extensions/Comments/CommentsPlugin.ts +37 -7
  48. package/src/extensions/KeyboardShortcuts/KeyboardShortcutsExtension.ts +30 -128
  49. package/src/extensions/SideMenu/SideMenuPlugin.ts +2 -0
  50. package/src/index.ts +1 -0
  51. package/src/schema/inlineContent/createSpec.ts +3 -0
  52. package/src/schema/inlineContent/types.ts +1 -0
  53. package/src/schema/schema.ts +49 -6
  54. package/src/schema/styles/createSpec.ts +6 -0
  55. package/src/schema/styles/types.ts +1 -0
  56. package/src/yjs/index.ts +1 -0
  57. package/src/yjs/utils.test.ts +1023 -0
  58. package/src/yjs/utils.ts +150 -0
  59. package/types/src/api/blockManipulation/commands/replaceBlocks/replaceBlocks.d.ts +1 -1
  60. package/types/src/api/blockManipulation/commands/replaceBlocks/util/fixColumnList.d.ts +32 -0
  61. package/types/src/api/nodeConversions/nodeToBlock.d.ts +1 -1
  62. package/types/src/editor/BlockNoteEditor.d.ts +6 -1
  63. package/types/src/editor/managers/ExportManager.d.ts +1 -1
  64. package/types/src/extensions/Collaboration/schemaMigration/migrationRules/moveColorAttributes.test.d.ts +1 -0
  65. package/types/src/extensions/Comments/CommentsPlugin.d.ts +1 -1
  66. package/types/src/index.d.ts +1 -0
  67. package/types/src/schema/inlineContent/createSpec.d.ts +1 -0
  68. package/types/src/schema/inlineContent/types.d.ts +1 -0
  69. package/types/src/schema/styles/createSpec.d.ts +1 -0
  70. package/types/src/schema/styles/types.d.ts +1 -0
  71. package/types/src/yjs/index.d.ts +1 -0
  72. package/types/src/yjs/utils.d.ts +55 -0
  73. package/types/src/yjs/utils.test.d.ts +1 -0
  74. package/dist/BlockNoteSchema-COA0fsXW.cjs +0 -11
  75. package/dist/BlockNoteSchema-COA0fsXW.cjs.map +0 -1
  76. package/dist/BlockNoteSchema-CYRHak18.js +0 -4375
  77. package/dist/BlockNoteSchema-CYRHak18.js.map +0 -1
  78. package/src/extensions/BackgroundColor/BackgroundColorMark.ts +0 -46
  79. package/src/extensions/TextColor/TextColorMark.ts +0 -38
  80. package/types/src/extensions/BackgroundColor/BackgroundColorMark.d.ts +0 -10
  81. package/types/src/extensions/TextColor/TextColorMark.d.ts +0 -10
@@ -0,0 +1,1023 @@
1
+ import { Block, docToBlocks } from "../index.js";
2
+ import { BlockNoteEditor } from "../editor/BlockNoteEditor.js";
3
+ import { describe, expect, it } from "vitest";
4
+ import * as Y from "yjs";
5
+ import {
6
+ _blocksToProsemirrorNode,
7
+ blocksToYDoc,
8
+ blocksToYXmlFragment,
9
+ yDocToBlocks,
10
+ yXmlFragmentToBlocks,
11
+ } from "./utils.js";
12
+
13
+ describe("Test yjs utils", () => {
14
+ const editor = BlockNoteEditor.create();
15
+
16
+ const testConversion = (testName: string, blocks: Block[]) => {
17
+ it(`${testName} - converts to and from prosemirror (doc)`, () => {
18
+ const node = _blocksToProsemirrorNode(editor, blocks);
19
+ const blockOutput = docToBlocks(node);
20
+ expect(blockOutput).toEqual(blocks);
21
+ });
22
+
23
+ it(`${testName} - converts to and from yjs (doc)`, () => {
24
+ const ydoc = blocksToYDoc(editor, blocks);
25
+ const blockOutput = yDocToBlocks(editor, ydoc);
26
+ expect(blockOutput).toEqual(blocks);
27
+ });
28
+
29
+ it(`${testName} - converts to and from yjs (fragment)`, () => {
30
+ const doc = new Y.Doc();
31
+ const fragment = doc.getXmlFragment("test");
32
+ blocksToYXmlFragment(editor, blocks, fragment);
33
+
34
+ const blockOutput = yXmlFragmentToBlocks(editor, fragment);
35
+ expect(blockOutput).toEqual(blocks);
36
+ });
37
+ };
38
+
39
+ describe("Original test case", () => {
40
+ const blocks: Block[] = [
41
+ {
42
+ id: "1",
43
+ type: "heading",
44
+ props: {
45
+ backgroundColor: "blue",
46
+ textColor: "yellow",
47
+ textAlignment: "right",
48
+ level: 2,
49
+ isToggleable: false,
50
+ },
51
+ content: [
52
+ {
53
+ type: "text",
54
+ text: "Heading ",
55
+ styles: {
56
+ bold: true,
57
+ underline: true,
58
+ },
59
+ },
60
+ {
61
+ type: "text",
62
+ text: "2",
63
+ styles: {
64
+ italic: true,
65
+ strike: true,
66
+ },
67
+ },
68
+ ],
69
+ children: [
70
+ {
71
+ id: "2",
72
+ type: "paragraph",
73
+ props: {
74
+ backgroundColor: "red",
75
+ textAlignment: "left",
76
+ textColor: "default",
77
+ },
78
+ content: [
79
+ {
80
+ type: "text",
81
+ text: "Paragraph",
82
+ styles: {},
83
+ },
84
+ ],
85
+ children: [],
86
+ },
87
+ {
88
+ id: "3",
89
+ type: "bulletListItem",
90
+ props: {
91
+ backgroundColor: "default",
92
+ textColor: "default",
93
+ textAlignment: "left",
94
+ },
95
+ content: [
96
+ {
97
+ type: "text",
98
+ text: "list item",
99
+ styles: {},
100
+ },
101
+ ],
102
+ children: [],
103
+ },
104
+ ],
105
+ },
106
+ {
107
+ id: "4",
108
+ type: "image",
109
+ props: {
110
+ backgroundColor: "default",
111
+ textAlignment: "left",
112
+ name: "Example",
113
+ url: "exampleURL",
114
+ caption: "Caption",
115
+ showPreview: true,
116
+ previewWidth: 256,
117
+ },
118
+ content: undefined,
119
+ children: [],
120
+ },
121
+ {
122
+ id: "5",
123
+ type: "image",
124
+ props: {
125
+ backgroundColor: "default",
126
+ textAlignment: "left",
127
+ name: "Example",
128
+ url: "exampleURL",
129
+ caption: "Caption",
130
+ showPreview: false,
131
+ previewWidth: 256,
132
+ },
133
+ content: undefined,
134
+ children: [],
135
+ },
136
+ ];
137
+
138
+ testConversion("original test case", blocks);
139
+ });
140
+
141
+ describe("Empty document", () => {
142
+ it("empty document - handles empty array", () => {
143
+ const blocks: Block[] = [];
144
+ const node = _blocksToProsemirrorNode(editor, blocks);
145
+ const blockOutput = docToBlocks(node);
146
+ expect(blockOutput).toEqual([]);
147
+ });
148
+
149
+ it("empty document - converts to and from yjs (doc)", () => {
150
+ const blocks: Block[] = [];
151
+ const ydoc = blocksToYDoc(editor, blocks);
152
+ const blockOutput = yDocToBlocks(editor, ydoc);
153
+ expect(blockOutput).toEqual([]);
154
+ });
155
+
156
+ it("empty document - converts to and from yjs (fragment)", () => {
157
+ const blocks: Block[] = [];
158
+ const doc = new Y.Doc();
159
+ const fragment = doc.getXmlFragment("test");
160
+ blocksToYXmlFragment(editor, blocks, fragment);
161
+
162
+ const blockOutput = yXmlFragmentToBlocks(editor, fragment);
163
+ expect(blockOutput).toEqual([]);
164
+ });
165
+ });
166
+
167
+ describe("Simple paragraphs", () => {
168
+ const blocks: Block[] = [
169
+ {
170
+ id: "1",
171
+ type: "paragraph",
172
+ props: {
173
+ backgroundColor: "default",
174
+ textColor: "default",
175
+ textAlignment: "left",
176
+ },
177
+ content: [
178
+ {
179
+ type: "text",
180
+ text: "First paragraph",
181
+ styles: {},
182
+ },
183
+ ],
184
+ children: [],
185
+ },
186
+ {
187
+ id: "2",
188
+ type: "paragraph",
189
+ props: {
190
+ backgroundColor: "default",
191
+ textColor: "default",
192
+ textAlignment: "center",
193
+ },
194
+ content: [
195
+ {
196
+ type: "text",
197
+ text: "Second paragraph",
198
+ styles: {},
199
+ },
200
+ ],
201
+ children: [],
202
+ },
203
+ ];
204
+ testConversion("simple paragraphs", blocks);
205
+ });
206
+
207
+ describe("Deeply nested lists", () => {
208
+ const blocks: Block[] = [
209
+ {
210
+ id: "1",
211
+ type: "bulletListItem",
212
+ props: {
213
+ backgroundColor: "default",
214
+ textColor: "default",
215
+ textAlignment: "left",
216
+ },
217
+ content: [
218
+ {
219
+ type: "text",
220
+ text: "Level 1",
221
+ styles: {},
222
+ },
223
+ ],
224
+ children: [
225
+ {
226
+ id: "2",
227
+ type: "bulletListItem",
228
+ props: {
229
+ backgroundColor: "default",
230
+ textColor: "default",
231
+ textAlignment: "left",
232
+ },
233
+ content: [
234
+ {
235
+ type: "text",
236
+ text: "Level 2",
237
+ styles: {},
238
+ },
239
+ ],
240
+ children: [
241
+ {
242
+ id: "3",
243
+ type: "bulletListItem",
244
+ props: {
245
+ backgroundColor: "default",
246
+ textColor: "default",
247
+ textAlignment: "left",
248
+ },
249
+ content: [
250
+ {
251
+ type: "text",
252
+ text: "Level 3",
253
+ styles: {},
254
+ },
255
+ ],
256
+ children: [
257
+ {
258
+ id: "4",
259
+ type: "bulletListItem",
260
+ props: {
261
+ backgroundColor: "default",
262
+ textColor: "default",
263
+ textAlignment: "left",
264
+ },
265
+ content: [
266
+ {
267
+ type: "text",
268
+ text: "Level 4",
269
+ styles: {},
270
+ },
271
+ ],
272
+ children: [],
273
+ },
274
+ ],
275
+ },
276
+ ],
277
+ },
278
+ ],
279
+ },
280
+ ];
281
+ testConversion("deeply nested lists", blocks);
282
+ });
283
+
284
+ describe("Numbered lists", () => {
285
+ const blocks = [
286
+ {
287
+ id: "1",
288
+ type: "numberedListItem",
289
+ props: {
290
+ backgroundColor: "default",
291
+ textColor: "default",
292
+ textAlignment: "left",
293
+ },
294
+ content: [
295
+ {
296
+ type: "text",
297
+ text: "First item",
298
+ styles: {},
299
+ },
300
+ ],
301
+ children: [],
302
+ },
303
+ {
304
+ id: "2",
305
+ type: "numberedListItem",
306
+ props: {
307
+ backgroundColor: "default",
308
+ textColor: "default",
309
+ textAlignment: "left",
310
+ },
311
+ content: [
312
+ {
313
+ type: "text",
314
+ text: "Second item",
315
+ styles: {},
316
+ },
317
+ ],
318
+ children: [
319
+ {
320
+ id: "3",
321
+ type: "numberedListItem",
322
+ props: {
323
+ backgroundColor: "default",
324
+ textColor: "default",
325
+ textAlignment: "left",
326
+ },
327
+ content: [
328
+ {
329
+ type: "text",
330
+ text: "Nested item",
331
+ styles: {},
332
+ },
333
+ ],
334
+ children: [],
335
+ },
336
+ ],
337
+ },
338
+ ] as unknown as Block[];
339
+ testConversion("numbered lists", blocks);
340
+ });
341
+
342
+ describe("Checklists", () => {
343
+ const blocks: Block[] = [
344
+ {
345
+ id: "1",
346
+ type: "checkListItem",
347
+ props: {
348
+ backgroundColor: "default",
349
+ textColor: "default",
350
+ textAlignment: "left",
351
+ checked: true,
352
+ },
353
+ content: [
354
+ {
355
+ type: "text",
356
+ text: "Completed task",
357
+ styles: {},
358
+ },
359
+ ],
360
+ children: [],
361
+ },
362
+ {
363
+ id: "2",
364
+ type: "checkListItem",
365
+ props: {
366
+ backgroundColor: "default",
367
+ textColor: "default",
368
+ textAlignment: "left",
369
+ checked: false,
370
+ },
371
+ content: [
372
+ {
373
+ type: "text",
374
+ text: "Pending task",
375
+ styles: {},
376
+ },
377
+ ],
378
+ children: [
379
+ {
380
+ id: "3",
381
+ type: "checkListItem",
382
+ props: {
383
+ backgroundColor: "default",
384
+ textColor: "default",
385
+ textAlignment: "left",
386
+ checked: false,
387
+ },
388
+ content: [
389
+ {
390
+ type: "text",
391
+ text: "Subtask",
392
+ styles: {},
393
+ },
394
+ ],
395
+ children: [],
396
+ },
397
+ ],
398
+ },
399
+ ];
400
+ testConversion("checklists", blocks);
401
+ });
402
+
403
+ describe("Toggle lists", () => {
404
+ const blocks: Block[] = [
405
+ {
406
+ id: "1",
407
+ type: "toggleListItem",
408
+ props: {
409
+ backgroundColor: "default",
410
+ textColor: "default",
411
+ textAlignment: "left",
412
+ },
413
+ content: [
414
+ {
415
+ type: "text",
416
+ text: "Toggle item",
417
+ styles: {},
418
+ },
419
+ ],
420
+ children: [
421
+ {
422
+ id: "2",
423
+ type: "paragraph",
424
+ props: {
425
+ backgroundColor: "default",
426
+ textColor: "default",
427
+ textAlignment: "left",
428
+ },
429
+ content: [
430
+ {
431
+ type: "text",
432
+ text: "Hidden content",
433
+ styles: {},
434
+ },
435
+ ],
436
+ children: [],
437
+ },
438
+ ],
439
+ },
440
+ ];
441
+ testConversion("toggle lists", blocks);
442
+ });
443
+
444
+ describe("Code blocks", () => {
445
+ const blocks: Block[] = [
446
+ {
447
+ id: "1",
448
+ type: "codeBlock",
449
+ props: {
450
+ language: "javascript",
451
+ },
452
+ content: [
453
+ {
454
+ type: "text",
455
+ text: 'console.log("Hello, world!");',
456
+ styles: {},
457
+ },
458
+ ],
459
+ children: [],
460
+ },
461
+ {
462
+ id: "2",
463
+ type: "codeBlock",
464
+ props: {
465
+ language: "typescript",
466
+ },
467
+ content: [
468
+ {
469
+ type: "text",
470
+ text: "const x: number = 42;",
471
+ styles: {},
472
+ },
473
+ ],
474
+ children: [],
475
+ },
476
+ ];
477
+ testConversion("code blocks", blocks);
478
+ });
479
+
480
+ describe("Quotes", () => {
481
+ const blocks: Block[] = [
482
+ {
483
+ id: "1",
484
+ type: "quote",
485
+ props: {
486
+ backgroundColor: "default",
487
+ textColor: "default",
488
+ },
489
+ content: [
490
+ {
491
+ type: "text",
492
+ text: "This is a quote",
493
+ styles: {
494
+ italic: true,
495
+ },
496
+ },
497
+ ],
498
+ children: [
499
+ {
500
+ id: "2",
501
+ type: "paragraph",
502
+ props: {
503
+ backgroundColor: "default",
504
+ textColor: "default",
505
+ textAlignment: "left",
506
+ },
507
+ content: [
508
+ {
509
+ type: "text",
510
+ text: "Nested in quote",
511
+ styles: {},
512
+ },
513
+ ],
514
+ children: [],
515
+ },
516
+ ],
517
+ },
518
+ ];
519
+ testConversion("quotes", blocks);
520
+ });
521
+
522
+ describe("Headings with different levels", () => {
523
+ const blocks: Block[] = [
524
+ {
525
+ id: "1",
526
+ type: "heading",
527
+ props: {
528
+ backgroundColor: "default",
529
+ textColor: "default",
530
+ textAlignment: "left",
531
+ level: 1,
532
+ isToggleable: false,
533
+ },
534
+ content: [
535
+ {
536
+ type: "text",
537
+ text: "Heading 1",
538
+ styles: {},
539
+ },
540
+ ],
541
+ children: [],
542
+ },
543
+ {
544
+ id: "2",
545
+ type: "heading",
546
+ props: {
547
+ backgroundColor: "default",
548
+ textColor: "default",
549
+ textAlignment: "left",
550
+ level: 2,
551
+ isToggleable: false,
552
+ },
553
+ content: [
554
+ {
555
+ type: "text",
556
+ text: "Heading 2",
557
+ styles: {},
558
+ },
559
+ ],
560
+ children: [],
561
+ },
562
+ {
563
+ id: "3",
564
+ type: "heading",
565
+ props: {
566
+ backgroundColor: "default",
567
+ textColor: "default",
568
+ textAlignment: "left",
569
+ level: 3,
570
+ isToggleable: true,
571
+ },
572
+ content: [
573
+ {
574
+ type: "text",
575
+ text: "Toggle Heading 3",
576
+ styles: {},
577
+ },
578
+ ],
579
+ children: [
580
+ {
581
+ id: "4",
582
+ type: "paragraph",
583
+ props: {
584
+ backgroundColor: "default",
585
+ textColor: "default",
586
+ textAlignment: "left",
587
+ },
588
+ content: [
589
+ {
590
+ type: "text",
591
+ text: "Content under toggle heading",
592
+ styles: {},
593
+ },
594
+ ],
595
+ children: [],
596
+ },
597
+ ],
598
+ },
599
+ ];
600
+ testConversion("headings with different levels", blocks);
601
+ });
602
+
603
+ describe("Inline styles and links", () => {
604
+ const blocks: Block[] = [
605
+ {
606
+ id: "1",
607
+ type: "paragraph",
608
+ props: {
609
+ backgroundColor: "default",
610
+ textColor: "default",
611
+ textAlignment: "left",
612
+ },
613
+ content: [
614
+ {
615
+ type: "text",
616
+ text: "Bold ",
617
+ styles: {
618
+ bold: true,
619
+ },
620
+ },
621
+ {
622
+ type: "text",
623
+ text: "italic ",
624
+ styles: {
625
+ italic: true,
626
+ },
627
+ },
628
+ {
629
+ type: "text",
630
+ text: "underline ",
631
+ styles: {
632
+ underline: true,
633
+ },
634
+ },
635
+ {
636
+ type: "text",
637
+ text: "strikethrough ",
638
+ styles: {
639
+ strike: true,
640
+ },
641
+ },
642
+ {
643
+ type: "text",
644
+ text: "code",
645
+ styles: {
646
+ code: true,
647
+ },
648
+ },
649
+ ],
650
+ children: [],
651
+ },
652
+ {
653
+ id: "2",
654
+ type: "paragraph",
655
+ props: {
656
+ backgroundColor: "default",
657
+ textColor: "default",
658
+ textAlignment: "left",
659
+ },
660
+ content: [
661
+ {
662
+ type: "link",
663
+ href: "https://example.com",
664
+ content: [
665
+ {
666
+ type: "text",
667
+ text: "Link text",
668
+ styles: {},
669
+ },
670
+ ],
671
+ },
672
+ ],
673
+ children: [],
674
+ },
675
+ ];
676
+ testConversion("inline styles and links", blocks);
677
+ });
678
+
679
+ describe("Tables", () => {
680
+ const blocks = [
681
+ {
682
+ id: "1",
683
+ type: "table",
684
+ props: {
685
+ textColor: "default",
686
+ },
687
+ content: {
688
+ type: "tableContent",
689
+ columnWidths: [100, 100, 100],
690
+ headerRows: 1,
691
+ headerCols: undefined,
692
+ rows: [
693
+ {
694
+ cells: [
695
+ {
696
+ type: "tableCell",
697
+ props: {
698
+ backgroundColor: "default",
699
+ textColor: "default",
700
+ textAlignment: "left",
701
+ colspan: 1,
702
+ rowspan: 1,
703
+ },
704
+ content: [
705
+ {
706
+ type: "text",
707
+ text: "Header 1",
708
+ styles: {
709
+ bold: true,
710
+ },
711
+ },
712
+ ],
713
+ },
714
+ {
715
+ type: "tableCell",
716
+ props: {
717
+ backgroundColor: "default",
718
+ textColor: "default",
719
+ textAlignment: "left",
720
+ colspan: 1,
721
+ rowspan: 1,
722
+ },
723
+ content: [
724
+ {
725
+ type: "text",
726
+ text: "Header 2",
727
+ styles: {
728
+ bold: true,
729
+ },
730
+ },
731
+ ],
732
+ },
733
+ {
734
+ type: "tableCell",
735
+ props: {
736
+ backgroundColor: "default",
737
+ textColor: "default",
738
+ textAlignment: "left",
739
+ colspan: 1,
740
+ rowspan: 1,
741
+ },
742
+ content: [
743
+ {
744
+ type: "text",
745
+ text: "Header 3",
746
+ styles: {
747
+ bold: true,
748
+ },
749
+ },
750
+ ],
751
+ },
752
+ ],
753
+ },
754
+ {
755
+ cells: [
756
+ {
757
+ type: "tableCell",
758
+ props: {
759
+ backgroundColor: "default",
760
+ textColor: "default",
761
+ textAlignment: "left",
762
+ colspan: 1,
763
+ rowspan: 1,
764
+ },
765
+ content: [
766
+ {
767
+ type: "text",
768
+ text: "Cell 1",
769
+ styles: {},
770
+ },
771
+ ],
772
+ },
773
+ {
774
+ type: "tableCell",
775
+ props: {
776
+ backgroundColor: "default",
777
+ textColor: "default",
778
+ textAlignment: "left",
779
+ colspan: 1,
780
+ rowspan: 1,
781
+ },
782
+ content: [
783
+ {
784
+ type: "text",
785
+ text: "Cell 2",
786
+ styles: {},
787
+ },
788
+ ],
789
+ },
790
+ {
791
+ type: "tableCell",
792
+ props: {
793
+ backgroundColor: "default",
794
+ textColor: "default",
795
+ textAlignment: "left",
796
+ colspan: 1,
797
+ rowspan: 1,
798
+ },
799
+ content: [
800
+ {
801
+ type: "text",
802
+ text: "Cell 3",
803
+ styles: {},
804
+ },
805
+ ],
806
+ },
807
+ ],
808
+ },
809
+ ],
810
+ },
811
+ children: [],
812
+ },
813
+ ] as unknown as Block[];
814
+ testConversion("tables", blocks);
815
+ });
816
+
817
+ describe("Divider", () => {
818
+ const blocks = [
819
+ {
820
+ id: "1",
821
+ type: "paragraph",
822
+ props: {
823
+ backgroundColor: "default",
824
+ textColor: "default",
825
+ textAlignment: "left",
826
+ },
827
+ content: [
828
+ {
829
+ type: "text",
830
+ text: "Before divider",
831
+ styles: {},
832
+ },
833
+ ],
834
+ children: [],
835
+ },
836
+ {
837
+ id: "2",
838
+ type: "divider",
839
+ props: {},
840
+ content: undefined,
841
+ children: [],
842
+ },
843
+ {
844
+ id: "3",
845
+ type: "paragraph",
846
+ props: {
847
+ backgroundColor: "default",
848
+ textColor: "default",
849
+ textAlignment: "left",
850
+ },
851
+ content: [
852
+ {
853
+ type: "text",
854
+ text: "After divider",
855
+ styles: {},
856
+ },
857
+ ],
858
+ children: [],
859
+ },
860
+ ] as unknown as Block[];
861
+ testConversion("divider", blocks);
862
+ });
863
+
864
+ describe("Complex mixed document", () => {
865
+ const blocks: Block[] = [
866
+ {
867
+ id: "1",
868
+ type: "heading",
869
+ props: {
870
+ backgroundColor: "blue",
871
+ textColor: "yellow",
872
+ textAlignment: "center",
873
+ level: 1,
874
+ isToggleable: false,
875
+ },
876
+ content: [
877
+ {
878
+ type: "text",
879
+ text: "Main Title",
880
+ styles: {
881
+ bold: true,
882
+ },
883
+ },
884
+ ],
885
+ children: [],
886
+ },
887
+ {
888
+ id: "2",
889
+ type: "paragraph",
890
+ props: {
891
+ backgroundColor: "red",
892
+ textColor: "default",
893
+ textAlignment: "right",
894
+ },
895
+ content: [
896
+ {
897
+ type: "text",
898
+ text: "This is a paragraph with ",
899
+ styles: {},
900
+ },
901
+ {
902
+ type: "text",
903
+ text: "mixed",
904
+ styles: {
905
+ bold: true,
906
+ italic: true,
907
+ },
908
+ },
909
+ {
910
+ type: "text",
911
+ text: " styles and a ",
912
+ styles: {},
913
+ },
914
+ {
915
+ type: "link",
916
+ href: "https://example.com",
917
+ content: [
918
+ {
919
+ type: "text",
920
+ text: "link",
921
+ styles: {},
922
+ },
923
+ ],
924
+ },
925
+ {
926
+ type: "text",
927
+ text: ".",
928
+ styles: {},
929
+ },
930
+ ],
931
+ children: [
932
+ {
933
+ id: "3",
934
+ type: "bulletListItem",
935
+ props: {
936
+ backgroundColor: "default",
937
+ textColor: "default",
938
+ textAlignment: "left",
939
+ },
940
+ content: [
941
+ {
942
+ type: "text",
943
+ text: "Nested list item",
944
+ styles: {},
945
+ },
946
+ ],
947
+ children: [],
948
+ },
949
+ ],
950
+ },
951
+ {
952
+ id: "4",
953
+ type: "quote",
954
+ props: {
955
+ backgroundColor: "default",
956
+ textColor: "default",
957
+ },
958
+ content: [
959
+ {
960
+ type: "text",
961
+ text: "Important quote",
962
+ styles: {
963
+ italic: true,
964
+ },
965
+ },
966
+ ],
967
+ children: [],
968
+ },
969
+ {
970
+ id: "5",
971
+ type: "codeBlock",
972
+ props: {
973
+ language: "typescript",
974
+ },
975
+ content: [
976
+ {
977
+ type: "text",
978
+ text: "const example = () => {\n return 'code';\n};",
979
+ styles: {},
980
+ },
981
+ ],
982
+ children: [],
983
+ },
984
+ {
985
+ id: "6",
986
+ type: "checkListItem",
987
+ props: {
988
+ backgroundColor: "default",
989
+ textColor: "default",
990
+ textAlignment: "left",
991
+ checked: true,
992
+ },
993
+ content: [
994
+ {
995
+ type: "text",
996
+ text: "Completed checklist item",
997
+ styles: {},
998
+ },
999
+ ],
1000
+ children: [],
1001
+ },
1002
+ {
1003
+ id: "7",
1004
+ type: "checkListItem",
1005
+ props: {
1006
+ backgroundColor: "default",
1007
+ textColor: "default",
1008
+ textAlignment: "left",
1009
+ checked: false,
1010
+ },
1011
+ content: [
1012
+ {
1013
+ type: "text",
1014
+ text: "Pending checklist item",
1015
+ styles: {},
1016
+ },
1017
+ ],
1018
+ children: [],
1019
+ },
1020
+ ];
1021
+ testConversion("complex mixed document", blocks);
1022
+ });
1023
+ });