Loading...
Files
components/list-classic-demo.tsx
'use client';

import * as React from 'react';

import { Plate, usePlateEditor } from 'platejs/react';

import { EditorKit } from '@/components/editor/editor-kit';
import { AutoformatKit } from '@/components/editor/plugins/autoformat-classic-kit';
import { FixedToolbarKit } from '@/components/editor/plugins/fixed-toolbar-classic-kit';
import { ListKit } from '@/components/editor/plugins/list-classic-kit';
import { listValue } from '@/registry/examples/values/list-classic-value';
import { Editor, EditorContainer } from '@/components/ui/editor';

export default function ListClassicDemo() {
  const editor = usePlateEditor({
    // Disable EditorKit's indent and list plugins
    override: {
      enabled: {
        indent: false,
        list: false,
      },
    },
    plugins: [...EditorKit, ...ListKit, ...FixedToolbarKit, ...AutoformatKit],
    value: listValue,
  });

  return (
    <Plate editor={editor}>
      <EditorContainer variant="demo">
        <Editor />
      </EditorContainer>
    </Plate>
  );
}

Choose Your List Plugin

Plate offers two approaches for implementing lists:

  1. This List Classic 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
  2. The 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
    • Supports nested todo lists
    • Better for free-form content organization

Choose based on your needs:

  • Use the List Classic plugin when you need standard HTML list compatibility
  • Use the 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
  • List types:

    • Unordered (bulleted) lists
    • Ordered (numbered) lists
    • 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
  • Limitations (use the List plugin for these features):

    • Drag & drop only supports root-level lists
    • List items cannot be aligned

For a more flexible, Word-like approach, see the List plugin.

Kit Usage

Installation

The fastest way to add list functionality is with the ListKit, which includes pre-configured list plugins with Plate UI components and keyboard shortcuts.

'use client';
 
import {
  BulletedListPlugin,
  ListItemPlugin,
  ListPlugin,
  NumberedListPlugin,
} from '@platejs/list-classic/react';
 
import {
  BulletedListElement,
  NumberedListElement,
} from '@/components/ui/list-classic-node';
 
export const ListKit = [
  ListPlugin,
  BulletedListPlugin.configure({
    node: { component: BulletedListElement },
    shortcuts: { toggle: { keys: 'mod+alt+5' } },
  }),
  NumberedListPlugin.configure({
    node: { component: NumberedListElement },
    shortcuts: { toggle: { keys: 'mod+alt+6' } },
  }),
  ListItemPlugin,
];

Add Kit

Add the kit to your plugins:

import { createPlateEditor } from 'platejs/react';
import { ListKit } from '@/components/editor/plugins/list-classic-kit';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    ...ListKit,
  ],
});

Manual Usage

Installation

pnpm add @platejs/list-classic

Add Plugins

Include the list plugins in your Plate plugins array when creating the editor.

import { ListPlugin, BulletedListPlugin, NumberedListPlugin, ListItemPlugin } from '@platejs/list-classic/react';
import { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    ListPlugin,
    BulletedListPlugin,
    NumberedListPlugin,
    ListItemPlugin,
  ],
});

Configure Plugins

Configure the plugins with custom components and keyboard shortcuts.

import { ListPlugin, BulletedListPlugin, NumberedListPlugin, ListItemPlugin } from '@platejs/list-classic/react';
import { createPlateEditor } from 'platejs/react';
import { BulletedListElement, NumberedListElement } from '@/components/ui/list-classic-node';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    ListPlugin,
    BulletedListPlugin.configure({
      node: { component: BulletedListElement },
      shortcuts: { toggle: { keys: 'mod+alt+5' } },
    }),
    NumberedListPlugin.configure({
      node: { component: NumberedListElement },
      shortcuts: { toggle: { keys: 'mod+alt+6' } },
    }),
    ListItemPlugin,
  ],
});

Add Toolbar Button

You can add ListToolbarButton to your Toolbar to create and manage lists.

Turn Into Toolbar Button

You can add these items to the Turn Into Toolbar Button to convert blocks into lists:

{
  icon: <ListIcon />,
  label: 'Bulleted list',
  value: KEYS.ul,
}
{
  icon: <ListOrderedIcon />,
  label: 'Numbered list',
  value: KEYS.ol,
}

Insert Toolbar Button

You can add these items to the Insert Toolbar Button to insert list elements:

{
  icon: <ListIcon />,
  label: 'Bulleted list',
  value: KEYS.ul,
}
{
  icon: <ListOrderedIcon />,
  label: 'Numbered list',
  value: KEYS.ol,
}

Plugins

ListPlugin

Contains the following element plugins:

  • BulletedListPlugin
  • NumberedListPlugin
  • ListItemPlugin
  • ListItemContentPlugin

Optionsobject

Collapse all

    Valid child node types for list items (besides p and ul).

    Whether Shift+Tab should reset list indent level.

BulletedListPlugin

Plugin for unordered (bulleted) lists.

NumberedListPlugin

Plugin for ordered (numbered) lists.

ListItemPlugin

Plugin for list items.

ListItemContentPlugin

Plugin for list item content.

Transforms

tf.ul.toggle()

Toggles a bulleted list (ul).

Example Shortcut: Mod+Alt+5

tf.ol.toggle()

Toggles an ordered list (ol).

Example Shortcut: Mod+Alt+6

API

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

Optionsobject

Collapse all

    Path of list item.

    Path of different list.

ReturnsPath | undefined

    Path of highest deletable end list.

getListItemEntry

Returns the nearest li and ul/ol wrapping node entries for a given path (default = selection).

Optionsobject

Collapse all

    Location to get entries from.

    • Default: editor.selection

ReturnsElementEntry | undefined

    Nearest li and ul/ol wrapping node entries.

getListRoot

Searches upward for root list element.

Parameters

Collapse all

    Location to start search from.

    • Default: editor.selection

ReturnsElementEntry | undefined

    Root list element entry.

getListTypes

Gets array of supported list types.

Returnsstring[]

    Array of supported list types.

moveListSiblingsAfterCursor

Moves list siblings after cursor to specified path.

Optionsoptions

Collapse all

    Cursor position path.

    Destination path.

Returnsnumber

    Number of siblings moved.

removeFirstListItem

Removes first list item if not nested and not first child.

Optionsoptions

Collapse all

    List entry containing item.

    List item to remove.

Returnsboolean

    Whether item was removed.

removeListItem

Removes list item and moves sublist to parent if any.

OptionsRemoveListItemOptions

Collapse all

    List entry containing item.

    List item to remove.

    Whether to reverse sublist items.

    • Default: true

Returnsboolean

    Whether item was removed.

someList

Checks if selection is inside list of specific type.

Parameters

Collapse all

    List type to check.

Returnsboolean

    Whether selection is in specified list type.

unindentListItems

Decreases indentation level of list items.

OptionsUnindentListItemsOptions

    Target path for unindenting.

unwrapList

Removes list formatting from selected items.

Optionsoptions

Collapse all

    Target path for unwrapping.

Hooks

useListToolbarButton

A behavior hook for a list toolbar button.

State

Collapse all

    Button pressed state.

    List node type.

    • Default: BulletedListPlugin.key

Returnsobject

Collapse all

    Props for toolbar button.