List
'use client';
import React from 'react';
import { withProps } from '@udecode/cn';
import { Plate, PlateElement } from '@udecode/plate/react';
import {
BulletedListPlugin,
ListItemPlugin,
ListPlugin,
NumberedListPlugin,
TodoListPlugin,
} from '@udecode/plate-list/react';
import { autoformatListPlugin } from '@/components/editor/plugins/autoformat-list-plugin';
import { editorPlugins } from '@/components/editor/plugins/editor-plugins';
import { FixedToolbarListPlugin } from '@/components/editor/plugins/fixed-toolbar-list-plugin';
import { useCreateEditor } from '@/components/editor/use-create-editor';
import { listValue } from '@/components/values/list-value';
import { Editor, EditorContainer } from '@/components/plate-ui/editor';
import { ListElement } from '@/components/plate-ui/list-element';
import { TodoListElement } from '@/components/plate-ui/todo-list-element';
export default function ListDemo() {
const editor = useCreateEditor({
components: {
[BulletedListPlugin.key]: withProps(ListElement, { variant: 'ul' }),
[ListItemPlugin.key]: withProps(PlateElement, { as: 'li' }),
[NumberedListPlugin.key]: withProps(ListElement, { variant: 'ol' }),
[TodoListPlugin.key]: TodoListElement,
},
plugins: [
...editorPlugins,
ListPlugin,
TodoListPlugin,
FixedToolbarListPlugin,
autoformatListPlugin,
],
value: listValue,
});
return (
<Plate editor={editor}>
<EditorContainer variant="demo">
<Editor />
</EditorContainer>
</Plate>
);
}
Plate offers two approaches for implementing lists:
-
This List plugin - Traditional HTML-spec lists with strict nesting rules:
- Follows standard HTML list structure (
ul
/ol
>li
) - Maintains consistent list hierarchy
- Best for content that may be exported to HTML/markdown
- Highest complexity
- Follows standard HTML list structure (
-
The Indent List plugin - Flexible indentation-based lists:
- More like Word/Google Docs behavior
- Any block can be indented to create list-like structures
- Used in the AI editor
- Better for free-form content organization
Choose based on your needs:
- Use the List plugin when you need standard HTML list compatibility
- Use the Indent List plugin when you want more flexible indentation behavior
Features
-
HTML-compliant lists:
- Standard
ul
/ol
>li
structure - Proper nesting and hierarchy
- SEO-friendly markup
- Clean HTML/markdown export
- Standard
-
List types:
- Unordered (bulleted) lists
- Ordered (numbered) lists
- Todo lists with checkboxes
- Nested sublists
-
Drag & drop:
- Currently supports root-level list items only
- Sibling and nested items drag & drop not yet supported
-
Shortcuts:
- Combined with the autoformat plugin, use markdown shortcuts (
-
,*
,1.
) to create lists - Tab/Shift+Tab for indentation control
- Combined with the autoformat plugin, use markdown shortcuts (
-
Limitations (use Indent List for these features):
- Drag & drop only supports root-level lists
- List items cannot be aligned
For a more flexible, Word-like approach, see the Indent List plugin.
Installation
npm install @udecode/plate-list
Usage
import { ListPlugin } from '@udecode/plate-list/react';
const plugins = [
// ...otherPlugins,
ListPlugin,
];
Keyboard Shortcuts
Key | Description |
---|---|
Cmd + Opt + 4 | Insert a numbered list. |
Cmd + Shift + 4 | Insert a numbered list. |
Plugins
ListPlugin
BulletedListPlugin
Plugin for unordered (bulleted) lists.
NumberedListPlugin
Plugin for ordered (numbered) lists.
ListItemPlugin
Plugin for list items.
ListItemContentPlugin
Plugin for list item content.
API
editor.tf.toggle.list
Toggles a list in the editor.
getHighestEmptyList
Finds the highest end list that can be deleted. The path of the list should be different from diffListPath
. If the highest end list has 2 or more items, returns liPath
. It traverses up the parent lists until:
- The list has less than 2 items
- Its path is not equal to
diffListPath
getListItemEntry
Returns the nearest li
and ul
/ol
wrapping node entries for a given path (default = selection
).
getListRoot
Searches upward for root list element.
getListTypes
Gets array of supported list types.
moveListSiblingsAfterCursor
Moves list siblings after cursor to specified path.
removeFirstListItem
Removes first list item if not nested and not first child.
removeListItem
Removes list item and moves sublist to parent if any.
someList
Checks if selection is inside list of specific type.
unindentListItems
Decreases indentation level of list items.
unwrapList
Removes list formatting from selected items.
Hooks
useListToolbarButton
A behavior hook for a list toolbar button.
Todo List API
getTodoListItemEntry
Gets nearest todo list and item entries.
useTodoListElement
A behavior hook a todo list item element.