{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "combobox",
  "title": "Combobox",
  "description": "A filterable select, single or multiple with chips.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "https://ui.ndekocode.dev/r/theme.json",
    "https://ui.ndekocode.dev/r/utils.json",
    "https://ui.ndekocode.dev/r/icons.json",
    "https://ui.ndekocode.dev/r/recipes.json",
    "https://ui.ndekocode.dev/r/selected-mark.json"
  ],
  "files": [
    {
      "path": "registry/ndeko/ui/combobox.tsx",
      "content": "'use client';\n\nimport { Combobox as ComboboxPrimitive } from '@base-ui/react/combobox';\n\nimport { ChevronsUpDownIcon, XIcon } from '@/registry/ndeko/lib/icons';\nimport {\n  CONTROL_RECIPE,\n  CONTROL_SIZES,\n  MENU_ITEM,\n  MENU_LABEL,\n  MENU_POPUP,\n  MENU_SEPARATOR,\n  type ControlSize,\n} from '@/registry/ndeko/lib/recipes';\nimport { cn } from '@/registry/ndeko/lib/utils';\nimport { SelectedMark } from '@/registry/ndeko/ui/selected-mark';\n\ntype WithClassName<Props> = Omit<Props, 'className'> & { className?: string };\n\nconst ITEM_INDICATOR =\n  'absolute right-1.5 flex items-center transition-[scale,opacity] duration-150 ease-(--ease-out-strong) data-ending-style:scale-75 data-ending-style:opacity-0 data-starting-style:scale-75 data-starting-style:opacity-0';\n\nconst Combobox = ComboboxPrimitive.Root;\n\nconst ComboboxValue = ComboboxPrimitive.Value;\n\nfunction ComboboxInputGroup({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.InputGroup.Props>) {\n  return (\n    <ComboboxPrimitive.InputGroup\n      data-slot='combobox-input-group'\n      className={cn(\n        CONTROL_RECIPE,\n        'focus-within:border-foreground/30 focus-within:ring-ring/25 dark:focus-within:ring-ring/25 flex min-h-8 cursor-text flex-wrap items-center gap-1 px-1.5 py-1 focus-within:ring-[3px]',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxInput({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.Input.Props>) {\n  return (\n    <ComboboxPrimitive.Input\n      data-slot='combobox-input'\n      className={cn(\n        'placeholder:text-muted-foreground/75 h-6 min-w-12 flex-1 bg-transparent px-1 text-base outline-none md:text-[13px]',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxTrigger({\n  className,\n  children,\n  ...props\n}: WithClassName<ComboboxPrimitive.Trigger.Props>) {\n  return (\n    <ComboboxPrimitive.Trigger\n      data-slot='combobox-trigger'\n      className={cn(\n        'text-muted-foreground hover:bg-foreground/5 focus-visible:ring-ring/25 ms-auto flex size-6 shrink-0 items-center justify-center rounded-md transition-colors duration-150 outline-none focus-visible:ring-[3px]',\n        className\n      )}\n      {...props}\n    >\n      {children ?? <ChevronsUpDownIcon className='size-3.5' />}\n    </ComboboxPrimitive.Trigger>\n  );\n}\n\ntype ComboboxSelectTriggerProps =\n  WithClassName<ComboboxPrimitive.Trigger.Props> & {\n    size?: ControlSize;\n    /** Shown while nothing is chosen. Ignored when children are given. */\n    placeholder?: React.ReactNode;\n  };\n\n/**\n * A trigger drawn like the select trigger: it shows the chosen value or the placeholder and opens the list.\n * Put the `ComboboxInput` inside `ComboboxContent` to search from the popup.\n */\nfunction ComboboxSelectTrigger({\n  className,\n  children,\n  size = 'default',\n  placeholder,\n  ...props\n}: ComboboxSelectTriggerProps) {\n  const chosenValue = children ?? <ComboboxValue placeholder={placeholder} />;\n\n  return (\n    <ComboboxPrimitive.Trigger\n      data-slot='combobox-select-trigger'\n      className={cn(\n        CONTROL_RECIPE,\n        CONTROL_SIZES[size],\n        'data-popup-open:border-foreground/30 data-placeholder:text-muted-foreground/75 flex cursor-pointer items-center justify-between gap-2 text-left',\n        \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span data-slot='combobox-select-value' className='flex-1 truncate'>\n        {chosenValue}\n      </span>\n      <ComboboxPrimitive.Icon className='text-muted-foreground flex'>\n        <ChevronsUpDownIcon className='size-3.5' />\n      </ComboboxPrimitive.Icon>\n    </ComboboxPrimitive.Trigger>\n  );\n}\n\nfunction ComboboxClear({\n  className,\n  label = 'Clear',\n  ...props\n}: WithClassName<ComboboxPrimitive.Clear.Props> & { label?: string }) {\n  return (\n    <ComboboxPrimitive.Clear\n      data-slot='combobox-clear'\n      aria-label={label}\n      className={cn(\n        'text-muted-foreground hover:bg-foreground/5 hover:text-foreground focus-visible:ring-ring/25 flex size-6 shrink-0 items-center justify-center rounded-md transition-colors duration-150 outline-none focus-visible:ring-[3px]',\n        className\n      )}\n      {...props}\n    >\n      <XIcon className='size-3.5' />\n    </ComboboxPrimitive.Clear>\n  );\n}\n\nfunction ComboboxChips({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.Chips.Props>) {\n  return (\n    <ComboboxPrimitive.Chips\n      data-slot='combobox-chips'\n      className={cn('flex w-full flex-wrap items-center gap-1', className)}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxChip({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.Chip.Props>) {\n  return (\n    <ComboboxPrimitive.Chip\n      data-slot='combobox-chip'\n      className={cn(\n        'bg-card text-foreground hairline-ring ring-foreground/12 focus-within:ring-ring/50 data-highlighted:bg-foreground/5 flex h-6 cursor-default items-center gap-1 rounded-md ps-2 pe-0.5 text-xs font-medium shadow-[0_1px_1px_rgb(0_0_0/0.04)] outline-none',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxChipRemove({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.ChipRemove.Props>) {\n  return (\n    <ComboboxPrimitive.ChipRemove\n      data-slot='combobox-chip-remove'\n      className={cn(\n        'text-muted-foreground hover:bg-foreground/5 hover:text-foreground flex size-5 items-center justify-center rounded-[5px] outline-none',\n        className\n      )}\n      {...props}\n    >\n      <XIcon className='size-3' />\n    </ComboboxPrimitive.ChipRemove>\n  );\n}\n\ntype ComboboxContentProps = WithClassName<ComboboxPrimitive.Popup.Props> &\n  Pick<\n    ComboboxPrimitive.Positioner.Props,\n    'side' | 'sideOffset' | 'align' | 'alignOffset' | 'anchor'\n  >;\n\nfunction ComboboxContent({\n  className,\n  side = 'bottom',\n  sideOffset = 6,\n  align = 'start',\n  alignOffset = 0,\n  anchor,\n  ...props\n}: ComboboxContentProps) {\n  return (\n    <ComboboxPrimitive.Portal>\n      <ComboboxPrimitive.Positioner\n        side={side}\n        sideOffset={sideOffset}\n        align={align}\n        alignOffset={alignOffset}\n        anchor={anchor}\n        className='z-50 outline-none'\n      >\n        <ComboboxPrimitive.Popup\n          data-slot='combobox-content'\n          className={cn(\n            MENU_POPUP,\n            'w-(--anchor-width) max-w-(--available-width) overscroll-contain',\n            className\n          )}\n          {...props}\n        />\n      </ComboboxPrimitive.Positioner>\n    </ComboboxPrimitive.Portal>\n  );\n}\n\nfunction ComboboxEmpty({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.Empty.Props>) {\n  return (\n    <ComboboxPrimitive.Empty\n      data-slot='combobox-empty'\n      className={cn(\n        'text-muted-foreground px-2 py-6 text-center text-[13px] empty:hidden',\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxList({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.List.Props>) {\n  return (\n    <ComboboxPrimitive.List\n      data-slot='combobox-list'\n      className={cn('outline-none', className)}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxItem({\n  className,\n  children,\n  ...props\n}: WithClassName<ComboboxPrimitive.Item.Props>) {\n  return (\n    <ComboboxPrimitive.Item\n      data-slot='combobox-item'\n      className={cn(MENU_ITEM, 'pr-8', className)}\n      {...props}\n    >\n      {children}\n      <ComboboxPrimitive.ItemIndicator className={ITEM_INDICATOR}>\n        <SelectedMark />\n      </ComboboxPrimitive.ItemIndicator>\n    </ComboboxPrimitive.Item>\n  );\n}\n\nfunction ComboboxGroup(props: ComboboxPrimitive.Group.Props) {\n  return <ComboboxPrimitive.Group data-slot='combobox-group' {...props} />;\n}\n\nfunction ComboboxGroupLabel({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.GroupLabel.Props>) {\n  return (\n    <ComboboxPrimitive.GroupLabel\n      data-slot='combobox-group-label'\n      className={cn(MENU_LABEL, className)}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxSeparator({\n  className,\n  ...props\n}: WithClassName<ComboboxPrimitive.Separator.Props>) {\n  return (\n    <ComboboxPrimitive.Separator\n      data-slot='combobox-separator'\n      className={cn(MENU_SEPARATOR, className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Combobox,\n  ComboboxChip,\n  ComboboxChipRemove,\n  ComboboxChips,\n  ComboboxClear,\n  ComboboxContent,\n  ComboboxEmpty,\n  ComboboxGroup,\n  ComboboxGroupLabel,\n  ComboboxInput,\n  ComboboxInputGroup,\n  ComboboxItem,\n  ComboboxList,\n  ComboboxSelectTrigger,\n  ComboboxSeparator,\n  ComboboxTrigger,\n  ComboboxValue,\n  type ComboboxSelectTriggerProps,\n};\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "primitives"
  ],
  "type": "registry:ui"
}