{
  "schemaVersion": 1,
  "name": "dropdown-menu",
  "useFor": "Use for actions on one thing behind a single control (an agent's row actions, the account menu), and for small option sets with DropdownMenuCheckboxItem or DropdownMenuRadioItem. Mark a destructive action with variant=\"destructive\" and keep it last, after a separator.",
  "constraints": [
    "Navigation between pages in a dropdown",
    "More than one level of submenu",
    "Animating the highlighted row",
    "Icons that move on hover"
  ],
  "documentation": "",
  "source": "Extrapolated from the Inkbox console (Figma 427:2715): nav rows (38px, 8px corners, filled glyphs, lilac current row), section labels (Channels), the raised panel",
  "exports": [
    "DropdownMenu",
    "DropdownMenuCheckboxItem",
    "DropdownMenuContent",
    "DropdownMenuGroup",
    "DropdownMenuItem",
    "DropdownMenuLabel",
    "DropdownMenuPortal",
    "DropdownMenuRadioGroup",
    "DropdownMenuRadioItem",
    "DropdownMenuSeparator",
    "DropdownMenuShortcut",
    "DropdownMenuSub",
    "DropdownMenuSubContent",
    "DropdownMenuSubTrigger",
    "DropdownMenuTrigger"
  ],
  "client": true,
  "docsUrl": "https://inkbox-ds.vercel.app/components/dropdown-menu",
  "markdownUrl": "https://inkbox-ds.vercel.app/r/dropdown-menu.md",
  "examples": [
    {
      "path": "examples/dropdown-menu.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { BuildingsIcon, DotsThreeIcon, GearSixIcon, KeyIcon, PencilSimpleIcon, QuestionIcon, SignOutIcon, TrashIcon, UsersThreeIcon } from \"@phosphor-icons/react/ssr\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\n\nfunction AccountItems() {\n  return (\n    <>\n      <DropdownMenuLabel>Robert Ligthart</DropdownMenuLabel>\n      <DropdownMenuGroup>\n        <DropdownMenuItem>\n          <BuildingsIcon weight=\"fill\" />\n          My Organisation\n          <DropdownMenuShortcut>⇧⌘O</DropdownMenuShortcut>\n        </DropdownMenuItem>\n        <DropdownMenuItem>\n          <KeyIcon weight=\"fill\" />\n          API Keys\n          <DropdownMenuShortcut>⌘K</DropdownMenuShortcut>\n        </DropdownMenuItem>\n        <DropdownMenuSub>\n          <DropdownMenuSubTrigger>\n            <UsersThreeIcon weight=\"fill\" />\n            Invite people\n          </DropdownMenuSubTrigger>\n          <DropdownMenuSubContent>\n            <DropdownMenuItem>By email</DropdownMenuItem>\n            <DropdownMenuItem>Copy invite link</DropdownMenuItem>\n          </DropdownMenuSubContent>\n        </DropdownMenuSub>\n        <DropdownMenuItem>\n          <GearSixIcon weight=\"fill\" />\n          Settings\n        </DropdownMenuItem>\n      </DropdownMenuGroup>\n      <DropdownMenuSeparator />\n      <DropdownMenuItem>\n        <QuestionIcon weight=\"fill\" />\n        Help\n      </DropdownMenuItem>\n      <DropdownMenuItem disabled>Billing (admins only)</DropdownMenuItem>\n      <DropdownMenuSeparator />\n      <DropdownMenuItem variant=\"destructive\">\n        <SignOutIcon weight=\"fill\" />\n        Log out\n      </DropdownMenuItem>\n    </>\n  );\n}\n\nexport function Preview() {\n  return (\n    <div className=\"flex justify-center\">\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <Button variant=\"outline\">Account</Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent align=\"start\" className=\"w-60\">\n          <AccountItems />\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  );\n}\n\nexport function Open() {\n  return (\n    <div className=\"flex min-h-110 items-start justify-center\">\n      <DropdownMenu defaultOpen>\n        <DropdownMenuTrigger asChild>\n          <Button variant=\"outline\">Account</Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent className=\"w-60\">\n          <AccountItems />\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  );\n}\n\nexport function RowActions() {\n  return (\n    <div className=\"flex justify-center\">\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <Button variant=\"ghost\" size=\"icon\" aria-label=\"Actions for @acme\">\n            <DotsThreeIcon weight=\"bold\" />\n          </Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent align=\"end\" className=\"w-48\">\n          <DropdownMenuItem>\n            <PencilSimpleIcon weight=\"fill\" />\n            Edit agent\n          </DropdownMenuItem>\n          <DropdownMenuItem>\n            <KeyIcon weight=\"fill\" />\n            Rotate API key\n          </DropdownMenuItem>\n          <DropdownMenuSeparator />\n          <DropdownMenuItem variant=\"destructive\">\n            <TrashIcon weight=\"fill\" />\n            Delete agent\n          </DropdownMenuItem>\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  );\n}\n\nexport function Options() {\n  const [channels, setChannels] = React.useState({ email: true, phone: true, imessage: false });\n  const [mode, setMode] = React.useState(\"edge\");\n  return (\n    <div className=\"flex justify-center\">\n      <DropdownMenu>\n        <DropdownMenuTrigger asChild>\n          <Button variant=\"outline\">Filter</Button>\n        </DropdownMenuTrigger>\n        <DropdownMenuContent className=\"w-56\">\n          <DropdownMenuLabel>Channels</DropdownMenuLabel>\n          <DropdownMenuCheckboxItem checked={channels.email} onCheckedChange={(v) => setChannels((c) => ({ ...c, email: v === true }))}>\n            Email\n          </DropdownMenuCheckboxItem>\n          <DropdownMenuCheckboxItem checked={channels.phone} onCheckedChange={(v) => setChannels((c) => ({ ...c, phone: v === true }))}>\n            Phone\n          </DropdownMenuCheckboxItem>\n          <DropdownMenuCheckboxItem checked={channels.imessage} onCheckedChange={(v) => setChannels((c) => ({ ...c, imessage: v === true }))}>\n            iMessage\n          </DropdownMenuCheckboxItem>\n          <DropdownMenuSeparator />\n          <DropdownMenuLabel>Tunnel TLS mode</DropdownMenuLabel>\n          <DropdownMenuRadioGroup value={mode} onValueChange={setMode}>\n            <DropdownMenuRadioItem value=\"edge\">Edge (default)</DropdownMenuRadioItem>\n            <DropdownMenuRadioItem value=\"passthrough\">Passthrough</DropdownMenuRadioItem>\n          </DropdownMenuRadioGroup>\n        </DropdownMenuContent>\n      </DropdownMenu>\n    </div>\n  );\n}\n",
      "exports": [
        "Preview",
        "Open",
        "RowActions",
        "Options"
      ],
      "requires": [
        "dropdown-menu",
        "button"
      ],
      "packages": [
        "@phosphor-icons/react"
      ],
      "previews": [
        {
          "name": "Preview",
          "url": "https://inkbox-ds.vercel.app/preview/dropdown-menu/Preview"
        },
        {
          "name": "Open",
          "url": "https://inkbox-ds.vercel.app/preview/dropdown-menu/Open"
        },
        {
          "name": "RowActions",
          "url": "https://inkbox-ds.vercel.app/preview/dropdown-menu/RowActions"
        },
        {
          "name": "Options",
          "url": "https://inkbox-ds.vercel.app/preview/dropdown-menu/Options"
        }
      ]
    }
  ],
  "type": "ui",
  "title": "Dropdown Menu",
  "description": "A raised white menu of 36px rows with filled glyphs, lilac highlight, purple section labels and checks.",
  "surface": "site",
  "kinds": [],
  "requires": [
    "theme",
    "surface",
    "utils"
  ],
  "packages": [
    "radix-ui",
    "@phosphor-icons/react"
  ],
  "files": [
    {
      "path": "components/ui/dropdown-menu.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\";\nimport { CaretRightIcon, CheckIcon } from \"@phosphor-icons/react/ssr\";\n\nimport { usePortalContainer } from \"@/lib/surface\";\nimport { cn } from \"@/lib/utils\";\n\n// A menu, extrapolated from the console (Figma 427:2715): the panel is a raised white panel (8px corners, the floating\n// shadow) with 4px of padding; items are 36px rows with 8px corners like the rail's nav rows, a 20px glyph in the\n// action-glyph purple 10px from a 14px ink label, and the lilac under the highlighted row. Section labels are 13px in\n// the label purple (\"Channels\"), separators the rail's hairline, shortcuts 12px muted, destructive items red. The\n// panel grows out of its trigger from 96 percent with a fade; highlighting a row is instant (menus are used by keyboard\n// and many times a day).\nconst CONTENT =\n  \"z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-48 overflow-x-hidden overflow-y-auto rounded-control bg-surface p-1 text-fg shadow-floating outline-none data-[state=closed]:animate-pop-out data-[state=open]:animate-pop-in\";\nconst ITEM =\n  \"relative flex h-9 cursor-default items-center gap-2.5 rounded-control px-2.5 font-sans text-body leading-tight text-fg outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-subtle data-[inset]:pl-10.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-5.5 [&_svg:not([class*='text-'])]:text-icon-secondary\";\n\nfunction DropdownMenu(props: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n  return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n}\n\nfunction DropdownMenuPortal(props: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n  const container = usePortalContainer();\n  return <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" container={container} {...props} />;\n}\n\nfunction DropdownMenuTrigger(props: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n  return <DropdownMenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n}\n\nfunction DropdownMenuContent({ className, sideOffset = 6, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n  return (\n    <DropdownMenuPortal>\n      <DropdownMenuPrimitive.Content data-slot=\"dropdown-menu-content\" sideOffset={sideOffset} className={cn(CONTENT, \"origin-(--radix-dropdown-menu-content-transform-origin)\", className)} {...props} />\n    </DropdownMenuPortal>\n  );\n}\n\nfunction DropdownMenuGroup(props: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n  return <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n}\n\nfunction DropdownMenuItem({ className, inset, variant = \"default\", ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & { inset?: boolean; variant?: \"default\" | \"destructive\" }) {\n  return (\n    <DropdownMenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset || undefined}\n      data-variant={variant}\n      className={cn(ITEM, \"data-[variant=destructive]:text-danger data-[variant=destructive]:[&_svg]:text-danger\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction DropdownMenuCheckboxItem({ className, children, checked, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem>) {\n  return (\n    <DropdownMenuPrimitive.CheckboxItem data-slot=\"dropdown-menu-checkbox-item\" checked={checked} className={cn(ITEM, \"pl-10.5\", className)} {...props}>\n      <span className=\"pointer-events-none absolute left-2.5 flex size-5.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <CheckIcon weight=\"bold\" className=\"size-4.5 text-fg-brand\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.CheckboxItem>\n  );\n}\n\nfunction DropdownMenuRadioGroup(props: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n  return <DropdownMenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n}\n\n// The selected choice wears the console's radio mark: a pink ring around white.\nfunction DropdownMenuRadioItem({ className, children, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem>) {\n  return (\n    <DropdownMenuPrimitive.RadioItem data-slot=\"dropdown-menu-radio-item\" className={cn(ITEM, \"pl-10.5\", className)} {...props}>\n      <span className=\"pointer-events-none absolute left-2.5 flex size-5.5 items-center justify-center\">\n        <DropdownMenuPrimitive.ItemIndicator>\n          <span className=\"block size-3.5 rounded-pill border-[3.5px] border-pink bg-surface\" />\n        </DropdownMenuPrimitive.ItemIndicator>\n      </span>\n      {children}\n    </DropdownMenuPrimitive.RadioItem>\n  );\n}\n\nfunction DropdownMenuLabel({ className, inset, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & { inset?: boolean }) {\n  return <DropdownMenuPrimitive.Label data-slot=\"dropdown-menu-label\" data-inset={inset || undefined} className={cn(\"px-2.5 pt-2 pb-1 font-sans text-body-sm leading-tight text-fg-label data-[inset]:pl-10.5\", className)} {...props} />;\n}\n\nfunction DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n  return <DropdownMenuPrimitive.Separator data-slot=\"dropdown-menu-separator\" className={cn(\"-mx-1 my-1 h-px bg-line-subtle\", className)} {...props} />;\n}\n\nfunction DropdownMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n  return <span data-slot=\"dropdown-menu-shortcut\" className={cn(\"ml-auto pl-4 font-sans text-caption text-fg-muted\", className)} {...props} />;\n}\n\nfunction DropdownMenuSub(props: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n  return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />;\n}\n\nfunction DropdownMenuSubTrigger({ className, inset, children, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & { inset?: boolean }) {\n  return (\n    <DropdownMenuPrimitive.SubTrigger data-slot=\"dropdown-menu-sub-trigger\" data-inset={inset || undefined} className={cn(ITEM, \"data-[state=open]:bg-subtle\", className)} {...props}>\n      {children}\n      <CaretRightIcon className=\"ml-auto size-4.5 text-fg-muted\" />\n    </DropdownMenuPrimitive.SubTrigger>\n  );\n}\n\nfunction DropdownMenuSubContent({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n  return (\n    <DropdownMenuPortal>\n      <DropdownMenuPrimitive.SubContent data-slot=\"dropdown-menu-sub-content\" className={cn(CONTENT, \"max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin)\", className)} {...props} />\n    </DropdownMenuPortal>\n  );\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuCheckboxItem,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuPortal,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubContent,\n  DropdownMenuSubTrigger,\n  DropdownMenuTrigger,\n};\n"
    }
  ]
}
