Skip to content

Task List

The TaskList node provides a block-level checkbox list container (<ul data-type="taskList">). It uses a data-type attribute to distinguish from regular bullet lists, and includes markdown-style input rules ([ ] for unchecked, [x] for checked), a keyboard shortcut (Mod-Shift-9), and automatic inclusion of the TaskItem node.

Type [ ] (brackets with space) at the start of a line for an unchecked task, or [x] for a checked task. Use Mod-Shift-9 to toggle. Press Mod-Enter to toggle the checked state.

Click to try it out

TaskList is included in StarterKit. If you are building a custom setup without StarterKit, add it manually:

import { Editor, Document, Text, Paragraph, TaskList } from '@domternal/core';
const editor = new Editor({
element: document.getElementById('editor')!,
extensions: [Document, Text, Paragraph, TaskList],
content: `
<ul data-type="taskList">
<li data-type="taskItem" data-checked="false">
<label contenteditable="false"><input type="checkbox"></label>
<div><p>Unchecked task</p></div>
</li>
<li data-type="taskItem" data-checked="true">
<label contenteditable="false"><input type="checkbox" checked></label>
<div><p>Checked task</p></div>
</li>
</ul>
`,
});
PropertyValue
ProseMirror nametaskList
TypeNode
Groupblock list
ContenttaskItem+ (one or more task items)
HTML tag<ul data-type="taskList">

The data-type="taskList" attribute distinguishes this from a regular <ul> (BulletList). The parse rule uses priority: 51 to ensure it takes precedence over the BulletList parser when both are present.

OptionTypeDefaultDescription
HTMLAttributesRecord<string, unknown>{}HTML attributes added to the <ul> element
itemTypeNamestring'taskItem'Name of the task item node type used by toggleList
import { TaskList } from '@domternal/core';
const CustomTaskList = TaskList.configure({
HTMLAttributes: { class: 'my-task-list' },
});
CommandDescription
toggleTaskList()Toggle the current selection between task list and paragraph
// Toggle task list on/off
editor.commands.toggleTaskList();
// With chaining
editor.chain().focus().toggleTaskList().run();

toggleTaskList wraps the selected blocks in a task list with task items. If the selection is already inside a task list, it unwraps it back to paragraphs. If the selection is inside a different list type (bullet list, ordered list), it converts it to a task list.

ShortcutCommand
Mod-Shift-9toggleTaskList()
EnterSplit task item at cursor, or lift out of list if empty
TabIndent task item (sink)
Shift-TabOutdent task item (lift)
Mod-EnterToggle checked state of current task item

The Enter, Tab, Shift-Tab, and Mod-Enter shortcuts are provided by the TaskItem node, which is automatically included when you add TaskList.

InputResult
[ ] + spaceUnchecked task item
[x] + spaceChecked task item
[X] + spaceChecked task item

Type the bracket pattern at the start of a new line, then press space. The line wraps in a task list. These input rules only fire outside of existing lists - typing [ ] inside a list item inserts the characters as plain text. To nest lists, use Tab to indent.

TaskList registers a button in the toolbar with the name taskList in group lists at priority 170.

ItemCommandIconShortcut
Task ListtoggleTaskListlistChecksMod-Shift-9

TaskList automatically includes this extension via addExtensions():

ExtensionDescription
TaskItemThe checkbox <li> node used inside the task list

This means adding TaskList to your extensions array is sufficient. You don’t need to add TaskItem separately.

{
"type": "taskList",
"content": [
{
"type": "taskItem",
"attrs": { "checked": false },
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Unchecked task" }
]
}
]
},
{
"type": "taskItem",
"attrs": { "checked": true },
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Completed task" }
]
}
]
}
]
}

@domternal/core - TaskList.ts