Skip to content

Commit 800a1f0

Browse files
feat: Page break (#1372)
* feat: Page break block * feat: Add page break support to PDF & DOCX exporters * feat: Add CSS to support Page break when printing * Small UX changes * Removed page break from default schema * Fixed unit tests * Fixed lint * Implemented PR feedback --------- Co-authored-by: matthewlipski <[email protected]>
1 parent 8461552 commit 800a1f0

File tree

43 files changed

+2374
-1320
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2374
-1320
lines changed

examples/01-basic/04-all-blocks/App.tsx

Lines changed: 2 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,11 @@
1-
import {
2-
BlockNoteSchema,
3-
combineByGroup,
4-
filterSuggestionItems,
5-
locales,
6-
} from "@blocknote/core";
71
import "@blocknote/core/fonts/inter.css";
82
import { BlockNoteView } from "@blocknote/mantine";
93
import "@blocknote/mantine/style.css";
10-
import {
11-
SuggestionMenuController,
12-
getDefaultReactSlashMenuItems,
13-
useCreateBlockNote,
14-
} from "@blocknote/react";
15-
import {
16-
getMultiColumnSlashMenuItems,
17-
multiColumnDropCursor,
18-
locales as multiColumnLocales,
19-
withMultiColumn,
20-
} from "@blocknote/xl-multi-column";
21-
import { useMemo } from "react";
4+
import { useCreateBlockNote } from "@blocknote/react";
225

236
export default function App() {
247
// Creates a new editor instance.
258
const editor = useCreateBlockNote({
26-
schema: withMultiColumn(BlockNoteSchema.create()),
27-
dropCursor: multiColumnDropCursor,
28-
dictionary: {
29-
...locales.en,
30-
multi_column: multiColumnLocales.en,
31-
},
329
initialContent: [
3310
{
3411
type: "paragraph",
@@ -51,35 +28,6 @@ export default function App() {
5128
type: "paragraph",
5229
content: "Paragraph",
5330
},
54-
{
55-
type: "columnList",
56-
children: [
57-
{
58-
type: "column",
59-
props: {
60-
width: 0.8,
61-
},
62-
children: [
63-
{
64-
type: "paragraph",
65-
content: "Hello to the left!",
66-
},
67-
],
68-
},
69-
{
70-
type: "column",
71-
props: {
72-
width: 1.2,
73-
},
74-
children: [
75-
{
76-
type: "paragraph",
77-
content: "Hello to the right!",
78-
},
79-
],
80-
},
81-
],
82-
},
8331
{
8432
type: "heading",
8533
content: "Heading",
@@ -189,20 +137,6 @@ export default function App() {
189137
],
190138
});
191139

192-
const slashMenuItems = useMemo(() => {
193-
return combineByGroup(
194-
getDefaultReactSlashMenuItems(editor),
195-
getMultiColumnSlashMenuItems(editor)
196-
);
197-
}, [editor]);
198-
199140
// Renders the editor instance using a React component.
200-
return (
201-
<BlockNoteView editor={editor} slashMenu={false}>
202-
<SuggestionMenuController
203-
triggerCharacter={"/"}
204-
getItems={async (query) => filterSuggestionItems(slashMenuItems, query)}
205-
/>
206-
</BlockNoteView>
207-
);
141+
return <BlockNoteView editor={editor} />;
208142
}

examples/05-interoperability/05-converting-blocks-to-pdf/App.tsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1+
import {
2+
BlockNoteSchema,
3+
combineByGroup,
4+
filterSuggestionItems,
5+
withPageBreak,
6+
} from "@blocknote/core";
17
import "@blocknote/core/fonts/inter.css";
28
import { BlockNoteView } from "@blocknote/mantine";
39
import "@blocknote/mantine/style.css";
4-
import { useCreateBlockNote } from "@blocknote/react";
10+
import {
11+
getDefaultReactSlashMenuItems,
12+
getPageBreakReactSlashMenuItems,
13+
SuggestionMenuController,
14+
useCreateBlockNote,
15+
} from "@blocknote/react";
516
import {
617
PDFExporter,
718
pdfDefaultSchemaMappings,
819
} from "@blocknote/xl-pdf-exporter";
920
import { PDFViewer } from "@react-pdf/renderer";
10-
import { useEffect, useState } from "react";
21+
import { useEffect, useMemo, useState } from "react";
22+
1123
import "./styles.css";
1224

1325
export default function App() {
@@ -16,6 +28,7 @@ export default function App() {
1628

1729
// Creates a new editor instance with some initial content.
1830
const editor = useCreateBlockNote({
31+
schema: withPageBreak(BlockNoteSchema.create()),
1932
initialContent: [
2033
{
2134
type: "paragraph",
@@ -180,6 +193,9 @@ export default function App() {
180193
],
181194
},
182195
},
196+
{
197+
type: "pageBreak",
198+
},
183199
{
184200
type: "file",
185201
},
@@ -308,11 +324,25 @@ export default function App() {
308324
// eslint-disable-next-line react-hooks/exhaustive-deps
309325
}, []);
310326

327+
const slashMenuItems = useMemo(() => {
328+
return combineByGroup(
329+
getDefaultReactSlashMenuItems(editor),
330+
getPageBreakReactSlashMenuItems(editor)
331+
);
332+
}, [editor]);
333+
311334
// Renders the editor instance, and its contents as HTML below.
312335
return (
313336
<div className="wrapper">
314337
<div className="editor">
315-
<BlockNoteView editor={editor} onChange={onChange} />
338+
<BlockNoteView editor={editor} slashMenu={false} onChange={onChange}>
339+
<SuggestionMenuController
340+
triggerCharacter={"/"}
341+
getItems={async (query) =>
342+
filterSuggestionItems(slashMenuItems, query)
343+
}
344+
/>
345+
</BlockNoteView>
316346
</div>
317347
<div className="pdf">
318348
<PDFViewer width={"100%"}>{pdfDocument}</PDFViewer>

examples/05-interoperability/06-converting-blocks-to-docx/App.tsx

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
1+
import {
2+
BlockNoteSchema,
3+
combineByGroup,
4+
filterSuggestionItems,
5+
withPageBreak,
6+
} from "@blocknote/core";
17
import "@blocknote/core/fonts/inter.css";
28
import { BlockNoteView } from "@blocknote/mantine";
39
import "@blocknote/mantine/style.css";
4-
import { useCreateBlockNote } from "@blocknote/react";
10+
import {
11+
getDefaultReactSlashMenuItems,
12+
getPageBreakReactSlashMenuItems,
13+
SuggestionMenuController,
14+
useCreateBlockNote,
15+
} from "@blocknote/react";
516
import {
617
DOCXExporter,
718
docxDefaultSchemaMappings,
819
} from "@blocknote/xl-docx-exporter";
20+
import { useMemo } from "react";
21+
922
import "./styles.css";
1023

1124
export default function App() {
1225
// Creates a new editor instance with some initial content.
1326
const editor = useCreateBlockNote({
27+
schema: withPageBreak(BlockNoteSchema.create()),
1428
initialContent: [
1529
{
1630
type: "paragraph",
@@ -175,6 +189,9 @@ export default function App() {
175189
],
176190
},
177191
},
192+
{
193+
type: "pageBreak",
194+
},
178195
{
179196
type: "file",
180197
},
@@ -305,6 +322,13 @@ export default function App() {
305322
window.URL.revokeObjectURL(link.href);
306323
};
307324

325+
const slashMenuItems = useMemo(() => {
326+
return combineByGroup(
327+
getDefaultReactSlashMenuItems(editor),
328+
getPageBreakReactSlashMenuItems(editor)
329+
);
330+
}, [editor]);
331+
308332
// Renders the editor instance, and its contents as HTML below.
309333
return (
310334
<div>
@@ -314,7 +338,14 @@ export default function App() {
314338
</button>
315339
</div>
316340
<div className="item">
317-
<BlockNoteView editor={editor} />
341+
<BlockNoteView editor={editor} slashMenu={false}>
342+
<SuggestionMenuController
343+
triggerCharacter={"/"}
344+
getItems={async (query) =>
345+
filterSuggestionItems(slashMenuItems, query)
346+
}
347+
/>
348+
</BlockNoteView>
318349
</div>
319350
</div>
320351
);

package-lock.json

Lines changed: 39 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div data-page-break=""></div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div class="bn-block-group" data-node-type="blockGroup"><div class="bn-block-outer" data-node-type="blockOuter" data-id="1"><div class="bn-block" data-node-type="blockContainer" data-id="1"><div class="bn-block-content" data-content-type="pageBreak"><div class="bn-page-break" data-page-break=""></div></div></div></div></div>

packages/core/src/api/exporters/markdown/__snapshots__/pageBreak/basic/markdown.md

Whitespace-only changes.

packages/core/src/api/nodeConversions/__snapshots__/nodeConversions.test.ts.snap

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,6 +1605,22 @@ exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert
16051605
}
16061606
`;
16071607

1608+
exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert pageBreak/basic to/from prosemirror 1`] = `
1609+
{
1610+
"attrs": {
1611+
"backgroundColor": "default",
1612+
"id": "1",
1613+
"textColor": "default",
1614+
},
1615+
"content": [
1616+
{
1617+
"type": "pageBreak",
1618+
},
1619+
],
1620+
"type": "blockContainer",
1621+
}
1622+
`;
1623+
16081624
exports[`Test BlockNote-Prosemirror conversion > Case: default schema > Convert paragraph/basic to/from prosemirror 1`] = `
16091625
{
16101626
"attrs": {

packages/core/src/api/testUtil/cases/defaultSchema.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,22 @@ import {
66
DefaultInlineContentSchema,
77
DefaultStyleSchema,
88
} from "../../../blocks/defaultBlocks.js";
9+
import {
10+
pageBreakSchema,
11+
withPageBreak,
12+
} from "../../../blocks/PageBreakBlockContent/schema.js";
913
import { BlockNoteEditor } from "../../../editor/BlockNoteEditor.js";
14+
import { BlockNoteSchema } from "../../../editor/BlockNoteSchema.js";
1015

1116
export const defaultSchemaTestCases: EditorTestCases<
12-
DefaultBlockSchema,
17+
DefaultBlockSchema & typeof pageBreakSchema.blockSchema,
1318
DefaultInlineContentSchema,
1419
DefaultStyleSchema
1520
> = {
1621
name: "default schema",
1722
createEditor: () => {
1823
return BlockNoteEditor.create({
24+
schema: withPageBreak(BlockNoteSchema.create()),
1925
uploadFile: uploadToTmpFilesDotOrg_DEV_ONLY,
2026
});
2127
},
@@ -202,6 +208,14 @@ export const defaultSchemaTestCases: EditorTestCases<
202208
},
203209
],
204210
},
211+
{
212+
name: "pageBreak/basic",
213+
blocks: [
214+
{
215+
type: "pageBreak",
216+
},
217+
],
218+
},
205219
{
206220
name: "file/button",
207221
blocks: [

0 commit comments

Comments
 (0)