Skip to content

Commit f391178

Browse files
committed
✨(frontend) add odt export for callout and upload loader blocks
Added ODT mappings for callout with emoji and upload loader with icons. Signed-off-by: Cyril <c.gromoff@gmail.com>
1 parent 2f010cf commit f391178

File tree

6 files changed

+149
-279
lines changed

6 files changed

+149
-279
lines changed

src/frontend/apps/impress/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"@blocknote/react": "0.41.1",
2626
"@blocknote/xl-docx-exporter": "0.41.1",
2727
"@blocknote/xl-multi-column": "0.41.1",
28+
"@blocknote/xl-odt-exporter": "^0.41.1",
2829
"@blocknote/xl-pdf-exporter": "0.41.1",
2930
"@dnd-kit/core": "6.3.1",
3031
"@dnd-kit/modifiers": "9.0.0",
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
3+
import { DocsExporterODT } from '../types';
4+
5+
export const blockMappingCalloutODT: DocsExporterODT['mappings']['blockMapping']['callout'] =
6+
(block, exporter) => {
7+
// Map callout to paragraph with emoji prefix
8+
const emoji = block.props.emoji || '💡';
9+
10+
// Transform inline content (text, bold, links, etc.)
11+
const inlineContent = exporter.transformInlineContent(block.content);
12+
13+
const textAlignment =
14+
block.props.textAlignment === 'center'
15+
? 'center'
16+
: block.props.textAlignment === 'right'
17+
? 'right'
18+
: 'left';
19+
20+
// Simple paragraph with emoji - ODT background colors are complex to implement
21+
// and not well supported across different ODT readers
22+
return React.createElement(
23+
'text:p',
24+
{
25+
'text:style-name': textAlignment,
26+
},
27+
`${emoji} `,
28+
...inlineContent,
29+
);
30+
};
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './calloutDocx';
2+
export * from './calloutODT';
23
export * from './calloutPDF';
34
export * from './headingPDF';
45
export * from './imageDocx';
@@ -7,5 +8,6 @@ export * from './paragraphPDF';
78
export * from './quoteDocx';
89
export * from './quotePDF';
910
export * from './tablePDF';
10-
export * from './uploadLoaderPDF';
1111
export * from './uploadLoaderDocx';
12+
export * from './uploadLoaderODT';
13+
export * from './uploadLoaderPDF';
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
3+
import { DocsExporterODT } from '../types';
4+
5+
export const blockMappingUploadLoaderODT: DocsExporterODT['mappings']['blockMapping']['uploadLoader'] =
6+
(block) => {
7+
// Map uploadLoader to paragraph with information text
8+
const information = block.props.information || '';
9+
const type = block.props.type || 'loading';
10+
const prefix = type === 'warning' ? '⚠️ ' : '⏳ ';
11+
12+
return React.createElement(
13+
'text:p',
14+
{ 'text:style-name': 'Text_20_body' },
15+
`${prefix}${information}`,
16+
);
17+
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { odtDefaultSchemaMappings } from '@blocknote/xl-odt-exporter';
2+
3+
import {
4+
blockMappingCalloutODT,
5+
blockMappingImageODT,
6+
blockMappingUploadLoaderODT,
7+
} from './blocks-mapping';
8+
9+
// Note: Using `as any` due to strict typing constraints in @blocknote/xl-odt-exporter
10+
// when extending with custom block mappings. The mappings are functionally correct.
11+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12+
export const odtDocsSchemaMappings: any = {
13+
...odtDefaultSchemaMappings,
14+
blockMapping: {
15+
...odtDefaultSchemaMappings.blockMapping,
16+
// Custom mappings for our custom blocks
17+
callout: blockMappingCalloutODT,
18+
image: blockMappingImageODT,
19+
// We're reusing the file block mapping for PDF blocks
20+
pdf: odtDefaultSchemaMappings.blockMapping.file,
21+
uploadLoader: blockMappingUploadLoaderODT,
22+
},
23+
inlineContentMapping: {
24+
...odtDefaultSchemaMappings.inlineContentMapping,
25+
},
26+
styleMapping: {
27+
...odtDefaultSchemaMappings.styleMapping,
28+
},
29+
};

0 commit comments

Comments
 (0)