{
  "$schema": "https://ethereal-ui.saefulrohman.dev/schema/registry-item.json",
  "name": "context-menu",
  "title": "Context Menu",
  "type": "registry:primitives",
  "description": "Right-click contextual action menu with keyboard shortcut labels and destructive item styling.",
  "dependencies": [
    "lucide-react"
  ],
  "usage": "import { ContextMenuBox } from \"@etherealui/react\"\n\nexport function ContextMenuDemo() {\n  return (\n    <ContextMenuBox\n      actions={[\n        { label: \"View details\", shortcut: \"⌘ I\" },\n        { label: \"Duplicate row\", shortcut: \"⌘ D\" },\n        { label: \"Delete record\", shortcut: \"⌘ ⌫\", destructive: true },\n      ]}\n      className=\"flex h-36 w-80 items-center justify-center rounded-xl border border-dashed border-zinc-300 dark:border-zinc-700 text-xs text-zinc-500\"\n    >\n      Right-click anywhere here\n    </ContextMenuBox>\n  )\n}",
  "files": [
    {
      "path": "packages/ui/src/primitives/dropdown-menu.tsx",
      "target": "components/ui/context-menu.tsx",
      "type": "registry:primitives",
      "content": "import * as React from \"react\"\nimport * as DropdownMenuPrimitive from \"@radix-ui/react-dropdown-menu\"\nimport { cn } from \"../utils/cn\"\n\nconst DropdownMenu = DropdownMenuPrimitive.Root\nconst DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\nconst DropdownMenuGroup = DropdownMenuPrimitive.Group\n\nconst DropdownMenuContent = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 6, ...props }, ref) => (\n  <DropdownMenuPrimitive.Portal>\n    <DropdownMenuPrimitive.Content\n      ref={ref}\n      sideOffset={sideOffset}\n      className={cn(\n        \"z-50 min-w-[11rem] overflow-hidden rounded-xl border border-zinc-200 bg-white p-1 text-zinc-900 shadow-lg focus:outline-none dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-100\",\n        className\n      )}\n      {...props}\n    />\n  </DropdownMenuPrimitive.Portal>\n))\nDropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownMenuItem = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n    shortcut?: string\n    destructive?: boolean\n  }\n>(({ className, shortcut, destructive, children, ...props }, ref) => (\n  <DropdownMenuPrimitive.Item\n    ref={ref}\n    className={cn(\n      \"relative flex cursor-pointer select-none items-center justify-between gap-3 rounded-lg px-2.5 py-1.5 text-xs outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n      destructive\n        ? \"text-rose-600 focus:bg-rose-50 dark:text-rose-400 dark:focus:bg-rose-500/15\"\n        : \"text-zinc-700 focus:bg-zinc-100 focus:text-zinc-900 dark:text-zinc-200 dark:focus:bg-zinc-800 dark:focus:text-white\",\n      className\n    )}\n    {...props}\n  >\n    <span className=\"flex items-center gap-2\">{children}</span>\n    {shortcut && (\n      <span className=\"font-mono text-[10px] text-zinc-400\">{shortcut}</span>\n    )}\n  </DropdownMenuPrimitive.Item>\n))\nDropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownMenuSeparator = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.Separator\n    ref={ref}\n    className={cn(\"-mx-1 my-1 h-px bg-zinc-200 dark:bg-zinc-800\", className)}\n    {...props}\n  />\n))\nDropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownMenuLabel = React.forwardRef<\n  React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n  React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label>\n>(({ className, ...props }, ref) => (\n  <DropdownMenuPrimitive.Label\n    ref={ref}\n    className={cn(\"px-2.5 py-1.5 text-[11px] font-semibold text-zinc-400\", className)}\n    {...props}\n  />\n))\nDropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nexport interface ContextMenuAction {\n  label: string\n  shortcut?: string\n  icon?: React.ReactNode\n  destructive?: boolean\n  onClick?: () => void\n}\n\nexport interface ContextMenuBoxProps extends React.HTMLAttributes<HTMLDivElement> {\n  actions: ContextMenuAction[]\n}\n\nconst ContextMenuBox: React.FC<ContextMenuBoxProps> = ({\n  actions,\n  children,\n  className,\n  ...props\n}) => {\n  const [coords, setCoords] = React.useState<{ x: number; y: number } | null>(null)\n\n  React.useEffect(() => {\n    const close = () => setCoords(null)\n    window.addEventListener(\"click\", close)\n    return () => window.removeEventListener(\"click\", close)\n  }, [])\n\n  return (\n    <div\n      onContextMenu={(e) => {\n        e.preventDefault()\n        const rect = e.currentTarget.getBoundingClientRect()\n        setCoords({\n          x: Math.min(e.clientX - rect.left, rect.width - 180),\n          y: Math.min(e.clientY - rect.top, rect.height - 140),\n        })\n      }}\n      className={cn(\"relative select-none\", className)}\n      {...props}\n    >\n      {children}\n      {coords && (\n        <div\n          style={{ left: coords.x, top: coords.y }}\n          className=\"absolute z-40 min-w-[180px] rounded-xl border border-zinc-200 bg-white p-1 text-zinc-900 shadow-xl dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-100\"\n        >\n          {actions.map((act, idx) => (\n            <button\n              key={idx}\n              type=\"button\"\n              onClick={() => {\n                act.onClick?.()\n                setCoords(null)\n              }}\n              className={cn(\n                \"flex w-full items-center justify-between rounded-lg px-2.5 py-1.5 text-xs transition-colors cursor-pointer\",\n                act.destructive\n                  ? \"text-rose-600 hover:bg-rose-50 dark:text-rose-400 dark:hover:bg-rose-500/15\"\n                  : \"text-zinc-700 hover:bg-zinc-100 dark:text-zinc-200 dark:hover:bg-zinc-800\"\n              )}\n            >\n              <span className=\"flex items-center gap-2\">\n                {act.icon}\n                {act.label}\n              </span>\n              {act.shortcut && (\n                <span className=\"font-mono text-[10px] text-zinc-400\">\n                  {act.shortcut}\n                </span>\n              )}\n            </button>\n          ))}\n        </div>\n      )}\n    </div>\n  )\n}\nContextMenuBox.displayName = \"ContextMenuBox\"\n\nexport {\n  DropdownMenu,\n  DropdownMenuTrigger,\n  DropdownMenuGroup,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuSeparator,\n  DropdownMenuLabel,\n  ContextMenuBox,\n}\n"
    }
  ]
}