{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "extends": "none",
  "name": "dropdown",
  "title": "dropdown",
  "description": "dropdown",
  "dependencies": [
    "@heroicons/react",
    "react-aria-components",
    "tailwind-merge",
    "tailwind-variants"
  ],
  "registryDependencies": [
    "https://intentui.com/r/keyboard"
  ],
  "files": [
    {
      "path": "src/components/ui/dropdown.tsx",
      "content": "'use client'\n\nimport { CheckIcon } from '@heroicons/react/20/solid'\nimport { Collection } from 'react-aria-components/Collection'\nimport { composeRenderProps } from 'react-aria-components/composeRenderProps'\nimport { Header } from 'react-aria-components/Header'\nimport type { ListBoxItemProps, ListBoxSectionProps } from 'react-aria-components/ListBox'\nimport { ListBoxItem as ListBoxItemPrimitive, ListBoxSection } from 'react-aria-components/ListBox'\nimport { Separator, type SeparatorProps } from 'react-aria-components/Separator'\nimport { Text, type TextProps } from 'react-aria-components/Text'\nimport { twJoin, twMerge } from 'tailwind-merge'\nimport { tv } from 'tailwind-variants'\nimport { Keyboard } from './keyboard'\n\nconst dropdownSectionStyles = tv({\n  slots: {\n    section: 'col-span-full grid grid-cols-[auto_1fr]',\n    header:\n      'col-span-full px-3 py-2 font-medium text-muted-fg text-sm/6 sm:px-2.5 sm:py-1.5 sm:text-xs/3',\n  },\n})\n\nconst { section, header } = dropdownSectionStyles()\n\ninterface DropdownSectionProps<T> extends ListBoxSectionProps<T> {\n  title?: string\n}\n\nconst DropdownSection = <T extends object>({\n  className,\n  children,\n  ...props\n}: DropdownSectionProps<T>) => {\n  return (\n    <ListBoxSection className={section({ className })}>\n      {'title' in props && <Header className={header()}>{props.title}</Header>}\n      <Collection items={props.items}>{children}</Collection>\n    </ListBoxSection>\n  )\n}\n\nconst dropdownItemStyles = tv({\n  base: [\n    'min-w-0 [--me-icon:--spacing(2.5)] sm:[--me-icon:--spacing(2)]',\n    'col-span-full grid grid-cols-[auto_1fr_1.5rem_0.5rem_auto] px-3 py-2 supports-[grid-template-columns:subgrid]:grid-cols-subgrid sm:px-2.5 sm:py-1.5',\n    'not-has-[[slot=description]]:items-center',\n    'group relative cursor-default select-none rounded-[calc(var(--radius-lg)-(--spacing(1)))] outline-0',\n    // text\n    'text-base/6 text-fg sm:text-sm/6 forced-colors:text-[CanvasText]',\n    // avatar\n    '*:data-[slot=avatar]:*:me-(--me-icon) *:data-[slot=avatar]:me-(--me-icon) has-[[slot=description]]:*:data-[slot=avatar]:row-span-2 *:data-[slot=avatar]:[--avatar-size:--spacing(5)] sm:*:data-[slot=avatar]:[--avatar-size:--spacing(4)]',\n    // icon\n    \"[&_svg:not([class*='text-'])]:text-muted-fg *:[svg:not([data-slot='check-indicator'])]:col-start-1 *:[svg:not([data-slot='check-indicator'])]:row-start-1 *:[svg:not([data-slot='check-indicator'])]:-ms-0.5 *:[svg:not([data-slot='check-indicator'])]:me-(--me-icon) *:[svg]:shrink-0\",\n    'not-has-[[slot=description]]:*:[svg]:size-5 sm:not-has-[[slot=description]]:*:[svg]:size-4',\n    \"has-[[slot=description]]:[&_svg:not([class*='w-'])]:w-5 sm:has-[[slot=description]]:[&_svg:not([class*='w-'])]:w-4 has-[[slot=description]]:*:[svg]:h-lh\",\n    \"[&>[slot=label]+svg:not([data-slot='check-indicator'])]:absolute [&>[slot=label]+svg:not([data-slot='check-indicator'])]:inset-e-0 [&>[slot=label]+svg:not([data-slot='check-indicator'])]:top-1\",\n    \"selected:[&>svg:not([data-slot='check-indicator']):has(+svg:not([data-slot='check-indicator']))]:absolute selected:[&>svg:not([data-slot='check-indicator']):has(+svg:not([data-slot='check-indicator']))]:inset-e-0 selected:[&>svg:not([data-slot='check-indicator']):has(+svg:not([data-slot='check-indicator']))]:top-1\",\n    \"selected:[&>svg:not([data-slot='check-indicator']):has(+[data-slot=avatar])]:absolute selected:[&>svg:not([data-slot='check-indicator']):has(+[data-slot=avatar])]:inset-e-0 selected:[&>svg:not([data-slot='check-indicator']):has(+[data-slot=avatar])]:top-1\",\n    \"selected:[&>[data-slot=avatar]+[slot=label]]:me-6 selected:[&>[data-slot=avatar]+svg:not([data-slot='check-indicator'])+[slot=label]]:me-6 selected:[&>svg:not([data-slot='check-indicator'])+[data-slot=avatar]+[slot=label]]:me-6 selected:[&>svg:not([data-slot='check-indicator'])+[slot=label]]:me-6\",\n    // keyboard\n    '*:data-[slot=keyboard]:inset-e-3',\n    // force color adjust\n    'forced-color-adjust-none forced-colors:focus:bg-[Highlight] forced-colors:focus:text-[HighlightText] forced-colors:focus:*:[svg]:text-[HighlightText]',\n  ],\n  variants: {\n    intent: {\n      danger: [\n        \"text-danger-subtle-fg focus:text-danger-subtle-fg [&_svg:not([class*='text-'])]:text-danger-subtle-fg/70\",\n        '*:[[slot=description]]:text-danger-subtle-fg/80 focus:*:[[slot=description]]:text-danger-subtle-fg focus:*:[[slot=label]]:text-danger-subtle-fg',\n        \"focus:bg-danger-subtle focus:text-danger-subtle-fg forced-colors:focus:text-[Mark] focus:[&_svg:not([class*='text-'])]:text-danger-subtle-fg\",\n        '*:data-[slot=keyboard]:text-danger-subtle-fg/70 focus:*:data-[slot=keyboard]:text-danger-subtle-fg',\n      ],\n      warning: [\n        \"text-warning-subtle-fg focus:text-warning-subtle-fg [&_svg:not([class*='text-'])]:text-warning-subtle-fg/70\",\n        '*:[[slot=description]]:text-warning-subtle-fg/80 focus:*:[[slot=description]]:text-warning-subtle-fg focus:*:[[slot=label]]:text-warning-subtle-fg',\n        \"focus:bg-warning-subtle focus:text-warning-subtle-fg focus:[&_svg:not([class*='text-'])]:text-warning-subtle-fg\",\n        '*:data-[slot=keyboard]:text-warning-subtle-fg/70 focus:*:data-[slot=keyboard]:text-warning-subtle-fg',\n      ],\n    },\n    isDisabled: {\n      true: 'opacity-50 forced-colors:text-[GrayText]',\n    },\n    isSelected: {\n      true: \"[&_svg:not([class*='text-'])]:text-accent-fg\",\n    },\n    isFocused: {\n      true: [\n        \"*:data-[slot=keyboard]:text-accent-fg [&_svg:not([class*='text-'])]:text-accent-fg\",\n        'bg-accent text-accent-fg forced-colors:bg-[Highlight] forced-colors:text-[HighlightText]',\n        '[&_.text-muted-fg]:text-accent-fg/80 *:[[slot=description]]:text-accent-fg *:[[slot=label]]:text-accent-fg',\n      ],\n    },\n    isHovered: {\n      true: [\n        \"*:data-[slot=keyboard]:text-accent-fg [&_svg:not([class*='text-'])]:text-accent-fg\",\n        'bg-accent text-accent-fg forced-colors:bg-[Highlight] forced-colors:text-[HighlightText]',\n        '[&_.text-muted-fg]:text-accent-fg/80 *:[[slot=description]]:text-accent-fg *:[[slot=label]]:text-accent-fg',\n      ],\n    },\n  },\n})\n\ninterface DropdownItemProps extends ListBoxItemProps {\n  intent?: 'danger' | 'warning'\n}\n\nconst DropdownItem = ({ className, children, intent, ...props }: DropdownItemProps) => {\n  const textValue = typeof children === 'string' ? children : undefined\n  return (\n    <ListBoxItemPrimitive\n      textValue={textValue}\n      className={composeRenderProps(className, (className, renderProps) =>\n        dropdownItemStyles({ ...renderProps, intent, className })\n      )}\n      {...props}\n    >\n      {composeRenderProps(children, (children, { isSelected }) => (\n        <>\n          {isSelected && (\n            <CheckIcon\n              className={twJoin(\n                '-ms-0.5 me-1.5 h-lh w-4 shrink-0',\n                \"group-has-[svg:not([data-slot='check-indicator'])]:absolute group-has-[svg:not([data-slot='check-indicator'])]:inset-e-0.5 group-has-[svg:not([data-slot='check-indicator'])]:top-1/2 group-has-[svg:not([data-slot='check-indicator'])]:-translate-y-1/2\",\n                'group-has-data-[slot=avatar]:absolute group-has-data-[slot=avatar]:inset-e-0.5 group-has-data-[slot=avatar]:top-1/2 group-has-data-[slot=avatar]:-translate-y-1/2'\n              )}\n              data-slot=\"check-indicator\"\n            />\n          )}\n          {typeof children === 'string' ? <DropdownLabel>{children}</DropdownLabel> : children}\n        </>\n      ))}\n    </ListBoxItemPrimitive>\n  )\n}\n\nconst DropdownLabel = ({ className, ...props }: TextProps) => (\n  <Text slot=\"label\" className={twMerge('col-start-2 [&:has(+svg)]:pe-6', className)} {...props} />\n)\n\nconst DropdownDescription = ({ className, ...props }: TextProps) => (\n  <Text\n    slot=\"description\"\n    className={twMerge('col-start-2 font-normal text-muted-fg text-sm', className)}\n    {...props}\n  />\n)\n\nconst DropdownSeparator = ({ className, ...props }: Omit<SeparatorProps, 'orientation'>) => (\n  <Separator\n    orientation=\"horizontal\"\n    className={twMerge('col-span-full -mx-1 h-px bg-fg/10', className)}\n    {...props}\n  />\n)\n\nconst DropdownKeyboard = ({ className, ...props }: React.ComponentProps<typeof Keyboard>) => {\n  return (\n    <Keyboard\n      className={twMerge(\n        'absolute end-2 ps-2 group-hover:text-primary-fg group-focus:text-primary-fg',\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\n/**\n * Note: This is not exposed component, but it's used in other components to render dropdowns.\n * @internal\n */\nexport type { DropdownItemProps, DropdownSectionProps }\nexport {\n  DropdownDescription,\n  DropdownItem,\n  DropdownKeyboard,\n  DropdownLabel,\n  DropdownSection,\n  DropdownSeparator,\n  dropdownItemStyles,\n  dropdownSectionStyles,\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}