Skip to content

Commit 8de551c

Browse files
committed
Merge branch 'main' into pnpm-11
2 parents 0be007e + b3afcdd commit 8de551c

120 files changed

Lines changed: 6969 additions & 1067 deletions

File tree

Some content is hidden

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

CHANGELOG.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,63 @@
1+
## 0.51.2 (2026-05-20)
2+
3+
### 🩹 Fixes
4+
5+
- color picker icons (BLO-1189) ([#2762](https://github.com/TypeCellOS/BlockNote/pull/2762))
6+
7+
### ❤️ Thank You
8+
9+
- Matthew Lipski @matthewlipski
10+
11+
## 0.51.1 (2026-05-18)
12+
13+
### 🩹 Fixes
14+
15+
- backslash newlines when copying from a code block ([#2709](https://github.com/TypeCellOS/BlockNote/pull/2709))
16+
17+
### ❤️ Thank You
18+
19+
- Claude Opus 4.7 (1M context)
20+
- Nick Perez
21+
22+
## 0.51.0 (2026-05-14)
23+
24+
### 🚀 Features
25+
26+
- Trailing block extension rewrite ([#2733](https://github.com/TypeCellOS/BlockNote/pull/2733))
27+
- **markdown:** replace unified.js with custom markdown parser/serializer ([#2624](https://github.com/TypeCellOS/BlockNote/pull/2624))
28+
- **react:** configurable portal targets for floating UI ([#2729](https://github.com/TypeCellOS/BlockNote/pull/2729), [#2692](https://github.com/TypeCellOS/BlockNote/issues/2692))
29+
30+
### 🩹 Fixes
31+
32+
- Pasting plain text from VSCode (BLO-366) ([#2713](https://github.com/TypeCellOS/BlockNote/pull/2713))
33+
- Parse new lines in `text/plain` as line breaks (BLO-1170) ([#2712](https://github.com/TypeCellOS/BlockNote/pull/2712))
34+
- Code block PDF export (BLO-987) ([#2725](https://github.com/TypeCellOS/BlockNote/pull/2725))
35+
- Formatting toolbar opening when inserting file block with `trailingBlock: false` (BLO-860) ([#2704](https://github.com/TypeCellOS/BlockNote/pull/2704))
36+
- numbered list item decorations missed on initial render ([#2734](https://github.com/TypeCellOS/BlockNote/pull/2734))
37+
- flicker-free mobile formatting toolbar via CSS custom properties ([#2617](https://github.com/TypeCellOS/BlockNote/pull/2617), [#2616](https://github.com/TypeCellOS/BlockNote/issues/2616))
38+
- add `bn-thread-orphaned` CSS class to distinguish orphaned threads ([#2737](https://github.com/TypeCellOS/BlockNote/pull/2737), [#2735](https://github.com/TypeCellOS/BlockNote/issues/2735))
39+
- set width attribute on image and video elements in editor render ([#2740](https://github.com/TypeCellOS/BlockNote/pull/2740), [#2726](https://github.com/TypeCellOS/BlockNote/issues/2726))
40+
- **a11y:** use figure/figcaption for media block captions ([#2717](https://github.com/TypeCellOS/BlockNote/pull/2717))
41+
- **ai:** loosen serialization of blocks in columns ([#2716](https://github.com/TypeCellOS/BlockNote/pull/2716), [#2718](https://github.com/TypeCellOS/BlockNote/pull/2718))
42+
- **core:** trigger codeblock input rule on Enter and place cursor inside ([#2686](https://github.com/TypeCellOS/BlockNote/pull/2686))
43+
- **core:** preserve list item type when pasting into empty list items ([#2722](https://github.com/TypeCellOS/BlockNote/pull/2722), [#2330](https://github.com/TypeCellOS/BlockNote/issues/2330))
44+
- **core:** unmount editors in transformPasted tests to prevent unhandled error ([e62880b21](https://github.com/TypeCellOS/BlockNote/commit/e62880b21))
45+
- **drag-n-drop:** support PDF block drag & drop (BLO-893) ([#2714](https://github.com/TypeCellOS/BlockNote/pull/2714))
46+
- **i18:** improve french translation for empty toggle list ([#2721](https://github.com/TypeCellOS/BlockNote/pull/2721))
47+
- **markdown:** emit tight lists when serializing blocks to markdown ([#2715](https://github.com/TypeCellOS/BlockNote/pull/2715))
48+
- **markdown:** skip placeholder text for empty files ([#434](https://github.com/TypeCellOS/BlockNote/pull/434), [#2719](https://github.com/TypeCellOS/BlockNote/pull/2719))
49+
- **markdown:** stable round-trip for tables, captions, and audio ([#2720](https://github.com/TypeCellOS/BlockNote/pull/2720))
50+
- **tests:** stabilize webkit keyboard handler tests with programmatic cursor positioning ([#2746](https://github.com/TypeCellOS/BlockNote/pull/2746))
51+
52+
### ❤️ Thank You
53+
54+
- Cyril G
55+
- Manuel Raynaud @lunika
56+
- Matthew Lipski @matthewlipski
57+
- Movm
58+
- Nick Perez
59+
- Nick the Sick @nperez0111
60+
161
## 0.50.0 (2026-05-04)
262

363
### 🚀 Features

docs/content/docs/react/components/index.mdx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,23 @@ BlockNote includes a number of UI Components (like menus and toolbars) that can
1414
{/* - [Image Toolbar](/docs/react/components/image-toolbar) */}
1515

1616
<CardTable path="/react/components" />
17+
18+
## Configuring Portal Targets
19+
20+
By default, all floating UI elements (toolbars, menus, table handles, etc.) portal into the editor's `bn-container` so they stay scoped to the editor. If your layout needs them to escape — e.g. an `overflow: hidden` ancestor that would clip large dropdowns, or a host modal with its own stacking context — pass a `portalElements` prop to `BlockNoteView`:
21+
22+
```tsx
23+
<BlockNoteView
24+
editor={editor}
25+
portalElements={{
26+
// Global default for any element not listed below.
27+
default: document.body,
28+
// Per-element overrides. Values can be HTMLElement, a CSS selector, or null (= document.body).
29+
tableHandles: ".bn-container",
30+
}}
31+
/>
32+
```
33+
34+
Keys mirror the default UI flags (`formattingToolbar`, `linkToolbar`, `slashMenu`, `emojiPicker`, `sideMenu`, `filePanel`, `tableHandles`, `comments`). Manually-mounted Controllers also accept a `portalElement` prop that takes precedence over the map. See the [Portal Targets example](/examples/ui-components/portal-elements).
35+
36+
Note: changing `portalElements.default` after mount requires remounting the editor (`editor.mount()` consults it once); per-element keys update reactively.

docs/content/docs/reference/editor/manipulating-content.mdx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,18 +252,26 @@ editor.replaceBlocks(
252252
#### Reordering Blocks
253253

254254
```typescript
255-
moveBlocksUp(): void
256-
moveBlocksDown(): void
255+
moveBlocksUp(blockIdentifier?: BlockIdentifier): void
256+
moveBlocksDown(blockIdentifier?: BlockIdentifier): void
257257
```
258258

259-
Moves the currently selected blocks up or down in the document.
259+
Moves the currently selected blocks up or down in the document. If a
260+
`blockIdentifier` is provided, that block is moved instead of the selection,
261+
and the selection is left unchanged.
260262

261263
```typescript
262264
// Move selected blocks up
263265
editor.moveBlocksUp();
264266

265267
// Move selected blocks down
266268
editor.moveBlocksDown();
269+
270+
// Move a specific block up, without changing the selection
271+
editor.moveBlocksUp("block-123");
272+
273+
// Move a specific block down, without changing the selection
274+
editor.moveBlocksDown("block-123");
267275
```
268276

269277
### Nesting Blocks

examples/01-basic/17-no-trailing-block/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@
1616
"@blocknote/mantine": "latest",
1717
"@blocknote/react": "latest",
1818
"@blocknote/shadcn": "latest",
19-
"@mantine/core": "^8.3.11",
20-
"@mantine/hooks": "^8.3.11",
21-
"@mantine/utils": "^6.0.22",
19+
"@mantine/core": "^9.0.2",
20+
"@mantine/hooks": "^9.0.2",
2221
"react": "^19.2.3",
2322
"react-dom": "^19.2.3"
2423
},
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"playground": true,
3+
"docs": true,
4+
"author": "nperez0111",
5+
"tags": ["UI Components", "Advanced"]
6+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Configuring Portal Targets
2+
3+
By default, BlockNote's floating UI elements (formatting toolbar, slash menu, table handles, etc.) mount inside the editor's `bn-container`. The `portalElements` prop on `BlockNoteView` lets you change that — globally via `default`, or per element by key.
4+
5+
This example renders two editors side-by-side, both wrapped in a small `overflow: hidden` container. The left editor uses the default — the slash menu is clipped by the editor's bounds. The right editor passes `portalElements={{ default: document.body }}` so floating UI escapes the wrapper and renders fully.
6+
7+
```tsx
8+
<BlockNoteView
9+
editor={editor}
10+
portalElements={{ default: document.body }}
11+
/>
12+
```
13+
14+
**Relevant Docs:**
15+
16+
- [UI Components](/docs/react/components)
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>Configuring Portal Targets</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: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "@blocknote/example-ui-components-portal-elements",
3+
"description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
4+
"type": "module",
5+
"private": true,
6+
"version": "0.12.4",
7+
"scripts": {
8+
"start": "vite",
9+
"dev": "vite",
10+
"build:prod": "tsc && vite build",
11+
"preview": "vite preview"
12+
},
13+
"dependencies": {
14+
"@blocknote/ariakit": "latest",
15+
"@blocknote/core": "latest",
16+
"@blocknote/mantine": "latest",
17+
"@blocknote/react": "latest",
18+
"@blocknote/shadcn": "latest",
19+
"@mantine/core": "^9.0.2",
20+
"@mantine/hooks": "^9.0.2",
21+
"react": "^19.2.3",
22+
"react-dom": "^19.2.3"
23+
},
24+
"devDependencies": {
25+
"@types/react": "^19.2.3",
26+
"@types/react-dom": "^19.2.3",
27+
"@vitejs/plugin-react": "^6.0.1",
28+
"vite": "^8.0.8"
29+
}
30+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import "@blocknote/core/fonts/inter.css";
2+
import { BlockNoteView } from "@blocknote/mantine";
3+
import "@blocknote/mantine/style.css";
4+
import { useCreateBlockNote, type PortalElementsMap } from "@blocknote/react";
5+
6+
import "./styles.css";
7+
8+
const initialContent = [
9+
{
10+
type: "paragraph" as const,
11+
content: "Click in this editor and press / to open the slash menu.",
12+
},
13+
{
14+
type: "paragraph" as const,
15+
content:
16+
"Notice whether the menu fits inside the box or escapes it.",
17+
},
18+
{
19+
type: "paragraph" as const,
20+
},
21+
];
22+
23+
function PortalDemoEditor({
24+
label,
25+
description,
26+
portalElements,
27+
}: {
28+
label: string;
29+
description: string;
30+
portalElements?: PortalElementsMap;
31+
}) {
32+
const editor = useCreateBlockNote({ initialContent });
33+
return (
34+
<div className="view-wrapper">
35+
<div className="view-label">{label}</div>
36+
<div className="view-description">{description}</div>
37+
<div className="view">
38+
<BlockNoteView editor={editor} portalElements={portalElements} />
39+
</div>
40+
</div>
41+
);
42+
}
43+
44+
export default function App() {
45+
return (
46+
<div className="views">
47+
<PortalDemoEditor
48+
label="Default — clipped"
49+
description="No portalElements prop. Floating UI mounts inside .bn-container — the slash menu is clipped by the editor's bounds."
50+
/>
51+
<PortalDemoEditor
52+
label="portalElements={{ default: document.body }} — escapes"
53+
description="Every floating UI element escapes the editor container and renders directly under <body>."
54+
portalElements={{ default: document.body }}
55+
/>
56+
</div>
57+
);
58+
}

0 commit comments

Comments
 (0)