diff --git a/packages/core/src/blocks/ListItem/CheckListItem/block.test.ts b/packages/core/src/blocks/ListItem/CheckListItem/block.test.ts
new file mode 100644
index 0000000000..c635aeda3a
--- /dev/null
+++ b/packages/core/src/blocks/ListItem/CheckListItem/block.test.ts
@@ -0,0 +1,61 @@
+import { expect, it } from "vitest";
+import { BlockNoteEditor } from "../../../editor/BlockNoteEditor.js";
+import type { Block } from "../../defaultBlocks.js";
+
+/**
+ * Tests for CheckListItem block behaviour, especially that the checkbox
+ * respects the editor's editable state (disabled when not editable,
+ * and change handler no-ops when not editable).
+ *
+ * @vitest-environment jsdom
+ */
+function getCheckboxFromView(view: {
+ dom: HTMLElement | DocumentFragment;
+}): HTMLInputElement {
+ const el = view.dom.querySelector('input[type="checkbox"]');
+ if (!(el instanceof HTMLInputElement)) {
+ throw new Error("Checkbox input not found in rendered output");
+ }
+ return el;
+}
+
+it("renders checkbox as enabled when editor is editable", () => {
+ const editor = BlockNoteEditor.create();
+ const block: Block = {
+ id: "1",
+ type: "checkListItem",
+ props: {
+ backgroundColor: "default",
+ textAlignment: "left",
+ textColor: "default",
+ checked: false,
+ },
+ content: [],
+ children: [],
+ };
+ const spec = editor.schema.blockSpecs.checkListItem;
+ const view = spec.implementation.render(block, editor);
+ const checkbox = getCheckboxFromView(view);
+ expect(checkbox.disabled).toBe(false);
+});
+
+it("renders checkbox as disabled when editor is not editable", () => {
+ const editor = BlockNoteEditor.create();
+ editor.isEditable = false;
+ const block: Block = {
+ id: "1",
+ type: "checkListItem",
+ props: {
+ backgroundColor: "default",
+ textAlignment: "left",
+ textColor: "default",
+ checked: false,
+ },
+ content: [],
+ children: [],
+ };
+ const spec = editor.schema.blockSpecs.checkListItem;
+ const view = spec.implementation.render(block, editor);
+ const checkbox = getCheckboxFromView(view);
+ expect(checkbox.disabled).toBe(true);
+});
diff --git a/packages/core/src/blocks/ListItem/CheckListItem/block.ts b/packages/core/src/blocks/ListItem/CheckListItem/block.ts
index b32ee408ea..6d514270bf 100644
--- a/packages/core/src/blocks/ListItem/CheckListItem/block.ts
+++ b/packages/core/src/blocks/ListItem/CheckListItem/block.ts
@@ -82,7 +82,11 @@ export const createCheckListItemBlockSpec = createBlockSpec(
if (block.props.checked) {
checkbox.setAttribute("checked", "");
}
+ checkbox.disabled = !editor.isEditable;
checkbox.addEventListener("change", () => {
+ if (!editor.isEditable) {
+ return;
+ }
editor.updateBlock(block, { props: { checked: !block.props.checked } });
});
// We use a
tag, because for
tags we'd need a element to put
diff --git a/packages/xl-odt-exporter/package.json b/packages/xl-odt-exporter/package.json
index e0c6a4ad11..6ceb465a4d 100644
--- a/packages/xl-odt-exporter/package.json
+++ b/packages/xl-odt-exporter/package.json
@@ -67,6 +67,7 @@
"@testing-library/react": "^16.3.0",
"@types/react": "^19.2.3",
"@types/react-dom": "^19.2.3",
+ "eslint": "^8.57.1",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"rollup-plugin-webpack-stats": "^0.2.6",
diff --git a/playground/vite.config.ts b/playground/vite.config.ts
index 7ec61e9835..ed5983af53 100644
--- a/playground/vite.config.ts
+++ b/playground/vite.config.ts
@@ -44,10 +44,10 @@ export default defineConfig((conf) => ({
__dirname,
"../packages/xl-multi-column/src",
),
- "@liveblocks/react-blocknote": resolve(
- __dirname,
- "../../liveblocks/packages/liveblocks-react-blocknote/src/",
- ),
+ // "@liveblocks/react-blocknote": resolve(
+ // __dirname,
+ // "../../liveblocks/packages/liveblocks-react-blocknote/src/",
+ // ),
"@blocknote/xl-email-exporter": resolve(
__dirname,
"../packages/xl-email-exporter/src",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1d0c20a8a4..461388700a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15,7 +15,7 @@ importers:
devDependencies:
'@nx/js':
specifier: ^21.6.5
- version: 21.6.5(@babel/traverse@7.28.4)(nx@21.6.5)
+ version: 21.6.5(@babel/traverse@7.29.0)(nx@21.6.5)
'@typescript-eslint/eslint-plugin':
specifier: ^5.62.0
version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)
@@ -5509,6 +5509,9 @@ importers:
'@types/react-dom':
specifier: ^19.2.3
version: 19.2.3(@types/react@19.2.8)
+ eslint:
+ specifier: ^8.57.1
+ version: 8.57.1
react:
specifier: ^19.2.3
version: 19.2.3
@@ -19630,7 +19633,7 @@ snapshots:
tslib: 2.8.1
yargs-parser: 21.1.1
- '@nx/js@21.6.5(@babel/traverse@7.28.4)(nx@21.6.5)':
+ '@nx/js@21.6.5(@babel/traverse@7.29.0)(nx@21.6.5)':
dependencies:
'@babel/core': 7.28.4
'@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.4)
@@ -19644,7 +19647,7 @@ snapshots:
'@zkochan/js-yaml': 0.0.7
babel-plugin-const-enum: 1.2.0(@babel/core@7.28.4)
babel-plugin-macros: 3.1.0
- babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.28.4)(@babel/traverse@7.28.4)
+ babel-plugin-transform-typescript-metadata: 0.3.2(@babel/core@7.28.4)(@babel/traverse@7.29.0)
chalk: 4.1.2
columnify: 1.6.0
detect-port: 1.6.1
@@ -22934,9 +22937,9 @@ snapshots:
flatted: 3.3.3
pathe: 1.1.2
sirv: 3.0.2
- tinyglobby: 0.2.15
+ tinyglobby: 0.2.12
tinyrainbow: 1.2.0
- vitest: 2.1.9(@types/node@25.0.7)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(msw@2.11.5(@types/node@25.0.7)(typescript@5.9.3))(terser@5.46.0)
+ vitest: 2.1.9(@types/node@25.2.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.2)(msw@2.11.5(@types/node@25.2.1)(typescript@5.9.3))(terser@5.46.0)
optional: true
'@vitest/utils@2.1.9':
@@ -23343,12 +23346,12 @@ snapshots:
babel-plugin-transform-react-remove-prop-types@0.4.24: {}
- babel-plugin-transform-typescript-metadata@0.3.2(@babel/core@7.28.4)(@babel/traverse@7.28.4):
+ babel-plugin-transform-typescript-metadata@0.3.2(@babel/core@7.28.4)(@babel/traverse@7.29.0):
dependencies:
'@babel/core': 7.28.4
'@babel/helper-plugin-utils': 7.27.1
optionalDependencies:
- '@babel/traverse': 7.28.4
+ '@babel/traverse': 7.29.0
babel-preset-react-app@10.1.0:
dependencies: