@blocknote/xl-pdf-exporter 0.22.0 → 0.23.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.
@@ -2,6 +2,8 @@ import {
2
2
  BlockMapping,
3
3
  DefaultBlockSchema,
4
4
  DefaultProps,
5
+ pageBreakSchema,
6
+ StyledText,
5
7
  } from "@blocknote/core";
6
8
  import { Image, Link, Path, Svg, Text, View } from "@react-pdf/renderer";
7
9
  import {
@@ -16,7 +18,7 @@ const PIXELS_PER_POINT = 0.75;
16
18
  const FONT_SIZE = 16;
17
19
 
18
20
  export const pdfBlockMappingForDefaultSchema: BlockMapping<
19
- DefaultBlockSchema,
21
+ DefaultBlockSchema & typeof pageBreakSchema.blockSchema,
20
22
  any,
21
23
  any,
22
24
  React.ReactElement<Text>,
@@ -69,7 +71,38 @@ export const pdfBlockMappingForDefaultSchema: BlockMapping<
69
71
  );
70
72
  },
71
73
  codeBlock: (block) => {
72
- return <Text>{block.type + " not implemented"}</Text>;
74
+ const textContent = (block.content as StyledText<any>[])[0]?.text || "";
75
+ const lines = textContent.split("\n").map((line, index) => {
76
+ const indent = line.match(/^\s*/)?.[0].length || 0;
77
+
78
+ return (
79
+ <Text
80
+ key={`line_${index}`}
81
+ style={{
82
+ marginLeft: indent * 9.5 * PIXELS_PER_POINT,
83
+ }}>
84
+ {line.trimStart() || <>&nbsp;</>}
85
+ </Text>
86
+ );
87
+ });
88
+
89
+ return (
90
+ <View
91
+ wrap={false}
92
+ style={{
93
+ padding: 24 * PIXELS_PER_POINT,
94
+ backgroundColor: "#161616",
95
+ color: "#ffffff",
96
+ lineHeight: 1.25,
97
+ fontSize: FONT_SIZE * PIXELS_PER_POINT,
98
+ fontFamily: "GeistMono",
99
+ }}>
100
+ {lines}
101
+ </View>
102
+ );
103
+ },
104
+ pageBreak: () => {
105
+ return <View break />;
73
106
  },
74
107
  audio: (block, exporter) => {
75
108
  return (
@@ -62,7 +62,7 @@ export const pdfStyleMappingForDefaultSchema: StyleMapping<
62
62
  return {};
63
63
  }
64
64
  return {
65
- fontFamily: "Courier",
65
+ fontFamily: "GeistMono",
66
66
  };
67
67
  },
68
68
  };
@@ -6,10 +6,11 @@ import {
6
6
  defaultBlockSpecs,
7
7
  defaultInlineContentSpecs,
8
8
  defaultStyleSpecs,
9
+ PageBreak,
9
10
  } from "@blocknote/core";
10
11
  import { Text } from "@react-pdf/renderer";
11
12
  import { testDocument } from "@shared/testDocument.js";
12
- import { prettyDOM, render } from "@testing-library/react";
13
+ import reactElementToJSXString from "react-element-to-jsx-string";
13
14
  import { describe, expect, it } from "vitest";
14
15
  import { pdfDefaultSchemaMappings } from "./defaultSchema/index.js";
15
16
  import { PDFExporter } from "./pdfExporter.js";
@@ -26,6 +27,7 @@ describe("exporter", () => {
26
27
  const schema = BlockNoteSchema.create({
27
28
  blockSpecs: {
28
29
  ...defaultBlockSpecs,
30
+ pageBreak: PageBreak,
29
31
  extraBlock: createBlockSpec(
30
32
  {
31
33
  content: "none",
@@ -155,13 +157,15 @@ describe("exporter", () => {
155
157
 
156
158
  it("should export a document", async () => {
157
159
  const exporter = new PDFExporter(
158
- BlockNoteSchema.create(),
160
+ BlockNoteSchema.create({
161
+ blockSpecs: { ...defaultBlockSpecs, pageBreak: PageBreak },
162
+ }),
159
163
  pdfDefaultSchemaMappings
160
164
  );
161
165
 
162
166
  const transformed = await exporter.toReactPDFDocument(testDocument);
163
- const view = render(transformed);
164
- const str = prettyDOM(view.container, undefined, { highlight: false });
167
+ const str = reactElementToJSXString(transformed);
168
+
165
169
  expect(str).toMatchFileSnapshot("__snapshots__/example.jsx");
166
170
 
167
171
  // would be nice to compare pdf images, but currently doesn't work on mac os (due to node canvas installation issue)
@@ -186,7 +190,9 @@ describe("exporter", () => {
186
190
 
187
191
  it("should export a document with header and footer", async () => {
188
192
  const exporter = new PDFExporter(
189
- BlockNoteSchema.create(),
193
+ BlockNoteSchema.create({
194
+ blockSpecs: { ...defaultBlockSpecs, pageBreak: PageBreak },
195
+ }),
190
196
  pdfDefaultSchemaMappings
191
197
  );
192
198
 
@@ -194,8 +200,7 @@ describe("exporter", () => {
194
200
  header: <Text>Header</Text>,
195
201
  footer: <Text>Footer</Text>,
196
202
  });
197
- const view = render(transformed);
198
- const str = prettyDOM(view.container, undefined, { highlight: false });
203
+ const str = reactElementToJSXString(transformed);
199
204
  expect(str).toMatchFileSnapshot(
200
205
  "__snapshots__/exampleWithHeaderAndFooter.jsx"
201
206
  );
@@ -63,7 +63,6 @@ export class PDFExporter<
63
63
  fontSize: FONT_SIZE * PIXELS_PER_POINT, // pixels
64
64
  lineHeight: 1.5,
65
65
  },
66
- section: {},
67
66
  block: {},
68
67
  blockChildren: {},
69
68
  header: {},
@@ -145,6 +144,11 @@ export class PDFExporter<
145
144
  numberedListIndex
146
145
  ); // TODO: any
147
146
 
147
+ if (b.type === "pageBreak") {
148
+ ret.push(self);
149
+ continue;
150
+ }
151
+
148
152
  const style = this.blocknoteDefaultPropsToReactPDFStyle(b.props as any);
149
153
  ret.push(
150
154
  <>
@@ -216,6 +220,14 @@ export class PDFExporter<
216
220
  fontWeight: "bold",
217
221
  });
218
222
 
223
+ font = await loadFontDataUrl(
224
+ await import("@shared/assets/fonts/GeistMono-Regular.ttf")
225
+ );
226
+ Font.register({
227
+ family: "GeistMono",
228
+ src: font,
229
+ });
230
+
219
231
  this.fontsRegistered = true;
220
232
  }
221
233
 
@@ -247,9 +259,7 @@ export class PDFExporter<
247
259
  {options.header}
248
260
  </View>
249
261
  )}
250
- <View style={this.styles.section}>
251
- {await this.transformBlocks(blocks)}
252
- </View>
262
+ {await this.transformBlocks(blocks)}
253
263
  {options.footer && (
254
264
  <View
255
265
  fixed
@@ -1,4 +1,4 @@
1
1
  /// <reference types="react" />
2
- import { BlockMapping, DefaultBlockSchema } from "@blocknote/core";
2
+ import { BlockMapping, DefaultBlockSchema, pageBreakSchema } from "@blocknote/core";
3
3
  import { Link, Text } from "@react-pdf/renderer";
4
- export declare const pdfBlockMappingForDefaultSchema: BlockMapping<DefaultBlockSchema, any, any, React.ReactElement<Text>, React.ReactElement<Text> | React.ReactElement<Link>>;
4
+ export declare const pdfBlockMappingForDefaultSchema: BlockMapping<DefaultBlockSchema & typeof pageBreakSchema.blockSchema, any, any, React.ReactElement<Text>, React.ReactElement<Text> | React.ReactElement<Link>>;
@@ -447,6 +447,23 @@ export declare const pdfDefaultSchemaMappings: {
447
447
  fileBlockAccept: string[];
448
448
  }, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
449
449
  };
450
+ }> & import("@blocknote/core").BlockSchemaFromSpecs<{
451
+ pageBreak: {
452
+ config: {
453
+ type: "pageBreak";
454
+ propSchema: {};
455
+ content: "none";
456
+ isFileBlock: false;
457
+ isSelectable: false;
458
+ };
459
+ implementation: import("@blocknote/core").TiptapBlockImplementation<{
460
+ type: "pageBreak";
461
+ propSchema: {};
462
+ content: "none";
463
+ isFileBlock: false;
464
+ isSelectable: false;
465
+ }, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
466
+ };
450
467
  }>, any, any, import("react").ReactElement<import("@react-pdf/renderer").Text, string | import("react").JSXElementConstructor<any>>, import("react").ReactElement<import("@react-pdf/renderer").Text, string | import("react").JSXElementConstructor<any>> | import("react").ReactElement<import("@react-pdf/renderer").Link, string | import("react").JSXElementConstructor<any>>>;
451
468
  inlineContentMapping: import("@blocknote/core").InlineContentMapping<import("@blocknote/core").InlineContentSchemaFromSpecs<{
452
469
  text: {
@@ -27,7 +27,6 @@ export declare class PDFExporter<B extends BlockSchema, S extends StyleSchema, I
27
27
  fontSize: number;
28
28
  lineHeight: number;
29
29
  };
30
- section: {};
31
30
  block: {};
32
31
  blockChildren: {};
33
32
  header: {};