@tiptap/extension-task-item 2.0.0-beta.17 → 2.0.0-beta.194

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.
@@ -1,7 +1,9 @@
1
1
  import { Node } from '@tiptap/core';
2
+ import { Node as ProseMirrorNode } from 'prosemirror-model';
2
3
  export interface TaskItemOptions {
4
+ onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean;
3
5
  nested: boolean;
4
6
  HTMLAttributes: Record<string, any>;
5
7
  }
6
8
  export declare const inputRegex: RegExp;
7
- export declare const TaskItem: Node<TaskItemOptions>;
9
+ export declare const TaskItem: Node<TaskItemOptions, any>;
@@ -3,14 +3,15 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var core = require('@tiptap/core');
6
- var prosemirrorInputrules = require('prosemirror-inputrules');
7
6
 
8
- const inputRegex = /^\s*(\[([ |x])\])\s$/;
7
+ const inputRegex = /^\s*(\[([( |x])?\])\s$/;
9
8
  const TaskItem = core.Node.create({
10
9
  name: 'taskItem',
11
- defaultOptions: {
12
- nested: false,
13
- HTMLAttributes: {},
10
+ addOptions() {
11
+ return {
12
+ nested: false,
13
+ HTMLAttributes: {},
14
+ };
14
15
  },
15
16
  content() {
16
17
  return this.options.nested ? 'paragraph block*' : 'paragraph+';
@@ -20,38 +21,53 @@ const TaskItem = core.Node.create({
20
21
  return {
21
22
  checked: {
22
23
  default: false,
23
- parseHTML: element => ({
24
- checked: element.getAttribute('data-checked') === 'true',
25
- }),
24
+ keepOnSplit: false,
25
+ parseHTML: element => element.getAttribute('data-checked') === 'true',
26
26
  renderHTML: attributes => ({
27
27
  'data-checked': attributes.checked,
28
28
  }),
29
- keepOnSplit: false,
30
29
  },
31
30
  };
32
31
  },
33
32
  parseHTML() {
34
33
  return [
35
34
  {
36
- tag: 'li[data-type="taskItem"]',
35
+ tag: `li[data-type="${this.name}"]`,
37
36
  priority: 51,
38
37
  },
39
38
  ];
40
39
  },
41
- renderHTML({ HTMLAttributes }) {
42
- return ['li', core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': 'taskItem' }), 0];
40
+ renderHTML({ node, HTMLAttributes }) {
41
+ return [
42
+ 'li',
43
+ core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
44
+ 'data-type': this.name,
45
+ }),
46
+ [
47
+ 'label',
48
+ [
49
+ 'input',
50
+ {
51
+ type: 'checkbox',
52
+ checked: node.attrs.checked ? 'checked' : null,
53
+ },
54
+ ],
55
+ ['span'],
56
+ ],
57
+ ['div', 0],
58
+ ];
43
59
  },
44
60
  addKeyboardShortcuts() {
45
61
  const shortcuts = {
46
- Enter: () => this.editor.commands.splitListItem('taskItem'),
47
- 'Shift-Tab': () => this.editor.commands.liftListItem('taskItem'),
62
+ Enter: () => this.editor.commands.splitListItem(this.name),
63
+ 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
48
64
  };
49
65
  if (!this.options.nested) {
50
66
  return shortcuts;
51
67
  }
52
68
  return {
53
69
  ...shortcuts,
54
- Tab: () => this.editor.commands.sinkListItem('taskItem'),
70
+ Tab: () => this.editor.commands.sinkListItem(this.name),
55
71
  };
56
72
  },
57
73
  addNodeView() {
@@ -64,9 +80,9 @@ const TaskItem = core.Node.create({
64
80
  checkboxWrapper.contentEditable = 'false';
65
81
  checkbox.type = 'checkbox';
66
82
  checkbox.addEventListener('change', event => {
67
- // if the editor isn’t editable
68
- // we have to undo the latest change
69
- if (!editor.isEditable) {
83
+ // if the editor isn’t editable and we don't have a handler for
84
+ // readonly checks we have to undo the latest change
85
+ if (!editor.isEditable && !this.options.onReadOnlyChecked) {
70
86
  checkbox.checked = !checkbox.checked;
71
87
  return;
72
88
  }
@@ -74,15 +90,27 @@ const TaskItem = core.Node.create({
74
90
  if (editor.isEditable && typeof getPos === 'function') {
75
91
  editor
76
92
  .chain()
77
- .focus()
93
+ .focus(undefined, { scrollIntoView: false })
78
94
  .command(({ tr }) => {
79
- tr.setNodeMarkup(getPos(), undefined, {
95
+ const position = getPos();
96
+ const currentNode = tr.doc.nodeAt(position);
97
+ tr.setNodeMarkup(position, undefined, {
98
+ ...currentNode === null || currentNode === void 0 ? void 0 : currentNode.attrs,
80
99
  checked,
81
100
  });
82
101
  return true;
83
102
  })
84
103
  .run();
85
104
  }
105
+ if (!editor.isEditable && this.options.onReadOnlyChecked) {
106
+ // Reset state if onReadOnlyChecked returns false
107
+ if (!this.options.onReadOnlyChecked(node, checked)) {
108
+ checkbox.checked = !checkbox.checked;
109
+ }
110
+ }
111
+ });
112
+ Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
113
+ listItem.setAttribute(key, value);
86
114
  });
87
115
  listItem.dataset.checked = node.attrs.checked;
88
116
  if (node.attrs.checked) {
@@ -90,9 +118,7 @@ const TaskItem = core.Node.create({
90
118
  }
91
119
  checkboxWrapper.append(checkbox, checkboxStyler);
92
120
  listItem.append(checkboxWrapper, content);
93
- Object
94
- .entries(HTMLAttributes)
95
- .forEach(([key, value]) => {
121
+ Object.entries(HTMLAttributes).forEach(([key, value]) => {
96
122
  listItem.setAttribute(key, value);
97
123
  });
98
124
  return {
@@ -116,14 +142,18 @@ const TaskItem = core.Node.create({
116
142
  },
117
143
  addInputRules() {
118
144
  return [
119
- prosemirrorInputrules.wrappingInputRule(inputRegex, this.type, match => ({
120
- checked: match[match.length - 1] === 'x',
121
- })),
145
+ core.wrappingInputRule({
146
+ find: inputRegex,
147
+ type: this.type,
148
+ getAttributes: match => ({
149
+ checked: match[match.length - 1] === 'x',
150
+ }),
151
+ }),
122
152
  ];
123
153
  },
124
154
  });
125
155
 
126
156
  exports.TaskItem = TaskItem;
127
- exports.default = TaskItem;
157
+ exports["default"] = TaskItem;
128
158
  exports.inputRegex = inputRegex;
129
159
  //# sourceMappingURL=tiptap-extension-task-item.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tiptap-extension-task-item.cjs.js","sources":["../src/task-item.ts"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core'\nimport { wrappingInputRule } from 'prosemirror-inputrules'\n\nexport interface TaskItemOptions {\n nested: boolean,\n HTMLAttributes: Record<string, any>,\n}\n\nexport const inputRegex = /^\\s*(\\[([ |x])\\])\\s$/\n\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n defaultOptions: {\n nested: false,\n HTMLAttributes: {},\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 parseHTML: element => ({\n checked: element.getAttribute('data-checked') === 'true',\n }),\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n keepOnSplit: false,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'li[data-type=\"taskItem\"]',\n priority: 51,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['li', mergeAttributes(\n this.options.HTMLAttributes,\n HTMLAttributes,\n { 'data-type': 'taskItem' },\n ), 0]\n },\n\n addKeyboardShortcuts() {\n const shortcuts = {\n Enter: () => this.editor.commands.splitListItem('taskItem'),\n 'Shift-Tab': () => this.editor.commands.liftListItem('taskItem'),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem('taskItem'),\n }\n },\n\n addNodeView() {\n return ({\n node,\n HTMLAttributes,\n getPos,\n 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('change', event => {\n // if the editor isn’t editable\n // we have to undo the latest change\n if (!editor.isEditable) {\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()\n .command(({ tr }) => {\n tr.setNodeMarkup(getPos(), undefined, {\n checked,\n })\n\n return true\n })\n .run()\n }\n })\n\n listItem.dataset.checked = node.attrs.checked\n if (node.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n }\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object\n .entries(HTMLAttributes)\n .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 if (updatedNode.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n } else {\n checkbox.removeAttribute('checked')\n }\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule(\n inputRegex,\n this.type,\n 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":"tiptap-extension-task-item.cjs.js","sources":["../src/task-item.ts"],"sourcesContent":["import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\n\nexport interface TaskItemOptions {\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n nested: boolean\n HTMLAttributes: Record<string, any>\n}\n\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\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 => element.getAttribute('data-checked') === 'true',\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 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('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 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 if (node.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n }\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 if (updatedNode.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n } else {\n checkbox.removeAttribute('checked')\n }\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,12 +1,13 @@
1
- import { Node, mergeAttributes } from '@tiptap/core';
2
- import { wrappingInputRule } from 'prosemirror-inputrules';
1
+ import { Node, mergeAttributes, wrappingInputRule } from '@tiptap/core';
3
2
 
4
- const inputRegex = /^\s*(\[([ |x])\])\s$/;
3
+ const inputRegex = /^\s*(\[([( |x])?\])\s$/;
5
4
  const TaskItem = Node.create({
6
5
  name: 'taskItem',
7
- defaultOptions: {
8
- nested: false,
9
- HTMLAttributes: {},
6
+ addOptions() {
7
+ return {
8
+ nested: false,
9
+ HTMLAttributes: {},
10
+ };
10
11
  },
11
12
  content() {
12
13
  return this.options.nested ? 'paragraph block*' : 'paragraph+';
@@ -16,38 +17,53 @@ const TaskItem = Node.create({
16
17
  return {
17
18
  checked: {
18
19
  default: false,
19
- parseHTML: element => ({
20
- checked: element.getAttribute('data-checked') === 'true',
21
- }),
20
+ keepOnSplit: false,
21
+ parseHTML: element => element.getAttribute('data-checked') === 'true',
22
22
  renderHTML: attributes => ({
23
23
  'data-checked': attributes.checked,
24
24
  }),
25
- keepOnSplit: false,
26
25
  },
27
26
  };
28
27
  },
29
28
  parseHTML() {
30
29
  return [
31
30
  {
32
- tag: 'li[data-type="taskItem"]',
31
+ tag: `li[data-type="${this.name}"]`,
33
32
  priority: 51,
34
33
  },
35
34
  ];
36
35
  },
37
- renderHTML({ HTMLAttributes }) {
38
- return ['li', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': 'taskItem' }), 0];
36
+ renderHTML({ node, HTMLAttributes }) {
37
+ return [
38
+ 'li',
39
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
40
+ 'data-type': this.name,
41
+ }),
42
+ [
43
+ 'label',
44
+ [
45
+ 'input',
46
+ {
47
+ type: 'checkbox',
48
+ checked: node.attrs.checked ? 'checked' : null,
49
+ },
50
+ ],
51
+ ['span'],
52
+ ],
53
+ ['div', 0],
54
+ ];
39
55
  },
40
56
  addKeyboardShortcuts() {
41
57
  const shortcuts = {
42
- Enter: () => this.editor.commands.splitListItem('taskItem'),
43
- 'Shift-Tab': () => this.editor.commands.liftListItem('taskItem'),
58
+ Enter: () => this.editor.commands.splitListItem(this.name),
59
+ 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
44
60
  };
45
61
  if (!this.options.nested) {
46
62
  return shortcuts;
47
63
  }
48
64
  return {
49
65
  ...shortcuts,
50
- Tab: () => this.editor.commands.sinkListItem('taskItem'),
66
+ Tab: () => this.editor.commands.sinkListItem(this.name),
51
67
  };
52
68
  },
53
69
  addNodeView() {
@@ -60,9 +76,9 @@ const TaskItem = Node.create({
60
76
  checkboxWrapper.contentEditable = 'false';
61
77
  checkbox.type = 'checkbox';
62
78
  checkbox.addEventListener('change', event => {
63
- // if the editor isn’t editable
64
- // we have to undo the latest change
65
- if (!editor.isEditable) {
79
+ // if the editor isn’t editable and we don't have a handler for
80
+ // readonly checks we have to undo the latest change
81
+ if (!editor.isEditable && !this.options.onReadOnlyChecked) {
66
82
  checkbox.checked = !checkbox.checked;
67
83
  return;
68
84
  }
@@ -70,15 +86,27 @@ const TaskItem = Node.create({
70
86
  if (editor.isEditable && typeof getPos === 'function') {
71
87
  editor
72
88
  .chain()
73
- .focus()
89
+ .focus(undefined, { scrollIntoView: false })
74
90
  .command(({ tr }) => {
75
- tr.setNodeMarkup(getPos(), undefined, {
91
+ const position = getPos();
92
+ const currentNode = tr.doc.nodeAt(position);
93
+ tr.setNodeMarkup(position, undefined, {
94
+ ...currentNode === null || currentNode === void 0 ? void 0 : currentNode.attrs,
76
95
  checked,
77
96
  });
78
97
  return true;
79
98
  })
80
99
  .run();
81
100
  }
101
+ if (!editor.isEditable && this.options.onReadOnlyChecked) {
102
+ // Reset state if onReadOnlyChecked returns false
103
+ if (!this.options.onReadOnlyChecked(node, checked)) {
104
+ checkbox.checked = !checkbox.checked;
105
+ }
106
+ }
107
+ });
108
+ Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
109
+ listItem.setAttribute(key, value);
82
110
  });
83
111
  listItem.dataset.checked = node.attrs.checked;
84
112
  if (node.attrs.checked) {
@@ -86,9 +114,7 @@ const TaskItem = Node.create({
86
114
  }
87
115
  checkboxWrapper.append(checkbox, checkboxStyler);
88
116
  listItem.append(checkboxWrapper, content);
89
- Object
90
- .entries(HTMLAttributes)
91
- .forEach(([key, value]) => {
117
+ Object.entries(HTMLAttributes).forEach(([key, value]) => {
92
118
  listItem.setAttribute(key, value);
93
119
  });
94
120
  return {
@@ -112,13 +138,16 @@ const TaskItem = Node.create({
112
138
  },
113
139
  addInputRules() {
114
140
  return [
115
- wrappingInputRule(inputRegex, this.type, match => ({
116
- checked: match[match.length - 1] === 'x',
117
- })),
141
+ wrappingInputRule({
142
+ find: inputRegex,
143
+ type: this.type,
144
+ getAttributes: match => ({
145
+ checked: match[match.length - 1] === 'x',
146
+ }),
147
+ }),
118
148
  ];
119
149
  },
120
150
  });
121
151
 
122
- export default TaskItem;
123
- export { TaskItem, inputRegex };
152
+ export { TaskItem, TaskItem as default, inputRegex };
124
153
  //# sourceMappingURL=tiptap-extension-task-item.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tiptap-extension-task-item.esm.js","sources":["../src/task-item.ts"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core'\nimport { wrappingInputRule } from 'prosemirror-inputrules'\n\nexport interface TaskItemOptions {\n nested: boolean,\n HTMLAttributes: Record<string, any>,\n}\n\nexport const inputRegex = /^\\s*(\\[([ |x])\\])\\s$/\n\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n defaultOptions: {\n nested: false,\n HTMLAttributes: {},\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 parseHTML: element => ({\n checked: element.getAttribute('data-checked') === 'true',\n }),\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n keepOnSplit: false,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'li[data-type=\"taskItem\"]',\n priority: 51,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['li', mergeAttributes(\n this.options.HTMLAttributes,\n HTMLAttributes,\n { 'data-type': 'taskItem' },\n ), 0]\n },\n\n addKeyboardShortcuts() {\n const shortcuts = {\n Enter: () => this.editor.commands.splitListItem('taskItem'),\n 'Shift-Tab': () => this.editor.commands.liftListItem('taskItem'),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem('taskItem'),\n }\n },\n\n addNodeView() {\n return ({\n node,\n HTMLAttributes,\n getPos,\n 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('change', event => {\n // if the editor isn’t editable\n // we have to undo the latest change\n if (!editor.isEditable) {\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()\n .command(({ tr }) => {\n tr.setNodeMarkup(getPos(), undefined, {\n checked,\n })\n\n return true\n })\n .run()\n }\n })\n\n listItem.dataset.checked = node.attrs.checked\n if (node.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n }\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object\n .entries(HTMLAttributes)\n .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 if (updatedNode.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n } else {\n checkbox.removeAttribute('checked')\n }\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule(\n inputRegex,\n this.type,\n match => ({\n checked: match[match.length - 1] === 'x',\n }),\n ),\n ]\n },\n})\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tiptap-extension-task-item.esm.js","sources":["../src/task-item.ts"],"sourcesContent":["import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\n\nexport interface TaskItemOptions {\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n nested: boolean\n HTMLAttributes: Record<string, any>\n}\n\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\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 => element.getAttribute('data-checked') === 'true',\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 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('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 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 if (node.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n }\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 if (updatedNode.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n } else {\n checkbox.removeAttribute('checked')\n }\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,15 +1,17 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core'), require('prosemirror-inputrules')) :
3
- typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core', 'prosemirror-inputrules'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['@tiptap/extension-task-item'] = {}, global.core, global.prosemirrorInputrules));
5
- }(this, (function (exports, core, prosemirrorInputrules) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tiptap/core')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', '@tiptap/core'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@tiptap/extension-task-item"] = {}, global.core));
5
+ })(this, (function (exports, core) { 'use strict';
6
6
 
7
- const inputRegex = /^\s*(\[([ |x])\])\s$/;
7
+ const inputRegex = /^\s*(\[([( |x])?\])\s$/;
8
8
  const TaskItem = core.Node.create({
9
9
  name: 'taskItem',
10
- defaultOptions: {
11
- nested: false,
12
- HTMLAttributes: {},
10
+ addOptions() {
11
+ return {
12
+ nested: false,
13
+ HTMLAttributes: {},
14
+ };
13
15
  },
14
16
  content() {
15
17
  return this.options.nested ? 'paragraph block*' : 'paragraph+';
@@ -19,38 +21,53 @@
19
21
  return {
20
22
  checked: {
21
23
  default: false,
22
- parseHTML: element => ({
23
- checked: element.getAttribute('data-checked') === 'true',
24
- }),
24
+ keepOnSplit: false,
25
+ parseHTML: element => element.getAttribute('data-checked') === 'true',
25
26
  renderHTML: attributes => ({
26
27
  'data-checked': attributes.checked,
27
28
  }),
28
- keepOnSplit: false,
29
29
  },
30
30
  };
31
31
  },
32
32
  parseHTML() {
33
33
  return [
34
34
  {
35
- tag: 'li[data-type="taskItem"]',
35
+ tag: `li[data-type="${this.name}"]`,
36
36
  priority: 51,
37
37
  },
38
38
  ];
39
39
  },
40
- renderHTML({ HTMLAttributes }) {
41
- return ['li', core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { 'data-type': 'taskItem' }), 0];
40
+ renderHTML({ node, HTMLAttributes }) {
41
+ return [
42
+ 'li',
43
+ core.mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
44
+ 'data-type': this.name,
45
+ }),
46
+ [
47
+ 'label',
48
+ [
49
+ 'input',
50
+ {
51
+ type: 'checkbox',
52
+ checked: node.attrs.checked ? 'checked' : null,
53
+ },
54
+ ],
55
+ ['span'],
56
+ ],
57
+ ['div', 0],
58
+ ];
42
59
  },
43
60
  addKeyboardShortcuts() {
44
61
  const shortcuts = {
45
- Enter: () => this.editor.commands.splitListItem('taskItem'),
46
- 'Shift-Tab': () => this.editor.commands.liftListItem('taskItem'),
62
+ Enter: () => this.editor.commands.splitListItem(this.name),
63
+ 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
47
64
  };
48
65
  if (!this.options.nested) {
49
66
  return shortcuts;
50
67
  }
51
68
  return {
52
69
  ...shortcuts,
53
- Tab: () => this.editor.commands.sinkListItem('taskItem'),
70
+ Tab: () => this.editor.commands.sinkListItem(this.name),
54
71
  };
55
72
  },
56
73
  addNodeView() {
@@ -63,9 +80,9 @@
63
80
  checkboxWrapper.contentEditable = 'false';
64
81
  checkbox.type = 'checkbox';
65
82
  checkbox.addEventListener('change', event => {
66
- // if the editor isn’t editable
67
- // we have to undo the latest change
68
- if (!editor.isEditable) {
83
+ // if the editor isn’t editable and we don't have a handler for
84
+ // readonly checks we have to undo the latest change
85
+ if (!editor.isEditable && !this.options.onReadOnlyChecked) {
69
86
  checkbox.checked = !checkbox.checked;
70
87
  return;
71
88
  }
@@ -73,15 +90,27 @@
73
90
  if (editor.isEditable && typeof getPos === 'function') {
74
91
  editor
75
92
  .chain()
76
- .focus()
93
+ .focus(undefined, { scrollIntoView: false })
77
94
  .command(({ tr }) => {
78
- tr.setNodeMarkup(getPos(), undefined, {
95
+ const position = getPos();
96
+ const currentNode = tr.doc.nodeAt(position);
97
+ tr.setNodeMarkup(position, undefined, {
98
+ ...currentNode === null || currentNode === void 0 ? void 0 : currentNode.attrs,
79
99
  checked,
80
100
  });
81
101
  return true;
82
102
  })
83
103
  .run();
84
104
  }
105
+ if (!editor.isEditable && this.options.onReadOnlyChecked) {
106
+ // Reset state if onReadOnlyChecked returns false
107
+ if (!this.options.onReadOnlyChecked(node, checked)) {
108
+ checkbox.checked = !checkbox.checked;
109
+ }
110
+ }
111
+ });
112
+ Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
113
+ listItem.setAttribute(key, value);
85
114
  });
86
115
  listItem.dataset.checked = node.attrs.checked;
87
116
  if (node.attrs.checked) {
@@ -89,9 +118,7 @@
89
118
  }
90
119
  checkboxWrapper.append(checkbox, checkboxStyler);
91
120
  listItem.append(checkboxWrapper, content);
92
- Object
93
- .entries(HTMLAttributes)
94
- .forEach(([key, value]) => {
121
+ Object.entries(HTMLAttributes).forEach(([key, value]) => {
95
122
  listItem.setAttribute(key, value);
96
123
  });
97
124
  return {
@@ -115,18 +142,22 @@
115
142
  },
116
143
  addInputRules() {
117
144
  return [
118
- prosemirrorInputrules.wrappingInputRule(inputRegex, this.type, match => ({
119
- checked: match[match.length - 1] === 'x',
120
- })),
145
+ core.wrappingInputRule({
146
+ find: inputRegex,
147
+ type: this.type,
148
+ getAttributes: match => ({
149
+ checked: match[match.length - 1] === 'x',
150
+ }),
151
+ }),
121
152
  ];
122
153
  },
123
154
  });
124
155
 
125
156
  exports.TaskItem = TaskItem;
126
- exports.default = TaskItem;
157
+ exports["default"] = TaskItem;
127
158
  exports.inputRegex = inputRegex;
128
159
 
129
160
  Object.defineProperty(exports, '__esModule', { value: true });
130
161
 
131
- })));
162
+ }));
132
163
  //# sourceMappingURL=tiptap-extension-task-item.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tiptap-extension-task-item.umd.js","sources":["../src/task-item.ts"],"sourcesContent":["import { Node, mergeAttributes } from '@tiptap/core'\nimport { wrappingInputRule } from 'prosemirror-inputrules'\n\nexport interface TaskItemOptions {\n nested: boolean,\n HTMLAttributes: Record<string, any>,\n}\n\nexport const inputRegex = /^\\s*(\\[([ |x])\\])\\s$/\n\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n defaultOptions: {\n nested: false,\n HTMLAttributes: {},\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 parseHTML: element => ({\n checked: element.getAttribute('data-checked') === 'true',\n }),\n renderHTML: attributes => ({\n 'data-checked': attributes.checked,\n }),\n keepOnSplit: false,\n },\n }\n },\n\n parseHTML() {\n return [\n {\n tag: 'li[data-type=\"taskItem\"]',\n priority: 51,\n },\n ]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['li', mergeAttributes(\n this.options.HTMLAttributes,\n HTMLAttributes,\n { 'data-type': 'taskItem' },\n ), 0]\n },\n\n addKeyboardShortcuts() {\n const shortcuts = {\n Enter: () => this.editor.commands.splitListItem('taskItem'),\n 'Shift-Tab': () => this.editor.commands.liftListItem('taskItem'),\n }\n\n if (!this.options.nested) {\n return shortcuts\n }\n\n return {\n ...shortcuts,\n Tab: () => this.editor.commands.sinkListItem('taskItem'),\n }\n },\n\n addNodeView() {\n return ({\n node,\n HTMLAttributes,\n getPos,\n 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('change', event => {\n // if the editor isn’t editable\n // we have to undo the latest change\n if (!editor.isEditable) {\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()\n .command(({ tr }) => {\n tr.setNodeMarkup(getPos(), undefined, {\n checked,\n })\n\n return true\n })\n .run()\n }\n })\n\n listItem.dataset.checked = node.attrs.checked\n if (node.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n }\n\n checkboxWrapper.append(checkbox, checkboxStyler)\n listItem.append(checkboxWrapper, content)\n\n Object\n .entries(HTMLAttributes)\n .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 if (updatedNode.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n } else {\n checkbox.removeAttribute('checked')\n }\n\n return true\n },\n }\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule(\n inputRegex,\n this.type,\n 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":"tiptap-extension-task-item.umd.js","sources":["../src/task-item.ts"],"sourcesContent":["import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'\nimport { Node as ProseMirrorNode } from 'prosemirror-model'\n\nexport interface TaskItemOptions {\n onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean\n nested: boolean\n HTMLAttributes: Record<string, any>\n}\n\nexport const inputRegex = /^\\s*(\\[([( |x])?\\])\\s$/\n\nexport const TaskItem = Node.create<TaskItemOptions>({\n name: 'taskItem',\n\n addOptions() {\n return {\n nested: false,\n HTMLAttributes: {},\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 => element.getAttribute('data-checked') === 'true',\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 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('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 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 if (node.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n }\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 if (updatedNode.attrs.checked) {\n checkbox.setAttribute('checked', 'checked')\n } else {\n checkbox.removeAttribute('checked')\n }\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/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.0.0-beta.17",
4
+ "version": "2.0.0-beta.194",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -21,15 +21,12 @@
21
21
  "dist"
22
22
  ],
23
23
  "peerDependencies": {
24
- "@tiptap/core": "^2.0.0-beta.1"
25
- },
26
- "dependencies": {
27
- "prosemirror-inputrules": "^1.1.3"
24
+ "@tiptap/core": "^2.0.0-beta.193",
25
+ "prosemirror-model": "1.18.1"
28
26
  },
29
27
  "repository": {
30
28
  "type": "git",
31
29
  "url": "https://github.com/ueberdosis/tiptap",
32
30
  "directory": "packages/extension-task-item"
33
- },
34
- "gitHead": "345ea8cf8abba6422dabc6e548594fb8e2c30409"
31
+ }
35
32
  }
package/src/task-item.ts CHANGED
@@ -1,19 +1,22 @@
1
- import { Node, mergeAttributes } from '@tiptap/core'
2
- import { wrappingInputRule } from 'prosemirror-inputrules'
1
+ import { mergeAttributes, Node, wrappingInputRule } from '@tiptap/core'
2
+ import { Node as ProseMirrorNode } from 'prosemirror-model'
3
3
 
4
4
  export interface TaskItemOptions {
5
- nested: boolean,
6
- HTMLAttributes: Record<string, any>,
5
+ onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean
6
+ nested: boolean
7
+ HTMLAttributes: Record<string, any>
7
8
  }
8
9
 
9
- export const inputRegex = /^\s*(\[([ |x])\])\s$/
10
+ export const inputRegex = /^\s*(\[([( |x])?\])\s$/
10
11
 
11
12
  export const TaskItem = Node.create<TaskItemOptions>({
12
13
  name: 'taskItem',
13
14
 
14
- defaultOptions: {
15
- nested: false,
16
- HTMLAttributes: {},
15
+ addOptions() {
16
+ return {
17
+ nested: false,
18
+ HTMLAttributes: {},
19
+ }
17
20
  },
18
21
 
19
22
  content() {
@@ -26,13 +29,11 @@ export const TaskItem = Node.create<TaskItemOptions>({
26
29
  return {
27
30
  checked: {
28
31
  default: false,
29
- parseHTML: element => ({
30
- checked: element.getAttribute('data-checked') === 'true',
31
- }),
32
+ keepOnSplit: false,
33
+ parseHTML: element => element.getAttribute('data-checked') === 'true',
32
34
  renderHTML: attributes => ({
33
35
  'data-checked': attributes.checked,
34
36
  }),
35
- keepOnSplit: false,
36
37
  },
37
38
  }
38
39
  },
@@ -40,24 +41,37 @@ export const TaskItem = Node.create<TaskItemOptions>({
40
41
  parseHTML() {
41
42
  return [
42
43
  {
43
- tag: 'li[data-type="taskItem"]',
44
+ tag: `li[data-type="${this.name}"]`,
44
45
  priority: 51,
45
46
  },
46
47
  ]
47
48
  },
48
49
 
49
- renderHTML({ HTMLAttributes }) {
50
- return ['li', mergeAttributes(
51
- this.options.HTMLAttributes,
52
- HTMLAttributes,
53
- { 'data-type': 'taskItem' },
54
- ), 0]
50
+ renderHTML({ node, HTMLAttributes }) {
51
+ return [
52
+ 'li',
53
+ mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
54
+ 'data-type': this.name,
55
+ }),
56
+ [
57
+ 'label',
58
+ [
59
+ 'input',
60
+ {
61
+ type: 'checkbox',
62
+ checked: node.attrs.checked ? 'checked' : null,
63
+ },
64
+ ],
65
+ ['span'],
66
+ ],
67
+ ['div', 0],
68
+ ]
55
69
  },
56
70
 
57
71
  addKeyboardShortcuts() {
58
72
  const shortcuts = {
59
- Enter: () => this.editor.commands.splitListItem('taskItem'),
60
- 'Shift-Tab': () => this.editor.commands.liftListItem('taskItem'),
73
+ Enter: () => this.editor.commands.splitListItem(this.name),
74
+ 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
61
75
  }
62
76
 
63
77
  if (!this.options.nested) {
@@ -66,16 +80,13 @@ export const TaskItem = Node.create<TaskItemOptions>({
66
80
 
67
81
  return {
68
82
  ...shortcuts,
69
- Tab: () => this.editor.commands.sinkListItem('taskItem'),
83
+ Tab: () => this.editor.commands.sinkListItem(this.name),
70
84
  }
71
85
  },
72
86
 
73
87
  addNodeView() {
74
88
  return ({
75
- node,
76
- HTMLAttributes,
77
- getPos,
78
- editor,
89
+ node, HTMLAttributes, getPos, editor,
79
90
  }) => {
80
91
  const listItem = document.createElement('li')
81
92
  const checkboxWrapper = document.createElement('label')
@@ -86,9 +97,9 @@ export const TaskItem = Node.create<TaskItemOptions>({
86
97
  checkboxWrapper.contentEditable = 'false'
87
98
  checkbox.type = 'checkbox'
88
99
  checkbox.addEventListener('change', event => {
89
- // if the editor isn’t editable
90
- // we have to undo the latest change
91
- if (!editor.isEditable) {
100
+ // if the editor isn’t editable and we don't have a handler for
101
+ // readonly checks we have to undo the latest change
102
+ if (!editor.isEditable && !this.options.onReadOnlyChecked) {
92
103
  checkbox.checked = !checkbox.checked
93
104
 
94
105
  return
@@ -99,9 +110,13 @@ export const TaskItem = Node.create<TaskItemOptions>({
99
110
  if (editor.isEditable && typeof getPos === 'function') {
100
111
  editor
101
112
  .chain()
102
- .focus()
113
+ .focus(undefined, { scrollIntoView: false })
103
114
  .command(({ tr }) => {
104
- tr.setNodeMarkup(getPos(), undefined, {
115
+ const position = getPos()
116
+ const currentNode = tr.doc.nodeAt(position)
117
+
118
+ tr.setNodeMarkup(position, undefined, {
119
+ ...currentNode?.attrs,
105
120
  checked,
106
121
  })
107
122
 
@@ -109,6 +124,16 @@ export const TaskItem = Node.create<TaskItemOptions>({
109
124
  })
110
125
  .run()
111
126
  }
127
+ if (!editor.isEditable && this.options.onReadOnlyChecked) {
128
+ // Reset state if onReadOnlyChecked returns false
129
+ if (!this.options.onReadOnlyChecked(node, checked)) {
130
+ checkbox.checked = !checkbox.checked
131
+ }
132
+ }
133
+ })
134
+
135
+ Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => {
136
+ listItem.setAttribute(key, value)
112
137
  })
113
138
 
114
139
  listItem.dataset.checked = node.attrs.checked
@@ -119,11 +144,9 @@ export const TaskItem = Node.create<TaskItemOptions>({
119
144
  checkboxWrapper.append(checkbox, checkboxStyler)
120
145
  listItem.append(checkboxWrapper, content)
121
146
 
122
- Object
123
- .entries(HTMLAttributes)
124
- .forEach(([key, value]) => {
125
- listItem.setAttribute(key, value)
126
- })
147
+ Object.entries(HTMLAttributes).forEach(([key, value]) => {
148
+ listItem.setAttribute(key, value)
149
+ })
127
150
 
128
151
  return {
129
152
  dom: listItem,
@@ -148,13 +171,13 @@ export const TaskItem = Node.create<TaskItemOptions>({
148
171
 
149
172
  addInputRules() {
150
173
  return [
151
- wrappingInputRule(
152
- inputRegex,
153
- this.type,
154
- match => ({
174
+ wrappingInputRule({
175
+ find: inputRegex,
176
+ type: this.type,
177
+ getAttributes: match => ({
155
178
  checked: match[match.length - 1] === 'x',
156
179
  }),
157
- ),
180
+ }),
158
181
  ]
159
182
  },
160
183
  })
package/CHANGELOG.md DELETED
@@ -1,266 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- # [2.0.0-beta.17](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.16...@tiptap/extension-task-item@2.0.0-beta.17) (2021-07-26)
7
-
8
- **Note:** Version bump only for package @tiptap/extension-task-item
9
-
10
-
11
-
12
-
13
-
14
- # [2.0.0-beta.16](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.15...@tiptap/extension-task-item@2.0.0-beta.16) (2021-05-27)
15
-
16
-
17
- ### Bug Fixes
18
-
19
- * prevent checkbox change when editor isn’t editable, fix [#1386](https://github.com/ueberdosis/tiptap/issues/1386) ([c58a753](https://github.com/ueberdosis/tiptap/commit/c58a753e9442c1766050a1a4733e56d553d2e8c5))
20
-
21
-
22
-
23
-
24
-
25
- # [2.0.0-beta.15](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.14...@tiptap/extension-task-item@2.0.0-beta.15) (2021-05-18)
26
-
27
- **Note:** Version bump only for package @tiptap/extension-task-item
28
-
29
-
30
-
31
-
32
-
33
- # [2.0.0-beta.14](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.13...@tiptap/extension-task-item@2.0.0-beta.14) (2021-05-13)
34
-
35
- **Note:** Version bump only for package @tiptap/extension-task-item
36
-
37
-
38
-
39
-
40
-
41
- # [2.0.0-beta.13](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.12...@tiptap/extension-task-item@2.0.0-beta.13) (2021-05-07)
42
-
43
-
44
- ### Bug Fixes
45
-
46
- * revert adding exports ([bc320d0](https://github.com/ueberdosis/tiptap/commit/bc320d0b4b80b0e37a7e47a56e0f6daec6e65d98))
47
-
48
-
49
-
50
-
51
-
52
- # [2.0.0-beta.12](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.11...@tiptap/extension-task-item@2.0.0-beta.12) (2021-05-06)
53
-
54
-
55
- ### Bug Fixes
56
-
57
- * revert adding type: module ([f8d6475](https://github.com/ueberdosis/tiptap/commit/f8d6475e2151faea6f96baecdd6bd75880d50d2c))
58
-
59
-
60
-
61
-
62
-
63
- # [2.0.0-beta.11](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.10...@tiptap/extension-task-item@2.0.0-beta.11) (2021-05-06)
64
-
65
-
66
- ### Bug Fixes
67
-
68
- * add exports to package.json ([1277fa4](https://github.com/ueberdosis/tiptap/commit/1277fa47151e9c039508cdb219bdd0ffe647f4ee))
69
-
70
-
71
-
72
-
73
-
74
- # [2.0.0-beta.10](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.9...@tiptap/extension-task-item@2.0.0-beta.10) (2021-05-06)
75
-
76
- **Note:** Version bump only for package @tiptap/extension-task-item
77
-
78
-
79
-
80
-
81
-
82
- # [2.0.0-beta.9](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.8...@tiptap/extension-task-item@2.0.0-beta.9) (2021-05-05)
83
-
84
- **Note:** Version bump only for package @tiptap/extension-task-item
85
-
86
-
87
-
88
-
89
-
90
- # [2.0.0-beta.8](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.7...@tiptap/extension-task-item@2.0.0-beta.8) (2021-04-23)
91
-
92
- **Note:** Version bump only for package @tiptap/extension-task-item
93
-
94
-
95
-
96
-
97
-
98
- # [2.0.0-beta.7](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.6...@tiptap/extension-task-item@2.0.0-beta.7) (2021-04-23)
99
-
100
- **Note:** Version bump only for package @tiptap/extension-task-item
101
-
102
-
103
-
104
-
105
-
106
- # [2.0.0-beta.6](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.5...@tiptap/extension-task-item@2.0.0-beta.6) (2021-04-22)
107
-
108
- **Note:** Version bump only for package @tiptap/extension-task-item
109
-
110
-
111
-
112
-
113
-
114
- # [2.0.0-beta.5](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.4...@tiptap/extension-task-item@2.0.0-beta.5) (2021-04-21)
115
-
116
- **Note:** Version bump only for package @tiptap/extension-task-item
117
-
118
-
119
-
120
-
121
-
122
- # [2.0.0-beta.4](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.3...@tiptap/extension-task-item@2.0.0-beta.4) (2021-04-16)
123
-
124
- **Note:** Version bump only for package @tiptap/extension-task-item
125
-
126
-
127
-
128
-
129
-
130
- # [2.0.0-beta.3](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.2...@tiptap/extension-task-item@2.0.0-beta.3) (2021-04-15)
131
-
132
- **Note:** Version bump only for package @tiptap/extension-task-item
133
-
134
-
135
-
136
-
137
-
138
- # [2.0.0-beta.2](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-beta.1...@tiptap/extension-task-item@2.0.0-beta.2) (2021-04-06)
139
-
140
-
141
- ### Bug Fixes
142
-
143
- * fix checkbox in firefox, fix [#251](https://github.com/ueberdosis/tiptap/issues/251) ([5622dec](https://github.com/ueberdosis/tiptap/commit/5622deca30397170bae341a000b9fe4693280c9b))
144
-
145
-
146
-
147
-
148
-
149
- # [2.0.0-beta.1](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.12...@tiptap/extension-task-item@2.0.0-beta.1) (2021-03-05)
150
-
151
- **Note:** Version bump only for package @tiptap/extension-task-item
152
-
153
-
154
-
155
-
156
-
157
- # [2.0.0-alpha.12](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.11...@tiptap/extension-task-item@2.0.0-alpha.12) (2021-02-16)
158
-
159
- **Note:** Version bump only for package @tiptap/extension-task-item
160
-
161
-
162
-
163
-
164
-
165
- # [2.0.0-alpha.11](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.10...@tiptap/extension-task-item@2.0.0-alpha.11) (2021-02-07)
166
-
167
- **Note:** Version bump only for package @tiptap/extension-task-item
168
-
169
-
170
-
171
-
172
-
173
- # [2.0.0-alpha.10](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.9...@tiptap/extension-task-item@2.0.0-alpha.10) (2021-02-05)
174
-
175
- **Note:** Version bump only for package @tiptap/extension-task-item
176
-
177
-
178
-
179
-
180
-
181
- # [2.0.0-alpha.9](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.8...@tiptap/extension-task-item@2.0.0-alpha.9) (2021-01-29)
182
-
183
- **Note:** Version bump only for package @tiptap/extension-task-item
184
-
185
-
186
-
187
-
188
-
189
- # [2.0.0-alpha.8](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.7...@tiptap/extension-task-item@2.0.0-alpha.8) (2021-01-29)
190
-
191
- **Note:** Version bump only for package @tiptap/extension-task-item
192
-
193
-
194
-
195
-
196
-
197
- # [2.0.0-alpha.7](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.6...@tiptap/extension-task-item@2.0.0-alpha.7) (2021-01-28)
198
-
199
- **Note:** Version bump only for package @tiptap/extension-task-item
200
-
201
-
202
-
203
-
204
-
205
- # [2.0.0-alpha.6](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.5...@tiptap/extension-task-item@2.0.0-alpha.6) (2020-12-18)
206
-
207
- **Note:** Version bump only for package @tiptap/extension-task-item
208
-
209
-
210
-
211
-
212
-
213
- # [2.0.0-alpha.5](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.4...@tiptap/extension-task-item@2.0.0-alpha.5) (2020-12-02)
214
-
215
- **Note:** Version bump only for package @tiptap/extension-task-item
216
-
217
-
218
-
219
-
220
-
221
- # [2.0.0-alpha.4](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.3...@tiptap/extension-task-item@2.0.0-alpha.4) (2020-12-02)
222
-
223
- **Note:** Version bump only for package @tiptap/extension-task-item
224
-
225
-
226
-
227
-
228
-
229
- # [2.0.0-alpha.3](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.2...@tiptap/extension-task-item@2.0.0-alpha.3) (2020-11-19)
230
-
231
- **Note:** Version bump only for package @tiptap/extension-task-item
232
-
233
-
234
-
235
-
236
-
237
- # [2.0.0-alpha.2](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@2.0.0-alpha.1...@tiptap/extension-task-item@2.0.0-alpha.2) (2020-11-19)
238
-
239
- **Note:** Version bump only for package @tiptap/extension-task-item
240
-
241
-
242
-
243
-
244
-
245
- # [2.0.0-alpha.1](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@1.0.0-alpha.2...@tiptap/extension-task-item@2.0.0-alpha.1) (2020-11-18)
246
-
247
- **Note:** Version bump only for package @tiptap/extension-task-item
248
-
249
-
250
-
251
-
252
-
253
- # [1.0.0-alpha.2](https://github.com/ueberdosis/tiptap/compare/@tiptap/extension-task-item@1.0.0-alpha.1...@tiptap/extension-task-item@1.0.0-alpha.2) (2020-11-16)
254
-
255
- **Note:** Version bump only for package @tiptap/extension-task-item
256
-
257
-
258
-
259
-
260
-
261
- # 1.0.0-alpha.1 (2020-11-16)
262
-
263
-
264
- ### Reverts
265
-
266
- * Revert "use global namespace" ([0c9ce26](https://github.com/ueberdosis/tiptap/commit/0c9ce26c02c07d88a757c01b0a9d7f9e2b0b7502))
package/LICENSE.md DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2021, überdosis GbR
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.