Back to Plate

Block Menu

content/docs/(plugins)/(functionality)/block-menu.mdx

53.0.86.2 KB
Original Source

Block Menu adds a right-click menu on top of block selection. BlockMenuPlugin owns the open state and pointer position; BlockSelectionPlugin decides which blocks the menu edits. The registry BlockContextMenu renders the menu actions.

<ComponentPreview name="block-menu-demo" /> <PackageInfo>

Features

  • Right-click block selection.
  • Context menu open state through openId and position.
  • Delete, duplicate, turn-into, indent, outdent, align, and Ask AI actions.
  • Touch-device and read-only guards.
  • Element-level opt in/out with data-plate-open-context-menu.
  • Plus menu with drag-handle entry, combobox filtering, nested actions, colors, comments, and AI.
</PackageInfo>

Fast Path

<Steps>

Add The Kit

BlockMenuKit spreads BlockSelectionKit and renders BlockContextMenu above the editable.

<ComponentSource name="block-menu-kit" />
tsx
import { createPlateEditor } from 'platejs/react';

import { BlockMenuKit } from '@/components/editor/plugins/block-menu-kit';

export const editor = createPlateEditor({
  plugins: BlockMenuKit,
});

Render The Menu

block-context-menu is the registry UI used by the kit.

<ComponentSource name="block-context-menu" />

Try The Plus Menu

<ComponentPreviewPro name="block-menu-pro" /> </Steps>

Ownership

SurfaceOwnerWhat It Does
BlockMenuPlugin@platejs/selection/reactStores openId and pointer position, then exposes menu show/hide APIs.
BlockSelectionPlugin@platejs/selection/reactSelects the block under the context-menu event and applies actions to selected blocks.
BlockSelectionKitRegistryEnables context-menu selection and filters non-selectable blocks such as columns, code lines, and table cells.
BlockMenuKitRegistryCombines BlockSelectionKit with BlockMenuPlugin.render.aboveEditable.
BlockContextMenuRegistry UIRenders Radix context-menu items and calls block-selection transforms.
block-menu-demoRegistry exampleShows the default menu in the full editor.
block-menu-proPlus exampleAdds drag-handle entry, nested filtering, colors, comments, and AI actions.

The menu is UI state, not document state. The document stores block ids and node properties; it does not store whether a menu is open.

Manual Setup

<Steps>

Install Packages

bash
npm install @platejs/selection @platejs/ai

@platejs/ai is needed only when you keep the Ask AI item from the registry menu.

Add Plugins

Use BlockSelectionKit when you want to keep the registry selection behavior but replace the menu wiring.

tsx
import { BlockMenuPlugin } from '@platejs/selection/react';
import { createPlateEditor } from 'platejs/react';

import { BlockSelectionKit } from '@/components/editor/plugins/block-selection-kit';
import { BlockContextMenu } from '@/components/ui/block-context-menu';

export const editor = createPlateEditor({
  plugins: [
    ...BlockSelectionKit,
    BlockMenuPlugin.configure({
      render: { aboveEditable: BlockContextMenu },
    }),
  ],
});

Use this lower-level shape only when you are replacing both registry kits.

tsx
import {
  BlockMenuPlugin,
  BlockSelectionPlugin,
} from '@platejs/selection/react';
import { createPlateEditor } from 'platejs/react';

import { BlockContextMenu } from '@/components/ui/block-context-menu';

export const editor = createPlateEditor({
  plugins: [
    BlockSelectionPlugin.configure({
      options: {
        enableContextMenu: true,
      },
    }),
    BlockMenuPlugin.configure({
      render: { aboveEditable: BlockContextMenu },
    }),
  ],
});
</Steps>

Context Menu Rules

CaseBehavior
Right-click on a selectable blockSelects that block, then opens the context menu at the pointer position.
Shift + right-clickAdds the block to the current block selection.
Right-click inside a focused text selectionLeaves the browser context menu unless the block is already selected, void, or explicitly opted in.
Left-click while the menu is openPrevents the click and hides the menu.
Touch deviceRenders children without the context-menu wrapper.
Read-only editorPrevents the context menu.

Disable the Plate context menu for a specific surface with data-plate-open-context-menu={false}.

tsx
<PlateElement data-plate-open-context-menu={false} {...props}>
  {children}
</PlateElement>

Force it open from a focused block with data-plate-open-context-menu="true" when the block should bypass the focused-selection guard.

BlockContextMenu acts on the current block selection.

ActionSource
Ask AIOpens AIChatPlugin after the menu closes.
DeleteCalls editor.getTransforms(BlockSelectionPlugin).blockSelection.removeNodes().
DuplicateCalls editor.getTransforms(BlockSelectionPlugin).blockSelection.duplicate().
Turn intoCalls the registry setBlockType helper for paragraph, headings, blockquote, and code drawing.
Indent / OutdentCalls blockSelection.setIndent(1) or blockSelection.setIndent(-1).
AlignCalls blockSelection.setNodes({ align }).

The menu focuses block selection after close so keyboard selection remains active.

API Reference

APIPackageUse
BLOCK_CONTEXT_MENU_ID@platejs/selection/reactBuilt-in open id for the registry context menu.
BlockMenuPlugin@platejs/selection/reactMenu state plugin with openId and position options.
api.blockMenu.hide()@platejs/selection/reactCloses the menu and moves its stored position offscreen.
api.blockMenu.show(id, position?)@platejs/selection/reactOpens a menu by id and optionally sets pointer coordinates.
api.blockMenu.showContextMenu(blockId, position)@platejs/selection/reactSelects one block by id, then opens the context menu at the pointer coordinates.
BlockSelectionPlugin.options.enableContextMenu@platejs/selection/reactEnables block selection from right-click events.
api.blockSelection.addOnContextMenu@platejs/selection/reactShared right-click handler used by selectable block node props.
BlockContextMenuRegistry UIDefault context menu component used by BlockMenuKit.