Loading...
Files
components/demo.tsx
'use client';

import * as React from 'react';

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

import { EditorKit } from '@/components/editor/editor-kit';
import { Editor, EditorContainer } from '@/components/ui/editor';

import { DEMO_VALUES } from './values/demo-values';

export default function Demo({ id }: { id: string }) {
  const editor = usePlateEditor({
    plugins: EditorKit,
    value: DEMO_VALUES[id],
  });

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

Features

  • Automatically generates a table of contents from document headings
  • Smooth scrolling to headings

Kit Usage

Installation

The fastest way to add table of contents functionality is with the TocKit, which includes pre-configured TocPlugin with the Plate UI component.

'use client';
 
import { TocPlugin } from '@platejs/toc/react';
 
import { TocElement } from '@/components/ui/toc-node';
 
export const TocKit = [
  TocPlugin.configure({
    options: {
      // isScroll: true,
      topOffset: 80,
    },
  }).withComponent(TocElement),
];

Add Kit

Add the kit to your plugins:

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

Manual Usage

Installation

pnpm add @platejs/basic-nodes @platejs/toc

Add Plugins

Include TocPlugin and HnPlugin in your Plate plugins array when creating the editor.

import { TocPlugin } from '@platejs/toc/react';
import { H1Plugin, H2Plugin, H3Plugin } from '@platejs/basic-nodes/react';
import { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    H1Plugin,
    H2Plugin,
    H3Plugin,
    TocPlugin,
  ],
});

Configure Plugin

Configure the TocPlugin with custom component and scroll options.

import { TocPlugin } from '@platejs/toc/react';
import { H1Plugin, H2Plugin, H3Plugin } from '@platejs/basic-nodes/react';
import { createPlateEditor } from 'platejs/react';
import { TocElement } from '@/components/ui/toc-node';
import { H1Element, H2Element, H3Element } from '@/components/ui/heading-node';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    H1Plugin.withComponent(H1Element),
    H2Plugin.withComponent(H2Element),
    H3Plugin.withComponent(H3Element),
    TocPlugin.configure({
      node: { component: TocElement },
      options: {
        topOffset: 80,
        isScroll: true,
      },
    }),
  ],
});
  • node.component: Assigns TocElement to render table of contents elements.
  • options.topOffset: Sets the top offset when scrolling to headings.
  • options.isScroll: Enables scrolling behavior to headings.

Insert Toolbar Button

You can add this item to the Insert Toolbar Button to insert table of contents elements:

{
  icon: <TableOfContentsIcon />,
  label: 'Table of contents',
  value: KEYS.toc,
}

Scroll Container Setup

  • If your scrolling element is EditorContainer, you can skip this step.
  • If your scrolling element is the editor container, pass useEditorContainerRef() as the ref prop. For example:
// Below <Plate> component
function EditorContainer({ children }: { children: React.ReactNode }) {
  const containerRef = useEditorContainerRef();
 
  return <div ref={containerRef}>{children}</div>;
}
  • If your scrolling element is an ancestor of the editor container, pass useEditorScrollRef() as the ref prop. For example:
// Below <Plate> component
function Layout() {
  const scrollRef = useEditorScrollRef();
 
  return (
    <main ref={scrollRef}>
      <EditorContainer>
        <PlateContent />
      </EditorContainer>
    </main>
  );
}

Plate Plus

  • Sticky TOC sidebar
  • Hover-to-expand: Opens automatically when you move your mouse over it
  • Interactive navigation: Click on items to smoothly scroll to the corresponding heading
  • Visual feedback: Highlights the current section in the sidebar
  • Beautifully crafted UI

Plugins

TocPlugin

Plugin for generating table of contents.

Options

Collapse all

    Enable scrolling behavior.

    • Default: true

    Top offset when scrolling to heading.

    • Default: 80

    Custom function to query headings.

Transforms

tf.insertToc

Insert table of contents element.

OptionsInsertNodesOptions<SlateEditor>

    Node insertion options.

Hooks

useTocElementState

Manage TOC element state.

Returns

Collapse all

    Document headings array.

    Heading scroll handler.

useTocElement

Handle TOC element interactions.

Parameters

Collapse all

    Scroll handler from useTocElementState.

Returns

Collapse all

    Props for TOC element.

useTocSideBarState

Manage TOC sidebar state.

Parameters

Collapse all

    Initial open state.

    • Default: true

    Intersection Observer root margin.

    • Default: '0px 0px 0px 0px'

    Scroll top offset.

    • Default: 0

Returns

Collapse all

    Active section ID.

    Document headings.

    Mouse over TOC state.

    Sidebar open state.

    Set observation state.

    Set mouse over state.

    TOC element ref.

    Content scroll handler.

useTocSideBar

This hook provides props and handlers for the TOC sidebar component.

Parameters

Collapse all

    Mouse over TOC state.

    Sidebar open state.

    Set observation state.

    Set mouse over state.

    TOC element ref.

    Content scroll handler.

Returns

Collapse all

    Navigation element props.

    navProps.onContentClick (e: React.MouseEvent<HTMLElement, MouseEvent>, item: Heading, behavior?: ScrollBehavior) => void

    TOC item click handler.