{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "block-menu-docs",
  "title": "Block Menu",
  "description": "Context-menu actions for selected editor blocks.",
  "files": [
    {
      "path": "../../content/docs/(plugins)/(functionality)/block-menu.mdx",
      "content": "---\ntitle: Block Menu\ndescription: Context-menu actions for selected editor blocks.\ndocs:\n  - route: /docs/block-selection\n    title: Block Selection\n  - route: /docs/components/block-context-menu\n    title: Block Context Menu\n  - route: /docs/examples/block-menu\n    title: Demo\n  - route: https://pro.platejs.org/docs/examples/block-menu\n    title: Plus\n---\n\nBlock 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.\n\n<ComponentPreview name=\"block-menu-demo\" />\n\n<PackageInfo>\n\n## Features\n\n- Right-click block selection.\n- Context menu open state through `openId` and `position`.\n- Delete, duplicate, turn-into, indent, outdent, align, and Ask AI actions.\n- Touch-device and read-only guards.\n- Element-level opt in/out with `data-plate-open-context-menu`.\n- Plus menu with drag-handle entry, combobox filtering, nested actions, colors, comments, and AI.\n\n</PackageInfo>\n\n## Fast Path\n\n<Steps>\n\n### Add The Kit\n\n`BlockMenuKit` spreads `BlockSelectionKit` and renders `BlockContextMenu` above the editable.\n\n<ComponentSource name=\"block-menu-kit\" />\n\n```tsx\nimport { createPlateEditor } from 'platejs/react';\n\nimport { BlockMenuKit } from '@/components/editor/plugins/block-menu-kit';\n\nexport const editor = createPlateEditor({\n  plugins: BlockMenuKit,\n});\n```\n\n### Render The Menu\n\n`block-context-menu` is the registry UI used by the kit.\n\n<ComponentSource name=\"block-context-menu\" />\n\n### Try The Plus Menu\n\n<ComponentPreviewPro name=\"block-menu-pro\" />\n\n</Steps>\n\n## Ownership\n\n| Surface | Owner | What It Does |\n|---------|-------|--------------|\n| `BlockMenuPlugin` | `@platejs/selection/react` | Stores `openId` and pointer `position`, then exposes menu show/hide APIs. |\n| `BlockSelectionPlugin` | `@platejs/selection/react` | Selects the block under the context-menu event and applies actions to selected blocks. |\n| `BlockSelectionKit` | Registry | Enables context-menu selection and filters non-selectable blocks such as columns, code lines, and table cells. |\n| `BlockMenuKit` | Registry | Combines `BlockSelectionKit` with `BlockMenuPlugin.render.aboveEditable`. |\n| `BlockContextMenu` | Registry UI | Renders Radix context-menu items and calls block-selection transforms. |\n| `block-menu-demo` | Registry example | Shows the default menu in the full editor. |\n| `block-menu-pro` | Plus example | Adds drag-handle entry, nested filtering, colors, comments, and AI actions. |\n\nThe menu is UI state, not document state. The document stores block ids and node properties; it does not store whether a menu is open.\n\n## Manual Setup\n\n<Steps>\n\n### Install Packages\n\n```bash\nnpm install @platejs/selection @platejs/ai\n```\n\n`@platejs/ai` is needed only when you keep the `Ask AI` item from the registry menu.\n\n### Add Plugins\n\nUse `BlockSelectionKit` when you want to keep the registry selection behavior but replace the menu wiring.\n\n```tsx\nimport { BlockMenuPlugin } from '@platejs/selection/react';\nimport { createPlateEditor } from 'platejs/react';\n\nimport { BlockSelectionKit } from '@/components/editor/plugins/block-selection-kit';\nimport { BlockContextMenu } from '@/components/ui/block-context-menu';\n\nexport const editor = createPlateEditor({\n  plugins: [\n    ...BlockSelectionKit,\n    BlockMenuPlugin.configure({\n      render: { aboveEditable: BlockContextMenu },\n    }),\n  ],\n});\n```\n\nUse this lower-level shape only when you are replacing both registry kits.\n\n```tsx\nimport {\n  BlockMenuPlugin,\n  BlockSelectionPlugin,\n} from '@platejs/selection/react';\nimport { createPlateEditor } from 'platejs/react';\n\nimport { BlockContextMenu } from '@/components/ui/block-context-menu';\n\nexport const editor = createPlateEditor({\n  plugins: [\n    BlockSelectionPlugin.configure({\n      options: {\n        enableContextMenu: true,\n      },\n    }),\n    BlockMenuPlugin.configure({\n      render: { aboveEditable: BlockContextMenu },\n    }),\n  ],\n});\n```\n\n</Steps>\n\n## Context Menu Rules\n\n| Case | Behavior |\n|------|----------|\n| Right-click on a selectable block | Selects that block, then opens the context menu at the pointer position. |\n| Shift + right-click | Adds the block to the current block selection. |\n| Right-click inside a focused text selection | Leaves the browser context menu unless the block is already selected, void, or explicitly opted in. |\n| Left-click while the menu is open | Prevents the click and hides the menu. |\n| Touch device | Renders children without the context-menu wrapper. |\n| Read-only editor | Prevents the context menu. |\n\nDisable the Plate context menu for a specific surface with `data-plate-open-context-menu={false}`.\n\n```tsx\n<PlateElement data-plate-open-context-menu={false} {...props}>\n  {children}\n</PlateElement>\n```\n\nForce it open from a focused block with `data-plate-open-context-menu=\"true\"` when the block should bypass the focused-selection guard.\n\n## Menu Actions\n\n`BlockContextMenu` acts on the current block selection.\n\n| Action | Source |\n|--------|--------|\n| Ask AI | Opens `AIChatPlugin` after the menu closes. |\n| Delete | Calls `editor.getTransforms(BlockSelectionPlugin).blockSelection.removeNodes()`. |\n| Duplicate | Calls `editor.getTransforms(BlockSelectionPlugin).blockSelection.duplicate()`. |\n| Turn into | Calls the registry `setBlockType` helper for paragraph, headings, blockquote, and code drawing. |\n| Indent / Outdent | Calls `blockSelection.setIndent(1)` or `blockSelection.setIndent(-1)`. |\n| Align | Calls `blockSelection.setNodes({ align })`. |\n\nThe menu focuses block selection after close so keyboard selection remains active.\n\n## API Reference\n\n| API | Package | Use |\n|-----|---------|-----|\n| `BLOCK_CONTEXT_MENU_ID` | `@platejs/selection/react` | Built-in open id for the registry context menu. |\n| `BlockMenuPlugin` | `@platejs/selection/react` | Menu state plugin with `openId` and `position` options. |\n| `api.blockMenu.hide()` | `@platejs/selection/react` | Closes the menu and moves its stored position offscreen. |\n| `api.blockMenu.show(id, position?)` | `@platejs/selection/react` | Opens a menu by id and optionally sets pointer coordinates. |\n| `api.blockMenu.showContextMenu(blockId, position)` | `@platejs/selection/react` | Selects one block by id, then opens the context menu at the pointer coordinates. |\n| `BlockSelectionPlugin.options.enableContextMenu` | `@platejs/selection/react` | Enables block selection from right-click events. |\n| `api.blockSelection.addOnContextMenu` | `@platejs/selection/react` | Shared right-click handler used by selectable block node props. |\n| `BlockContextMenu` | Registry UI | Default context menu component used by `BlockMenuKit`. |\n",
      "type": "registry:file",
      "target": "content/docs/plate/(plugins)/(functionality)/block-menu.mdx"
    }
  ],
  "type": "registry:file"
}