Plate
PlateEditorsTemplates
GitHub16kGitHub
DiscordDiscord
    • Stream
    • Copilot
  • Comments
  • Discussion
  • Suggestions
    • Basic Blocks
      • Blockquote
      • Heading
      • Horizontal Rule
    • Callout
    • Code Block
    • Column
    • Date
    • Equation
    • Link
    • Media
    • MentionElement
    • Table
    • Table of Contents
    • Footnote
    • Details
  • Marks
    • Bold
    • Italic
    • Underline
    • Code
    • Highlight
    • Keyboard Input
    • Strikethrough
    • Subscript
    • Superscript
      • Font
      • Line Height
      • Text Align
    • Indent
    • List
      • Exit Break
      • Single Block
      • Trailing Block
    • Autoformat
    • Block Menu
    • Block Placeholder
    • Combobox
      • Emoji
      • MentionElement
      • Slash Command
    • Drag & Drop
    • Navigation Feedback
    • Tabbable
    • Toolbar
    • Yjs
    • Multi SelectEditor
    • CSV
    • DOCX
    • HTML
    • Markdown

List

PreviousNext

Flat semantic list items with derived numbering.

List Toolbar Button

List turns supported blocks into flat list items. Kind, marker style, explicit numbering boundaries, task state, and indentation are separate fields.

Loading…
IndentExit Break

On This Page

FeaturesKit usageValueCommandsHTML and MarkdownAPI Reference
Build your editor
Production-ready AI template and reusable components.
Get all-access

Features

  • listType is bulleted, numbered, or task.
  • listStyle optionally selects a CSS marker.
  • listStart stores a conditional start that applies only while the item is first in its sequence.
  • listRestart forces a numbered-list boundary at that item.
  • checked belongs to task items.
  • Display ordinals are derived without rewriting following nodes.
  • Markdown rules cover bullets, numbers, and tasks.
Report an issue

Kit usage

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

Value

const value = [
  {
    type: 'paragraph',
    listType: 'numbered',
    listStart: 4,
    indent: 1,
    children: [{ text: 'Four' }],
  },
  {
    type: 'paragraph',
    listType: 'numbered',
    indent: 1,
    children: [{ text: 'Five' }],
  },
  {
    type: 'paragraph',
    listType: 'task',
    checked: false,
    indent: 1,
    children: [{ text: 'Ship it' }],
  },
];
const value = [
  {
    type: 'paragraph',
    listType: 'numbered',
    listStart: 4,
    indent: 1,
    children: [{ text: 'Four' }],
  },
  {
    type: 'paragraph',
    listType: 'numbered',
    indent: 1,
    children: [{ text: 'Five' }],
  },
  {
    type: 'paragraph',
    listType: 'task',
    checked: false,
    indent: 1,
    children: [{ text: 'Ship it'

The second item does not store 5. Plate derives it with editor.read.list.ordinal(at), where at is the item's path, node or key; a static renderer that already knows the path passes it.

listStart is latent author intent. Plate ignores it while a compatible previous item exists, keeps it in the document, and applies it if later edits make that item first. Use listRestart when the item must begin a new sequence even with a compatible predecessor.

Both fields are signed safe integers, so zero and negative ordered-list starts remain valid.

Commands

import { ListStyle, ListType } from 'platejs';
import { ListPlugin } from 'platejs/react';
 
const list = editor.plugin(ListPlugin);
 
list.update.toggle({ type: ListType.Bulleted });
list.update.toggle({
  type: ListType.Bulleted,
  listStyle: ListStyle.Square,
});
list.update.toggle({
  type: ListType.Numbered,
  listStart: 4,
});
list.update.toggle({
  type: ListType.Numbered,
  listRestart: 4,
});
list.update.toggle({ type: ListType.Task });
 
list.update.indent({ type: ListType.Bulleted });
list.update.outdent();
list.update.clear();
list.update.insert({ type: ListType.Numbered }, { replaceEmpty: true, select: true });
import { ListStyle, ListType } from 'platejs';
import { ListPlugin } from 'platejs/react';
 
const list = editor.plugin(ListPlugin);
 
list.update.toggle({ type: ListType.Bulleted });
list.update.toggle({
  type: ListType.Bulleted,
  listStyle: ListStyle.Square,
});
list.update.toggle({
  type: ListType.Numbered,
  listStart: 4,
});
list.update.toggle({
  type: ListType.Numbered,
  listRestart: 4,
});
list.update.toggle({ type: ListType.Task });
 
list.update.


clear removes list fields and indentation from the selected list items without expanding to their unselected siblings. It preserves each block's type and text. Pass at to target a location or node selection. insert creates a paragraph list item after the current block; replaceEmpty replaces an empty source in the same history step. An explicit at keeps node-insertion placement, while after identifies the block to insert beside.

HTML and Markdown

HTML ul and ol tags map to listType. Explicit CSS list-style-type maps to listStyle. A natural ol start maps to listStart; a following compatible ol boundary maps to listRestart. Plate clipboard HTML carries both fields in private list metadata.

MDAST list.ordered maps to listType. Both start policies serialize as the currently visible list.start, and a non-default structural MDAST start parses as listRestart. Markdown cannot retain the conditional-versus-forced distinction. Task checkboxes map to task listType plus checked. Inside a GFM table cell, list paragraphs are written as inline <ul>, <ol start>, and <li> HTML and read back as lists; see Markdown.

API Reference

APIPurpose
ListTypeSemantic bulleted, numbered, and task constants.
ListStyleCSS marker constants.
update.toggle(options)Set or remove list semantics.
update.indent(options)Increase indentation and set list semantics.
update.outdent(options)Decrease indentation and clear list fields at the outer level.
update.clear(options?)Remove list semantics from the exact selected list items.
update.insert(input, options?)Insert a list item with owned construction and placement.
read.ordinal(at)Derive a numbered item's display ordinal, or undefined when at is not a numbered item in the editor's root.
}],
},
];
indent
({ type: ListType.Bulleted });
list.update.outdent();
list.update.clear();
list.update.insert({ type: ListType.Numbered }, { replaceEmpty: true, select: true });