{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"combobox","title":"Combobox","description":"An input that filters a list of options as the user types and lets them pick a value from a popup.","dependencies":["cn","@base-ui/react","lucide-react"],"registryDependencies":["@sortui/button","@sortui/input-group"],"files":[{"path":"components/ui/combobox.tsx","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react\"\nimport { cn } from \"cn\"\n\nimport { Button } from \"@/components/ui/button\"\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupInput,\n} from \"@/components/ui/input-group\"\nimport { ChevronDownIcon, XIcon, CheckIcon } from \"lucide-react\"\n\nconst Combobox = ComboboxPrimitive.Root\n\nfunction ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {\n  return <ComboboxPrimitive.Value data-slot=\"combobox-value\" {...props} />\n}\n\nfunction ComboboxTrigger({\n  className,\n  children,\n  ...props\n}: ComboboxPrimitive.Trigger.Props) {\n  return (\n    <ComboboxPrimitive.Trigger\n      data-slot=\"combobox-trigger\"\n      aria-label={children == null ? \"Show options\" : undefined}\n      className={cn(\"[&_svg:not([class*='size-'])]:size-4\", className)}\n      {...props}\n    >\n      {children}\n      <ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />\n    </ComboboxPrimitive.Trigger>\n  )\n}\n\nfunction ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {\n  return (\n    <ComboboxPrimitive.Clear\n      data-slot=\"combobox-clear\"\n      aria-label=\"Clear\"\n      render={<InputGroupButton variant=\"ghost\" size=\"icon-xs\" />}\n      className={className}\n      {...props}\n    >\n      <XIcon className=\"pointer-events-none\" />\n    </ComboboxPrimitive.Clear>\n  )\n}\n\nfunction ComboboxInput({\n  className,\n  children,\n  disabled = false,\n  showTrigger = true,\n  showClear = false,\n  size,\n  ...props\n}: Omit<ComboboxPrimitive.Input.Props, \"size\"> & {\n  showTrigger?: boolean\n  showClear?: boolean\n  size?: number | \"default\" | \"lg\" | \"xl\"\n}) {\n  return (\n    <InputGroup\n      size={typeof size === \"string\" ? size : \"default\"}\n      className={cn(\"w-auto\", className)}\n    >\n      <ComboboxPrimitive.Input\n        render={\n          <InputGroupInput\n            disabled={disabled}\n            size={typeof size === \"number\" ? size : undefined}\n          />\n        }\n        {...props}\n      />\n      <InputGroupAddon align=\"inline-end\">\n        {showTrigger && (\n          <InputGroupButton\n            size=\"icon-xs\"\n            variant=\"ghost\"\n            render={<ComboboxTrigger />}\n            data-slot=\"input-group-button\"\n            className=\"text-muted-foreground group-has-data-[slot=combobox-clear]/input-group:hidden hover:text-foreground data-pressed:bg-transparent\"\n            disabled={disabled}\n          />\n        )}\n        {showClear && <ComboboxClear disabled={disabled} />}\n      </InputGroupAddon>\n      {children}\n    </InputGroup>\n  )\n}\n\nfunction ComboboxContent({\n  className,\n  side = \"bottom\",\n  sideOffset = 6,\n  align = \"start\",\n  alignOffset = 0,\n  anchor,\n  ...props\n}: ComboboxPrimitive.Popup.Props &\n  Pick<\n    ComboboxPrimitive.Positioner.Props,\n    \"side\" | \"align\" | \"sideOffset\" | \"alignOffset\" | \"anchor\"\n  >) {\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=\"isolate z-50\"\n      >\n        <ComboboxPrimitive.Popup\n          data-slot=\"combobox-content\"\n          data-chips={!!anchor}\n          className={cn(\n            \"group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-14 bg-popover text-popover-foreground shadow-(--shadow-popover) ring-1 ring-border duration-100 has-[[data-slot=input-group]]:min-w-(--anchor-width) data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n            className\n          )}\n          {...props}\n        />\n      </ComboboxPrimitive.Positioner>\n    </ComboboxPrimitive.Portal>\n  )\n}\n\nfunction ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {\n  return (\n    <ComboboxPrimitive.List\n      data-slot=\"combobox-list\"\n      className={cn(\n        \"no-scrollbar max-h-[min(--spacing(66),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxItem({\n  className,\n  children,\n  ...props\n}: ComboboxPrimitive.Item.Props) {\n  return (\n    <ComboboxPrimitive.Item\n      data-slot=\"combobox-item\"\n      className={cn(\n        \"relative flex w-full cursor-default items-center gap-2 rounded-lg py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ComboboxPrimitive.ItemIndicator\n        render={\n          <span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\n        }\n      >\n        <CheckIcon className=\"pointer-events-none\" />\n      </ComboboxPrimitive.ItemIndicator>\n    </ComboboxPrimitive.Item>\n  )\n}\n\nfunction ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {\n  return (\n    <ComboboxPrimitive.Group\n      data-slot=\"combobox-group\"\n      className={className}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxLabel({\n  className,\n  ...props\n}: ComboboxPrimitive.GroupLabel.Props) {\n  return (\n    <ComboboxPrimitive.GroupLabel\n      data-slot=\"combobox-label\"\n      className={cn(\"px-2 py-1 text-2xs text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {\n  return (\n    <ComboboxPrimitive.Collection data-slot=\"combobox-collection\" {...props} />\n  )\n}\n\nfunction ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {\n  return (\n    <ComboboxPrimitive.Empty\n      data-slot=\"combobox-empty\"\n      className={cn(\n        \"hidden w-full justify-center py-2 text-center text-sm text-muted-foreground group-data-empty/combobox-content:flex\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxSeparator({\n  className,\n  ...props\n}: ComboboxPrimitive.Separator.Props) {\n  return (\n    <ComboboxPrimitive.Separator\n      data-slot=\"combobox-separator\"\n      className={cn(\"-mx-1 mt-1 mb-[3px] h-px bg-border\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxChips({\n  className,\n  children,\n  showTrigger = true,\n  ...props\n}: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> &\n  ComboboxPrimitive.Chips.Props & {\n    showTrigger?: boolean\n  }) {\n  return (\n    <ComboboxPrimitive.Chips\n      data-slot=\"combobox-chips\"\n      className={cn(\n        \"relative flex min-h-8 flex-wrap items-center gap-1 rounded-lg bg-field px-2.5 py-1.5 text-xs outline-1 -outline-offset-1 outline-field-border transition-[color,box-shadow,outline-color] duration-200 outline-solid has-aria-invalid:ring-2 has-aria-invalid:ring-destructive/20 has-aria-invalid:outline-destructive has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-ring/30 has-[:focus-visible]:outline-ring dark:has-aria-invalid:ring-destructive/40 dark:has-aria-invalid:outline-destructive/50\",\n        showTrigger && \"pr-9.5\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      {showTrigger && (\n        <ComboboxTrigger\n          render={<Button variant=\"ghost\" size=\"icon-xs\" />}\n          className=\"absolute top-1/2 right-1 -translate-y-1/2 data-pressed:bg-transparent\"\n        />\n      )}\n    </ComboboxPrimitive.Chips>\n  )\n}\n\nfunction ComboboxChip({\n  className,\n  children,\n  showRemove = true,\n  ...props\n}: ComboboxPrimitive.Chip.Props & {\n  showRemove?: boolean\n}) {\n  return (\n    <ComboboxPrimitive.Chip\n      data-slot=\"combobox-chip\"\n      className={cn(\n        \"flex h-5 w-fit items-center justify-center gap-1 rounded-full bg-control px-2 text-2xs font-medium whitespace-nowrap text-foreground shadow-xs outline-1 outline-control-border outline-solid has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0.5\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      {showRemove && (\n        <ComboboxPrimitive.ChipRemove\n          render={<Button variant=\"ghost\" size=\"icon-xs\" />}\n          className=\"size-4.5 opacity-50 hover:opacity-100 aria-disabled:pointer-events-none\"\n          data-slot=\"combobox-chip-remove\"\n          aria-label=\"Remove\"\n        >\n          <XIcon className=\"pointer-events-none size-3\" />\n        </ComboboxPrimitive.ChipRemove>\n      )}\n    </ComboboxPrimitive.Chip>\n  )\n}\n\nfunction ComboboxChipsInput({\n  className,\n  ...props\n}: ComboboxPrimitive.Input.Props) {\n  return (\n    <ComboboxPrimitive.Input\n      data-slot=\"combobox-chip-input\"\n      className={cn(\n        \"min-w-16 flex-1 text-xs outline-none [[data-slot=combobox-chip]~&]:pl-1\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction useComboboxAnchor() {\n  return React.useRef<HTMLDivElement | null>(null)\n}\n\nexport {\n  Combobox,\n  ComboboxInput,\n  ComboboxContent,\n  ComboboxList,\n  ComboboxItem,\n  ComboboxGroup,\n  ComboboxLabel,\n  ComboboxCollection,\n  ComboboxEmpty,\n  ComboboxSeparator,\n  ComboboxChips,\n  ComboboxChip,\n  ComboboxChipsInput,\n  ComboboxTrigger,\n  ComboboxValue,\n  useComboboxAnchor,\n}\n","type":"registry:ui"}],"cssVars":{"theme":{"color-field":"var(--field)","color-control":"var(--control)","color-control-border":"var(--control-border)","color-field-border":"var(--field-border)","radius-14":"0.875rem","text-2xs--letter-spacing":"-0.005em","text-xs--letter-spacing":"-0.005em","text-sm--letter-spacing":"-0.005em","text-2xs":"0.75rem","text-2xs--line-height":"calc(1 / 0.75)","text-xs":"0.8125rem","text-xs--line-height":"calc(1.25 / 0.8125)","shadow-popover":"0 10px 15px -3px oklch(0 0 0 / 7%), 0 4px 6px -4px oklch(0 0 0 / 7%)"},"light":{"field":"oklch(0.556 0 0 / 2.5%)","control":"oklch(1 0 0)","control-border":"oklch(0.145 0 0 / 10%)","field-border":"oklch(0.145 0 0 / 10%)"},"dark":{"field":"oklch(1 0 0 / 2.5%)","control":"oklch(0.237 0 0)","control-border":"oklch(1 0 0 / 10%)","field-border":"oklch(1 0 0 / 15%)"}},"categories":["forms"],"type":"registry:ui"}