Skip to content

Commit b468c24

Browse files
committed
Merge branch 'refactor/ai-prompts' into feature/ai-abort-2
2 parents a48326c + e1f961e commit b468c24

File tree

371 files changed

+9298
-9765
lines changed

Some content is hidden

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

371 files changed

+9298
-9765
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## 0.43.0 (2025-12-01)
2+
3+
### 🚀 Features
4+
5+
- Major Extensions & UI Refactor ([#2143](https://github.com/TypeCellOS/BlockNote/pull/2143))
6+
7+
### 🩹 Fixes
8+
9+
- allow configuring the email body's styles ([#2182](https://github.com/TypeCellOS/BlockNote/pull/2182))
10+
- **xl-docx-exporter:** improve OOXML interoperability ([#2206](https://github.com/TypeCellOS/BlockNote/pull/2206))
11+
12+
### ❤️ Thank You
13+
14+
- Nick Perez
15+
- Stephan Meijer @StephanMeijer
16+
117
## 0.42.3 (2025-11-19)
218

319
### 🩹 Fixes

docs/app/(home)/hero/DemoEditor.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import {
22
BlockNoteSchema,
33
combineByGroup,
4-
filterSuggestionItems,
54
uploadToTmpFilesDotOrg_DEV_ONLY,
65
} from "@blocknote/core";
7-
import * as locales from "@blocknote/core/locales";
6+
import { filterSuggestionItems } from "@blocknote/core/extensions";
87
import "@blocknote/core/fonts/inter.css";
8+
import * as locales from "@blocknote/core/locales";
9+
import { BlockNoteView } from "@blocknote/mantine";
10+
import "@blocknote/mantine/style.css";
911
import {
1012
getDefaultReactSlashMenuItems,
1113
SuggestionMenuController,
1214
useCreateBlockNote,
1315
} from "@blocknote/react";
14-
import { BlockNoteView } from "@blocknote/mantine";
1516
import {
1617
getMultiColumnSlashMenuItems,
17-
locales as multiColumnLocales,
1818
multiColumnDropCursor,
19+
locales as multiColumnLocales,
1920
withMultiColumn,
2021
} from "@blocknote/xl-multi-column";
21-
import "@blocknote/mantine/style.css";
2222
import { useTheme } from "next-themes";
2323
import { useCallback, useMemo, useState } from "react";
2424
import YPartyKitProvider from "y-partykit/provider";

docs/content/docs/features/ai/custom-commands.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ First, we define a new AI command. Let's create one that makes selected text mor
2626

2727
```tsx
2828
import {
29+
AIExtension,
2930
AIMenuSuggestionItem,
30-
getAIExtension,
3131
aiDocumentFormats,
3232
} from "@blocknote/xl-ai";
3333

@@ -40,7 +40,7 @@ export const makeInformal = (
4040
aliases: ["informal", "make informal", "casual"],
4141
icon: <RiEmotionHappyFill size={18} />,
4242
onItemClick: async () => {
43-
await getAIExtension(editor).invokeAI({
43+
await editor.getExtension(AIExtension)?.invokeAI({
4444
// The prompt to send to the LLM:
4545
userPrompt: "Give the selected text a more informal (casual) tone",
4646
// Tell the LLM to specifically use the selected content as context (instead of the whole document)

docs/content/docs/features/ai/reference.mdx

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,6 @@ type AIRequestHelpers = {
5959
};
6060
```
6161

62-
## `getAIExtension`
63-
64-
Use `getAIExtension` to retrieve the AI extension instance registered to the editor:
65-
66-
```typescript
67-
function getAIExtension(editor: BlockNoteEditor): AIExtension;
68-
```
69-
7062
## `AIExtension`
7163

7264
The `AIExtension` class is the main class for the AI extension. It exposes state and methods to interact with BlockNote's AI features.
@@ -79,9 +71,9 @@ class AIExtension {
7971
invokeAI(opts: InvokeAIOptions): Promise<void>;
8072

8173
/**
82-
* Returns a read-only zustand store with the state of the AI Menu
74+
* Returns a read-only Tanstack Store with the state of the AI Menu
8375
*/
84-
get store(): ReadonlyStoreApi<{
76+
get store(): Store<{
8577
aiMenuState:
8678
| ({
8779
/**
@@ -106,10 +98,10 @@ class AIExtension {
10698
}>;
10799

108100
/**
109-
* Returns a zustand store with the global configuration of the AI Extension.
101+
* Returns a Tanstack Store with the global configuration of the AI Extension.
110102
* These options are used by default across all LLM calls when calling {@link invokeAI}
111103
*/
112-
readonly options: StoreApi<AIRequestHelpers>;
104+
readonly options: Store<AIRequestHelpers>;
113105

114106
/** Open the AI menu at a specific block */
115107
openAIMenuAtBlock(blockID: string): void;

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ See the [full example](/examples/interoperability/converting-blocks-to-react-ema
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)
5858
- **container**: Customize the container element (A component which will wrap the email content including the header and footer)
59+
- **bodyStyles**: Customize the body styles (a `CSSProperties` object), providing an object here will completely override the default styles with what you provide
5960

6061
Example usage:
6162

@@ -82,6 +83,14 @@ const html = await exporter.toReactEmailDocument(editor.document, {
8283
footer: <Text>Footer</Text>,
8384
head: <title>My email</title>,
8485
container: ({ children }) => <Container>{children}</Container>,
86+
// These are the default body styles that are set by default
87+
bodyStyles: {
88+
fontFamily:
89+
"'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif",
90+
fontSize: "16px",
91+
lineHeight: "1.5",
92+
color: "#333",
93+
},
8594
});
8695
```
8796

docs/content/docs/features/extensions.mdx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ BlockNote includes an extensions system which lets you expand the editor's behav
1414

1515
## Creating an extension
1616

17-
An extension is an instance of the [`BlockNoteExtension`](https://github.com/TypeCellOS/BlockNote/blob/10cdbfb5f77ef82f3617c0fa1191e0bf5b7358c5/packages/core/src/editor/BlockNoteExtension.ts#L13) class. However, it's recommended for most use cases to create extensions using the `createBlockNoteExtension` function, rather than instanciating the class directly:
17+
You can create extensions using the `createExtension` function:
1818

1919
```typescript
20-
type BlockNoteExtensionOptions = {
20+
type Extension = {
2121
key: string;
2222
keyboardShortcuts?: Record<
2323
string,
@@ -35,18 +35,16 @@ type BlockNoteExtensionOptions = {
3535
tiptapExtensions?: AnyExtension[];
3636
}
3737

38-
const customBlockExtensionOptions: BlockNoteExtensionOptions = {
38+
const CustomExtension = createExtension({
3939
key: "customBlockExtension",
4040
keyboardShortcuts: ...,
4141
inputRules: ...,
4242
plugins: ...,
4343
tiptapExtensions: ...,
44-
}
45-
46-
const CustomExtension = createBlockNoteExtension(customBlockExtensionOptions);
44+
});
4745
```
4846

49-
Let's go over the options that can be passed into `createBlockNoteExtension`:
47+
Let's go over the options that can be passed into `createExtension`:
5048

5149
`key:` The name of the extension.
5250

@@ -68,20 +66,20 @@ Extensions can be added to the editor on their own via the [editor options](/doc
6866

6967
### Adding directly to the editor
7068

71-
The `extensions` [editor option](/docs/reference/editor/overview#options) takes an array of `BlockNoteExtension`s to be added to the editor:
69+
The `extensions` [editor option](/docs/reference/editor/overview#options) takes an array of extensions to be added to the editor:
7270

7371
```typescript
7472
const editor = useCreateBlockNote({
7573
extensions: [
7674
// Add extensions here:
77-
createBlockNoteExtension({ ... })
75+
createExtension({ ... })
7876
],
7977
});
8078
```
8179

8280
### Adding to custom blocks
8381

84-
When creating a [custom block](/docs/features/custom-schemas/custom-blocks#creating-a-custom-block-type) using `createReactBlockSpec`, you can pass an array of `BlockNoteExtension`s to the third parameter:
82+
When creating a [custom block](/docs/features/custom-schemas/custom-blocks#creating-a-custom-block-type) using `createReactBlockSpec`, you can pass an array of extensions to the third parameter:
8583

8684
```typescript
8785
const createCustomBlock = createReactBlockSpec(
@@ -95,7 +93,7 @@ const createCustomBlock = createReactBlockSpec(
9593
}
9694
[
9795
// Add extensions here:
98-
createBlockNoteExtension({ ... })
96+
createExtension({ ... })
9997
],
10098
});
10199
```

docs/content/docs/reference/editor/events.mdx

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,6 @@ The editor emits events for:
1616
- **Content changes** - When blocks are inserted, updated, or deleted
1717
- **Selection changes** - When the cursor position or selection changes
1818

19-
## `onCreate`
20-
21-
The `onCreate` callback is called when the editor has been initialized and is ready for use.
22-
23-
```typescript
24-
editor.onCreate(() => {
25-
console.log("Editor is ready for use");
26-
// Initialize plugins, set up event listeners, etc.
27-
});
28-
```
29-
3019
## `onMount`
3120

3221
The `onMount` callback is called when the editor has been mounted.

docs/package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
"better-sqlite3": "^11.10.0",
7878
"classnames": "2.3.2",
7979
"clsx": "2.1.1",
80-
"docx": "^9.0.2",
80+
"docx": "^9.5.1",
8181
"framer-motion": "^11.18.2",
8282
"fumadocs-core": "15.5.4",
8383
"fumadocs-docgen": "2.0.1",
@@ -103,8 +103,7 @@
103103
"twoslash": "^0.3.4",
104104
"y-partykit": "^0.0.25",
105105
"yjs": "^13.6.27",
106-
"zod": "^3.25.76",
107-
"zustand": "^5.0.3"
106+
"zod": "^3.25.76"
108107
},
109108
"devDependencies": {
110109
"@blocknote/ariakit": "workspace:*",
@@ -142,4 +141,4 @@
142141
"y-partykit": "^0.0.33",
143142
"yjs": "^13.6.27"
144143
}
145-
}
144+
}

examples/01-basic/03-multi-column/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import {
22
BlockNoteSchema,
33
combineByGroup,
4-
filterSuggestionItems,
54
} from "@blocknote/core";
5+
import { filterSuggestionItems } from "@blocknote/core/extensions";
66
import * as locales from "@blocknote/core/locales";
77
import "@blocknote/core/fonts/inter.css";
88
import { BlockNoteView } from "@blocknote/mantine";

examples/03-ui-components/02-formatting-toolbar-buttons/src/BlueButton.tsx

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import "@blocknote/mantine/style.css";
22
import {
33
useBlockNoteEditor,
44
useComponentsContext,
5-
useEditorContentOrSelectionChange,
5+
useEditorState,
66
useSelectedBlocks,
77
} from "@blocknote/react";
8-
import { useState } from "react";
98

109
// Custom Formatting Toolbar Button to toggle blue text & background color.
1110
export function BlueButton() {
@@ -14,18 +13,12 @@ export function BlueButton() {
1413
const Components = useComponentsContext()!;
1514

1615
// Tracks whether the text & background are both blue.
17-
const [isSelected, setIsSelected] = useState<boolean>(
18-
editor.getActiveStyles().textColor === "blue" &&
19-
editor.getActiveStyles().backgroundColor === "blue",
20-
);
21-
22-
// Updates state on content or selection change.
23-
useEditorContentOrSelectionChange(() => {
24-
setIsSelected(
16+
const isSelected = useEditorState({
17+
editor,
18+
selector: ({ editor }) =>
2519
editor.getActiveStyles().textColor === "blue" &&
26-
editor.getActiveStyles().backgroundColor === "blue",
27-
);
28-
}, editor);
20+
editor.getActiveStyles().backgroundColor === "blue",
21+
});
2922

3023
// Doesn't render unless a at least one block with inline content is
3124
// selected. You can use a similar pattern of returning `null` to

0 commit comments

Comments
 (0)