{
  "schemaVersion": 1,
  "name": "context-menu",
  "useFor": "Use for shortcuts on an item in a list or table (copy an order ID, retry a checkout). Every action in it must also be reachable another way, such as a row's menu key. Use ContextMenuShortcut for keys, ContextMenuSub for one level of submenu and variant=\"destructive\" on a destructive item.",
  "constraints": [
    "The only way to reach an action",
    "More than one level of submenu",
    "A context menu on text people want to select"
  ],
  "documentation": "",
  "source": "Extension from opencommerce-agentcard-web src/app/globals.css (.nav-tray) and dropdown-menu.tsx",
  "exports": [
    "ContextMenu",
    "ContextMenuCheckboxItem",
    "ContextMenuContent",
    "ContextMenuGroup",
    "ContextMenuItem",
    "ContextMenuLabel",
    "ContextMenuPortal",
    "ContextMenuRadioGroup",
    "ContextMenuRadioItem",
    "ContextMenuSeparator",
    "ContextMenuShortcut",
    "ContextMenuSub",
    "ContextMenuSubContent",
    "ContextMenuSubTrigger",
    "ContextMenuTrigger"
  ],
  "client": true,
  "docsUrl": "https://opencommerce-ds.vercel.app/components/context-menu",
  "markdownUrl": "https://opencommerce-ds.vercel.app/r/context-menu.md",
  "examples": [
    {
      "path": "examples/context-menu.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Copy, ExternalLink, RotateCcw, Trash2 } from \"lucide-react\";\n\nimport {\n  ContextMenu,\n  ContextMenuCheckboxItem,\n  ContextMenuContent,\n  ContextMenuItem,\n  ContextMenuLabel,\n  ContextMenuRadioGroup,\n  ContextMenuRadioItem,\n  ContextMenuSeparator,\n  ContextMenuShortcut,\n  ContextMenuSub,\n  ContextMenuSubContent,\n  ContextMenuSubTrigger,\n  ContextMenuTrigger,\n} from \"@/components/ui/context-menu\";\n\nfunction Order({ defaultOpen = false }: { defaultOpen?: boolean }) {\n  const [status, setStatus] = React.useState(\"Right click the order, or press and hold on a phone.\");\n  const [notify, setNotify] = React.useState(true);\n  const [speed, setSpeed] = React.useState(\"standard\");\n  return (\n    <div className=\"grid w-full max-w-110 gap-3\">\n      <ContextMenu modal={!defaultOpen}>\n        <ContextMenuTrigger className=\"grid gap-1 rounded-panel border border-line-window bg-surface p-5 shadow-card\">\n          <span className=\"flex items-baseline justify-between gap-3\">\n            <span className=\"font-display text-h5 font-medium tracking-tight text-fg\">Northwind Outfitters</span>\n            <span className=\"font-mono text-snippet text-fg tabular-nums\">$222.00</span>\n          </span>\n          <span className=\"font-mono text-bar text-fg-muted\">ord_8KQ2 · placed 2 minutes ago</span>\n        </ContextMenuTrigger>\n        <ContextMenuContent className=\"w-60\">\n          <ContextMenuLabel>Order ord_8KQ2</ContextMenuLabel>\n          <ContextMenuItem onSelect={() => setStatus(\"Copied ord_8KQ2.\")}>\n            <Copy strokeWidth={1.5} />\n            Copy order ID\n            <ContextMenuShortcut>⌘C</ContextMenuShortcut>\n          </ContextMenuItem>\n          <ContextMenuItem onSelect={() => setStatus(\"Opened the merchant's receipt.\")}>\n            <ExternalLink strokeWidth={1.5} />\n            Open receipt\n          </ContextMenuItem>\n          <ContextMenuItem onSelect={() => setStatus(\"Checkout retried.\")}>\n            <RotateCcw strokeWidth={1.5} />\n            Retry checkout\n          </ContextMenuItem>\n          <ContextMenuSub>\n            <ContextMenuSubTrigger>Shipping</ContextMenuSubTrigger>\n            <ContextMenuSubContent className=\"w-48\">\n              <ContextMenuRadioGroup value={speed} onValueChange={setSpeed}>\n                <ContextMenuRadioItem value=\"standard\">Standard</ContextMenuRadioItem>\n                <ContextMenuRadioItem value=\"express\">Express</ContextMenuRadioItem>\n                <ContextMenuRadioItem value=\"overnight\">Overnight</ContextMenuRadioItem>\n              </ContextMenuRadioGroup>\n            </ContextMenuSubContent>\n          </ContextMenuSub>\n          <ContextMenuCheckboxItem checked={notify} onCheckedChange={(on) => setNotify(on === true)}>\n            Email me on delivery\n          </ContextMenuCheckboxItem>\n          <ContextMenuSeparator />\n          <ContextMenuItem variant=\"destructive\" onSelect={() => setStatus(\"Order canceled.\")}>\n            <Trash2 strokeWidth={1.5} />\n            Cancel order\n          </ContextMenuItem>\n        </ContextMenuContent>\n      </ContextMenu>\n      <p role=\"status\" className=\"text-body-sm text-fg-muted\">\n        {status} Shipping: {speed}. Delivery email {notify ? \"on\" : \"off\"}.\n      </p>\n    </div>\n  );\n}\n\nexport function Site() {\n  return <Order />;\n}\n",
      "exports": [
        "Site"
      ],
      "requires": [
        "context-menu"
      ],
      "packages": [
        "lucide-react"
      ],
      "previews": [
        {
          "name": "Site",
          "url": "https://opencommerce-ds.vercel.app/preview/context-menu/Site"
        }
      ]
    }
  ],
  "type": "ui",
  "title": "Context Menu",
  "description": "The brand's menu opened with a right click or a long press on an item.",
  "surface": "site",
  "kinds": [
    "menu-panel",
    "menu-item"
  ],
  "requires": [
    "theme",
    "surface",
    "utils"
  ],
  "packages": [
    "@radix-ui/react-context-menu",
    "lucide-react"
  ],
  "files": [
    {
      "path": "components/ui/context-menu.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as ContextMenuPrimitive from \"@radix-ui/react-context-menu\";\nimport { Check, ChevronRight } from \"lucide-react\";\n\nimport { usePortalContainer } from \"@/lib/surface\";\nimport { cn } from \"@/lib/utils\";\n\n// The brand's menu (dropdown-menu.tsx) opened with a right click or a long press on a surface: a floating white panel (a 9\n// percent ink edge, 8px corners, a soft drop, 4px of padding), rows in 14px Inter with 5px corners that take a faint\n// wash when highlighted, with no transition (menus are worked from the keyboard). It grows from the pointer (scale 0.97\n// and a fade, 160ms ease-out); reduced motion keeps the fade. Checks are drawn in blue; destructive rows are red.\nconst PANEL =\n  \"z-50 flex max-h-(--radix-context-menu-content-available-height) max-w-(--radix-context-menu-content-available-width) origin-(--radix-context-menu-content-transform-origin) animate-pop-in flex-col gap-0.5 overflow-y-auto overscroll-contain rounded-control border border-line bg-surface p-1 text-fg shadow-floating outline-none motion-reduce:animate-none\";\nconst ROW =\n  \"relative flex w-full cursor-default items-center gap-2 rounded-menu px-2.5 py-2 font-sans text-body-sm leading-snug text-fg-muted outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-40 data-[highlighted]:bg-wash-hover data-[highlighted]:text-fg data-[inset]:pl-8 [&_svg]:size-3.5 [&_svg]:shrink-0\";\nconst DANGER = \"text-danger data-[highlighted]:bg-danger/6 data-[highlighted]:text-danger\";\nconst QUIET = \"text-fg-faint\";\n\nfunction ContextMenu(props: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {\n  return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\n}\n\nfunction ContextMenuTrigger({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {\n  return <ContextMenuPrimitive.Trigger data-slot=\"context-menu-trigger\" className={cn(\"select-none\", className)} {...props} />;\n}\n\nfunction ContextMenuGroup(props: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {\n  return <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />;\n}\n\nfunction ContextMenuPortal(props: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {\n  return <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" container={usePortalContainer()} {...props} />;\n}\n\nfunction ContextMenuSub(props: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {\n  return <ContextMenuPrimitive.Sub data-slot=\"context-menu-sub\" {...props} />;\n}\n\nfunction ContextMenuRadioGroup(props: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {\n  return <ContextMenuPrimitive.RadioGroup data-slot=\"context-menu-radio-group\" {...props} />;\n}\n\nfunction ContextMenuContent({ className, collisionPadding = 8, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Content>) {\n  return (\n    <ContextMenuPrimitive.Portal container={usePortalContainer()}>\n      <ContextMenuPrimitive.Content data-slot=\"context-menu-content\" collisionPadding={collisionPadding} className={cn(PANEL, \"min-w-[min(12rem,var(--radix-context-menu-content-available-width))]\", className)} {...props} />\n    </ContextMenuPrimitive.Portal>\n  );\n}\n\nfunction ContextMenuItem({ className, inset, variant = \"default\", ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Item> & { inset?: boolean; variant?: \"default\" | \"destructive\" }) {\n  return <ContextMenuPrimitive.Item data-slot=\"context-menu-item\" data-inset={inset || undefined} data-variant={variant} className={cn(ROW, variant === \"destructive\" && DANGER, className)} {...props} />;\n}\n\nfunction ContextMenuSubTrigger({ className, inset, children, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & { inset?: boolean }) {\n  return (\n    <ContextMenuPrimitive.SubTrigger data-slot=\"context-menu-sub-trigger\" data-inset={inset || undefined} className={cn(ROW, \"data-[state=open]:bg-wash-hover data-[state=open]:text-fg\", className)} {...props}>\n      {children}\n      <ChevronRight className=\"ml-auto\" strokeWidth={1.5} />\n    </ContextMenuPrimitive.SubTrigger>\n  );\n}\n\nfunction ContextMenuSubContent({ className, collisionPadding = 8, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {\n  return (\n    <ContextMenuPrimitive.Portal container={usePortalContainer()}>\n      <ContextMenuPrimitive.SubContent data-slot=\"context-menu-sub-content\" collisionPadding={collisionPadding} className={cn(PANEL, \"min-w-[min(10rem,var(--radix-context-menu-content-available-width))]\", className)} {...props} />\n    </ContextMenuPrimitive.Portal>\n  );\n}\n\nfunction ContextMenuCheckboxItem({ className, children, checked, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem>) {\n  return (\n    <ContextMenuPrimitive.CheckboxItem data-slot=\"context-menu-checkbox-item\" checked={checked} className={cn(ROW, \"pr-8\", className)} {...props}>\n      {children}\n      <ContextMenuPrimitive.ItemIndicator className=\"absolute right-2.5 text-fg-brand\">\n        <Check strokeWidth={1.75} />\n      </ContextMenuPrimitive.ItemIndicator>\n    </ContextMenuPrimitive.CheckboxItem>\n  );\n}\n\nfunction ContextMenuRadioItem({ className, children, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem>) {\n  return (\n    <ContextMenuPrimitive.RadioItem data-slot=\"context-menu-radio-item\" className={cn(ROW, \"pr-8 data-[state=checked]:text-fg\", className)} {...props}>\n      {children}\n      <ContextMenuPrimitive.ItemIndicator className=\"absolute right-2.5 text-fg-brand\">\n        <Check strokeWidth={1.75} />\n      </ContextMenuPrimitive.ItemIndicator>\n    </ContextMenuPrimitive.RadioItem>\n  );\n}\n\nfunction ContextMenuLabel({ className, inset, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Label> & { inset?: boolean }) {\n  return <ContextMenuPrimitive.Label data-slot=\"context-menu-label\" data-inset={inset || undefined} className={cn(\"px-2.5 pt-2 pb-1 font-sans text-caption data-[inset]:pl-8\", QUIET, className)} {...props} />;\n}\n\nfunction ContextMenuSeparator({ className, ...props }: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {\n  return <ContextMenuPrimitive.Separator data-slot=\"context-menu-separator\" className={cn(\"-mx-1 my-1 h-px bg-line\", className)} {...props} />;\n}\n\nfunction ContextMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n  return <span data-slot=\"context-menu-shortcut\" className={cn(\"ml-auto pl-4 font-mono text-caption\", QUIET, className)} {...props} />;\n}\n\nexport {\n  ContextMenu,\n  ContextMenuCheckboxItem,\n  ContextMenuContent,\n  ContextMenuGroup,\n  ContextMenuItem,\n  ContextMenuLabel,\n  ContextMenuPortal,\n  ContextMenuRadioGroup,\n  ContextMenuRadioItem,\n  ContextMenuSeparator,\n  ContextMenuShortcut,\n  ContextMenuSub,\n  ContextMenuSubContent,\n  ContextMenuSubTrigger,\n  ContextMenuTrigger,\n};\n"
    }
  ]
}
