{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dropdown-menu",
  "dependencies": [
    "@base-ui/react",
    "lucide-react"
  ],
  "files": [
    {
      "path": "src/components/ui/dropdown-menu.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ChevronRightIcon, CheckIcon } from \"lucide-react\"\n\n// ── Size ────────────────────────────────────────────────────────────────\n// `size=\"sm\"` renders an identical menu, just denser: tighter content\n// padding, shorter items, smaller text + icons. The size set on the flat\n// `<DropdownMenu>` (or on `<DropdownMenuContent>`) flows to every nested\n// slot through context, so manually-composed menus inherit it too — and any\n// individual slot can still override with its own `size` prop.\n\nexport type DropdownMenuSize = \"default\" | \"sm\"\n\nconst DropdownMenuSizeContext = React.createContext<DropdownMenuSize>(\"default\")\n\nfunction useDropdownMenuSize(explicit?: DropdownMenuSize) {\n  const ctx = React.useContext(DropdownMenuSizeContext)\n  return explicit ?? ctx\n}\n\n/** Per-size class overrides, layered on top of each slot's base classes. */\nconst SIZE = {\n  content: { default: \"\", sm: \"p-1\" },\n  item: {\n    default: \"\",\n    sm: \"min-h-7 gap-1 px-2.5 py-1 text-xs [&_svg:not([class*='size-'])]:size-3.5\",\n  },\n  checkRadioItem: {\n    default: \"\",\n    sm: \"min-h-7 py-1 pr-8 pl-2.5 text-xs [&_svg:not([class*='size-'])]:size-3.5\",\n  },\n  label: { default: \"\", sm: \"py-0.5 text-[11px]\" },\n  separator: { default: \"\", sm: \"my-0.5\" },\n  indicator: { default: \"right-2\", sm: \"right-1.5\" },\n} as const\n\n// Public flat API: pass a `trigger` element plus an `items` array and\n// `<DropdownMenu>` emits the Root + Trigger + Content + Items for you. Without\n// those props it stays a plain Root and you compose the slot children\n// (DropdownMenuTrigger + DropdownMenuContent + …) manually — that escape hatch\n// is still exported for submenus, checkbox/radio items, and custom layouts.\n\n/**\n * One entry in the flat `items` array.\n *  - `\"separator\"` renders a divider.\n *  - `{ heading }` renders a non-interactive group label.\n *  - otherwise an actionable item with optional icon, shortcut, variant, etc.\n */\nexport type DropdownMenuItemSpec =\n  | \"separator\"\n  | { heading: React.ReactNode }\n  | {\n      label: React.ReactNode\n      /** Leading icon (any ReactNode, typically a lucide icon). */\n      icon?: React.ReactNode\n      /** Right-aligned shortcut hint (e.g. \"⌘C\"). */\n      shortcut?: React.ReactNode\n      /** Click handler. */\n      onClick?: React.MouseEventHandler<HTMLDivElement>\n      /** `destructive` tints the item red. */\n      variant?: \"default\" | \"destructive\"\n      disabled?: boolean\n    }\n\ntype DropdownMenuFlatProps = MenuPrimitive.Root.Props & {\n  /** Trigger element (rendered via Base UI `render`). E.g. `<Button …>`. */\n  trigger?: React.ReactElement\n  /** Menu entries. Presence of this (or `trigger`) switches on the flat API. */\n  items?: DropdownMenuItemSpec[]\n  /** Optional group label rendered above the items. */\n  label?: React.ReactNode\n  /** `sm` renders an identical menu, just more compact. */\n  size?: DropdownMenuSize\n  align?: \"start\" | \"center\" | \"end\"\n  side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n  sideOffset?: number\n  alignOffset?: number\n  /** Class override for the content popup. */\n  contentClassName?: string\n}\n\nfunction DropdownMenu({\n  trigger,\n  items,\n  label,\n  size,\n  align,\n  side,\n  sideOffset,\n  alignOffset,\n  contentClassName,\n  children,\n  ...rootProps\n}: DropdownMenuFlatProps) {\n  const usingFlatApi = trigger !== undefined || items !== undefined\n\n  if (!usingFlatApi) {\n    return (\n      <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...rootProps}>\n        {children}\n      </MenuPrimitive.Root>\n    )\n  }\n\n  return (\n    <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...rootProps}>\n      {trigger ? <DropdownMenuTrigger render={trigger} /> : null}\n      <DropdownMenuContent\n        size={size}\n        align={align}\n        side={side}\n        sideOffset={sideOffset}\n        alignOffset={alignOffset}\n        className={contentClassName}\n      >\n        <DropdownMenuGroup>\n          {label !== undefined ? (\n            <DropdownMenuLabel>{label}</DropdownMenuLabel>\n          ) : null}\n          {(items ?? []).map((item, i) => {\n            if (item === \"separator\") {\n              // eslint-disable-next-line react/no-array-index-key\n              return <DropdownMenuSeparator key={i} />\n            }\n            if (\"heading\" in item) {\n              // eslint-disable-next-line react/no-array-index-key\n              return <DropdownMenuLabel key={i}>{item.heading}</DropdownMenuLabel>\n            }\n            return (\n              <DropdownMenuItem\n                // eslint-disable-next-line react/no-array-index-key\n                key={i}\n                variant={item.variant}\n                disabled={item.disabled}\n                onClick={item.onClick}\n              >\n                {item.icon}\n                {item.label}\n                {item.shortcut !== undefined ? (\n                  <DropdownMenuShortcut>{item.shortcut}</DropdownMenuShortcut>\n                ) : null}\n              </DropdownMenuItem>\n            )\n          })}\n        </DropdownMenuGroup>\n      </DropdownMenuContent>\n    </MenuPrimitive.Root>\n  )\n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n  return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n  return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />\n}\n\nfunction DropdownMenuContent({\n  align = \"start\",\n  alignOffset = 0,\n  side = \"bottom\",\n  sideOffset = 4,\n  size: sizeProp,\n  className,\n  children,\n  ...props\n}: MenuPrimitive.Popup.Props &\n  Pick<\n    MenuPrimitive.Positioner.Props,\n    \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n  > & { size?: DropdownMenuSize }) {\n  const size = useDropdownMenuSize(sizeProp)\n  return (\n    <MenuPrimitive.Portal>\n      <MenuPrimitive.Positioner\n        className=\"squad-ui isolate z-[300] outline-none\"\n        align={align}\n        alignOffset={alignOffset}\n        side={side}\n        sideOffset={sideOffset}\n      >\n        <MenuPrimitive.Popup\n          data-slot=\"dropdown-menu-content\"\n          data-size={size}\n          className={cn(\"squad-ui\", \"t-dropdown z-50 max-h-(--available-height) w-max min-w-[max(var(--anchor-width),9rem)] max-w-(--available-width) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none\", SIZE.content[size], className )}\n          {...props}\n        >\n          <DropdownMenuSizeContext.Provider value={size}>\n            {children}\n          </DropdownMenuSizeContext.Provider>\n        </MenuPrimitive.Popup>\n      </MenuPrimitive.Positioner>\n    </MenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\n  return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  size: sizeProp,\n  ...props\n}: MenuPrimitive.GroupLabel.Props & {\n  inset?: boolean\n  size?: DropdownMenuSize\n}) {\n  const size = useDropdownMenuSize(sizeProp)\n  return (\n    <MenuPrimitive.GroupLabel\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\"squad-ui\",\n        \"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7\",\n        SIZE.label[size],\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  size: sizeProp,\n  ...props\n}: MenuPrimitive.Item.Props & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n  size?: DropdownMenuSize\n}) {\n  const size = useDropdownMenuSize(sizeProp)\n  return (\n    <MenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\"squad-ui\",\n        \"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 min-h-8 whitespace-nowrap rounded-md px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground dark:focus:bg-[#242428] not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\n        SIZE.item[size],\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n  return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  size: sizeProp,\n  children,\n  ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n  inset?: boolean\n  size?: DropdownMenuSize\n}) {\n  const size = useDropdownMenuSize(sizeProp)\n  return (\n    <MenuPrimitive.SubmenuTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\"squad-ui\",\n        \"flex cursor-default items-center gap-1.5 min-h-8 rounded-md px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground dark:focus:bg-[#242428] not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground dark:data-popup-open:bg-[#242428] dark:data-open:bg-[#242428] [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        SIZE.item[size],\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"squad-ui ml-auto\" />\n    </MenuPrimitive.SubmenuTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  align = \"start\",\n  alignOffset = -3,\n  side = \"right\",\n  sideOffset = 0,\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) {\n  return (\n    <DropdownMenuContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\"squad-ui\", \"w-auto min-w-[9rem] rounded-md bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10\", className )}\n      align={align}\n      alignOffset={alignOffset}\n      side={side}\n      sideOffset={sideOffset}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  inset,\n  size: sizeProp,\n  ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n  inset?: boolean\n  size?: DropdownMenuSize\n}) {\n  const size = useDropdownMenuSize(sizeProp)\n  return (\n    <MenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      data-inset={inset}\n      className={cn(\"squad-ui\",\n        \"relative flex cursor-default items-center gap-1.5 min-h-8 rounded-md py-1.5 pr-9 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground dark:focus:bg-[#242428] focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        SIZE.checkRadioItem[size],\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span\n        className={cn(\"squad-ui pointer-events-none absolute flex items-center justify-center\", SIZE.indicator[size])}\n        data-slot=\"dropdown-menu-checkbox-item-indicator\"\n      >\n        <MenuPrimitive.CheckboxItemIndicator>\n          <CheckIcon\n          />\n        </MenuPrimitive.CheckboxItemIndicator>\n      </span>\n      {children}\n    </MenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n  return (\n    <MenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  inset,\n  size: sizeProp,\n  ...props\n}: MenuPrimitive.RadioItem.Props & {\n  inset?: boolean\n  size?: DropdownMenuSize\n}) {\n  const size = useDropdownMenuSize(sizeProp)\n  return (\n    <MenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      data-inset={inset}\n      className={cn(\"squad-ui\",\n        \"relative flex cursor-default items-center gap-1.5 min-h-8 rounded-md py-1.5 pr-9 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground dark:focus:bg-[#242428] focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        SIZE.checkRadioItem[size],\n        className\n      )}\n      {...props}\n    >\n      <span\n        className={cn(\"squad-ui pointer-events-none absolute flex items-center justify-center\", SIZE.indicator[size])}\n        data-slot=\"dropdown-menu-radio-item-indicator\"\n      >\n        <MenuPrimitive.RadioItemIndicator>\n          <CheckIcon\n          />\n        </MenuPrimitive.RadioItemIndicator>\n      </span>\n      {children}\n    </MenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  size: sizeProp,\n  ...props\n}: MenuPrimitive.Separator.Props & { size?: DropdownMenuSize }) {\n  const size = useDropdownMenuSize(sizeProp)\n  return (\n    <MenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"squad-ui\", \"-mx-1 my-1 h-px bg-border\", SIZE.separator[size], className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\"squad-ui\", \n        \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}