@blocknote/xl-multi-column 0.19.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 (78) hide show
  1. package/LICENSE +661 -0
  2. package/dist/blocknote-xl-multi-column.js +3038 -0
  3. package/dist/blocknote-xl-multi-column.js.map +1 -0
  4. package/dist/blocknote-xl-multi-column.umd.cjs +69 -0
  5. package/dist/blocknote-xl-multi-column.umd.cjs.map +1 -0
  6. package/dist/webpack-stats.json +1 -0
  7. package/package.json +80 -0
  8. package/src/blocks/Columns/index.ts +15 -0
  9. package/src/blocks/schema.ts +43 -0
  10. package/src/extensions/ColumnResize/ColumnResizeExtension.ts +357 -0
  11. package/src/extensions/DropCursor/MultiColumnDropCursorPlugin.ts +480 -0
  12. package/src/extensions/SuggestionMenu/getMultiColumnSlashMenuItems.tsx +105 -0
  13. package/src/i18n/dictionary.ts +27 -0
  14. package/src/i18n/locales/ar.ts +18 -0
  15. package/src/i18n/locales/de.ts +18 -0
  16. package/src/i18n/locales/en.ts +16 -0
  17. package/src/i18n/locales/es.ts +18 -0
  18. package/src/i18n/locales/fr.ts +18 -0
  19. package/src/i18n/locales/hr.ts +18 -0
  20. package/src/i18n/locales/index.ts +15 -0
  21. package/src/i18n/locales/is.ts +18 -0
  22. package/src/i18n/locales/ja.ts +18 -0
  23. package/src/i18n/locales/ko.ts +18 -0
  24. package/src/i18n/locales/nl.ts +18 -0
  25. package/src/i18n/locales/pl.ts +18 -0
  26. package/src/i18n/locales/pt.ts +18 -0
  27. package/src/i18n/locales/ru.ts +18 -0
  28. package/src/i18n/locales/vi.ts +18 -0
  29. package/src/i18n/locales/zh.ts +18 -0
  30. package/src/index.ts +7 -0
  31. package/src/pm-nodes/Column.ts +87 -0
  32. package/src/pm-nodes/ColumnList.ts +44 -0
  33. package/src/test/commands/__snapshots__/insertBlocks.test.ts.snap +757 -0
  34. package/src/test/commands/__snapshots__/textCursorPosition.test.ts.snap +169 -0
  35. package/src/test/commands/__snapshots__/updateBlock.test.ts.snap +964 -0
  36. package/src/test/commands/insertBlocks.test.ts +206 -0
  37. package/src/test/commands/textCursorPosition.test.ts +19 -0
  38. package/src/test/commands/updateBlock.test.ts +212 -0
  39. package/src/test/conversions/__snapshots__/multi-column/undefined/external.html +1 -0
  40. package/src/test/conversions/__snapshots__/multi-column/undefined/internal.html +1 -0
  41. package/src/test/conversions/__snapshots__/nodeConversion.test.ts.snap +118 -0
  42. package/src/test/conversions/htmlConversion.test.ts +100 -0
  43. package/src/test/conversions/nodeConversion.test.ts +84 -0
  44. package/src/test/conversions/testCases.ts +54 -0
  45. package/src/test/setupTestEnv.ts +99 -0
  46. package/src/vite-env.d.ts +1 -0
  47. package/types/src/blocks/Columns/index.d.ts +32 -0
  48. package/types/src/blocks/schema.d.ts +102 -0
  49. package/types/src/extensions/ColumnResize/ColumnResizeExtension.d.ts +3 -0
  50. package/types/src/extensions/DropCursor/MultiColumnDropCursorPlugin.d.ts +11 -0
  51. package/types/src/extensions/SuggestionMenu/getMultiColumnSlashMenuItems.d.ts +5 -0
  52. package/types/src/i18n/dictionary.d.ts +19 -0
  53. package/types/src/i18n/locales/ar.d.ts +2 -0
  54. package/types/src/i18n/locales/de.d.ts +2 -0
  55. package/types/src/i18n/locales/en.d.ts +16 -0
  56. package/types/src/i18n/locales/es.d.ts +2 -0
  57. package/types/src/i18n/locales/fr.d.ts +2 -0
  58. package/types/src/i18n/locales/hr.d.ts +2 -0
  59. package/types/src/i18n/locales/index.d.ts +15 -0
  60. package/types/src/i18n/locales/is.d.ts +2 -0
  61. package/types/src/i18n/locales/ja.d.ts +2 -0
  62. package/types/src/i18n/locales/ko.d.ts +2 -0
  63. package/types/src/i18n/locales/nl.d.ts +2 -0
  64. package/types/src/i18n/locales/pl.d.ts +2 -0
  65. package/types/src/i18n/locales/pt.d.ts +2 -0
  66. package/types/src/i18n/locales/ru.d.ts +2 -0
  67. package/types/src/i18n/locales/vi.d.ts +2 -0
  68. package/types/src/i18n/locales/zh.d.ts +2 -0
  69. package/types/src/index.d.ts +7 -0
  70. package/types/src/pm-nodes/Column.d.ts +6 -0
  71. package/types/src/pm-nodes/ColumnList.d.ts +6 -0
  72. package/types/src/test/commands/insertBlocks.test.d.ts +1 -0
  73. package/types/src/test/commands/textCursorPosition.test.d.ts +1 -0
  74. package/types/src/test/commands/updateBlock.test.d.ts +1 -0
  75. package/types/src/test/conversions/htmlConversion.test.d.ts +1 -0
  76. package/types/src/test/conversions/nodeConversion.test.d.ts +1 -0
  77. package/types/src/test/conversions/testCases.d.ts +3 -0
  78. package/types/src/test/setupTestEnv.d.ts +1041 -0
@@ -0,0 +1,206 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { setupTestEnv } from "../setupTestEnv.js";
4
+
5
+ const getEditor = setupTestEnv();
6
+
7
+ describe("Test insertBlocks", () => {
8
+ it("Insert empty column list", () => {
9
+ // should throw an error as we don't allow empty column lists
10
+ expect(() => {
11
+ getEditor().insertBlocks(
12
+ [{ type: "columnList" }],
13
+ "paragraph-0",
14
+ "after"
15
+ );
16
+ }).toThrow();
17
+ });
18
+
19
+ it("Insert column list with empty column", () => {
20
+ // should throw an error as we don't allow empty columns
21
+ expect(() => {
22
+ getEditor().insertBlocks(
23
+ [
24
+ {
25
+ type: "columnList",
26
+ children: [
27
+ {
28
+ type: "column",
29
+ },
30
+ ],
31
+ },
32
+ ],
33
+ "paragraph-0",
34
+ "after"
35
+ );
36
+ }).toThrow();
37
+ });
38
+
39
+ it("Insert column list with single column", () => {
40
+ // should throw an error as we don't allow column list with single column
41
+ expect(() => {
42
+ getEditor().insertBlocks(
43
+ [
44
+ {
45
+ type: "columnList",
46
+ children: [
47
+ {
48
+ type: "column",
49
+ children: [
50
+ {
51
+ type: "paragraph",
52
+ content: "Inserted Column Paragraph",
53
+ },
54
+ ],
55
+ },
56
+ ],
57
+ },
58
+ ],
59
+ "paragraph-0",
60
+ "after"
61
+ );
62
+ }).toThrow();
63
+ });
64
+
65
+ it("Insert valid column list with two columns", () => {
66
+ getEditor().insertBlocks(
67
+ [
68
+ {
69
+ type: "columnList",
70
+ children: [
71
+ {
72
+ type: "column",
73
+ children: [
74
+ {
75
+ type: "paragraph",
76
+ content: "Inserted Column Paragraph",
77
+ },
78
+ ],
79
+ },
80
+ {
81
+ type: "column",
82
+ children: [
83
+ {
84
+ type: "paragraph",
85
+ content: "Inserted Second Column Paragraph",
86
+ },
87
+ ],
88
+ },
89
+ ],
90
+ },
91
+ ],
92
+ "paragraph-0",
93
+ "after"
94
+ );
95
+
96
+ expect(getEditor().document).toMatchSnapshot();
97
+ });
98
+
99
+ it("Insert column with paragraph into column list", () => {
100
+ getEditor().insertBlocks(
101
+ [
102
+ {
103
+ type: "column",
104
+ children: [
105
+ {
106
+ type: "paragraph",
107
+ content: "Inserted Column Paragraph",
108
+ },
109
+ ],
110
+ },
111
+ ],
112
+ "column-0",
113
+ "before"
114
+ );
115
+
116
+ expect(getEditor().document).toMatchSnapshot();
117
+ });
118
+
119
+ it("Insert column list into paragraph", () => {
120
+ getEditor().insertBlocks(
121
+ [
122
+ {
123
+ type: "columnList",
124
+ children: [
125
+ {
126
+ type: "column",
127
+ children: [
128
+ {
129
+ type: "paragraph",
130
+ content: "Inserted Column Paragraph",
131
+ },
132
+ ],
133
+ },
134
+ {
135
+ type: "column",
136
+ children: [
137
+ {
138
+ type: "paragraph",
139
+ content: "Inserted Column Paragraph",
140
+ },
141
+ ],
142
+ },
143
+ ],
144
+ },
145
+ ],
146
+ "nested-paragraph-0",
147
+ "after"
148
+ );
149
+
150
+ expect(getEditor().document).toMatchSnapshot();
151
+ });
152
+
153
+ // TODO: failing because prosemirror "insert" finds a place to insert this using the fitting algorithm
154
+ it.skip("Insert column into paragraph", () => {
155
+ // should throw an error as we don't allow columns to be children of paragraphs
156
+ expect(() => {
157
+ getEditor().insertBlocks(
158
+ [
159
+ {
160
+ type: "column",
161
+ children: [
162
+ {
163
+ type: "paragraph",
164
+ content: "Inserted Column Paragraph",
165
+ },
166
+ ],
167
+ },
168
+ ],
169
+ "nested-paragraph-0",
170
+ "after"
171
+ );
172
+ }).toThrow();
173
+ });
174
+
175
+ // TODO: failing because prosemirror "insert" finds a place to insert this using the fitting algorithm
176
+ it.skip("Insert paragraph into column list", () => {
177
+ // should throw an error as we don't allow paragraphs to be children of column lists
178
+ expect(() => {
179
+ getEditor().insertBlocks(
180
+ [
181
+ {
182
+ type: "paragraph",
183
+ content: "Inserted Column List Paragraph",
184
+ },
185
+ ],
186
+ "column-0",
187
+ "after"
188
+ );
189
+ }).toThrow();
190
+ });
191
+
192
+ it("Insert paragraph into column", () => {
193
+ getEditor().insertBlocks(
194
+ [
195
+ {
196
+ type: "paragraph",
197
+ content: "Inserted Column List Paragraph",
198
+ },
199
+ ],
200
+ "column-paragraph-0",
201
+ "after"
202
+ );
203
+
204
+ expect(getEditor().document).toMatchSnapshot();
205
+ });
206
+ });
@@ -0,0 +1,19 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { setupTestEnv } from "../setupTestEnv.js";
4
+
5
+ const getEditor = setupTestEnv();
6
+
7
+ describe("Test getTextCursorPosition & setTextCursorPosition", () => {
8
+ it("Column list", () => {
9
+ getEditor().setTextCursorPosition("column-list-0");
10
+
11
+ expect(getEditor().getTextCursorPosition()).toMatchSnapshot();
12
+ });
13
+
14
+ it("Column", () => {
15
+ getEditor().setTextCursorPosition("column-0");
16
+
17
+ expect(getEditor().getTextCursorPosition()).toMatchSnapshot();
18
+ });
19
+ });
@@ -0,0 +1,212 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { setupTestEnv } from "../setupTestEnv.js";
4
+
5
+ const getEditor = setupTestEnv();
6
+
7
+ describe("Test updateBlock", () => {
8
+ it("Update column list new children", () => {
9
+ getEditor().updateBlock("column-list-0", {
10
+ type: "columnList",
11
+ children: [
12
+ {
13
+ type: "column",
14
+ children: [
15
+ {
16
+ type: "paragraph",
17
+ content: "Inserted Column Paragraph",
18
+ },
19
+ ],
20
+ },
21
+ {
22
+ type: "column",
23
+ children: [
24
+ {
25
+ type: "paragraph",
26
+ content: "Inserted Column Paragraph",
27
+ },
28
+ ],
29
+ },
30
+ ],
31
+ });
32
+
33
+ expect(getEditor().document).toMatchSnapshot();
34
+ });
35
+
36
+ it("Update column list new empty children", () => {
37
+ // should throw because we don't allow empty columns / single columns
38
+ expect(() => {
39
+ getEditor().updateBlock("column-list-0", {
40
+ type: "columnList",
41
+ children: [
42
+ {
43
+ type: "paragraph",
44
+ content: "Inserted Column Paragraph",
45
+ },
46
+ ],
47
+ });
48
+ }).toThrow();
49
+ });
50
+
51
+ it("Update column new children", () => {
52
+ getEditor().updateBlock("column-0", {
53
+ type: "column",
54
+ children: [
55
+ {
56
+ type: "paragraph",
57
+ content: "Inserted Column Paragraph",
58
+ },
59
+ ],
60
+ });
61
+
62
+ expect(getEditor().document).toMatchSnapshot();
63
+ });
64
+
65
+ it("Update paragraph to column list", () => {
66
+ getEditor().updateBlock("paragraph-0", {
67
+ type: "columnList",
68
+ children: [
69
+ {
70
+ type: "column",
71
+ children: [
72
+ {
73
+ type: "paragraph",
74
+ content: "Inserted Column Paragraph",
75
+ },
76
+ ],
77
+ },
78
+ {
79
+ type: "column",
80
+ children: [
81
+ {
82
+ type: "paragraph",
83
+ content: "Inserted Column Paragraph",
84
+ },
85
+ ],
86
+ },
87
+ ],
88
+ });
89
+
90
+ expect(getEditor().document).toMatchSnapshot();
91
+ });
92
+
93
+ it("Update nested paragraph to column list", () => {
94
+ getEditor().updateBlock("nested-paragraph-0", {
95
+ type: "columnList",
96
+ children: [
97
+ {
98
+ type: "column",
99
+ children: [
100
+ {
101
+ type: "paragraph",
102
+ content: "Inserted Column Paragraph",
103
+ },
104
+ ],
105
+ },
106
+ {
107
+ type: "column",
108
+ children: [
109
+ {
110
+ type: "paragraph",
111
+ content: "Inserted Column Paragraph",
112
+ },
113
+ ],
114
+ },
115
+ ],
116
+ });
117
+
118
+ expect(getEditor().document).toMatchSnapshot();
119
+ });
120
+
121
+ it("Update column to column list", () => {
122
+ // should throw an error as we don't allow a column list inside a columnlist
123
+ expect(() => {
124
+ getEditor().updateBlock("column-0", {
125
+ type: "columnList",
126
+ children: [
127
+ {
128
+ type: "column",
129
+ children: [
130
+ {
131
+ type: "paragraph",
132
+ content: "Inserted Column Paragraph",
133
+ },
134
+ ],
135
+ },
136
+ {
137
+ type: "column",
138
+ children: [
139
+ {
140
+ type: "paragraph",
141
+ content: "Inserted Column Paragraph",
142
+ },
143
+ ],
144
+ },
145
+ ],
146
+ });
147
+ }).toThrow();
148
+ });
149
+
150
+ it("Update paragraph to column", () => {
151
+ getEditor().updateBlock("paragraph-0", {
152
+ type: "column",
153
+ children: [
154
+ {
155
+ type: "paragraph",
156
+ content: "Inserted Column Paragraph",
157
+ },
158
+ ],
159
+ });
160
+
161
+ expect(getEditor().document).toMatchSnapshot();
162
+ });
163
+
164
+ it("Update nested paragraph to column", () => {
165
+ getEditor().updateBlock("nested-paragraph-0", {
166
+ type: "column",
167
+ children: [
168
+ {
169
+ type: "paragraph",
170
+ content: "Inserted Column Paragraph",
171
+ },
172
+ ],
173
+ });
174
+
175
+ expect(getEditor().document).toMatchSnapshot();
176
+ });
177
+
178
+ it("Update column list to column", () => {
179
+ // this would cause a column to become a child of a node that's not a column list, and should thus throw an error
180
+ expect(() => {
181
+ getEditor().updateBlock("column-list-0", {
182
+ type: "column",
183
+ children: [
184
+ {
185
+ type: "paragraph",
186
+ content: "Inserted Column Paragraph",
187
+ },
188
+ ],
189
+ });
190
+ }).toThrow();
191
+ });
192
+
193
+ it("Update column list to paragraph", () => {
194
+ // this would cause columns to become children of a paragraph, and should thus throw an error
195
+ expect(() => {
196
+ getEditor().updateBlock("column-list-0", {
197
+ type: "paragraph",
198
+ content: "Inserted Column Paragraph",
199
+ });
200
+ }).toThrow();
201
+ });
202
+
203
+ // TODO: this should throw, but currently doesn't, probably because of the fitting algorithm
204
+ it.skip("Update column to paragraph", () => {
205
+ expect(() => {
206
+ getEditor().updateBlock("column-0", {
207
+ type: "paragraph",
208
+ content: "Inserted Column Paragraph",
209
+ });
210
+ }).toThrow();
211
+ });
212
+ });
@@ -0,0 +1 @@
1
+ <div class="bn-block-column-list" data-node-type="columnList" data-id="1" style="display: flex;"><div class="bn-block-column" data-node-type="column" data-id="2" data-width="1" style="flex-grow: 1;"><p>Column Paragraph 0</p><p>Column Paragraph 1</p></div><div class="bn-block-column" data-node-type="column" data-id="5" data-width="1" style="flex-grow: 1;"><p>Column Paragraph 2</p><p>Column Paragraph 3</p></div></div>
@@ -0,0 +1 @@
1
+ <div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-column-list" data-node-type="columnList" data-id="1" style="display: flex;"><div class="bn-block-column" data-node-type="column" data-id="2" data-width="1" style="flex-grow: 1;"><div class="bn-block-outer" data-node-type="blockOuter" data-id="3"><div class="bn-block" data-node-type="blockContainer" data-id="3"><div class="bn-block-content" data-content-type="paragraph"><p class="bn-inline-content">Column Paragraph 0</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="4"><div class="bn-block" data-node-type="blockContainer" data-id="4"><div class="bn-block-content" data-content-type="paragraph"><p class="bn-inline-content">Column Paragraph 1</p></div></div></div></div><div class="bn-block-column" data-node-type="column" data-id="5" data-width="1" style="flex-grow: 1;"><div class="bn-block-outer" data-node-type="blockOuter" data-id="6"><div class="bn-block" data-node-type="blockContainer" data-id="6"><div class="bn-block-content" data-content-type="paragraph"><p class="bn-inline-content">Column Paragraph 2</p></div></div></div><div class="bn-block-outer" data-node-type="blockOuter" data-id="7"><div class="bn-block" data-node-type="blockContainer" data-id="7"><div class="bn-block-content" data-content-type="paragraph"><p class="bn-inline-content">Column Paragraph 3</p></div></div></div></div></div></div>
@@ -0,0 +1,118 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`Test BlockNote-Prosemirror conversion > Case: multi-column-schema > Convert multi-column to/from prosemirror 1`] = `
4
+ {
5
+ "attrs": {
6
+ "id": "1",
7
+ },
8
+ "content": [
9
+ {
10
+ "attrs": {
11
+ "id": "2",
12
+ "width": 1,
13
+ },
14
+ "content": [
15
+ {
16
+ "attrs": {
17
+ "backgroundColor": "default",
18
+ "id": "3",
19
+ "textColor": "default",
20
+ },
21
+ "content": [
22
+ {
23
+ "attrs": {
24
+ "textAlignment": "left",
25
+ },
26
+ "content": [
27
+ {
28
+ "text": "Column Paragraph 0",
29
+ "type": "text",
30
+ },
31
+ ],
32
+ "type": "paragraph",
33
+ },
34
+ ],
35
+ "type": "blockContainer",
36
+ },
37
+ {
38
+ "attrs": {
39
+ "backgroundColor": "default",
40
+ "id": "4",
41
+ "textColor": "default",
42
+ },
43
+ "content": [
44
+ {
45
+ "attrs": {
46
+ "textAlignment": "left",
47
+ },
48
+ "content": [
49
+ {
50
+ "text": "Column Paragraph 1",
51
+ "type": "text",
52
+ },
53
+ ],
54
+ "type": "paragraph",
55
+ },
56
+ ],
57
+ "type": "blockContainer",
58
+ },
59
+ ],
60
+ "type": "column",
61
+ },
62
+ {
63
+ "attrs": {
64
+ "id": "5",
65
+ "width": 1,
66
+ },
67
+ "content": [
68
+ {
69
+ "attrs": {
70
+ "backgroundColor": "default",
71
+ "id": "6",
72
+ "textColor": "default",
73
+ },
74
+ "content": [
75
+ {
76
+ "attrs": {
77
+ "textAlignment": "left",
78
+ },
79
+ "content": [
80
+ {
81
+ "text": "Column Paragraph 2",
82
+ "type": "text",
83
+ },
84
+ ],
85
+ "type": "paragraph",
86
+ },
87
+ ],
88
+ "type": "blockContainer",
89
+ },
90
+ {
91
+ "attrs": {
92
+ "backgroundColor": "default",
93
+ "id": "7",
94
+ "textColor": "default",
95
+ },
96
+ "content": [
97
+ {
98
+ "attrs": {
99
+ "textAlignment": "left",
100
+ },
101
+ "content": [
102
+ {
103
+ "text": "Column Paragraph 3",
104
+ "type": "text",
105
+ },
106
+ ],
107
+ "type": "paragraph",
108
+ },
109
+ ],
110
+ "type": "blockContainer",
111
+ },
112
+ ],
113
+ "type": "column",
114
+ },
115
+ ],
116
+ "type": "columnList",
117
+ }
118
+ `;
@@ -0,0 +1,100 @@
1
+ // @vitest-environment jsdom
2
+
3
+ import {
4
+ BlockNoteEditor,
5
+ BlockSchema,
6
+ InlineContentSchema,
7
+ PartialBlock,
8
+ StyleSchema,
9
+ addIdsToBlocks,
10
+ createExternalHTMLExporter,
11
+ createInternalHTMLSerializer,
12
+ partialBlocksToBlocksForTesting,
13
+ } from "@blocknote/core";
14
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
15
+
16
+ import { multiColumnSchemaTestCases } from "./testCases.js";
17
+
18
+ // TODO: code same from @blocknote/core, maybe create separate test util package
19
+ async function convertToHTMLAndCompareSnapshots<
20
+ B extends BlockSchema,
21
+ I extends InlineContentSchema,
22
+ S extends StyleSchema
23
+ >(
24
+ editor: BlockNoteEditor<B, I, S>,
25
+ blocks: PartialBlock<B, I, S>[],
26
+ snapshotDirectory: string,
27
+ snapshotName: string
28
+ ) {
29
+ addIdsToBlocks(blocks);
30
+ const serializer = createInternalHTMLSerializer(editor.pmSchema, editor);
31
+ const internalHTML = serializer.serializeBlocks(blocks, {});
32
+ const internalHTMLSnapshotPath =
33
+ "./__snapshots__/" +
34
+ snapshotDirectory +
35
+ "/" +
36
+ snapshotName +
37
+ "/internal.html";
38
+ expect(internalHTML).toMatchFileSnapshot(internalHTMLSnapshotPath);
39
+
40
+ // turn the internalHTML back into blocks, and make sure no data was lost
41
+ const fullBlocks = partialBlocksToBlocksForTesting(editor.schema, blocks);
42
+ const parsed = await editor.tryParseHTMLToBlocks(internalHTML);
43
+
44
+ expect(parsed).toStrictEqual(fullBlocks);
45
+
46
+ // Create the "external" HTML, which is a cleaned up HTML representation, but lossy
47
+ const exporter = createExternalHTMLExporter(editor.pmSchema, editor);
48
+ const externalHTML = exporter.exportBlocks(blocks, {});
49
+ const externalHTMLSnapshotPath =
50
+ "./__snapshots__/" +
51
+ snapshotDirectory +
52
+ "/" +
53
+ snapshotName +
54
+ "/external.html";
55
+ expect(externalHTML).toMatchFileSnapshot(externalHTMLSnapshotPath);
56
+ }
57
+
58
+ const testCases = [multiColumnSchemaTestCases];
59
+
60
+ describe("Test multi-column HTML conversion", () => {
61
+ for (const testCase of testCases) {
62
+ describe("Case: " + testCase.name, () => {
63
+ let editor: BlockNoteEditor<any, any, any>;
64
+ const div = document.createElement("div");
65
+ beforeEach(() => {
66
+ editor = testCase.createEditor();
67
+
68
+ // Note that we don't necessarily need to mount a root
69
+ // Currently, we do mount to a root so that it reflects the "production" use-case more closely.
70
+
71
+ // However, it would be nice to increased converage and share the same set of tests for these cases:
72
+ // - does render to a root
73
+ // - does not render to a root
74
+ // - runs in server (jsdom) environment using server-util
75
+ editor.mount(div);
76
+ });
77
+
78
+ afterEach(() => {
79
+ editor.mount(undefined);
80
+ editor._tiptapEditor.destroy();
81
+ editor = undefined as any;
82
+
83
+ delete (window as Window & { __TEST_OPTIONS?: any }).__TEST_OPTIONS;
84
+ });
85
+
86
+ for (const document of testCase.documents) {
87
+ // eslint-disable-next-line no-loop-func
88
+ it("Convert " + document.name + " to HTML", async () => {
89
+ const nameSplit = document.name.split("/");
90
+ await convertToHTMLAndCompareSnapshots(
91
+ editor,
92
+ document.blocks,
93
+ nameSplit[0],
94
+ nameSplit[1]
95
+ );
96
+ });
97
+ }
98
+ });
99
+ }
100
+ });