From 381471c1c0272c7baf057d0567b4bb0795fc863a Mon Sep 17 00:00:00 2001 From: yousefed Date: Thu, 24 Oct 2024 07:40:57 +0200 Subject: [PATCH] support colors --- packages/core/src/editor/Block.css | 8 +- packages/core/src/editor/defaultColors.ts | 77 +++++++++ packages/core/src/index.ts | 1 + packages/mantine/src/defaultThemes copy.ts | 159 ++++++++++++++++++ packages/mantine/src/defaultThemes.ts | 79 +-------- packages/pdf/src/Exporter.ts | 11 +- packages/pdf/src/docx/defaultSchema/blocks.ts | 70 ++++---- .../src/docx/defaultSchema/inlinecontent.ts | 4 +- packages/pdf/src/docx/defaultSchema/styles.ts | 17 +- packages/pdf/src/docx/docxExporter.ts | 17 +- packages/pdf/src/mapping.ts | 12 +- packages/pdf/src/pdf/defaultSchema/blocks.tsx | 20 +-- .../src/pdf/defaultSchema/inlinecontent.tsx | 8 +- packages/pdf/src/pdf/defaultSchema/styles.tsx | 15 +- packages/pdf/src/pdf/pdfExporter.tsx | 20 ++- .../src/react-email/reactEmailExporter.tsx | 17 +- 16 files changed, 377 insertions(+), 158 deletions(-) create mode 100644 packages/core/src/editor/defaultColors.ts create mode 100644 packages/mantine/src/defaultThemes copy.ts diff --git a/packages/core/src/editor/Block.css b/packages/core/src/editor/Block.css index cc9df706d..25f6d6957 100644 --- a/packages/core/src/editor/Block.css +++ b/packages/core/src/editor/Block.css @@ -196,7 +196,8 @@ NESTED BLOCKS cursor: pointer; } -.bn-block-content[data-content-type="checkListItem"][data-checked="true"] .bn-inline-content { +.bn-block-content[data-content-type="checkListItem"][data-checked="true"] + .bn-inline-content { text-decoration: line-through; } @@ -349,7 +350,8 @@ NESTED BLOCKS cursor: ew-resize; } -[data-content-type="audio"] > .bn-file-block-content-wrapper, .bn-audio { +[data-content-type="audio"] > .bn-file-block-content-wrapper, +.bn-audio { width: 100%; } @@ -425,7 +427,7 @@ NESTED BLOCKS } [data-background-color="orange"] { - background-color: #faebdd; + background-color: #f6e9d9; } [data-background-color="yellow"] { diff --git a/packages/core/src/editor/defaultColors.ts b/packages/core/src/editor/defaultColors.ts new file mode 100644 index 000000000..70d3a5e78 --- /dev/null +++ b/packages/core/src/editor/defaultColors.ts @@ -0,0 +1,77 @@ +export const COLORS_DEFAULT = { + gray: { + text: "#9b9a97", + background: "#ebeced", + }, + brown: { + text: "#64473a", + background: "#e9e5e3", + }, + red: { + text: "#e03e3e", + background: "#fbe4e4", + }, + orange: { + text: "#d9730d", + background: "#f6e9d9", + }, + yellow: { + text: "#dfab01", + background: "#fbf3db", + }, + green: { + text: "#4d6461", + background: "#ddedea", + }, + blue: { + text: "#0b6e99", + background: "#ddebf1", + }, + purple: { + text: "#6940a5", + background: "#eae4f2", + }, + pink: { + text: "#ad1a72", + background: "#f4dfeb", + }, +}; + +export const COLORS_DARK_MODE_DEFAULT = { + gray: { + text: "#bebdb8", + background: "#9b9a97", + }, + brown: { + text: "#8e6552", + background: "#64473a", + }, + red: { + text: "#ec4040", + background: "#be3434", + }, + orange: { + text: "#e3790d", + background: "#b7600a", + }, + yellow: { + text: "#dfab01", + background: "#b58b00", + }, + green: { + text: "#6b8b87", + background: "#4d6461", + }, + blue: { + text: "#0e87bc", + background: "#0b6e99", + }, + purple: { + text: "#8552d7", + background: "#6940a5", + }, + pink: { + text: "#da208f", + background: "#ad1a72", + }, +}; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ae98dff89..8abd97866 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -17,6 +17,7 @@ export * from "./blocks/defaultProps.js"; export * from "./editor/BlockNoteEditor.js"; export * from "./editor/BlockNoteExtensions.js"; export * from "./editor/BlockNoteSchema.js"; +export * from "./editor/defaultColors.js"; export * from "./editor/selectionTypes.js"; export * from "./extensions-shared/UiElementPosition.js"; export * from "./extensions/FilePanel/FilePanelPlugin.js"; diff --git a/packages/mantine/src/defaultThemes copy.ts b/packages/mantine/src/defaultThemes copy.ts new file mode 100644 index 000000000..553b382e5 --- /dev/null +++ b/packages/mantine/src/defaultThemes copy.ts @@ -0,0 +1,159 @@ +import { Theme } from "./BlockNoteTheme.js"; + +export const defaultColorScheme = [ + "#FFFFFF", + "#EFEFEF", + "#CFCFCF", + "#AFAFAF", + "#7F7F7F", + "#3F3F3F", + "#1F1F1F", + "#161616", + "#0F0F0F", + "#000000", +]; + +export const lightDefaultTheme = { + colors: { + editor: { + text: defaultColorScheme[5], + background: defaultColorScheme[0], + }, + menu: { + text: defaultColorScheme[5], + background: defaultColorScheme[0], + }, + tooltip: { + text: defaultColorScheme[5], + background: defaultColorScheme[1], + }, + hovered: { + text: defaultColorScheme[5], + background: defaultColorScheme[1], + }, + selected: { + text: defaultColorScheme[0], + background: defaultColorScheme[5], + }, + disabled: { + text: defaultColorScheme[3], + background: defaultColorScheme[1], + }, + shadow: defaultColorScheme[2], + border: defaultColorScheme[1], + sideMenu: defaultColorScheme[2], + highlights: { + gray: { + text: "#9b9a97", + background: "#ebeced", + }, + brown: { + text: "#64473a", + background: "#e9e5e3", + }, + red: { + text: "#e03e3e", + background: "#fbe4e4", + }, + orange: { + text: "#d9730d", + background: "#f6e9d9", + }, + yellow: { + text: "#dfab01", + background: "#fbf3db", + }, + green: { + text: "#4d6461", + background: "#ddedea", + }, + blue: { + text: "#0b6e99", + background: "#ddebf1", + }, + purple: { + text: "#6940a5", + background: "#eae4f2", + }, + pink: { + text: "#ad1a72", + background: "#f4dfeb", + }, + }, + }, + borderRadius: 6, + fontFamily: + '"Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, "Open Sans", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif', +} satisfies Theme; + +export const darkDefaultTheme = { + colors: { + editor: { + text: defaultColorScheme[2], + background: defaultColorScheme[6], + }, + menu: { + text: defaultColorScheme[2], + background: defaultColorScheme[6], + }, + tooltip: { + text: defaultColorScheme[2], + background: defaultColorScheme[7], + }, + hovered: { + text: defaultColorScheme[2], + background: defaultColorScheme[7], + }, + selected: { + text: defaultColorScheme[2], + background: defaultColorScheme[8], + }, + disabled: { + text: defaultColorScheme[5], + background: defaultColorScheme[7], + }, + shadow: defaultColorScheme[8], + border: defaultColorScheme[7], + sideMenu: defaultColorScheme[4], + highlights: { + gray: { + text: "#bebdb8", + background: "#9b9a97", + }, + brown: { + text: "#8e6552", + background: "#64473a", + }, + red: { + text: "#ec4040", + background: "#be3434", + }, + orange: { + text: "#e3790d", + background: "#b7600a", + }, + yellow: { + text: "#dfab01", + background: "#b58b00", + }, + green: { + text: "#6b8b87", + background: "#4d6461", + }, + blue: { + text: "#0e87bc", + background: "#0b6e99", + }, + purple: { + text: "#8552d7", + background: "#6940a5", + }, + pink: { + text: "#da208f", + background: "#ad1a72", + }, + }, + }, + borderRadius: lightDefaultTheme.borderRadius, + fontFamily: lightDefaultTheme.fontFamily, +} satisfies Theme; diff --git a/packages/mantine/src/defaultThemes.ts b/packages/mantine/src/defaultThemes.ts index 553b382e5..5aaf820ae 100644 --- a/packages/mantine/src/defaultThemes.ts +++ b/packages/mantine/src/defaultThemes.ts @@ -1,3 +1,4 @@ +import { COLORS_DARK_MODE_DEFAULT, COLORS_DEFAULT } from "@blocknote/core"; import { Theme } from "./BlockNoteTheme.js"; export const defaultColorScheme = [ @@ -42,44 +43,7 @@ export const lightDefaultTheme = { shadow: defaultColorScheme[2], border: defaultColorScheme[1], sideMenu: defaultColorScheme[2], - highlights: { - gray: { - text: "#9b9a97", - background: "#ebeced", - }, - brown: { - text: "#64473a", - background: "#e9e5e3", - }, - red: { - text: "#e03e3e", - background: "#fbe4e4", - }, - orange: { - text: "#d9730d", - background: "#f6e9d9", - }, - yellow: { - text: "#dfab01", - background: "#fbf3db", - }, - green: { - text: "#4d6461", - background: "#ddedea", - }, - blue: { - text: "#0b6e99", - background: "#ddebf1", - }, - purple: { - text: "#6940a5", - background: "#eae4f2", - }, - pink: { - text: "#ad1a72", - background: "#f4dfeb", - }, - }, + highlights: COLORS_DEFAULT, }, borderRadius: 6, fontFamily: @@ -115,44 +79,7 @@ export const darkDefaultTheme = { shadow: defaultColorScheme[8], border: defaultColorScheme[7], sideMenu: defaultColorScheme[4], - highlights: { - gray: { - text: "#bebdb8", - background: "#9b9a97", - }, - brown: { - text: "#8e6552", - background: "#64473a", - }, - red: { - text: "#ec4040", - background: "#be3434", - }, - orange: { - text: "#e3790d", - background: "#b7600a", - }, - yellow: { - text: "#dfab01", - background: "#b58b00", - }, - green: { - text: "#6b8b87", - background: "#4d6461", - }, - blue: { - text: "#0e87bc", - background: "#0b6e99", - }, - purple: { - text: "#8552d7", - background: "#6940a5", - }, - pink: { - text: "#da208f", - background: "#ad1a72", - }, - }, + highlights: COLORS_DARK_MODE_DEFAULT, }, borderRadius: lightDefaultTheme.borderRadius, fontFamily: lightDefaultTheme.fontFamily, diff --git a/packages/pdf/src/Exporter.ts b/packages/pdf/src/Exporter.ts index 4a0050966..709d28247 100644 --- a/packages/pdf/src/Exporter.ts +++ b/packages/pdf/src/Exporter.ts @@ -2,6 +2,7 @@ import { BlockFromConfig, BlockNoteSchema, BlockSchema, + COLORS_DEFAULT, InlineContent, InlineContentSchema, StyleSchema, @@ -11,6 +12,10 @@ import { import { BlockMapping, InlineContentMapping, StyleMapping } from "./mapping.js"; +export type ExporterOptions = { + resolveFileUrl?: (url: string) => Promise; + colors: typeof COLORS_DEFAULT; +}; export abstract class Exporter< B extends BlockSchema, I extends InlineContentSchema, @@ -27,9 +32,7 @@ export abstract class Exporter< inlineContentMapping: InlineContentMapping; styleMapping: StyleMapping; }, - public readonly options: { - resolveFileUrl?: (url: string) => Promise; - } + public readonly options: ExporterOptions ) {} public async resolveFile(url: string) { @@ -45,7 +48,7 @@ export abstract class Exporter< public mapStyles(styles: Styles) { const stylesArray = Object.entries(styles).map(([key, value]) => { - const mappedStyle = this.mappings.styleMapping[key](value); + const mappedStyle = this.mappings.styleMapping[key](value, this); return mappedStyle; }); return stylesArray; diff --git a/packages/pdf/src/docx/defaultSchema/blocks.ts b/packages/pdf/src/docx/defaultSchema/blocks.ts index 2bb0fda59..41e3c9775 100644 --- a/packages/pdf/src/docx/defaultSchema/blocks.ts +++ b/packages/pdf/src/docx/defaultSchema/blocks.ts @@ -1,4 +1,5 @@ import { + COLORS_DEFAULT, DefaultBlockSchema, DefaultProps, UnreachableCaseError, @@ -17,20 +18,26 @@ import { BlockMapping } from "../../mapping.js"; import { getImageDimensions } from "../../util/imageUtil.js"; import { Table } from "../util/Table.js"; -function blockPropsToStyles(props: Partial): IParagraphOptions { +function blockPropsToStyles( + props: Partial, + colors: typeof COLORS_DEFAULT +): IParagraphOptions { return { shading: - props.backgroundColor === "default" + props.backgroundColor === "default" || !props.backgroundColor ? undefined : { type: ShadingType.SOLID, - color: "00ff00", // TODO + color: + colors[ + props.backgroundColor as keyof typeof colors + ].background.slice(1), }, run: - props.textColor === "default" + props.textColor === "default" || !props.textColor ? undefined : { - color: "ff0000", // TODO + color: colors[props.textColor as keyof typeof colors].text.slice(1), }, alignment: !props.textAlignment || props.textAlignment === "left" @@ -56,57 +63,58 @@ export const docxBlockMappingForDefaultSchema: BlockMapping< | DocxTable, ParagraphChild > = { - paragraph: (block, t) => { + paragraph: (block, exporter) => { return new Paragraph({ - ...blockPropsToStyles(block.props), - children: t.transformInlineContent(block.content), + ...blockPropsToStyles(block.props, exporter.options.colors), + children: exporter.transformInlineContent(block.content), style: "Normal", run: { font: "Inter", }, }); }, - numberedListItem: (block, t, nestingLevel) => { + numberedListItem: (block, exporter, nestingLevel) => { return new Paragraph({ - ...blockPropsToStyles(block.props), - children: t.transformInlineContent(block.content), + ...blockPropsToStyles(block.props, exporter.options.colors), + children: exporter.transformInlineContent(block.content), numbering: { reference: "blocknote-numbered-list", level: nestingLevel, }, }); }, - bulletListItem: (block, t, nestingLevel) => { + bulletListItem: (block, exporter, nestingLevel) => { return new Paragraph({ - ...blockPropsToStyles(block.props), - children: t.transformInlineContent(block.content), + ...blockPropsToStyles(block.props, exporter.options.colors), + children: exporter.transformInlineContent(block.content), numbering: { reference: "blocknote-bullet-list", level: nestingLevel, }, }); }, - checkListItem: (block, t) => { + checkListItem: (block, exporter) => { return new Paragraph({ + ...blockPropsToStyles(block.props, exporter.options.colors), children: [ new CheckBox({ checked: block.props.checked }), new TextRun({ children: [" "], }), - ...t.transformInlineContent(block.content), + ...exporter.transformInlineContent(block.content), ], }); }, - heading: (block, t) => { + heading: (block, exporter) => { return new Paragraph({ - ...blockPropsToStyles(block.props), - children: t.transformInlineContent(block.content), + ...blockPropsToStyles(block.props, exporter.options.colors), + children: exporter.transformInlineContent(block.content), heading: `Heading${block.props.level}`, }); }, - audio: (block, _inlineContentTransformer) => { + audio: (block, exporter) => { return new Paragraph({ - ...blockPropsToStyles(block.props), + ...blockPropsToStyles(block.props, exporter.options.colors), children: [ new TextRun({ text: block.type + " not implemented", @@ -114,9 +122,9 @@ export const docxBlockMappingForDefaultSchema: BlockMapping< ], }); }, - video: (block, _inlineContentTransformer) => { + video: (block, exporter) => { return new Paragraph({ - ...blockPropsToStyles(block.props), + ...blockPropsToStyles(block.props, exporter.options.colors), children: [ new TextRun({ text: block.type + " not implemented", @@ -124,9 +132,9 @@ export const docxBlockMappingForDefaultSchema: BlockMapping< ], }); }, - file: (block, _inlineContentTransformer) => { + file: (block, exporter) => { return new Paragraph({ - ...blockPropsToStyles(block.props), + ...blockPropsToStyles(block.props, exporter.options.colors), children: [ new TextRun({ text: block.type + " not implemented", @@ -134,13 +142,13 @@ export const docxBlockMappingForDefaultSchema: BlockMapping< ], }); }, - image: async (block, t) => { - const blob = await t.resolveFile(block.props.url); + image: async (block, exporter) => { + const blob = await exporter.resolveFile(block.props.url); const { width, height } = await getImageDimensions(blob); return [ new Paragraph({ - ...blockPropsToStyles(block.props), + ...blockPropsToStyles(block.props, exporter.options.colors), children: [ new ImageRun({ data: await blob.arrayBuffer(), @@ -160,7 +168,7 @@ export const docxBlockMappingForDefaultSchema: BlockMapping< ], }), new Paragraph({ - ...blockPropsToStyles(block.props), + ...blockPropsToStyles(block.props, exporter.options.colors), children: [ new TextRun({ text: block.props.caption, @@ -170,7 +178,7 @@ export const docxBlockMappingForDefaultSchema: BlockMapping< }), ]; }, - table: (block, t) => { - return Table(block.content.rows, t); + table: (block, exporter) => { + return Table(block.content.rows, exporter); }, }; diff --git a/packages/pdf/src/docx/defaultSchema/inlinecontent.ts b/packages/pdf/src/docx/defaultSchema/inlinecontent.ts index 25be20abd..a7a2df997 100644 --- a/packages/pdf/src/docx/defaultSchema/inlinecontent.ts +++ b/packages/pdf/src/docx/defaultSchema/inlinecontent.ts @@ -12,10 +12,10 @@ export const docxInlineContentMappingForDefaultSchema: InlineContentMapping< ParagraphChild, TextRun > = { - link: (ic, t) => { + link: (ic, exporter) => { return new ExternalHyperlink({ children: ic.content.map((content) => { - return (t as DOCXExporter).transformStyledText( + return (exporter as DOCXExporter).transformStyledText( content, true ); diff --git a/packages/pdf/src/docx/defaultSchema/styles.ts b/packages/pdf/src/docx/defaultSchema/styles.ts index 56e9307f1..78e8331f8 100644 --- a/packages/pdf/src/docx/defaultSchema/styles.ts +++ b/packages/pdf/src/docx/defaultSchema/styles.ts @@ -40,22 +40,27 @@ export const docxStyleMappingForDefaultSchema: StyleMapping< strike: val, }; }, - backgroundColor: (val) => { - if (!val || val === "default") { + backgroundColor: (val, exporter) => { + if (!val) { return {}; } return { shading: { - fill: "00ff00", // TODO + fill: exporter.options.colors[ + val as keyof typeof exporter.options.colors + ].background.slice(1), }, }; }, - textColor: (val) => { - if (!val || val === "default") { + textColor: (val, exporter) => { + if (!val) { return {}; } return { - color: "dd0000", // TODO + color: + exporter.options.colors[ + val as keyof typeof exporter.options.colors + ].text.slice(1), }; }, code: (val) => { diff --git a/packages/pdf/src/docx/docxExporter.ts b/packages/pdf/src/docx/docxExporter.ts index b6ff791e4..2fc77a44e 100644 --- a/packages/pdf/src/docx/docxExporter.ts +++ b/packages/pdf/src/docx/docxExporter.ts @@ -2,6 +2,7 @@ import { Block, BlockNoteSchema, BlockSchema, + COLORS_DEFAULT, InlineContentSchema, StyleSchema, StyledText, @@ -19,7 +20,7 @@ import { TextRun, } from "docx"; -import { Exporter } from "../Exporter.js"; +import { Exporter, ExporterOptions } from "../Exporter.js"; import { loadFileBuffer } from "../util/fileUtil.js"; const DEFAULT_TAB_STOP = 16 * 0.75 * 1.5 * 20; /* twip */ @@ -50,11 +51,17 @@ export class DOCXExporter< IRunPropertiesOptions, TextRun >["mappings"], - options?: { - resolveFileUrl: (url: string) => Promise; - } + options?: Partial ) { - super(schema, mappings, options || {}); + const defaults = { + colors: COLORS_DEFAULT, + } satisfies Partial; + + const newOptions = { + ...defaults, + ...options, + }; + super(schema, mappings, newOptions); } public transformStyledText(styledText: StyledText, hyperlink?: boolean) { diff --git a/packages/pdf/src/mapping.ts b/packages/pdf/src/mapping.ts index 3599f93b2..add9fb573 100644 --- a/packages/pdf/src/mapping.ts +++ b/packages/pdf/src/mapping.ts @@ -21,7 +21,10 @@ export type BlockMapping< > = { [K in keyof B]: ( block: BlockFromConfigNoChildren, - transformer: Exporter, + // we don't know the exact types that are supported by the exporter at this point, + // because the mapping only knows about converting certain types (which might be a subset of the supported types) + // this is why there are many `any` types here (same for types below) + exporter: Exporter, nestingLevel: number, numberedListIndex?: number ) => RB | Promise; @@ -38,7 +41,7 @@ export type InlineContentMapping< > = { [K in keyof I]: ( inlineContent: InlineContentFromConfig, - transformer: Exporter + exporter: Exporter ) => RI; }; @@ -46,7 +49,10 @@ export type InlineContentMapping< * Defines a mapping from all style types with a schema to a result type R. */ export type StyleMapping = { - [K in keyof S]: (style: Styles[K]) => RS; + [K in keyof S]: ( + style: Styles[K], + exporter: Exporter + ) => RS; }; /** diff --git a/packages/pdf/src/pdf/defaultSchema/blocks.tsx b/packages/pdf/src/pdf/defaultSchema/blocks.tsx index 18a1bac1a..c5ab9c899 100644 --- a/packages/pdf/src/pdf/defaultSchema/blocks.tsx +++ b/packages/pdf/src/pdf/defaultSchema/blocks.tsx @@ -19,40 +19,40 @@ export const pdfBlockMappingForDefaultSchema: BlockMapping< React.ReactElement, React.ReactElement | React.ReactElement > = { - paragraph: (block, t) => { + paragraph: (block, exporter) => { // const style = blocknoteDefaultPropsToReactPDFStyle(block.props); - return {t.transformInlineContent(block.content)}; + return {exporter.transformInlineContent(block.content)}; }, - bulletListItem: (block, t) => { + bulletListItem: (block, exporter) => { // const style = t(block.props); return ( - {t.transformInlineContent(block.content)} + {exporter.transformInlineContent(block.content)} ); }, - numberedListItem: (block, t, _nestingLevel, numberedListIndex) => { + numberedListItem: (block, exporter, _nestingLevel, numberedListIndex) => { // const style = blocknoteDefaultPropsToReactPDFStyle(block.props); // console.log("NUMBERED LIST ITEM", block.props.textAlignment, style); return ( - {t.transformInlineContent(block.content)} + {exporter.transformInlineContent(block.content)} ); }, // would be nice to have pdf checkboxes: // https://github.com/diegomura/react-pdf/issues/2103 - checkListItem: (block, t) => { + checkListItem: (block, exporter) => { return ( - {t.transformInlineContent(block.content)} + {exporter.transformInlineContent(block.content)} ); }, - heading: (block, t) => { + heading: (block, exporter) => { const fontSizeEM = block.props.level === 1 ? 2 : block.props.level === 2 ? 1.5 : 1.17; return ( @@ -61,7 +61,7 @@ export const pdfBlockMappingForDefaultSchema: BlockMapping< fontSize: fontSizeEM * FONT_SIZE * PIXELS_PER_POINT, fontWeight: 700, }}> - {t.transformInlineContent(block.content)} + {exporter.transformInlineContent(block.content)} ); }, diff --git a/packages/pdf/src/pdf/defaultSchema/inlinecontent.tsx b/packages/pdf/src/pdf/defaultSchema/inlinecontent.tsx index 2ee18f4e6..1a1dfc2a0 100644 --- a/packages/pdf/src/pdf/defaultSchema/inlinecontent.tsx +++ b/packages/pdf/src/pdf/defaultSchema/inlinecontent.tsx @@ -8,14 +8,14 @@ export const pdfInlineContentMappingForDefaultSchema: InlineContentMapping< React.ReactElement | React.ReactElement, React.ReactElement > = { - link: (ic, transformer) => { + link: (ic, exporter) => { return ( - {ic.content.map((content) => transformer.transformStyledText(content))} + {ic.content.map((content) => exporter.transformStyledText(content))} ); }, - text: (ic, t) => { - return t.transformStyledText(ic); + text: (ic, exporter) => { + return exporter.transformStyledText(ic); }, }; diff --git a/packages/pdf/src/pdf/defaultSchema/styles.tsx b/packages/pdf/src/pdf/defaultSchema/styles.tsx index d34c000f4..050c92859 100644 --- a/packages/pdf/src/pdf/defaultSchema/styles.tsx +++ b/packages/pdf/src/pdf/defaultSchema/styles.tsx @@ -38,17 +38,24 @@ export const pdfStyleMappingForDefaultSchema: StyleMapping< textDecoration: "line-through", }; }, - backgroundColor: (val) => { + backgroundColor: (val, exporter) => { + if (!val) { + return {}; + } return { - backgroundColor: val, + backgroundColor: + exporter.options.colors[val as keyof typeof exporter.options.colors] + .background, }; }, - textColor: (val) => { + textColor: (val, exporter) => { if (!val) { return {}; } return { - color: val, + color: + exporter.options.colors[val as keyof typeof exporter.options.colors] + .text, }; }, code: (val) => { diff --git a/packages/pdf/src/pdf/pdfExporter.tsx b/packages/pdf/src/pdf/pdfExporter.tsx index d18d7e7b7..9254ae936 100644 --- a/packages/pdf/src/pdf/pdfExporter.tsx +++ b/packages/pdf/src/pdf/pdfExporter.tsx @@ -2,6 +2,7 @@ import { Block, BlockNoteSchema, BlockSchema, + COLORS_DEFAULT, DefaultProps, InlineContentSchema, StyleSchema, @@ -18,15 +19,14 @@ import { TextProps, View, } from "@react-pdf/renderer"; -import { Exporter } from "../Exporter.js"; +import { Exporter, ExporterOptions } from "../Exporter.js"; import { loadFontDataUrl } from "../util/fileUtil.js"; import { Style } from "./types.js"; const FONT_SIZE = 16; const PIXELS_PER_POINT = 0.75; -type Options = { - resolveFileUrl?: (url: string) => Promise; +type Options = ExporterOptions & { emojiSource: false | ReturnType; }; export class PDFExporter< @@ -62,6 +62,7 @@ export class PDFExporter< format: "png", url: "https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/", }, + colors: COLORS_DEFAULT, } satisfies Partial; const newOptions = { @@ -197,8 +198,17 @@ export class PDFExporter< return { textAlign: props.textAlignment, backgroundColor: - props.backgroundColor === "default" ? undefined : props.backgroundColor, - color: props.textColor, + props.backgroundColor === "default" || !props.backgroundColor + ? undefined + : this.options.colors[ + props.backgroundColor as keyof typeof this.options.colors + ].background, + color: + props.textColor === "default" || !props.textColor + ? undefined + : this.options.colors[ + props.textColor as keyof typeof this.options.colors + ].text, alignItems: props.textAlignment === "right" ? "flex-end" diff --git a/packages/pdf/src/react-email/reactEmailExporter.tsx b/packages/pdf/src/react-email/reactEmailExporter.tsx index 50d39bf81..8f1f1c9cb 100644 --- a/packages/pdf/src/react-email/reactEmailExporter.tsx +++ b/packages/pdf/src/react-email/reactEmailExporter.tsx @@ -2,6 +2,7 @@ import { Block, BlockNoteSchema, BlockSchema, + COLORS_DEFAULT, InlineContentSchema, StyleSchema, StyledText, @@ -17,7 +18,7 @@ import { Section, } from "@react-email/components"; import { CSSProperties } from "react"; -import { Exporter } from "../Exporter.js"; +import { Exporter, ExporterOptions } from "../Exporter.js"; export class ReactEmailExporter< B extends BlockSchema, @@ -43,11 +44,17 @@ export class ReactEmailExporter< CSSProperties, React.ReactElement >["mappings"], - options?: { - resolveFileUrl?: (url: string) => Promise; - } + options?: Partial ) { - super(schema, mappings, options || {}); + const defaults = { + colors: COLORS_DEFAULT, + } satisfies Partial; + + const newOptions = { + ...defaults, + ...options, + }; + super(schema, mappings, newOptions); } public transformStyledText(styledText: StyledText) {