💄(frontend) improve styles export pdf

When exporting a document to PDF, the headings
spacings were too small, the break lines were
not displayed. This commit fixes these issues
by extending PDFExporter.
This commit is contained in:
Anthony LC
2025-02-05 15:23:25 +01:00
parent a1bca9c436
commit 48cb2587be
4 changed files with 117 additions and 16 deletions

View File

@@ -10,8 +10,14 @@ and this project adheres to
## [Unreleased]
## Added
- 📝(doc) Add security.md and codeofconduct.md #604
## Fixed
- 💄improve export spacings PDF #613
## [2.1.0] - 2025-01-29
## Added

View File

@@ -1,3 +1,5 @@
import { BlockNoteEditor, BlockNoteSchema } from '@blocknote/core';
export interface DocAttachment {
file: string;
}
@@ -12,3 +14,19 @@ export type HeadingBlock = {
level: number;
};
};
export const blockNoteInstance = BlockNoteSchema.create();
export type DocsBlockSchema = typeof blockNoteInstance.blockSchema;
export type DocsInlineContentSchema =
typeof blockNoteInstance.inlineContentSchema;
export type DocsStyleSchema = typeof blockNoteInstance.styleSchema;
export type DocsBlockNoteEditor = BlockNoteEditor<
DocsBlockSchema,
DocsInlineContentSchema,
DocsStyleSchema
>;
export type DocsBlockNoteSchema = BlockNoteSchema<
DocsBlockSchema,
DocsInlineContentSchema,
DocsStyleSchema
>;

View File

@@ -2,10 +2,6 @@ import {
DOCXExporter,
docxDefaultSchemaMappings,
} from '@blocknote/xl-docx-exporter';
import {
PDFExporter,
pdfDefaultSchemaMappings,
} from '@blocknote/xl-pdf-exporter';
import {
Button,
Loader,
@@ -25,6 +21,7 @@ import { useEditorStore } from '@/features/docs/doc-editor';
import { Doc } from '@/features/docs/doc-management';
import { TemplatesOrdering, useTemplates } from '../api/useTemplates';
import { DocsPDFExporter } from '../libs/DocsPDFExporter';
import { downloadFile, exportResolveFileUrl } from '../utils';
enum DocDownloadFormat {
@@ -91,19 +88,12 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
let blobExport: Blob;
if (format === DocDownloadFormat.PDF) {
const defaultExporter = new PDFExporter(
editor.schema,
pdfDefaultSchemaMappings,
);
const defaultExporter = new DocsPDFExporter(editor.schema);
const exporter = new DocsPDFExporter(editor.schema, {
resolveFileUrl: async (url) =>
exportResolveFileUrl(url, defaultExporter.options.resolveFileUrl),
});
const exporter = new PDFExporter(
editor.schema,
pdfDefaultSchemaMappings,
{
resolveFileUrl: async (url) =>
exportResolveFileUrl(url, defaultExporter.options.resolveFileUrl),
},
);
const pdfDocument = await exporter.toReactPDFDocument(exportDocument);
blobExport = await pdf(pdfDocument).toBlob();
} else {

View File

@@ -0,0 +1,87 @@
import { Block, DefaultProps, ExporterOptions } from '@blocknote/core';
import {
PDFExporter,
pdfDefaultSchemaMappings,
} from '@blocknote/xl-pdf-exporter';
import { Font } from '@react-pdf/renderer';
import {
DocsBlockNoteSchema,
DocsBlockSchema,
DocsInlineContentSchema,
DocsStyleSchema,
} from '@/features/docs/doc-editor';
type Options = ExporterOptions & {
emojiSource: false | ReturnType<typeof Font.getEmojiSource>;
};
type DocsDefaultProps = DefaultProps & {
level?: number;
};
export class DocsPDFExporter extends PDFExporter<
DocsBlockSchema,
DocsStyleSchema,
DocsInlineContentSchema
> {
constructor(
protected readonly schemaMappings: DocsBlockNoteSchema,
options?: Partial<Options>,
) {
super(schemaMappings, pdfDefaultSchemaMappings, options);
}
/**
* Breaklines are not displayed in PDFs, by adding a space we ensure that the line is not ignored
* @param blocks
* @param nestingLevel
* @returns
*/
public transformBlocks(
blocks: Block<DocsBlockSchema, DocsInlineContentSchema, DocsStyleSchema>[], // Or BlockFromConfig<B[keyof B], I, S>?
nestingLevel?: number,
) {
blocks.forEach((block) => {
if (Array.isArray(block.content)) {
block.content.forEach((content) => {
if (content.type === 'text' && !content.text) {
content.text = ' ';
}
});
if (!block.content.length) {
block.content.push({
styles: {},
text: ' ',
type: 'text',
});
}
}
});
return super.transformBlocks(blocks, nestingLevel);
}
/**
* Override the method to add our custom styles
* @param props
* @returns
*/
public blocknoteDefaultPropsToReactPDFStyle(
props: Partial<DocsDefaultProps>,
) {
let styles = super.blocknoteDefaultPropsToReactPDFStyle(props);
// Add margin to headings
if (props.level) {
styles = {
marginTop: 15,
marginBottom: 15,
...styles,
};
}
return styles;
}
}