Skip to content

Commit 5dc2544

Browse files
committed
Fixed React custom block interactivity not working & added tests
1 parent 8ef6188 commit 5dc2544

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

packages/react/src/schema/ReactBlockSpec.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import {
77
BlockSpec,
88
camelToDataKebab,
99
CustomBlockImplementation,
10+
getBlockFromPos,
1011
inheritedProps,
1112
mergeCSSClasses,
1213
Props,
1314
PropSchema,
1415
} from "@blocknote/core";
1516
import {
17+
NodeViewProps,
1618
NodeViewWrapper,
1719
ReactNodeViewRenderer,
1820
useReactNodeView,
@@ -192,7 +194,19 @@ export function createReactBlockSpec<
192194
render(block, editor) {
193195
if (this.renderType === "nodeView") {
194196
return ReactNodeViewRenderer(
195-
() => {
197+
(props: NodeViewProps) => {
198+
// Vanilla JS node views are recreated on each update. However,
199+
// using `ReactNodeViewRenderer` makes it so the node view is
200+
// only created once, so the block we get in the node view will
201+
// be outdated. Therefore, we have to get the block in the
202+
// `ReactNodeViewRenderer` instead.
203+
const block = getBlockFromPos(
204+
props.getPos,
205+
editor,
206+
props.editor,
207+
blockConfig.type,
208+
);
209+
196210
const ref = useReactNodeView().nodeViewContentRef;
197211

198212
if (!ref) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { expect } from "@playwright/test";
2+
import { test } from "../../setup/setupScript.js";
3+
import {
4+
CUSTOM_BLOCKS_REACT_URL,
5+
CUSTOM_BLOCKS_VANILLA_URL,
6+
} from "../../utils/const.js";
7+
import { compareDocToSnapshot } from "../../utils/editor.js";
8+
9+
test.describe("Check custom block functionality", () => {
10+
test("Should be able to interactively update vanilla custom blocks", async ({
11+
page,
12+
}) => {
13+
await page.goto(CUSTOM_BLOCKS_VANILLA_URL);
14+
15+
await page.waitForTimeout(500);
16+
await page.locator("select").click();
17+
await page.keyboard.press("ArrowUp");
18+
await page.keyboard.press("Enter");
19+
await page.waitForTimeout(500);
20+
21+
await compareDocToSnapshot(page, "vanillaInteractivity");
22+
expect(await page.screenshot()).toMatchSnapshot(
23+
"vanilla-interactivity.png",
24+
);
25+
});
26+
27+
test("Should be able to interactively update React custom blocks", async ({
28+
page,
29+
}) => {
30+
await page.goto(CUSTOM_BLOCKS_REACT_URL);
31+
32+
await page.waitForTimeout(500);
33+
await page.locator("select").click();
34+
await page.keyboard.press("ArrowUp");
35+
await page.keyboard.press("Enter");
36+
await page.waitForTimeout(500);
37+
38+
await compareDocToSnapshot(page, "reactInteractivity");
39+
expect(await page.screenshot()).toMatchSnapshot("react-interactivity.png");
40+
});
41+
});

tests/src/utils/const.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ export const STATIC_URL = !process.env.RUN_IN_DOCKER
1515
? `http://localhost:${PORT}/backend/rendering-static-documents?hideMenu`
1616
: `http://host.docker.internal:${PORT}/backend/rendering-static-documents?hideMenu`;
1717

18+
export const CUSTOM_BLOCKS_VANILLA_URL = !process.env.RUN_IN_DOCKER
19+
? `http://localhost:${PORT}/vanilla-js/react-vanilla-custom-blocks`
20+
: `http://host.docker.internal:${PORT}/vanilla-js/react-vanilla-custom-blocks`;
21+
22+
export const CUSTOM_BLOCKS_REACT_URL = !process.env.RUN_IN_DOCKER
23+
? `http://localhost:${PORT}/custom-schema/react-custom-blocks`
24+
: `http://host.docker.internal:${PORT}/custom-schema/react-custom-blocks`;
25+
1826
export const PASTE_ZONE_SELECTOR = "#pasteZone";
1927

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

0 commit comments

Comments
 (0)