{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "combobox",
  "title": "Combobox",
  "description": "Filterable select on Base UI with Mira soft-rect, popup settle, and list stagger ≤40ms.",
  "dependencies": [
    "@base-ui/react",
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "@atroui/utils",
    "@atroui/motion"
  ],
  "files": [
    {
      "path": "registry/default/ui/combobox.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react/combobox\"\nimport { Check, ChevronDown, X } from \"lucide-react\"\nimport {\n  AnimatePresence,\n  LayoutGroup,\n  motion,\n  useReducedMotion,\n} from \"motion/react\"\n\nimport {\n  easeOutExpo,\n  layoutTween,\n  menuItemVariants,\n  menuPopupMotion,\n} from \"@/lib/motion\"\nimport { cn } from \"@/lib/utils\"\n\n/** Layered pop elevation — ring-as-border + cast stack + top light. */\nconst overlayElevation = \"ds-elev-pop\"\n\ntype ComboboxOpenContextValue = {\n  open: boolean\n}\n\nconst ComboboxOpenContext =\n  React.createContext<ComboboxOpenContextValue | null>(null)\n\ntype ComboboxHighlightContextValue = {\n  layoutId: string\n  activeId: string | null\n  setActiveId: (id: string | null) => void\n  reduce: boolean | null\n}\n\nconst ComboboxHighlightContext =\n  React.createContext<ComboboxHighlightContextValue | null>(null)\n\nfunction useComboboxOpen() {\n  const ctx = React.useContext(ComboboxOpenContext)\n  if (!ctx) {\n    throw new Error(\"Combobox parts must be used within <Combobox>\")\n  }\n  return ctx.open\n}\n\nfunction Combobox({\n  open: openProp,\n  defaultOpen = false,\n  onOpenChange,\n  ...props\n}: React.ComponentProps<typeof ComboboxPrimitive.Root>) {\n  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen)\n  const isControlled = openProp !== undefined\n  const open = isControlled ? openProp : uncontrolledOpen\n\n  const handleOpenChange = React.useCallback(\n    (next: boolean, eventDetails: Parameters<\n      NonNullable<\n        React.ComponentProps<typeof ComboboxPrimitive.Root>[\"onOpenChange\"]\n      >\n    >[1]) => {\n      if (!isControlled) setUncontrolledOpen(next)\n      onOpenChange?.(next, eventDetails)\n    },\n    [isControlled, onOpenChange]\n  )\n\n  return (\n    <ComboboxOpenContext.Provider value={{ open }}>\n      <ComboboxPrimitive.Root\n        data-slot=\"combobox\"\n        open={open}\n        onOpenChange={handleOpenChange}\n        {...props}\n      />\n    </ComboboxOpenContext.Provider>\n  )\n}\n\nfunction ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {\n  return <ComboboxPrimitive.Value data-slot=\"combobox-value\" {...props} />\n}\n\nfunction ComboboxInputGroup({\n  className,\n  ...props\n}: ComboboxPrimitive.InputGroup.Props) {\n  return (\n    <ComboboxPrimitive.InputGroup\n      data-slot=\"combobox-input-group\"\n      className={cn(\n        \"flex h-[var(--atro-control-height,2.25rem)] w-full min-w-0 items-center gap-1 rounded-[var(--atro-control-radius,var(--radius))] border border-border-subtle bg-background px-2\",\n        \"transition-[border-color,box-shadow] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)]\",\n        \"focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/20\",\n        \"has-aria-invalid:border-destructive has-aria-invalid:ring-2 has-aria-invalid:ring-destructive/20\",\n        \"has-data-disabled:opacity-50\",\n        \"motion-reduce:transition-none\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxInput({\n  className,\n  ...props\n}: ComboboxPrimitive.Input.Props) {\n  return (\n    <ComboboxPrimitive.Input\n      data-slot=\"combobox-input\"\n      className={cn(\n        \"h-full min-w-0 flex-1 bg-transparent px-1 text-base text-foreground outline-none sm:text-sm\",\n        \"placeholder:text-muted-foreground\",\n        \"disabled:cursor-not-allowed\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxTrigger({\n  className,\n  children,\n  ...props\n}: ComboboxPrimitive.Trigger.Props) {\n  const open = useComboboxOpen()\n  const reduce = useReducedMotion()\n\n  return (\n    <ComboboxPrimitive.Trigger\n      data-slot=\"combobox-trigger\"\n      className={cn(\n        \"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius)-2px)] text-muted-foreground outline-none\",\n        \"hover:bg-muted/60 hover:text-foreground\",\n        \"focus-visible:ring-2 focus-visible:ring-ring/20\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? (\n        <motion.span\n          aria-hidden\n          className=\"inline-flex\"\n          animate={{ rotate: open ? 180 : 0 }}\n          transition={\n            reduce ? { duration: 0 } : { duration: 0.2, ease: easeOutExpo }\n          }\n        >\n          <ChevronDown className=\"size-4\" />\n        </motion.span>\n      )}\n    </ComboboxPrimitive.Trigger>\n  )\n}\n\nfunction ComboboxClear({\n  className,\n  ...props\n}: ComboboxPrimitive.Clear.Props) {\n  return (\n    <ComboboxPrimitive.Clear\n      data-slot=\"combobox-clear\"\n      className={cn(\n        \"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius)-2px)] text-muted-foreground outline-none\",\n        \"hover:bg-muted/60 hover:text-foreground\",\n        \"focus-visible:ring-2 focus-visible:ring-ring/20\",\n        \"data-disabled:pointer-events-none\",\n        className\n      )}\n      {...props}\n    >\n      <X className=\"size-3.5\" strokeWidth={1.75} />\n      <span className=\"sr-only\">Clear</span>\n    </ComboboxPrimitive.Clear>\n  )\n}\n\nfunction ComboboxIcon({ className, ...props }: ComboboxPrimitive.Icon.Props) {\n  return (\n    <ComboboxPrimitive.Icon\n      data-slot=\"combobox-icon\"\n      className={cn(\"inline-flex shrink-0 text-muted-foreground\", className)}\n      {...props}\n    >\n      <ChevronDown className=\"size-4\" />\n    </ComboboxPrimitive.Icon>\n  )\n}\n\nfunction ComboboxContent({\n  className,\n  align = \"start\",\n  alignOffset = 0,\n  side = \"bottom\",\n  sideOffset = 6,\n  render,\n  onMouseLeave,\n  ...props\n}: ComboboxPrimitive.Popup.Props &\n  Pick<\n    ComboboxPrimitive.Positioner.Props,\n    \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n  >) {\n  const open = useComboboxOpen()\n  const reduce = useReducedMotion()\n  const groupId = React.useId()\n  const [activeId, setActiveId] = React.useState<string | null>(null)\n\n  const highlight = React.useMemo<ComboboxHighlightContextValue>(\n    () => ({\n      layoutId: `${groupId}-ink`,\n      activeId,\n      setActiveId,\n      reduce: reduce ?? false,\n    }),\n    [activeId, groupId, reduce]\n  )\n\n  return (\n    <AnimatePresence>\n      {open ? (\n        <ComboboxPrimitive.Portal keepMounted>\n          <ComboboxPrimitive.Positioner\n            className=\"isolate z-50 outline-none\"\n            align={align}\n            alignOffset={alignOffset}\n            side={side}\n            sideOffset={sideOffset}\n          >\n            <LayoutGroup id={groupId}>\n              <ComboboxHighlightContext.Provider value={highlight}>\n                <ComboboxPrimitive.Popup\n                  data-slot=\"combobox-content\"\n                  className={cn(\n                    \"z-50 max-h-(--available-height) min-w-(--anchor-width) origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-[var(--radius)] bg-popover p-1 text-popover-foreground outline-none\",\n                    \"data-closed:overflow-hidden\",\n                    overlayElevation,\n                    className\n                  )}\n                  render={render ?? <motion.div {...menuPopupMotion(reduce)} />}\n                  onMouseLeave={(event) => {\n                    setActiveId(null)\n                    onMouseLeave?.(event)\n                  }}\n                  {...props}\n                />\n              </ComboboxHighlightContext.Provider>\n            </LayoutGroup>\n          </ComboboxPrimitive.Positioner>\n        </ComboboxPrimitive.Portal>\n      ) : null}\n    </AnimatePresence>\n  )\n}\n\nfunction ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {\n  const reduce = useReducedMotion()\n\n  return (\n    <ComboboxPrimitive.List\n      data-slot=\"combobox-list\"\n      className={cn(\n        \"max-h-[min(280px,var(--available-height))] scroll-py-1 overflow-y-auto outline-none\",\n        className\n      )}\n      render={\n        reduce\n          ? undefined\n          : (\n              <motion.div\n                variants={{\n                  closed: {},\n                  open: {\n                    transition: {\n                      staggerChildren: 0.04,\n                      delayChildren: 0.02,\n                    },\n                  },\n                }}\n              />\n            )\n      }\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxHighlight({ itemId }: { itemId: string }) {\n  const highlight = React.useContext(ComboboxHighlightContext)\n  if (!highlight || highlight.reduce || highlight.activeId !== itemId) {\n    return null\n  }\n  return (\n    <motion.span\n      layoutId={highlight.layoutId}\n      className=\"absolute inset-0 z-0 rounded-[calc(var(--radius)-2px)] bg-muted\"\n      transition={layoutTween}\n      aria-hidden\n    />\n  )\n}\n\nconst itemBase =\n  \"relative flex cursor-default items-center gap-2 rounded-[calc(var(--radius)-2px)] px-2 py-1.5 text-[0.8125rem] outline-none select-none\"\n\nfunction ComboboxItem({\n  className,\n  children,\n  onMouseEnter,\n  onFocus,\n  ...props\n}: ComboboxPrimitive.Item.Props) {\n  const itemId = React.useId()\n  const highlight = React.useContext(ComboboxHighlightContext)\n  const reduce = highlight?.reduce ?? false\n\n  return (\n    <ComboboxPrimitive.Item\n      data-slot=\"combobox-item\"\n      className={cn(\n        itemBase,\n        reduce\n          ? \"data-highlighted:bg-muted data-highlighted:text-foreground\"\n          : \"data-highlighted:text-foreground\",\n        \"data-disabled:pointer-events-none data-disabled:opacity-50\",\n        className\n      )}\n      render={\n        reduce ? undefined : <motion.div variants={menuItemVariants} />\n      }\n      onMouseEnter={(event) => {\n        highlight?.setActiveId(itemId)\n        onMouseEnter?.(event)\n      }}\n      onFocus={(event) => {\n        highlight?.setActiveId(itemId)\n        onFocus?.(event)\n      }}\n      {...props}\n    >\n      <ComboboxHighlight itemId={itemId} />\n      <span className=\"relative z-[1] flex min-w-0 flex-1 items-center gap-2\">\n        {children}\n      </span>\n    </ComboboxPrimitive.Item>\n  )\n}\n\nfunction ComboboxItemIndicator({\n  className,\n  ...props\n}: ComboboxPrimitive.ItemIndicator.Props) {\n  return (\n    <ComboboxPrimitive.ItemIndicator\n      data-slot=\"combobox-item-indicator\"\n      className={cn(\n        \"ml-auto inline-flex size-3.5 shrink-0 items-center justify-center text-foreground\",\n        className\n      )}\n      {...props}\n    >\n      <Check className=\"size-3\" />\n    </ComboboxPrimitive.ItemIndicator>\n  )\n}\n\nfunction ComboboxEmpty({\n  className,\n  ...props\n}: ComboboxPrimitive.Empty.Props) {\n  return (\n    <ComboboxPrimitive.Empty\n      data-slot=\"combobox-empty\"\n      className={cn(\n        \"px-2 py-3 text-center text-[0.8125rem] text-muted-foreground\",\n        className\n      )}\n      {...props}\n    />\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}: ComboboxPrimitive.GroupLabel.Props) {\n  return (\n    <ComboboxPrimitive.GroupLabel\n      data-slot=\"combobox-group-label\"\n      className={cn(\n        \"px-2 py-1 text-[0.6875rem] font-medium tracking-wide text-muted-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxLabel({\n  className,\n  ...props\n}: ComboboxPrimitive.Label.Props) {\n  return (\n    <ComboboxPrimitive.Label\n      data-slot=\"combobox-label\"\n      className={cn(\n        \"mb-1.5 block text-[0.8125rem] font-medium text-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction ComboboxCollection({\n  ...props\n}: ComboboxPrimitive.Collection.Props) {\n  return (\n    <ComboboxPrimitive.Collection data-slot=\"combobox-collection\" {...props} />\n  )\n}\n\nexport {\n  Combobox,\n  ComboboxClear,\n  ComboboxCollection,\n  ComboboxContent,\n  ComboboxEmpty,\n  ComboboxGroup,\n  ComboboxGroupLabel,\n  ComboboxIcon,\n  ComboboxInput,\n  ComboboxInputGroup,\n  ComboboxItem,\n  ComboboxItemIndicator,\n  ComboboxLabel,\n  ComboboxList,\n  ComboboxTrigger,\n  ComboboxValue,\n}\n",
      "type": "registry:ui",
      "target": "components/ui/combobox.tsx"
    }
  ],
  "type": "registry:ui"
}