diff --git a/examples/Components/Routes/TodoList/index.vue b/examples/Components/Routes/TodoList/index.vue index cd144ceb2..c987ad30e 100644 --- a/examples/Components/Routes/TodoList/index.vue +++ b/examples/Components/Routes/TodoList/index.vue @@ -69,7 +69,9 @@ export default { new CodeBlock(), new HardBreak(), new Heading({ levels: [1, 2, 3] }), - new TodoItem(), + new TodoItem({ + nested: true, + }), new TodoList(), new Bold(), new Code(), @@ -135,14 +137,23 @@ li[data-type="todo_item"] { .todo-content { flex: 1; + > p:last-of-type { + margin-bottom: 0; + } + > ul[data-type="todo_list"] { + margin: .5rem 0; + } } li[data-done="true"] { - text-decoration: line-through; -} - -li[data-done="true"] .todo-checkbox { - background-color: $color-black; + > .todo-content { + > p { + text-decoration: line-through; + } + } + > .todo-checkbox { + background-color: $color-black; + } } li[data-done="false"] { diff --git a/packages/tiptap-commands/package.json b/packages/tiptap-commands/package.json index 494f8e452..cf5741e64 100644 --- a/packages/tiptap-commands/package.json +++ b/packages/tiptap-commands/package.json @@ -24,6 +24,7 @@ "prosemirror-inputrules": "^1.0.1", "prosemirror-schema-list": "^1.0.3", "prosemirror-state": "^1.2.2", + "prosemirror-model": "^1.7.0", "tiptap-utils": "^1.4.1" } } diff --git a/packages/tiptap-commands/src/commands/splitToDefaultListItem.js b/packages/tiptap-commands/src/commands/splitToDefaultListItem.js index 948bf4563..7fe95f8e2 100644 --- a/packages/tiptap-commands/src/commands/splitToDefaultListItem.js +++ b/packages/tiptap-commands/src/commands/splitToDefaultListItem.js @@ -1,3 +1,5 @@ +import { Fragment, Slice } from 'prosemirror-model' + // this is a copy of canSplit // see https://github.com/ProseMirror/prosemirror-transform/blob/master/src/structure.js diff --git a/packages/tiptap-extensions/src/nodes/TodoItem.js b/packages/tiptap-extensions/src/nodes/TodoItem.js index fdbf6bdd9..cde441167 100644 --- a/packages/tiptap-extensions/src/nodes/TodoItem.js +++ b/packages/tiptap-extensions/src/nodes/TodoItem.js @@ -1,5 +1,5 @@ import { Node } from 'tiptap' -import { splitToDefaultListItem, liftListItem } from 'tiptap-commands' +import { sinkListItem, splitToDefaultListItem, liftListItem } from 'tiptap-commands' export default class TodoItem extends Node { @@ -7,6 +7,12 @@ export default class TodoItem extends Node { return 'todo_item' } + get defaultOptions() { + return { + nested: false, + } + } + get view() { return { props: ['node', 'updateAttrs', 'editable'], @@ -34,7 +40,7 @@ export default class TodoItem extends Node { }, }, draggable: true, - content: 'paragraph', + content: this.options.nested ? '(paragraph|todo_list)+' : 'paragraph+', toDOM: node => { const { done } = node.attrs @@ -61,6 +67,7 @@ export default class TodoItem extends Node { keys({ type }) { return { Enter: splitToDefaultListItem(type), + Tab: this.options.nested ? sinkListItem(type) : () => {}, 'Shift-Tab': liftListItem(type), } } diff --git a/packages/tiptap-extensions/src/nodes/TodoList.js b/packages/tiptap-extensions/src/nodes/TodoList.js index 73c8c1545..d36543a7c 100644 --- a/packages/tiptap-extensions/src/nodes/TodoList.js +++ b/packages/tiptap-extensions/src/nodes/TodoList.js @@ -1,5 +1,5 @@ import { Node } from 'tiptap' -import { wrapInList, wrappingInputRule } from 'tiptap-commands' +import { toggleList, wrappingInputRule } from 'tiptap-commands' export default class TodoList extends Node { @@ -19,8 +19,8 @@ export default class TodoList extends Node { } } - commands({ type }) { - return () => wrapInList(type) + commands({ type, schema }) { + return () => toggleList(type, schema.nodes.todo_item) } inputRules({ type }) {