From zbeyens. The source code is available on GitHub.

Plate
PlatePliteEditorsTemplates
GitHub16kGitHub
DiscordDiscord
    • Stream
    • Copilot
  • Discussion
    • Comments
    • Suggestion
    • Basic Blocks
      • Blockquote
      • Heading
      • Horizontal Rule
    • Callout
    • Code Block
    • Column
    • Date
    • Equation
    • Link
    • List Classic
    • Media
    • MentionElement
    • Table
    • Table of Contents
    • Footnote
    • Toggle
  • 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
    • Cursor Overlay
    • 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 { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  plugins: [...ListKit],
});
import { ListKit } from '@/components/editor/list';
import { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  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(element).

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/list';
import { ListPlugin } from '@platejs/list/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();
import { ListStyle, ListType } from '@platejs/list';
import { ListPlugin } from '@platejs/list/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

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 deserializes as listRestart. Markdown cannot retain the conditional-versus-forced distinction. Task checkboxes map to listType task plus checked.

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.
read.ordinal(element)Derive a numbered item's display ordinal.
}],
},
];
({ type: ListType.Bulleted });
list.update.outdent();