Task item extension for Tiptap - enables interactive checkbox list items in rich text editors
npx @tessl/cli install tessl/npm-tiptap--extension-task-item@3.4.0Task item extension for Tiptap - enables interactive checkbox list items in rich text editors. This extension allows developers to create todo lists, project management interfaces, and interactive documentation systems within Tiptap rich text editors.
npm install @tiptap/extension-task-itemimport TaskItem, { TaskItemOptions } from '@tiptap/extension-task-item';For CommonJS:
const TaskItem = require('@tiptap/extension-task-item').default;
const { TaskItemOptions } = require('@tiptap/extension-task-item');Named imports:
import { TaskItem, TaskItemOptions } from '@tiptap/extension-task-item';import { Editor } from '@tiptap/core';
import TaskItem from '@tiptap/extension-task-item';
const editor = new Editor({
extensions: [
TaskItem.configure({
nested: true,
HTMLAttributes: {
class: 'my-task-item',
},
}),
],
content: `
<li data-type="taskItem" data-checked="false">
<p>Unchecked task item</p>
</li>
<li data-type="taskItem" data-checked="true">
<p>Checked task item</p>
</li>
`,
});The @tiptap/extension-task-item package is built around:
Node.create() method, integrating with the ProseMirror document modelThe main extension constant for creating task item nodes with interactive checkboxes. TaskItem is created using Tiptap's Node.create() method.
const TaskItem: Node<TaskItemOptions>;Usage Examples:
import TaskItem from '@tiptap/extension-task-item';
// Basic usage
const taskItem = TaskItem;
// With configuration
const configuredTaskItem = TaskItem.configure({
nested: true,
HTMLAttributes: {
class: 'task-item',
'data-test': 'task-item-element',
},
taskListTypeName: 'myTaskList',
});
// Extended with custom behavior
const extendedTaskItem = TaskItem.extend({
addKeyboardShortcuts() {
return {
...this.parent?.(),
'Ctrl-Enter': () => {
// Custom keyboard shortcut
return this.editor.commands.splitListItem(this.name);
},
};
},
});Configuration options interface for customizing TaskItem behavior.
interface TaskItemOptions {
/** Callback for checkbox clicks in readonly mode */
onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean;
/** Controls whether task items can be nested */
nested: boolean;
/** HTML attributes to add to the task item element */
HTMLAttributes: Record<string, any>;
/** Node type name for taskList nodes */
taskListTypeName: string;
/** Accessibility options for the task item */
a11y?: {
checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string;
};
}Configuration Examples:
// Basic configuration
const basicOptions: TaskItemOptions = {
nested: false,
HTMLAttributes: {},
taskListTypeName: 'taskList',
};
// Advanced configuration with accessibility
const advancedOptions: TaskItemOptions = {
nested: true,
HTMLAttributes: {
class: 'interactive-task-item',
'data-testid': 'task-item',
},
taskListTypeName: 'customTaskList',
onReadOnlyChecked: (node, checked) => {
console.log(`Task "${node.textContent}" ${checked ? 'checked' : 'unchecked'}`);
return true; // Allow the change
},
a11y: {
checkboxLabel: (node, checked) =>
`${checked ? 'Completed' : 'Incomplete'} task: ${node.textContent || 'empty task'}`,
},
};The TaskItem node includes a single attribute for tracking checkbox state.
interface TaskItemAttributes {
/** Boolean indicating if the task item is checked */
checked: boolean;
}Regular expression constant for matching markdown-style task item input.
const inputRegex: RegExp; // /^\s*(\[([( |x])?\])\s$/The input regex matches patterns like:
- [ ] (unchecked task item)- [x] (checked task item)- [X] (checked task item - case insensitive)- [ ] with extra whitespaceCore methods available on the TaskItem extension for editor integration. These are internal methods that define the extension's behavior.
interface TaskItemExtensionMethods {
/** Defines allowed content structure based on nesting option */
content(): string;
/** Returns default configuration options */
addOptions(): TaskItemOptions;
/** Defines node attributes schema */
addAttributes(): Record<string, Attribute>;
/** HTML parsing rules for task item elements */
parseHTML(): Array<{ tag: string; priority?: number }>;
/** Renders task item node to HTML structure */
renderHTML(props: { node: ProseMirrorNode; HTMLAttributes: Record<string, any> }): DOMOutputSpec;
/** Keyboard shortcuts for task item navigation */
addKeyboardShortcuts(): Record<string, KeyboardShortcutCommand>;
/** Custom DOM node view with interactive checkbox */
addNodeView(): NodeViewRenderer;
/** Input rules for markdown-style task items */
addInputRules(): Array<InputRule>;
}Built-in keyboard shortcuts for task item navigation and manipulation.
nested: true)The TaskItem node renders to the following HTML structure:
<li data-type="taskItem" data-checked="false">
<label>
<input type="checkbox" />
<span></span>
</label>
<div>
<!-- Task item content goes here -->
</div>
</li>The extension handles several edge cases:
onReadOnlyChecked callback is providedonReadOnlyChecked callback can return false to reject state changes// Core type imports
import type { Node as ProseMirrorNode } from '@tiptap/pm/model';
import type { Node, KeyboardShortcutCommand, NodeViewRenderer, InputRule, DOMOutputSpec, Attribute } from '@tiptap/core';
// TaskItem configuration interface
interface TaskItemOptions {
/** Callback for checkbox clicks in readonly mode */
onReadOnlyChecked?: (node: ProseMirrorNode, checked: boolean) => boolean;
/** Controls whether task items can be nested */
nested: boolean;
/** HTML attributes to add to the task item element */
HTMLAttributes: Record<string, any>;
/** Node type name for taskList nodes */
taskListTypeName: string;
/** Accessibility options for the task item */
a11y?: {
checkboxLabel?: (node: ProseMirrorNode, checked: boolean) => string;
};
}
// TaskItem node extension constant
const TaskItem: Node<TaskItemOptions>;
// Input pattern constant for markdown-style task items
const inputRegex: RegExp;
// TaskItem node attributes
interface TaskItemAttributes {
checked: boolean;
}