diff --git a/.changeset/task-checkbox-disabled-after-editable.md b/.changeset/task-checkbox-disabled-after-editable.md new file mode 100644 index 00000000..c55c24e1 --- /dev/null +++ b/.changeset/task-checkbox-disabled-after-editable.md @@ -0,0 +1,5 @@ +--- +"@inkeep/open-knowledge-core": patch +--- + +Task-list checkboxes now stay clickable when an editor transitions from read-only to editable. The list-item NodeView set the checkbox's `disabled` state once at creation from `editor.isEditable`, but a `setEditable()` flip updates the view's editable flag without a document change, so ProseMirror never re-renders the NodeView and the stale `disabled` was never cleared. A checkbox created while the editor was read-only (for example, content loaded before the editor goes live) stayed permanently uncheckable. The NodeView now keeps `disabled` in sync with editability via the editor's `update` event (which `setEditable()` emits) and on every NodeView update. diff --git a/packages/core/src/extensions/list.ts b/packages/core/src/extensions/list.ts index 6d3b483a..ffc5f9ed 100644 --- a/packages/core/src/extensions/list.ts +++ b/packages/core/src/extensions/list.ts @@ -329,6 +329,10 @@ export const ListItemNode = Node.create({ let checkbox: HTMLInputElement | null = null; const contentDiv = document.createElement('div'); + const syncDisabled = () => { + if (checkbox) checkbox.disabled = !editor.isEditable; + }; + if (node.attrs.checked !== null) { checkboxLabel = document.createElement('label'); checkboxLabel.contentEditable = 'false'; @@ -336,10 +340,8 @@ export const ListItemNode = Node.create({ checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = !!node.attrs.checked; - - if (!editor.isEditable) { - checkbox.disabled = true; - } + syncDisabled(); + editor.on('update', syncDisabled); checkbox.addEventListener('change', () => { const pos = getPos(); @@ -368,11 +370,15 @@ export const ListItemNode = Node.create({ } if (checkbox && updatedNode.attrs.checked !== null) { checkbox.checked = !!updatedNode.attrs.checked; + checkbox.disabled = !editor.isEditable; li.setAttribute('data-checked', String(!!updatedNode.attrs.checked)); } node = updatedNode; return true; }, + destroy() { + editor.off('update', syncDisabled); + }, }; }; },