Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/core/src/editor/Block.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ BASIC STYLES

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

/*
Expand Down
46 changes: 46 additions & 0 deletions tests/src/end-to-end/slashmenu/slashmenu-customblock.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { expect } from "@playwright/test";
import { test } from "../../setup/setupScript.js";
import { ALERT_BLOCK_URL, SLASH_MENU_SELECTOR } from "../../utils/const.js";

// Regression test for https://github.com/TypeCellOS/BlockNote/issues/2531
// The slash menu should open when "/" is typed after a space inside a custom
// block (isolating: true, separate contentDOM). Previously the menu failed to
// open in this scenario.
test.describe("Slash menu in custom (alert) block – issue #2531", () => {
test.beforeEach(async ({ page }) => {
await page.goto(ALERT_BLOCK_URL);
await page.waitForSelector(".bn-editor");
});

test("opens slash menu when / is typed at end of alert block content (no preceding space)", async ({
page,
}) => {
// Click into the editable content area of the alert block
const alertContent = page
.locator('[data-content-type="alert"]')
.first()
.locator(".bn-inline-content");
await alertContent.click();
await page.keyboard.press("End");

await page.keyboard.type("/");
await expect(page.locator(SLASH_MENU_SELECTOR)).toBeVisible();
});

test("opens slash menu when / is typed after a space inside alert block (the regression)", async ({
page,
}) => {
// Click into the editable content area of the alert block
const alertContent = page
.locator('[data-content-type="alert"]')
.first()
.locator(".bn-inline-content");
await alertContent.click();
await page.keyboard.press("End");

// Type a space first — this is the scenario that broke the menu
await page.keyboard.type(" ");
await page.keyboard.type("/");
await expect(page.locator(SLASH_MENU_SELECTOR)).toBeVisible();
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions tests/src/utils/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export const CUSTOM_BLOCKS_REACT_URL = !process.env.RUN_IN_DOCKER
? `http://localhost:${PORT}/custom-schema/react-custom-blocks?hideMenu`
: `http://host.docker.internal:${PORT}/custom-schema/react-custom-blocks?hideMenu`;

export const ALERT_BLOCK_URL = !process.env.RUN_IN_DOCKER
? `http://localhost:${PORT}/custom-schema/alert-block?hideMenu`
: `http://host.docker.internal:${PORT}/custom-schema/alert-block?hideMenu`;

export const PASTE_ZONE_SELECTOR = "#pasteZone";

export const EDITOR_SELECTOR = `.bn-editor`;
Expand Down
Loading