Skip to content

Commit 581b88d

Browse files
committed
Merge branch 'main' into fix/1844
2 parents 2c2ae42 + 9210de3 commit 581b88d

File tree

24 files changed

+1599
-154
lines changed

24 files changed

+1599
-154
lines changed

docs/content/docs/features/export/email.mdx

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,33 @@ See the [full example](/examples/interoperability/converting-blocks-to-react-ema
5555
- **header**: Add content to the top of the email (must be a React-Email compatible component)
5656
- **footer**: Add content to the bottom of the email (must be a React-Email compatible component)
5757
- **head**: Inject elements into the [Head element](https://react.email/docs/components/head)
58+
- **container**: Customize the container element (A component which will wrap the email content including the header and footer)
5859

5960
Example usage:
6061

61-
```tsx
62-
import { Text } from "@react-email/components";
62+
```tsx twoslash
63+
import React from "react";
64+
import {
65+
ReactEmailExporter,
66+
reactEmailDefaultSchemaMappings,
67+
} from "@blocknote/xl-email-exporter";
68+
import { BlockNoteEditor } from "@blocknote/core";
69+
import { Text, Container } from "@react-email/components";
70+
71+
const editor = BlockNoteEditor.create();
72+
73+
// ---cut---
74+
const exporter = new ReactEmailExporter(
75+
editor.schema,
76+
reactEmailDefaultSchemaMappings,
77+
);
78+
6379
const html = await exporter.toReactEmailDocument(editor.document, {
6480
preview: "This is a preview of the email content",
6581
header: <Text>Header</Text>,
6682
footer: <Text>Footer</Text>,
6783
head: <title>My email</title>,
84+
container: ({ children }) => <Container>{children}</Container>,
6885
});
6986
```
7087

@@ -106,3 +123,41 @@ const defaultOptions = {
106123
colors: COLORS_DEFAULT, // defaults from @blocknote/core
107124
};
108125
```
126+
127+
### Custom styles
128+
129+
Want to tweak the default styles of the email? You can use `reactEmailDefaultSchemaMappingsWithStyles` to create a custom mapping with your own styles.
130+
131+
```tsx
132+
import {
133+
ReactEmailExporter,
134+
reactEmailDefaultSchemaMappingsWithStyles,
135+
} from "@blocknote/xl-email-exporter";
136+
import { Text } from "@react-email/components";
137+
138+
const { blockMapping, inlineContentMapping, styleMapping } =
139+
reactEmailDefaultSchemaMappingsWithStyles({
140+
textStyles: {
141+
paragraph: {
142+
style: {
143+
fontSize: 16,
144+
lineHeight: 1.5,
145+
margin: 3,
146+
minHeight: 24,
147+
},
148+
},
149+
},
150+
});
151+
152+
new ReactEmailExporter(schema, {
153+
// You can still use the default block mapping, but you can also overwrite it
154+
blockMapping: {
155+
...blockMapping,
156+
audio: (block, exporter) => {
157+
return <Text>Audio block</Text>;
158+
},
159+
},
160+
inlineContentMapping,
161+
styleMapping,
162+
});
163+
```

docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
"fumadocs-typescript": "^4.0.6",
8585
"fumadocs-ui": "^15.5.4",
8686
"import-in-the-middle": "^1.14.2",
87-
"next": "^15.4.1",
87+
"next": "^15.4.3",
8888
"nodemailer": "^6.10.1",
8989
"partykit": "^0.0.115",
9090
"pg": "^8.15.5",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"playground": true,
3+
"docs": true,
4+
"author": "must",
5+
"tags": [
6+
"Intermediate",
7+
"UI Components",
8+
"Tables",
9+
"Appearance & Styling"
10+
]
11+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Advanced Tables with Calculated Columns
2+
3+
This example demonstrates advanced table features including automatic calculations. It shows how to create a table with calculated columns that automatically update when values change.
4+
5+
## Features
6+
7+
- **Automatic Calculations**: Quantity × Price = Total for each row
8+
- **Grand Total**: Automatically calculated sum of all totals
9+
- **Real-time Updates**: Calculations update immediately when you change quantity or price values
10+
- **Split cells**: Merge and split table cells
11+
- **Cell background color**: Color individual cells
12+
- **Cell text color**: Change text color in cells
13+
- **Table row and column headers**: Use headers for better organization
14+
15+
## How It Works
16+
17+
The example uses the `onChange` event listener to detect when table content changes. When a table is updated, it automatically:
18+
19+
1. Extracts quantity and price values from each data row
20+
2. Calculates the total (quantity × price) for each row
21+
3. Updates the total column with the calculated values
22+
4. Calculates and updates the grand total
23+
24+
## Code Highlights
25+
26+
```tsx
27+
<BlockNoteView
28+
editor={editor}
29+
onChange={(editor, { getChanges }) => {
30+
const changes = getChanges();
31+
32+
changes.forEach((change) => {
33+
if (change.type === "update" && change.block.type === "table") {
34+
const updatedRows = calculateTableTotals(change.block);
35+
if (updatedRows) {
36+
editor.updateBlock(change.block, {
37+
type: "table",
38+
content: {
39+
...change.block.content,
40+
rows: updatedRows as any,
41+
} as any,
42+
});
43+
}
44+
}
45+
});
46+
}}
47+
></BlockNoteView>
48+
```
49+
50+
**Relevant Docs:**
51+
52+
- [Tables](/docs/features/blocks/tables)
53+
- [Editor Setup](/docs/getting-started/editor-setup)
54+
- [Events](/docs/reference/editor/events)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<html lang="en">
2+
<head>
3+
<meta charset="UTF-8" />
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
5+
<title>Advanced Tables with Calculated Columns</title>
6+
<script>
7+
<!-- AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY -->
8+
</script>
9+
</head>
10+
<body>
11+
<div id="root"></div>
12+
<script type="module" src="./main.tsx"></script>
13+
</body>
14+
</html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
2+
import React from "react";
3+
import { createRoot } from "react-dom/client";
4+
import App from "./src/App.jsx";
5+
6+
const root = createRoot(document.getElementById("root")!);
7+
root.render(
8+
<React.StrictMode>
9+
<App />
10+
</React.StrictMode>
11+
);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "@blocknote/example-ui-components-advanced-tables-2",
3+
"description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
4+
"private": true,
5+
"version": "0.12.4",
6+
"scripts": {
7+
"start": "vite",
8+
"dev": "vite",
9+
"build:prod": "tsc && vite build",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@blocknote/core": "latest",
14+
"@blocknote/react": "latest",
15+
"@blocknote/ariakit": "latest",
16+
"@blocknote/mantine": "latest",
17+
"@blocknote/shadcn": "latest",
18+
"react": "^19.1.0",
19+
"react-dom": "^19.1.0"
20+
},
21+
"devDependencies": {
22+
"@types/react": "^19.1.0",
23+
"@types/react-dom": "^19.1.0",
24+
"@vitejs/plugin-react": "^4.3.1",
25+
"vite": "^5.3.4"
26+
}
27+
}

0 commit comments

Comments
 (0)