{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "block-context-menu",
  "title": "Block Context Menu",
  "description": "A context menu for block-level operations.",
  "dependencies": [
    "@platejs/ai",
    "@platejs/selection"
  ],
  "registryDependencies": [
    "calendar",
    "context-menu",
    "https://platejs.org/r/use-is-touch-device.json"
  ],
  "files": [
    {
      "path": "src/registry/ui/block-context-menu.tsx",
      "content": "'use client';\n\nimport * as React from 'react';\n\nimport { AIChatPlugin } from '@platejs/ai/react';\nimport {\n  BLOCK_CONTEXT_MENU_ID,\n  BlockMenuPlugin,\n  BlockSelectionPlugin,\n} from '@platejs/selection/react';\nimport { KEYS } from 'platejs';\nimport {\n  useEditorPlugin,\n  useEditorReadOnly,\n  usePluginOption,\n} from 'platejs/react';\n\nimport {\n  ContextMenu,\n  ContextMenuContent,\n  ContextMenuGroup,\n  ContextMenuItem,\n  ContextMenuSub,\n  ContextMenuSubContent,\n  ContextMenuSubTrigger,\n  ContextMenuTrigger,\n} from '@/components/ui/context-menu';\nimport { setBlockType } from '@/registry/components/editor/transforms';\nimport { useIsTouchDevice } from '@/registry/hooks/use-is-touch-device';\n\ntype Value = 'askAI' | null;\n\nexport function BlockContextMenu({ children }: { children: React.ReactNode }) {\n  const { api, editor } = useEditorPlugin(BlockMenuPlugin);\n  const [value, setValue] = React.useState<Value>(null);\n  const isTouch = useIsTouchDevice();\n  const readOnly = useEditorReadOnly();\n  const openId = usePluginOption(BlockMenuPlugin, 'openId');\n  const isOpen = openId === BLOCK_CONTEXT_MENU_ID;\n\n  const handleTurnInto = React.useCallback(\n    (type: string) => {\n      editor\n        .getApi(BlockSelectionPlugin)\n        .blockSelection.getNodes()\n        .forEach(([, path]) => {\n          setBlockType(editor, type, { at: path });\n        });\n    },\n    [editor]\n  );\n\n  const handleAlign = React.useCallback(\n    (align: 'center' | 'left' | 'right') => {\n      editor\n        .getTransforms(BlockSelectionPlugin)\n        .blockSelection.setNodes({ align });\n    },\n    [editor]\n  );\n\n  if (isTouch) {\n    return children;\n  }\n\n  return (\n    <ContextMenu\n      onOpenChange={(open) => {\n        if (!open) {\n          api.blockMenu.hide();\n        }\n      }}\n      modal={false}\n    >\n      <ContextMenuTrigger\n        asChild\n        onContextMenu={(event) => {\n          const dataset = (event.target as HTMLElement).dataset;\n          const disabled =\n            dataset?.slateEditor === 'true' ||\n            readOnly ||\n            dataset?.plateOpenContextMenu === 'false';\n\n          if (disabled) return event.preventDefault();\n\n          setTimeout(() => {\n            api.blockMenu.show(BLOCK_CONTEXT_MENU_ID, {\n              x: event.clientX,\n              y: event.clientY,\n            });\n          }, 0);\n        }}\n      >\n        <div className=\"w-full\">{children}</div>\n      </ContextMenuTrigger>\n      {isOpen && (\n        <ContextMenuContent\n          className=\"w-64\"\n          onCloseAutoFocus={(e) => {\n            e.preventDefault();\n            editor.getApi(BlockSelectionPlugin).blockSelection.focus();\n\n            if (value === 'askAI') {\n              editor.getApi(AIChatPlugin).aiChat.show();\n            }\n\n            setValue(null);\n          }}\n        >\n          <ContextMenuGroup>\n            <ContextMenuItem\n              onClick={() => {\n                setValue('askAI');\n              }}\n            >\n              Ask AI\n            </ContextMenuItem>\n            <ContextMenuItem\n              onClick={() => {\n                editor\n                  .getTransforms(BlockSelectionPlugin)\n                  .blockSelection.removeNodes();\n                editor.tf.focus();\n              }}\n            >\n              Delete\n            </ContextMenuItem>\n            <ContextMenuItem\n              onClick={() => {\n                editor\n                  .getTransforms(BlockSelectionPlugin)\n                  .blockSelection.duplicate();\n              }}\n            >\n              Duplicate\n              {/* <ContextMenuShortcut>⌘ + D</ContextMenuShortcut> */}\n            </ContextMenuItem>\n            <ContextMenuSub>\n              <ContextMenuSubTrigger>Turn into</ContextMenuSubTrigger>\n              <ContextMenuSubContent className=\"w-48\">\n                <ContextMenuItem onClick={() => handleTurnInto(KEYS.p)}>\n                  Paragraph\n                </ContextMenuItem>\n\n                <ContextMenuItem onClick={() => handleTurnInto(KEYS.h1)}>\n                  Heading 1\n                </ContextMenuItem>\n                <ContextMenuItem onClick={() => handleTurnInto(KEYS.h2)}>\n                  Heading 2\n                </ContextMenuItem>\n                <ContextMenuItem onClick={() => handleTurnInto(KEYS.h3)}>\n                  Heading 3\n                </ContextMenuItem>\n                <ContextMenuItem\n                  onClick={() => handleTurnInto(KEYS.blockquote)}\n                >\n                  Blockquote\n                </ContextMenuItem>\n                <ContextMenuItem\n                  onClick={() => handleTurnInto(KEYS.codeDrawing)}\n                >\n                  Code Drawing\n                </ContextMenuItem>\n              </ContextMenuSubContent>\n            </ContextMenuSub>\n          </ContextMenuGroup>\n\n          <ContextMenuGroup>\n            <ContextMenuItem\n              onClick={() =>\n                editor\n                  .getTransforms(BlockSelectionPlugin)\n                  .blockSelection.setIndent(1)\n              }\n            >\n              Indent\n            </ContextMenuItem>\n            <ContextMenuItem\n              onClick={() =>\n                editor\n                  .getTransforms(BlockSelectionPlugin)\n                  .blockSelection.setIndent(-1)\n              }\n            >\n              Outdent\n            </ContextMenuItem>\n            <ContextMenuSub>\n              <ContextMenuSubTrigger>Align</ContextMenuSubTrigger>\n              <ContextMenuSubContent className=\"w-48\">\n                <ContextMenuItem onClick={() => handleAlign('left')}>\n                  Left\n                </ContextMenuItem>\n                <ContextMenuItem onClick={() => handleAlign('center')}>\n                  Center\n                </ContextMenuItem>\n                <ContextMenuItem onClick={() => handleAlign('right')}>\n                  Right\n                </ContextMenuItem>\n              </ContextMenuSubContent>\n            </ContextMenuSub>\n          </ContextMenuGroup>\n        </ContextMenuContent>\n      )}\n    </ContextMenu>\n  );\n}\n",
      "type": "registry:ui"
    }
  ],
  "meta": {
    "docs": [
      {
        "route": "/docs/block-menu"
      },
      {
        "route": "https://pro.platejs.org/docs/components/block-context-menu"
      }
    ],
    "examples": [
      "block-menu-demo",
      "block-menu-pro"
    ]
  },
  "type": "registry:ui"
}