@tiptap/extension-task-item 2.24.0 → 2.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -19,6 +19,7 @@ const TaskItem = core.Node.create({
19
19
  nested: false,
20
20
  HTMLAttributes: {},
21
21
  taskListTypeName: 'taskList',
22
+ a11y: undefined,
22
23
  };
23
24
  },
24
25
  content() {
@@ -88,6 +89,12 @@ const TaskItem = core.Node.create({
88
89
  const checkboxStyler = document.createElement('span');
89
90
  const checkbox = document.createElement('input');
90
91
  const content = document.createElement('div');
92
+ const updateA11Y = () => {
93
+ var _a, _b;
94
+ checkbox.ariaLabel = ((_b = (_a = this.options.a11y) === null || _a === void 0 ? void 0 : _a.checkboxLabel) === null || _b === void 0 ? void 0 : _b.call(_a, node, checkbox.checked))
95
+ || `Task item checkbox for ${node.textContent || 'empty task item'}`;
96
+ };
97
+ updateA11Y();
91
98
  checkboxWrapper.contentEditable = 'false';
92
99
  checkbox.type = 'checkbox';
93
100
  checkbox.addEventListener('mousedown', event => event.preventDefault());
@@ -143,6 +150,7 @@ const TaskItem = core.Node.create({
143
150
  }
144
151
  listItem.dataset.checked = updatedNode.attrs.checked;
145
152
  checkbox.checked = updatedNode.attrs.checked;
153
+ updateA11Y();
146
154
  return true;
147
155
  },
148
156
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/task-item.ts"],"sourcesContent":["import {\n KeyboardShortcutCommand, mergeAttributes, Node, wrappingInputRule,\n} from '@tiptap/core'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nexport interface TaskItemOptions {\n /**\n * A callback function that is called when the checkbox is clicked while the editor is in readonly mode.\n * @param node The prosemirror node of the task item\n * @param checked The new checked state\n * @returns boolean\n */\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n\n /**\n * Controls whether the task items can be nested or not.\n * @default false\n * @example true\n */\n nested: boolean\n\n /**\n * HTML attributes to add to the task item element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * The node type for taskList nodes\n * @default 'taskList'\n * @example 'myCustomTaskList'\n */\n taskListTypeName: string\n}\n\n/**\n * Matches a task item to a - [ ] on input.\n */\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\n/**\n * This extension allows you to create task items.\n * @see https://www.tiptap.dev/api/nodes/task-item\n */\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\n taskListTypeName: 'taskList',\n }\n },\n\n content() {\n return this.options.nested ? 'paragraph block*' : 'paragraph+'\n },\n\n defining: true,\n\n addAttributes() {\n return {\n checked: {\n default: false,\n keepOnSplit: false,\n parseHTML: element => {\n const dataChecked = element.getAttribute('data-checked')\n\n return dataChecked === '' || dataChecked === 'true'\n },\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `li[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'li',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n }),\n [\n 'label',\n [\n 'input',\n {\n type: 'checkbox',\n checked: node.attrs.checked ? 'checked' : null,\n },\n ],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n const shortcuts: {\n [key: string]: KeyboardShortcutCommand\n } = {\n Enter: () => this.editor.commands.splitListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem(this.name),\n }\n },\n\n addNodeView() {\n return ({\n node, HTMLAttributes, getPos, editor,\n }) => {\n const listItem = document.createElement('li')\n const checkboxWrapper = document.createElement('label')\n const checkboxStyler = document.createElement('span')\n const checkbox = document.createElement('input')\n const content = document.createElement('div')\n\n checkboxWrapper.contentEditable = 'false'\n checkbox.type = 'checkbox'\n checkbox.addEventListener('mousedown', event => event.preventDefault())\n checkbox.addEventListener('change', event => {\n // if the editor isn’t editable and we don't have a handler for\n // readonly checks we have to undo the latest change\n if (!editor.isEditable && !this.options.onReadOnlyChecked) {\n checkbox.checked = !checkbox.checked\n\n return\n }\n\n const { checked } = event.target as any\n\n if (editor.isEditable && typeof getPos === 'function') {\n editor\n .chain()\n .focus(undefined, { scrollIntoView: false })\n .command(({ tr }) => {\n const position = getPos()\n\n if (typeof position !== 'number') {\n return false\n }\n const currentNode = tr.doc.nodeAt(position)\n\n tr.setNodeMarkup(position, undefined, {\n ...currentNode?.attrs,\n checked,\n })\n\n return true\n })\n .run()\n }\n if (!editor.isEditable && this.options.onReadOnlyChecked) {\n // Reset state if onReadOnlyChecked returns false\n if (!this.options.onReadOnlyChecked(node, checked)) {\n checkbox.checked = !checkbox.checked\n }\n }\n })\n\n Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n listItem.dataset.checked = node.attrs.checked\n checkbox.checked = node.attrs.checked\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object.entries(HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n return {\n dom: listItem,\n contentDOM: content,\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n listItem.dataset.checked = updatedNode.attrs.checked\n checkbox.checked = updatedNode.attrs.checked\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n getAttributes: match => ({\n checked: match[match.length - 1] === 'x',\n }),\n }),\n ]\n },\n})\n"],"names":["Node","mergeAttributes","wrappingInputRule"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/task-item.ts"],"sourcesContent":["import {\n KeyboardShortcutCommand, mergeAttributes, Node, wrappingInputRule,\n} from '@tiptap/core'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nexport interface TaskItemOptions {\n /**\n * A callback function that is called when the checkbox is clicked while the editor is in readonly mode.\n * @param node The prosemirror node of the task item\n * @param checked The new checked state\n * @returns boolean\n */\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n\n /**\n * Controls whether the task items can be nested or not.\n * @default false\n * @example true\n */\n nested: boolean\n\n /**\n * HTML attributes to add to the task item element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * The node type for taskList nodes\n * @default 'taskList'\n * @example 'myCustomTaskList'\n */\n taskListTypeName: string\n\n /**\n * Accessibility options for the task item.\n * @default {}\n * @example\n * ```js\n * {\n * checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`\n * }\n */\n a11y?: {\n checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string\n }\n}\n\n/**\n * Matches a task item to a - [ ] on input.\n */\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\n/**\n * This extension allows you to create task items.\n * @see https://www.tiptap.dev/api/nodes/task-item\n */\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\n taskListTypeName: 'taskList',\n a11y: undefined,\n }\n },\n\n content() {\n return this.options.nested ? 'paragraph block*' : 'paragraph+'\n },\n\n defining: true,\n\n addAttributes() {\n return {\n checked: {\n default: false,\n keepOnSplit: false,\n parseHTML: element => {\n const dataChecked = element.getAttribute('data-checked')\n\n return dataChecked === '' || dataChecked === 'true'\n },\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `li[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'li',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n }),\n [\n 'label',\n [\n 'input',\n {\n type: 'checkbox',\n checked: node.attrs.checked ? 'checked' : null,\n },\n ],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n const shortcuts: {\n [key: string]: KeyboardShortcutCommand\n } = {\n Enter: () => this.editor.commands.splitListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem(this.name),\n }\n },\n\n addNodeView() {\n return ({\n node, HTMLAttributes, getPos, editor,\n }) => {\n const listItem = document.createElement('li')\n const checkboxWrapper = document.createElement('label')\n const checkboxStyler = document.createElement('span')\n const checkbox = document.createElement('input')\n const content = document.createElement('div')\n\n const updateA11Y = () => {\n checkbox.ariaLabel = this.options.a11y?.checkboxLabel?.(node, checkbox.checked)\n || `Task item checkbox for ${node.textContent || 'empty task item'}`\n }\n\n updateA11Y()\n\n checkboxWrapper.contentEditable = 'false'\n checkbox.type = 'checkbox'\n checkbox.addEventListener('mousedown', event => event.preventDefault())\n checkbox.addEventListener('change', event => {\n // if the editor isn’t editable and we don't have a handler for\n // readonly checks we have to undo the latest change\n if (!editor.isEditable && !this.options.onReadOnlyChecked) {\n checkbox.checked = !checkbox.checked\n\n return\n }\n\n const { checked } = event.target as any\n\n if (editor.isEditable && typeof getPos === 'function') {\n editor\n .chain()\n .focus(undefined, { scrollIntoView: false })\n .command(({ tr }) => {\n const position = getPos()\n\n if (typeof position !== 'number') {\n return false\n }\n const currentNode = tr.doc.nodeAt(position)\n\n tr.setNodeMarkup(position, undefined, {\n ...currentNode?.attrs,\n checked,\n })\n\n return true\n })\n .run()\n }\n if (!editor.isEditable && this.options.onReadOnlyChecked) {\n // Reset state if onReadOnlyChecked returns false\n if (!this.options.onReadOnlyChecked(node, checked)) {\n checkbox.checked = !checkbox.checked\n }\n }\n })\n\n Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n listItem.dataset.checked = node.attrs.checked\n checkbox.checked = node.attrs.checked\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object.entries(HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n return {\n dom: listItem,\n contentDOM: content,\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n listItem.dataset.checked = updatedNode.attrs.checked\n checkbox.checked = updatedNode.attrs.checked\n updateA11Y()\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n getAttributes: match => ({\n checked: match[match.length - 1] === 'x',\n }),\n }),\n ]\n },\n})\n"],"names":["Node","mergeAttributes","wrappingInputRule"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ const TaskItem = Node.create({
15
15
  nested: false,
16
16
  HTMLAttributes: {},
17
17
  taskListTypeName: 'taskList',
18
+ a11y: undefined,
18
19
  };
19
20
  },
20
21
  content() {
@@ -84,6 +85,12 @@ const TaskItem = Node.create({
84
85
  const checkboxStyler = document.createElement('span');
85
86
  const checkbox = document.createElement('input');
86
87
  const content = document.createElement('div');
88
+ const updateA11Y = () => {
89
+ var _a, _b;
90
+ checkbox.ariaLabel = ((_b = (_a = this.options.a11y) === null || _a === void 0 ? void 0 : _a.checkboxLabel) === null || _b === void 0 ? void 0 : _b.call(_a, node, checkbox.checked))
91
+ || `Task item checkbox for ${node.textContent || 'empty task item'}`;
92
+ };
93
+ updateA11Y();
87
94
  checkboxWrapper.contentEditable = 'false';
88
95
  checkbox.type = 'checkbox';
89
96
  checkbox.addEventListener('mousedown', event => event.preventDefault());
@@ -139,6 +146,7 @@ const TaskItem = Node.create({
139
146
  }
140
147
  listItem.dataset.checked = updatedNode.attrs.checked;
141
148
  checkbox.checked = updatedNode.attrs.checked;
149
+ updateA11Y();
142
150
  return true;
143
151
  },
144
152
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/task-item.ts"],"sourcesContent":["import {\n KeyboardShortcutCommand, mergeAttributes, Node, wrappingInputRule,\n} from '@tiptap/core'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nexport interface TaskItemOptions {\n /**\n * A callback function that is called when the checkbox is clicked while the editor is in readonly mode.\n * @param node The prosemirror node of the task item\n * @param checked The new checked state\n * @returns boolean\n */\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n\n /**\n * Controls whether the task items can be nested or not.\n * @default false\n * @example true\n */\n nested: boolean\n\n /**\n * HTML attributes to add to the task item element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * The node type for taskList nodes\n * @default 'taskList'\n * @example 'myCustomTaskList'\n */\n taskListTypeName: string\n}\n\n/**\n * Matches a task item to a - [ ] on input.\n */\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\n/**\n * This extension allows you to create task items.\n * @see https://www.tiptap.dev/api/nodes/task-item\n */\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\n taskListTypeName: 'taskList',\n }\n },\n\n content() {\n return this.options.nested ? 'paragraph block*' : 'paragraph+'\n },\n\n defining: true,\n\n addAttributes() {\n return {\n checked: {\n default: false,\n keepOnSplit: false,\n parseHTML: element => {\n const dataChecked = element.getAttribute('data-checked')\n\n return dataChecked === '' || dataChecked === 'true'\n },\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `li[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'li',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n }),\n [\n 'label',\n [\n 'input',\n {\n type: 'checkbox',\n checked: node.attrs.checked ? 'checked' : null,\n },\n ],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n const shortcuts: {\n [key: string]: KeyboardShortcutCommand\n } = {\n Enter: () => this.editor.commands.splitListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem(this.name),\n }\n },\n\n addNodeView() {\n return ({\n node, HTMLAttributes, getPos, editor,\n }) => {\n const listItem = document.createElement('li')\n const checkboxWrapper = document.createElement('label')\n const checkboxStyler = document.createElement('span')\n const checkbox = document.createElement('input')\n const content = document.createElement('div')\n\n checkboxWrapper.contentEditable = 'false'\n checkbox.type = 'checkbox'\n checkbox.addEventListener('mousedown', event => event.preventDefault())\n checkbox.addEventListener('change', event => {\n // if the editor isn’t editable and we don't have a handler for\n // readonly checks we have to undo the latest change\n if (!editor.isEditable && !this.options.onReadOnlyChecked) {\n checkbox.checked = !checkbox.checked\n\n return\n }\n\n const { checked } = event.target as any\n\n if (editor.isEditable && typeof getPos === 'function') {\n editor\n .chain()\n .focus(undefined, { scrollIntoView: false })\n .command(({ tr }) => {\n const position = getPos()\n\n if (typeof position !== 'number') {\n return false\n }\n const currentNode = tr.doc.nodeAt(position)\n\n tr.setNodeMarkup(position, undefined, {\n ...currentNode?.attrs,\n checked,\n })\n\n return true\n })\n .run()\n }\n if (!editor.isEditable && this.options.onReadOnlyChecked) {\n // Reset state if onReadOnlyChecked returns false\n if (!this.options.onReadOnlyChecked(node, checked)) {\n checkbox.checked = !checkbox.checked\n }\n }\n })\n\n Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n listItem.dataset.checked = node.attrs.checked\n checkbox.checked = node.attrs.checked\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object.entries(HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n return {\n dom: listItem,\n contentDOM: content,\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n listItem.dataset.checked = updatedNode.attrs.checked\n checkbox.checked = updatedNode.attrs.checked\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n getAttributes: match => ({\n checked: match[match.length - 1] === 'x',\n }),\n }),\n ]\n },\n})\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/task-item.ts"],"sourcesContent":["import {\n KeyboardShortcutCommand, mergeAttributes, Node, wrappingInputRule,\n} from '@tiptap/core'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nexport interface TaskItemOptions {\n /**\n * A callback function that is called when the checkbox is clicked while the editor is in readonly mode.\n * @param node The prosemirror node of the task item\n * @param checked The new checked state\n * @returns boolean\n */\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n\n /**\n * Controls whether the task items can be nested or not.\n * @default false\n * @example true\n */\n nested: boolean\n\n /**\n * HTML attributes to add to the task item element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * The node type for taskList nodes\n * @default 'taskList'\n * @example 'myCustomTaskList'\n */\n taskListTypeName: string\n\n /**\n * Accessibility options for the task item.\n * @default {}\n * @example\n * ```js\n * {\n * checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`\n * }\n */\n a11y?: {\n checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string\n }\n}\n\n/**\n * Matches a task item to a - [ ] on input.\n */\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\n/**\n * This extension allows you to create task items.\n * @see https://www.tiptap.dev/api/nodes/task-item\n */\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\n taskListTypeName: 'taskList',\n a11y: undefined,\n }\n },\n\n content() {\n return this.options.nested ? 'paragraph block*' : 'paragraph+'\n },\n\n defining: true,\n\n addAttributes() {\n return {\n checked: {\n default: false,\n keepOnSplit: false,\n parseHTML: element => {\n const dataChecked = element.getAttribute('data-checked')\n\n return dataChecked === '' || dataChecked === 'true'\n },\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `li[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'li',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n }),\n [\n 'label',\n [\n 'input',\n {\n type: 'checkbox',\n checked: node.attrs.checked ? 'checked' : null,\n },\n ],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n const shortcuts: {\n [key: string]: KeyboardShortcutCommand\n } = {\n Enter: () => this.editor.commands.splitListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem(this.name),\n }\n },\n\n addNodeView() {\n return ({\n node, HTMLAttributes, getPos, editor,\n }) => {\n const listItem = document.createElement('li')\n const checkboxWrapper = document.createElement('label')\n const checkboxStyler = document.createElement('span')\n const checkbox = document.createElement('input')\n const content = document.createElement('div')\n\n const updateA11Y = () => {\n checkbox.ariaLabel = this.options.a11y?.checkboxLabel?.(node, checkbox.checked)\n || `Task item checkbox for ${node.textContent || 'empty task item'}`\n }\n\n updateA11Y()\n\n checkboxWrapper.contentEditable = 'false'\n checkbox.type = 'checkbox'\n checkbox.addEventListener('mousedown', event => event.preventDefault())\n checkbox.addEventListener('change', event => {\n // if the editor isn’t editable and we don't have a handler for\n // readonly checks we have to undo the latest change\n if (!editor.isEditable && !this.options.onReadOnlyChecked) {\n checkbox.checked = !checkbox.checked\n\n return\n }\n\n const { checked } = event.target as any\n\n if (editor.isEditable && typeof getPos === 'function') {\n editor\n .chain()\n .focus(undefined, { scrollIntoView: false })\n .command(({ tr }) => {\n const position = getPos()\n\n if (typeof position !== 'number') {\n return false\n }\n const currentNode = tr.doc.nodeAt(position)\n\n tr.setNodeMarkup(position, undefined, {\n ...currentNode?.attrs,\n checked,\n })\n\n return true\n })\n .run()\n }\n if (!editor.isEditable && this.options.onReadOnlyChecked) {\n // Reset state if onReadOnlyChecked returns false\n if (!this.options.onReadOnlyChecked(node, checked)) {\n checkbox.checked = !checkbox.checked\n }\n }\n })\n\n Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n listItem.dataset.checked = node.attrs.checked\n checkbox.checked = node.attrs.checked\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object.entries(HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n return {\n dom: listItem,\n contentDOM: content,\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n listItem.dataset.checked = updatedNode.attrs.checked\n checkbox.checked = updatedNode.attrs.checked\n updateA11Y()\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n getAttributes: match => ({\n checked: match[match.length - 1] === 'x',\n }),\n }),\n ]\n },\n})\n"],"names":[],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -19,6 +19,7 @@
19
19
  nested: false,
20
20
  HTMLAttributes: {},
21
21
  taskListTypeName: 'taskList',
22
+ a11y: undefined,
22
23
  };
23
24
  },
24
25
  content() {
@@ -88,6 +89,12 @@
88
89
  const checkboxStyler = document.createElement('span');
89
90
  const checkbox = document.createElement('input');
90
91
  const content = document.createElement('div');
92
+ const updateA11Y = () => {
93
+ var _a, _b;
94
+ checkbox.ariaLabel = ((_b = (_a = this.options.a11y) === null || _a === void 0 ? void 0 : _a.checkboxLabel) === null || _b === void 0 ? void 0 : _b.call(_a, node, checkbox.checked))
95
+ || `Task item checkbox for ${node.textContent || 'empty task item'}`;
96
+ };
97
+ updateA11Y();
91
98
  checkboxWrapper.contentEditable = 'false';
92
99
  checkbox.type = 'checkbox';
93
100
  checkbox.addEventListener('mousedown', event => event.preventDefault());
@@ -143,6 +150,7 @@
143
150
  }
144
151
  listItem.dataset.checked = updatedNode.attrs.checked;
145
152
  checkbox.checked = updatedNode.attrs.checked;
153
+ updateA11Y();
146
154
  return true;
147
155
  },
148
156
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/task-item.ts"],"sourcesContent":["import {\n KeyboardShortcutCommand, mergeAttributes, Node, wrappingInputRule,\n} from '@tiptap/core'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nexport interface TaskItemOptions {\n /**\n * A callback function that is called when the checkbox is clicked while the editor is in readonly mode.\n * @param node The prosemirror node of the task item\n * @param checked The new checked state\n * @returns boolean\n */\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n\n /**\n * Controls whether the task items can be nested or not.\n * @default false\n * @example true\n */\n nested: boolean\n\n /**\n * HTML attributes to add to the task item element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * The node type for taskList nodes\n * @default 'taskList'\n * @example 'myCustomTaskList'\n */\n taskListTypeName: string\n}\n\n/**\n * Matches a task item to a - [ ] on input.\n */\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\n/**\n * This extension allows you to create task items.\n * @see https://www.tiptap.dev/api/nodes/task-item\n */\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\n taskListTypeName: 'taskList',\n }\n },\n\n content() {\n return this.options.nested ? 'paragraph block*' : 'paragraph+'\n },\n\n defining: true,\n\n addAttributes() {\n return {\n checked: {\n default: false,\n keepOnSplit: false,\n parseHTML: element => {\n const dataChecked = element.getAttribute('data-checked')\n\n return dataChecked === '' || dataChecked === 'true'\n },\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `li[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'li',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n }),\n [\n 'label',\n [\n 'input',\n {\n type: 'checkbox',\n checked: node.attrs.checked ? 'checked' : null,\n },\n ],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n const shortcuts: {\n [key: string]: KeyboardShortcutCommand\n } = {\n Enter: () => this.editor.commands.splitListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem(this.name),\n }\n },\n\n addNodeView() {\n return ({\n node, HTMLAttributes, getPos, editor,\n }) => {\n const listItem = document.createElement('li')\n const checkboxWrapper = document.createElement('label')\n const checkboxStyler = document.createElement('span')\n const checkbox = document.createElement('input')\n const content = document.createElement('div')\n\n checkboxWrapper.contentEditable = 'false'\n checkbox.type = 'checkbox'\n checkbox.addEventListener('mousedown', event => event.preventDefault())\n checkbox.addEventListener('change', event => {\n // if the editor isn’t editable and we don't have a handler for\n // readonly checks we have to undo the latest change\n if (!editor.isEditable && !this.options.onReadOnlyChecked) {\n checkbox.checked = !checkbox.checked\n\n return\n }\n\n const { checked } = event.target as any\n\n if (editor.isEditable && typeof getPos === 'function') {\n editor\n .chain()\n .focus(undefined, { scrollIntoView: false })\n .command(({ tr }) => {\n const position = getPos()\n\n if (typeof position !== 'number') {\n return false\n }\n const currentNode = tr.doc.nodeAt(position)\n\n tr.setNodeMarkup(position, undefined, {\n ...currentNode?.attrs,\n checked,\n })\n\n return true\n })\n .run()\n }\n if (!editor.isEditable && this.options.onReadOnlyChecked) {\n // Reset state if onReadOnlyChecked returns false\n if (!this.options.onReadOnlyChecked(node, checked)) {\n checkbox.checked = !checkbox.checked\n }\n }\n })\n\n Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n listItem.dataset.checked = node.attrs.checked\n checkbox.checked = node.attrs.checked\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object.entries(HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n return {\n dom: listItem,\n contentDOM: content,\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n listItem.dataset.checked = updatedNode.attrs.checked\n checkbox.checked = updatedNode.attrs.checked\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n getAttributes: match => ({\n checked: match[match.length - 1] === 'x',\n }),\n }),\n ]\n },\n})\n"],"names":["Node","mergeAttributes","wrappingInputRule"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/task-item.ts"],"sourcesContent":["import {\n KeyboardShortcutCommand, mergeAttributes, Node, wrappingInputRule,\n} from '@tiptap/core'\nimport { Node as ProseMirrorNode } from '@tiptap/pm/model'\n\nexport interface TaskItemOptions {\n /**\n * A callback function that is called when the checkbox is clicked while the editor is in readonly mode.\n * @param node The prosemirror node of the task item\n * @param checked The new checked state\n * @returns boolean\n */\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n\n /**\n * Controls whether the task items can be nested or not.\n * @default false\n * @example true\n */\n nested: boolean\n\n /**\n * HTML attributes to add to the task item element.\n * @default {}\n * @example { class: 'foo' }\n */\n HTMLAttributes: Record<string, any>\n\n /**\n * The node type for taskList nodes\n * @default 'taskList'\n * @example 'myCustomTaskList'\n */\n taskListTypeName: string\n\n /**\n * Accessibility options for the task item.\n * @default {}\n * @example\n * ```js\n * {\n * checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`\n * }\n */\n a11y?: {\n checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string\n }\n}\n\n/**\n * Matches a task item to a - [ ] on input.\n */\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\n/**\n * This extension allows you to create task items.\n * @see https://www.tiptap.dev/api/nodes/task-item\n */\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\n taskListTypeName: 'taskList',\n a11y: undefined,\n }\n },\n\n content() {\n return this.options.nested ? 'paragraph block*' : 'paragraph+'\n },\n\n defining: true,\n\n addAttributes() {\n return {\n checked: {\n default: false,\n keepOnSplit: false,\n parseHTML: element => {\n const dataChecked = element.getAttribute('data-checked')\n\n return dataChecked === '' || dataChecked === 'true'\n },\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: `li[data-type=\"${this.name}\"]`,\n priority: 51,\n },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'li',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': this.name,\n }),\n [\n 'label',\n [\n 'input',\n {\n type: 'checkbox',\n checked: node.attrs.checked ? 'checked' : null,\n },\n ],\n ['span'],\n ],\n ['div', 0],\n ]\n },\n\n addKeyboardShortcuts() {\n const shortcuts: {\n [key: string]: KeyboardShortcutCommand\n } = {\n Enter: () => this.editor.commands.splitListItem(this.name),\n 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem(this.name),\n }\n },\n\n addNodeView() {\n return ({\n node, HTMLAttributes, getPos, editor,\n }) => {\n const listItem = document.createElement('li')\n const checkboxWrapper = document.createElement('label')\n const checkboxStyler = document.createElement('span')\n const checkbox = document.createElement('input')\n const content = document.createElement('div')\n\n const updateA11Y = () => {\n checkbox.ariaLabel = this.options.a11y?.checkboxLabel?.(node, checkbox.checked)\n || `Task item checkbox for ${node.textContent || 'empty task item'}`\n }\n\n updateA11Y()\n\n checkboxWrapper.contentEditable = 'false'\n checkbox.type = 'checkbox'\n checkbox.addEventListener('mousedown', event => event.preventDefault())\n checkbox.addEventListener('change', event => {\n // if the editor isn’t editable and we don't have a handler for\n // readonly checks we have to undo the latest change\n if (!editor.isEditable && !this.options.onReadOnlyChecked) {\n checkbox.checked = !checkbox.checked\n\n return\n }\n\n const { checked } = event.target as any\n\n if (editor.isEditable && typeof getPos === 'function') {\n editor\n .chain()\n .focus(undefined, { scrollIntoView: false })\n .command(({ tr }) => {\n const position = getPos()\n\n if (typeof position !== 'number') {\n return false\n }\n const currentNode = tr.doc.nodeAt(position)\n\n tr.setNodeMarkup(position, undefined, {\n ...currentNode?.attrs,\n checked,\n })\n\n return true\n })\n .run()\n }\n if (!editor.isEditable && this.options.onReadOnlyChecked) {\n // Reset state if onReadOnlyChecked returns false\n if (!this.options.onReadOnlyChecked(node, checked)) {\n checkbox.checked = !checkbox.checked\n }\n }\n })\n\n Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n listItem.dataset.checked = node.attrs.checked\n checkbox.checked = node.attrs.checked\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object.entries(HTMLAttributes).forEach(([key, value]) => {\n listItem.setAttribute(key, value)\n })\n\n return {\n dom: listItem,\n contentDOM: content,\n update: updatedNode => {\n if (updatedNode.type !== this.type) {\n return false\n }\n\n listItem.dataset.checked = updatedNode.attrs.checked\n checkbox.checked = updatedNode.attrs.checked\n updateA11Y()\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: inputRegex,\n type: this.type,\n getAttributes: match => ({\n checked: match[match.length - 1] === 'x',\n }),\n }),\n ]\n },\n})\n"],"names":["Node","mergeAttributes","wrappingInputRule"],"mappings":"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"}
@@ -26,6 +26,18 @@ export interface TaskItemOptions {
26
26
  * @example 'myCustomTaskList'
27
27
  */
28
28
  taskListTypeName: string;
29
+ /**
30
+ * Accessibility options for the task item.
31
+ * @default {}
32
+ * @example
33
+ * ```js
34
+ * {
35
+ * checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
36
+ * }
37
+ */
38
+ a11y?: {
39
+ checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string;
40
+ };
29
41
  }
30
42
  /**
31
43
  * Matches a task item to a - [ ] on input.
@@ -1 +1 @@
1
- {"version":3,"file":"task-item.d.ts","sourceRoot":"","sources":["../src/task-item.ts"],"names":[],"mappings":"AAAA,OAAO,EACqC,IAAI,EAC/C,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAE1D,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;IAExE;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAA;IAEf;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEnC;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,QAA2B,CAAA;AAElD;;;GAGG;AACH,eAAO,MAAM,QAAQ,4BAiLnB,CAAA"}
1
+ {"version":3,"file":"task-item.d.ts","sourceRoot":"","sources":["../src/task-item.ts"],"names":[],"mappings":"AAAA,OAAO,EACqC,IAAI,EAC/C,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAE1D,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;IAExE;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAA;IAEf;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEnC;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,CAAA;IAExB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE;QACL,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,KAAK,MAAM,CAAA;KACpE,CAAA;CACF;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,QAA2B,CAAA;AAElD;;;GAGG;AACH,eAAO,MAAM,QAAQ,4BA0LnB,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/extension-task-item",
3
3
  "description": "task item extension for tiptap",
4
- "version": "2.24.0",
4
+ "version": "2.24.1",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -29,8 +29,8 @@
29
29
  "dist"
30
30
  ],
31
31
  "devDependencies": {
32
- "@tiptap/core": "^2.24.0",
33
- "@tiptap/pm": "^2.24.0"
32
+ "@tiptap/core": "^2.24.1",
33
+ "@tiptap/pm": "^2.24.1"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@tiptap/core": "^2.7.0",
package/src/task-item.ts CHANGED
@@ -32,6 +32,19 @@ export interface TaskItemOptions {
32
32
  * @example 'myCustomTaskList'
33
33
  */
34
34
  taskListTypeName: string
35
+
36
+ /**
37
+ * Accessibility options for the task item.
38
+ * @default {}
39
+ * @example
40
+ * ```js
41
+ * {
42
+ * checkboxLabel: (node) => `Task item: ${node.textContent || 'empty task item'}`
43
+ * }
44
+ */
45
+ a11y?: {
46
+ checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string
47
+ }
35
48
  }
36
49
 
37
50
  /**
@@ -51,6 +64,7 @@ export const TaskItem = Node.create<TaskItemOptions>({
51
64
  nested: false,
52
65
  HTMLAttributes: {},
53
66
  taskListTypeName: 'taskList',
67
+ a11y: undefined,
54
68
  }
55
69
  },
56
70
 
@@ -135,6 +149,13 @@ export const TaskItem = Node.create<TaskItemOptions>({
135
149
  const checkbox = document.createElement('input')
136
150
  const content = document.createElement('div')
137
151
 
152
+ const updateA11Y = () => {
153
+ checkbox.ariaLabel = this.options.a11y?.checkboxLabel?.(node, checkbox.checked)
154
+ || `Task item checkbox for ${node.textContent || 'empty task item'}`
155
+ }
156
+
157
+ updateA11Y()
158
+
138
159
  checkboxWrapper.contentEditable = 'false'
139
160
  checkbox.type = 'checkbox'
140
161
  checkbox.addEventListener('mousedown', event => event.preventDefault())
@@ -202,6 +223,7 @@ export const TaskItem = Node.create<TaskItemOptions>({
202
223
 
203
224
  listItem.dataset.checked = updatedNode.attrs.checked
204
225
  checkbox.checked = updatedNode.attrs.checked
226
+ updateA11Y()
205
227
 
206
228
  return true
207
229
  },