Skip to content

Commit a3fa416

Browse files
authored
fix: disable checkbox when editor is not editable #2406 (#2448)
1 parent d955d93 commit a3fa416

File tree

5 files changed

+80
-11
lines changed

5 files changed

+80
-11
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { expect, it } from "vitest";
2+
import { BlockNoteEditor } from "../../../editor/BlockNoteEditor.js";
3+
import type { Block } from "../../defaultBlocks.js";
4+
5+
/**
6+
* Tests for CheckListItem block behaviour, especially that the checkbox
7+
* respects the editor's editable state (disabled when not editable,
8+
* and change handler no-ops when not editable).
9+
*
10+
* @vitest-environment jsdom
11+
*/
12+
function getCheckboxFromView(view: {
13+
dom: HTMLElement | DocumentFragment;
14+
}): HTMLInputElement {
15+
const el = view.dom.querySelector('input[type="checkbox"]');
16+
if (!(el instanceof HTMLInputElement)) {
17+
throw new Error("Checkbox input not found in rendered output");
18+
}
19+
return el;
20+
}
21+
22+
it("renders checkbox as enabled when editor is editable", () => {
23+
const editor = BlockNoteEditor.create();
24+
const block: Block = {
25+
id: "1",
26+
type: "checkListItem",
27+
props: {
28+
backgroundColor: "default",
29+
textAlignment: "left",
30+
textColor: "default",
31+
checked: false,
32+
},
33+
content: [],
34+
children: [],
35+
};
36+
const spec = editor.schema.blockSpecs.checkListItem;
37+
const view = spec.implementation.render(block, editor);
38+
const checkbox = getCheckboxFromView(view);
39+
expect(checkbox.disabled).toBe(false);
40+
});
41+
42+
it("renders checkbox as disabled when editor is not editable", () => {
43+
const editor = BlockNoteEditor.create();
44+
editor.isEditable = false;
45+
const block: Block = {
46+
id: "1",
47+
type: "checkListItem",
48+
props: {
49+
backgroundColor: "default",
50+
textAlignment: "left",
51+
textColor: "default",
52+
checked: false,
53+
},
54+
content: [],
55+
children: [],
56+
};
57+
const spec = editor.schema.blockSpecs.checkListItem;
58+
const view = spec.implementation.render(block, editor);
59+
const checkbox = getCheckboxFromView(view);
60+
expect(checkbox.disabled).toBe(true);
61+
});

packages/core/src/blocks/ListItem/CheckListItem/block.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ export const createCheckListItemBlockSpec = createBlockSpec(
8282
if (block.props.checked) {
8383
checkbox.setAttribute("checked", "");
8484
}
85+
checkbox.disabled = !editor.isEditable;
8586
checkbox.addEventListener("change", () => {
87+
if (!editor.isEditable) {
88+
return;
89+
}
8690
editor.updateBlock(block, { props: { checked: !block.props.checked } });
8791
});
8892
// We use a <p> tag, because for <li> tags we'd need a <ul> element to put

packages/xl-odt-exporter/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"@testing-library/react": "^16.3.0",
6868
"@types/react": "^19.2.3",
6969
"@types/react-dom": "^19.2.3",
70+
"eslint": "^8.57.1",
7071
"react": "^19.2.3",
7172
"react-dom": "^19.2.3",
7273
"rollup-plugin-webpack-stats": "^0.2.6",

playground/vite.config.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ export default defineConfig((conf) => ({
4444
__dirname,
4545
"../packages/xl-multi-column/src",
4646
),
47-
"@liveblocks/react-blocknote": resolve(
48-
__dirname,
49-
"../../liveblocks/packages/liveblocks-react-blocknote/src/",
50-
),
47+
// "@liveblocks/react-blocknote": resolve(
48+
// __dirname,
49+
// "../../liveblocks/packages/liveblocks-react-blocknote/src/",
50+
// ),
5151
"@blocknote/xl-email-exporter": resolve(
5252
__dirname,
5353
"../packages/xl-email-exporter/src",

pnpm-lock.yaml

Lines changed: 10 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)