Skip to content

Commit 0e94795

Browse files
YousefEDclaude
andauthored
fix(core): slash menu fails in custom blocks after space BLO-1036 (#2553)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 389cb3c commit 0e94795

File tree

6 files changed

+56
-0
lines changed

6 files changed

+56
-0
lines changed

packages/core/src/editor/Block.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ BASIC STYLES
4242

4343
.bn-inline-content {
4444
width: 100%;
45+
/* Ensure pre-wrap even when a parent node view wrapper (e.g. tiptap's
46+
NodeViewWrapper) resets white-space to "normal". Without this, browsers
47+
normalize trailing spaces to NBSP on input, which causes ProseMirror to
48+
compute a replacement instead of a pure insertion and breaks the
49+
suggestion-menu trigger detection (issue #2531). */
50+
white-space: pre-wrap;
4551
}
4652

4753
/*
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { expect } from "@playwright/test";
2+
import { test } from "../../setup/setupScript.js";
3+
import { ALERT_BLOCK_URL, SLASH_MENU_SELECTOR } from "../../utils/const.js";
4+
5+
// Regression test for https://github.com/TypeCellOS/BlockNote/issues/2531
6+
// The slash menu should open when "/" is typed after a space inside a custom
7+
// block (isolating: true, separate contentDOM). Previously the menu failed to
8+
// open in this scenario.
9+
test.describe("Slash menu in custom (alert) block – issue #2531", () => {
10+
test.beforeEach(async ({ page }) => {
11+
await page.goto(ALERT_BLOCK_URL);
12+
await page.waitForSelector(".bn-editor");
13+
});
14+
15+
test("opens slash menu when / is typed at end of alert block content (no preceding space)", async ({
16+
page,
17+
}) => {
18+
// Click into the editable content area of the alert block
19+
const alertContent = page
20+
.locator('[data-content-type="alert"]')
21+
.first()
22+
.locator(".bn-inline-content");
23+
await alertContent.click();
24+
await page.keyboard.press("End");
25+
26+
await page.keyboard.type("/");
27+
await expect(page.locator(SLASH_MENU_SELECTOR)).toBeVisible();
28+
});
29+
30+
test("opens slash menu when / is typed after a space inside alert block (the regression)", async ({
31+
page,
32+
}) => {
33+
// Click into the editable content area of the alert block
34+
const alertContent = page
35+
.locator('[data-content-type="alert"]')
36+
.first()
37+
.locator(".bn-inline-content");
38+
await alertContent.click();
39+
await page.keyboard.press("End");
40+
41+
// Type a space first — this is the scenario that broke the menu
42+
await page.keyboard.type(" ");
43+
await page.keyboard.type("/");
44+
await expect(page.locator(SLASH_MENU_SELECTOR)).toBeVisible();
45+
});
46+
});
0 Bytes
Loading
934 Bytes
Loading
56 Bytes
Loading

tests/src/utils/const.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export const CUSTOM_BLOCKS_REACT_URL = !process.env.RUN_IN_DOCKER
3939
? `http://localhost:${PORT}/custom-schema/react-custom-blocks?hideMenu`
4040
: `http://host.docker.internal:${PORT}/custom-schema/react-custom-blocks?hideMenu`;
4141

42+
export const ALERT_BLOCK_URL = !process.env.RUN_IN_DOCKER
43+
? `http://localhost:${PORT}/custom-schema/alert-block?hideMenu`
44+
: `http://host.docker.internal:${PORT}/custom-schema/alert-block?hideMenu`;
45+
4246
export const PASTE_ZONE_SELECTOR = "#pasteZone";
4347

4448
export const EDITOR_SELECTOR = `.bn-editor`;

0 commit comments

Comments
 (0)