Skip to content

Commit c2464e1

Browse files
committed
Merge branch 'main' into releases
# Conflicts: # docs/package.json # lerna.json # package-lock.json # packages/ariakit/package.json # packages/core/package.json # packages/dev-scripts/package.json # packages/mantine/package.json # packages/react/package.json # packages/server-util/package.json # packages/shadcn/package.json # playground/package.json # tests/package.json
2 parents 2921a6a + 8717e57 commit c2464e1

File tree

506 files changed

+26097
-3439
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

506 files changed

+26097
-3439
lines changed

.eslintrc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ module.exports = {
3333
"error",
3434
{
3535
devDependencies: true,
36+
peerDependencies: true,
3637
optionalDependencies: false,
37-
peerDependencies: false,
3838
bundledDependencies: false,
3939
},
4040
],

.vscode/settings.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,8 @@
1111
"packages/website/docs/.vitepress": false,
1212
"**/.*": false
1313
},
14-
"typescript.tsdk": "node_modules/typescript/lib"
14+
"typescript.tsdk": "node_modules/typescript/lib",
15+
"[xml]": {
16+
"editor.defaultFormatter": "redhat.vscode-xml"
17+
}
1518
}

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,5 @@ BlockNote is built as part of [TypeCell](https://www.typecell.org). TypeCell is
121121
Hosting and deployments powered by Vercel:
122122

123123
<a href="https://vercel.com/?utm_source=TypeCell&utm_campaign=oss"><img src="https://images.ctfassets.net/e5382hct74si/78Olo8EZRdUlcDUFQvnzG7/fa4cdb6dc04c40fceac194134788a0e2/1618983297-powered-by-vercel.svg" alt="NLNet" width="150"></a>
124+
125+
This project is tested with BrowserStack

docs/components/example/styles.css

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
:focus-visible {
2-
box-shadow: unset !important;
2+
box-shadow: unset !important;
33
}
44

55
.demo .nextra-code-block pre {
6-
background-color: transparent !important;
7-
margin: 0 !important;
8-
padding: 0 !important;
6+
background-color: transparent !important;
7+
margin: 0 !important;
8+
padding: 0 !important;
99
}
1010

1111
.demo .nextra-code-block code > span {
12-
padding: 0 !important;
12+
padding: 0 !important;
1313
}
1414

1515
.demo .bn-container,
1616
.demo .bn-editor {
17-
height: 100%;
17+
height: 100%;
1818
}
1919

2020
.demo .bn-editor {
21-
overflow: auto;
22-
padding-block: 1rem;
21+
overflow: auto;
22+
padding-block: 1rem;
2323
}
2424

2525
.demo-contents a {
26-
color: revert;
27-
text-decoration: revert;
26+
color: revert;
27+
text-decoration: revert;
2828
}
29+
30+
.demo code.bn-inline-content {
31+
font-size: 1em;
32+
line-height: 1.5;
33+
display: block;
34+
}

docs/components/pages/landing/hero/DemoEditor.tsx

+47-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
1-
import { uploadToTmpFilesDotOrg_DEV_ONLY } from "@blocknote/core";
1+
import {
2+
BlockNoteSchema,
3+
combineByGroup,
4+
filterSuggestionItems,
5+
locales,
6+
uploadToTmpFilesDotOrg_DEV_ONLY,
7+
} from "@blocknote/core";
28
import "@blocknote/core/fonts/inter.css";
3-
import { useCreateBlockNote } from "@blocknote/react";
9+
import {
10+
getDefaultReactSlashMenuItems,
11+
SuggestionMenuController,
12+
useCreateBlockNote,
13+
} from "@blocknote/react";
414
import { BlockNoteView } from "@blocknote/mantine";
15+
import {
16+
getMultiColumnSlashMenuItems,
17+
locales as multiColumnLocales,
18+
multiColumnDropCursor,
19+
withMultiColumn,
20+
} from "@blocknote/xl-multi-column";
521
import "@blocknote/mantine/style.css";
622
import { useCallback, useMemo, useState } from "react";
723
import YPartyKitProvider from "y-partykit/provider";
@@ -67,6 +83,12 @@ export default function DemoEditor(props: { theme?: "light" | "dark" }) {
6783

6884
const editor = useCreateBlockNote(
6985
{
86+
dictionary: {
87+
...locales.en,
88+
multi_column: multiColumnLocales.en,
89+
},
90+
schema: withMultiColumn(BlockNoteSchema.create()),
91+
dropCursor: multiColumnDropCursor,
7092
collaboration: {
7193
provider,
7294
fragment: doc.getXmlFragment("blocknote"),
@@ -91,5 +113,27 @@ export default function DemoEditor(props: { theme?: "light" | "dark" }) {
91113
}
92114
}, [warningShown]);
93115

94-
return <BlockNoteView onFocus={focus} editor={editor} theme={props.theme} />;
116+
const getSlashMenuItems = useMemo(() => {
117+
return async (query: string) =>
118+
filterSuggestionItems(
119+
combineByGroup(
120+
getDefaultReactSlashMenuItems(editor),
121+
getMultiColumnSlashMenuItems(editor),
122+
),
123+
query,
124+
);
125+
}, [editor]);
126+
127+
return (
128+
<BlockNoteView
129+
onFocus={focus}
130+
editor={editor}
131+
theme={props.theme}
132+
slashMenu={false}>
133+
<SuggestionMenuController
134+
triggerCharacter={"/"}
135+
getItems={getSlashMenuItems}
136+
/>
137+
</BlockNoteView>
138+
);
95139
}

docs/components/pages/pricing/faq.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const faqs = [
1717
question:
1818
"What License is BlockNote using? Can I use it for commercial projects?",
1919
answer: `BlockNote is open source software licensed under the MPL 2.0 license, which allows you to use BlockNote in commercial (and closed-source) applications - even without a subscription.
20-
If you make changes to the BlockNote source files, you're expected to publish these changes so the wider community can benefit as well.`,
20+
If you make changes to the BlockNote source files, you're expected to publish these changes so the wider community can benefit as well. \nThe XL packages are dual-licensed and available under AGPL-3.0 or a commercial license as part of the BlockNote Business subscription or above.`,
2121
},
2222
// More questions...
2323
];

docs/package.json

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "docs",
3-
"version": "0.17.0",
3+
"version": "0.19.0",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",
@@ -9,11 +9,12 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12-
"@blocknote/ariakit": "^0.17.0",
13-
"@blocknote/core": "^0.17.0",
14-
"@blocknote/mantine": "^0.17.0",
15-
"@blocknote/react": "^0.17.0",
16-
"@blocknote/shadcn": "^0.17.0",
12+
"@blocknote/ariakit": "^0.19.0",
13+
"@blocknote/core": "^0.19.0",
14+
"@blocknote/mantine": "^0.19.0",
15+
"@blocknote/react": "^0.19.0",
16+
"@blocknote/shadcn": "^0.19.0",
17+
"@blocknote/xl-multi-column": "^0.19.0",
1718
"@headlessui/react": "^1.7.18",
1819
"@heroicons/react": "^2.1.4",
1920
"@mantine/core": "^7.10.1",

docs/pages/docs/advanced/nextjs.mdx

+24-2
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,26 @@ export default function Editor() {
2929

3030
## Import as dynamic
3131

32-
Now, you can use [Dynamic Imports](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading) to make sure BlockNote is only imported on the client-side.
32+
In the same directory, create a new file called `DynamicEditor.tsx`:
33+
Here, we will use [Dynamic Imports](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading) to make sure BlockNote is only imported on the client-side.
3334

3435
You can import the component we just created above using `next/dynamic` in your page:
3536

3637
```typescript jsx
38+
"use client";
39+
3740
import dynamic from "next/dynamic";
3841

39-
const Editor = dynamic(() => import("../components/Editor"), { ssr: false });
42+
export const Editor = dynamic(() => import("./Editor"), { ssr: false });
43+
```
44+
45+
## Import in a page / app
46+
47+
Now, you can import the dynamic editor in your page or app:
48+
49+
```typescript jsx
50+
import { Editor } from "../components/DynamicEditor";
51+
4052

4153
function App() {
4254
return (
@@ -47,4 +59,14 @@ function App() {
4759
}
4860
```
4961

62+
## React 19 / Next 15 StrictMode
63+
64+
BlockNote is not yet compatible with React 19 / Next 15 StrictMode. For now, disable StrictMode in your `next.config.ts`:
65+
66+
```typescript
67+
...
68+
reactStrictMode: false,
69+
...
70+
```
71+
5072
This should resolve any issues you might run into when embedding BlockNote in your Next.js React app!

docs/pages/docs/editor-api/_meta.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33
"manipulating-inline-content": "",
44
"cursor-selections": "",
55
"converting-blocks": "",
6-
"server-processing": ""
6+
"server-processing": "",
7+
"export-to-pdf": "",
8+
"export-to-docx": ""
79
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: Export to docx (Office Open XML)
3+
description: Export BlockNote documents to a docx word (Office Open XML) file.
4+
imageTitle: Export to docx
5+
path: /docs/export-to-docx
6+
---
7+
8+
import { Example } from "@/components/example";
9+
import { Callout } from "nextra/components";
10+
11+
# Exporting blocks to docx
12+
13+
It's possible to export BlockNote documents to docx, completely client-side.
14+
15+
<Callout type={"info"}>
16+
This feature is provided by the `@blocknote/xl-docx-exporter`. `xl-` packages
17+
are fully open source, but released under a copyleft license. A commercial
18+
license for usage in closed source, proprietary products comes as part of the
19+
[Business subscription](/pricing).
20+
</Callout>
21+
22+
First, install the `@blocknote/xl-docx-exporter` and `docx` packages:
23+
24+
```bash
25+
npm install @blocknote/xl-docx-exporter docx
26+
```
27+
28+
Then, create an instance of the `DOCXExporter` class. This exposes the following methods:
29+
30+
```typescript
31+
import {
32+
DOCXExporter,
33+
docxDefaultSchemaMappings,
34+
} from "@blocknote/xl-docx-exporter";
35+
import { Packer } from "docx";
36+
37+
// Create the exporter
38+
const exporter = new DOCXExporter(editor.schema, docxDefaultSchemaMappings);
39+
40+
// Convert the blocks to a docxjs document
41+
const docxDocument = await exporter.toDocxJsDocument(editor.document);
42+
43+
// Use docx to write to file:
44+
await Packer.toBuffer(docxDocument);
45+
```
46+
47+
See the [full example](/examples/interoperability/converting-blocks-to-docx) below:
48+
49+
<Example name="interoperability/converting-blocks-to-docx" />
50+
51+
### Customizing the Docx output file
52+
53+
`toDocxJsDocument` takes an optional `options` parameter, which allows you to customize document metadata (like the author) and section options (like headers and footers).
54+
55+
Example usage:
56+
57+
```typescript
58+
import { Paragraph, TextRun } from "docx";
59+
60+
const doc = await exporter.toDocxJsDocument(testDocument, {
61+
documentOptions: {
62+
creator: "John Doe",
63+
},
64+
sectionOptions: {
65+
headers: {
66+
default: {
67+
options: {
68+
children: [new Paragraph({ children: [new TextRun("Header")] })],
69+
},
70+
},
71+
},
72+
footers: {
73+
default: {
74+
options: {
75+
children: [new Paragraph({ children: [new TextRun("Footer")] })],
76+
},
77+
},
78+
},
79+
},
80+
});
81+
```
82+
83+
### Custom mappings / custom schemas
84+
85+
The `DOCXExporter` constructor takes a `schema`, `mappings` and `options` parameter.
86+
A _mapping_ defines how to convert a BlockNote schema element (a Block, Inline Content, or Style) to a [docxjs](https://docx.js.org/) element.
87+
If you're using a [custom schema](/docs/custom-schemas) in your editor, or if you want to overwrite how default BlockNote elements are converted to docx, you can pass your own `mappings`:
88+
89+
For example, use the following code in case your schema has an `extraBlock` type:
90+
91+
```typescript
92+
import {
93+
DOCXExporter,
94+
docxDefaultSchemaMappings,
95+
} from "@blocknote/xl-docx-exporter";
96+
import { Paragraph, TextRun } from "docx";
97+
98+
new DOCXExporter(schema, {
99+
blockMapping: {
100+
...docxDefaultSchemaMappings.blockMapping,
101+
myCustomBlock: (block, exporter) => {
102+
return new Paragraph({
103+
children: [
104+
new TextRun({
105+
text: "My custom block",
106+
}),
107+
],
108+
});
109+
},
110+
},
111+
inlineContentMapping: docxDefaultSchemaMappings.inlineContentMapping,
112+
styleMapping: docxDefaultSchemaMappings.styleMapping,
113+
});
114+
```
115+
116+
### Exporter options
117+
118+
The `DOCXExporter` constructor takes an optional `options` parameter.
119+
While conversion happens on the client-side, the default setup uses a server hosted proxy to resolve files:
120+
121+
```typescript
122+
const defaultOptions = {
123+
// a function to resolve external resources in order to avoid CORS issues
124+
// by default, this calls a BlockNote hosted server-side proxy to resolve files
125+
resolveFileUrl: corsProxyResolveFileUrl,
126+
// the colors to use in the Docx for things like highlighting, background colors and font colors.
127+
colors: COLORS_DEFAULT, // defaults from @blocknote/core
128+
};
129+
```

0 commit comments

Comments
 (0)