@blocknote/xl-pdf-exporter 0.21.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>>;
@@ -138,6 +138,10 @@ export declare const pdfDefaultSchemaMappings: {
138
138
  type: "numberedListItem";
139
139
  content: "inline";
140
140
  propSchema: {
141
+ start: {
142
+ default: undefined;
143
+ type: "number";
144
+ };
141
145
  backgroundColor: {
142
146
  default: "default";
143
147
  };
@@ -154,6 +158,10 @@ export declare const pdfDefaultSchemaMappings: {
154
158
  type: "numberedListItem";
155
159
  content: "inline";
156
160
  propSchema: {
161
+ start: {
162
+ default: undefined;
163
+ type: "number";
164
+ };
157
165
  backgroundColor: {
158
166
  default: "default";
159
167
  };
@@ -439,6 +447,23 @@ export declare const pdfDefaultSchemaMappings: {
439
447
  fileBlockAccept: string[];
440
448
  }, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
441
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
+ };
442
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>>>;
443
468
  inlineContentMapping: import("@blocknote/core").InlineContentMapping<import("@blocknote/core").InlineContentSchemaFromSpecs<{
444
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: {};