{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "autocomplete",
  "title": "Autocomplete",
  "description": "A autocomplete component.",
  "dependencies": [
    "@hugeicons/react",
    "@hugeicons/core-free-icons"
  ],
  "registryDependencies": [
    "@cubby-ui/scroll-area",
    "@cubby-ui/elevated"
  ],
  "files": [
    {
      "path": "registry/default/autocomplete/autocomplete.tsx",
      "content": "import * as React from \"react\";\nimport { Autocomplete as BaseAutocomplete } from \"@base-ui/react/autocomplete\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  elevatedSurface,\n  type SurfaceLevel,\n} from \"@/registry/default/lib/elevated\";\nimport {\n  ScrollArea,\n  type ScrollAreaProps,\n} from \"@/registry/default/scroll-area/scroll-area\";\n\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport ArrowDown01Icon from \"@hugeicons/core-free-icons/ArrowDown01Icon\";\nimport Cancel01Icon from \"@hugeicons/core-free-icons/Cancel01Icon\";\nconst AutocompleteRoot = BaseAutocomplete.Root;\n\nfunction AutocompleteInput({\n  className,\n  showTrigger = false,\n  showClear = false,\n  variant = \"default\",\n  ...props\n}: BaseAutocomplete.Input.Props & {\n  showTrigger?: boolean;\n  showClear?: boolean;\n  variant?: \"default\" | \"elevated\";\n}) {\n  return (\n    <BaseAutocomplete.InputGroup\n      data-slot=\"autocomplete-input-group\"\n      className={cn(\n        \"relative\",\n        \"has-data-[slot=autocomplete-clear]:**:data-[slot=autocomplete-input]:pr-7\",\n        \"has-data-[slot=autocomplete-trigger]:**:data-[slot=autocomplete-input]:pr-7\",\n        \"has-data-[slot=autocomplete-clear]:has-data-[slot=autocomplete-trigger]:**:data-[slot=autocomplete-input]:pr-13\",\n      )}\n    >\n      <BaseAutocomplete.Input\n        data-slot=\"autocomplete-input\"\n        className={cn(\n          \"placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground flex h-10 w-full min-w-0 rounded-lg border bg-clip-padding px-3 text-base font-normal disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-60 sm:h-9 md:text-sm\",\n          variant === \"default\" ? \"bg-input\" : \"bg-input-elevated\",\n          \"file:text-foreground file:inline-flex file:h-7 file:rounded-md file:border-0 file:bg-transparent file:text-sm file:font-medium\",\n          \"focus-visible:outline-ring/50 outline-0 outline-offset-0 outline-transparent transition-[outline-width,outline-offset,outline-color] duration-100 ease-out outline-solid focus-visible:outline-2 focus-visible:outline-offset-2\",\n          \"aria-invalid:outline-destructive/50 aria-invalid:outline-2 aria-invalid:outline-offset-2 aria-invalid:outline-solid\",\n          className,\n        )}\n        {...props}\n      />\n      {(showClear || showTrigger) && (\n        <div className=\"absolute inset-y-0 right-3 flex items-center gap-2\">\n          {showClear && <AutocompleteClear />}\n          {showTrigger && <AutocompleteTrigger />}\n        </div>\n      )}\n    </BaseAutocomplete.InputGroup>\n  );\n}\n\nfunction AutocompleteTrigger({\n  className,\n  children,\n  ...props\n}: BaseAutocomplete.Trigger.Props) {\n  return (\n    <BaseAutocomplete.Trigger\n      data-slot=\"autocomplete-trigger\"\n      aria-label=\"Open popup\"\n      className={cn(\n        \"inline-flex size-4 cursor-pointer items-center justify-center rounded-md border-none bg-transparent p-0 text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-60\",\n        \"focus-visible:ring-ring/70 outline-none focus-visible:ring-2\",\n        className,\n      )}\n      {...props}\n    >\n      {children ?? (\n        <HugeiconsIcon\n          icon={ArrowDown01Icon}\n          className=\"h-4 w-4\"\n          strokeWidth={2}\n        />\n      )}\n    </BaseAutocomplete.Trigger>\n  );\n}\n\nfunction AutocompleteIcon({\n  className,\n  ...props\n}: React.ComponentProps<typeof BaseAutocomplete.Icon>) {\n  return (\n    <BaseAutocomplete.Icon\n      data-slot=\"autocomplete-icon\"\n      className={cn(\"ml-2 h-4 w-4 shrink-0 opacity-50\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteClear({\n  className,\n  children,\n  ...props\n}: BaseAutocomplete.Clear.Props) {\n  return (\n    <BaseAutocomplete.Clear\n      data-slot=\"autocomplete-clear\"\n      aria-label=\"Clear selection\"\n      className={cn(\n        \"inline-flex h-4 w-4 cursor-pointer items-center justify-center rounded-sm opacity-70 transition-[opacity,scale,transform,translate] hover:opacity-100 disabled:pointer-events-none\",\n        \"focus-visible:ring-ring/70 duration-100 outline-none focus-visible:ring-2\",\n        \"data-ending-style:translate-x-1 data-ending-style:opacity-0 data-starting-style:translate-x-1 data-starting-style:opacity-0\",\n        className,\n      )}\n      {...props}\n    >\n      {children ?? (\n        <HugeiconsIcon\n          icon={Cancel01Icon}\n          className=\"h-4 w-4\"\n          strokeWidth={2}\n        />\n      )}\n    </BaseAutocomplete.Clear>\n  );\n}\n\nfunction AutocompleteValue({ ...props }: BaseAutocomplete.Value.Props) {\n  return <BaseAutocomplete.Value data-slot=\"autocomplete-value\" {...props} />;\n}\n\nfunction AutocompletePortal({ ...props }: BaseAutocomplete.Portal.Props) {\n  return <BaseAutocomplete.Portal data-slot=\"autocomplete-portal\" {...props} />;\n}\n\nfunction AutocompleteBackdrop({\n  className,\n  ...props\n}: BaseAutocomplete.Backdrop.Props) {\n  return (\n    <BaseAutocomplete.Backdrop\n      data-slot=\"autocomplete-backdrop\"\n      className={cn(\n        \"fixed inset-0 z-30 bg-black/50 data-ending-style:opacity-0 data-starting-style:opacity-0\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompletePositioner({\n  className,\n  ...props\n}: BaseAutocomplete.Positioner.Props) {\n  return (\n    <BaseAutocomplete.Positioner\n      data-slot=\"autocomplete-positioner\"\n      sideOffset={4}\n      className={cn(\"\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompletePopup({\n  className,\n  level = 3,\n  shadowLevel = 3,\n  ...props\n}: BaseAutocomplete.Popup.Props & {\n  /** Surface elevation level for the popup bg (1-8). Bump when nesting inside a Dialog. Defaults to 3. */\n  level?: SurfaceLevel;\n  /** Shadow weight (1-8). Pinned to 3 by default so the autocomplete reads the same regardless of nesting depth. */\n  shadowLevel?: SurfaceLevel;\n}) {\n  return (\n    <BaseAutocomplete.Popup\n      data-slot=\"autocomplete-popup\"\n      data-level={level}\n      className={cn(\n        \"text-popover-foreground ease-out-expo flex max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) origin-(--transform-origin) flex-col overflow-clip overscroll-contain rounded-xl transition-[transform,scale,opacity] duration-100 data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0\",\n        // Use elevatedSurface (rim on ::after) because group labels can be\n        // sticky and would otherwise hide the rim where they sit.\n        elevatedSurface(level, shadowLevel),\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteArrow({\n  className,\n  ...props\n}: BaseAutocomplete.Arrow.Props) {\n  return (\n    <BaseAutocomplete.Arrow\n      data-slot=\"autocomplete-arrow\"\n      className={cn(\n        \"data-[side=bottom]:top-[-8px] data-[side=left]:right-[-13px] data-[side=left]:rotate-90 data-[side=right]:left-[-13px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180\",\n        className,\n      )}\n      {...props}\n    >\n      <svg width=\"20\" height=\"10\" viewBox=\"0 0 20 10\" fill=\"none\">\n        <path\n          d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V9H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n          className=\"fill-(--popup-surface,var(--popover))\"\n        />\n        <path\n          d=\"M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z\"\n          className=\"fill-border/70\"\n        />\n      </svg>\n    </BaseAutocomplete.Arrow>\n  );\n}\n\nfunction AutocompleteStatus({\n  className,\n  ...props\n}: BaseAutocomplete.Status.Props) {\n  return (\n    <BaseAutocomplete.Status\n      data-slot=\"autocomplete-status\"\n      className={cn(\n        \"text-muted-foreground px-3 py-2.5 text-sm leading-5 empty:m-0 empty:p-0\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteEmpty({\n  className,\n  ...props\n}: BaseAutocomplete.Empty.Props) {\n  return (\n    <BaseAutocomplete.Empty\n      data-slot=\"autocomplete-empty\"\n      className={cn(\n        \"text-muted-foreground px-3 py-2.5 text-sm empty:m-0 empty:p-0\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteList({\n  className,\n  nativeScroll = false,\n  fadeEdges = true,\n  scrollbarGutter = false,\n  persistScrollbar,\n  hideScrollbar,\n  ...props\n}: BaseAutocomplete.List.Props &\n  Pick<\n    ScrollAreaProps,\n    | \"nativeScroll\"\n    | \"fadeEdges\"\n    | \"scrollbarGutter\"\n    | \"persistScrollbar\"\n    | \"hideScrollbar\"\n  >) {\n  return (\n    <ScrollArea\n      nativeScroll={nativeScroll}\n      fadeEdges={fadeEdges}\n      scrollbarGutter={scrollbarGutter}\n      persistScrollbar={persistScrollbar}\n      hideScrollbar={hideScrollbar}\n      className={cn(\"max-h-80\", className)}\n    >\n      <BaseAutocomplete.List\n        data-slot=\"autocomplete-list\"\n        className=\"rounded-xl\"\n        {...props}\n      />\n    </ScrollArea>\n  );\n}\n\nfunction AutocompleteVirtualizedList({\n  className,\n  children,\n  scrollRef,\n  totalSize,\n  emptyMessage = \"No results found.\",\n  fadeEdges = \"y\",\n  nativeScroll = false,\n  ...props\n}: Omit<React.ComponentProps<\"div\">, \"ref\"> &\n  Pick<ScrollAreaProps, \"fadeEdges\" | \"nativeScroll\"> & {\n    scrollRef: (element: HTMLDivElement | null) => void;\n    totalSize: number;\n    emptyMessage?: React.ReactNode;\n  }) {\n  return (\n    <>\n      <BaseAutocomplete.Empty\n        data-slot=\"autocomplete-empty\"\n        className=\"text-muted-foreground px-3 py-2.5 text-sm empty:m-0 empty:p-0\"\n      >\n        {emptyMessage}\n      </BaseAutocomplete.Empty>\n      <BaseAutocomplete.List\n        data-slot=\"autocomplete-list\"\n        className=\"w-full flex-1 overflow-hidden rounded-xl p-0 outline-hidden empty:m-0 empty:p-0\"\n      >\n        <ScrollArea\n          viewportRef={scrollRef}\n          viewportClassName={cn(\"scroll-py-2\", className)}\n          fadeEdges={fadeEdges}\n          nativeScroll={nativeScroll}\n          className=\"h-auto max-h-80 w-full\"\n          {...props}\n        >\n          {/* Virtual placeholder for total height */}\n          <div\n            role=\"presentation\"\n            className=\"relative w-full\"\n            style={{ height: totalSize }}\n          >\n            {children}\n          </div>\n        </ScrollArea>\n      </BaseAutocomplete.List>\n    </>\n  );\n}\n\nfunction AutocompleteCollection({\n  ...props\n}: BaseAutocomplete.Collection.Props) {\n  return (\n    <BaseAutocomplete.Collection\n      data-slot=\"autocomplete-collection\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteRow({ className, ...props }: BaseAutocomplete.Row.Props) {\n  return (\n    <BaseAutocomplete.Row\n      data-slot=\"autocomplete-row\"\n      className={cn(\"flex\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteItem({\n  className,\n  ref,\n  ...props\n}: BaseAutocomplete.Item.Props & {\n  ref?: React.Ref<HTMLDivElement>;\n}) {\n  return (\n    <BaseAutocomplete.Item\n      ref={ref}\n      data-slot=\"autocomplete-item\"\n      className={cn(\n        \"data-highlighted:text-accent-foreground data-highlighted:bg-surface-hover relative flex cursor-default items-center rounded-md px-2.5 py-2 text-sm outline-none select-none data-disabled:pointer-events-none data-disabled:opacity-60\",\n        // Spacing from list edges\n        \"mx-1 first:mt-1 last:mb-1\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteGroup({\n  className,\n  ...props\n}: BaseAutocomplete.Group.Props) {\n  return (\n    <BaseAutocomplete.Group\n      data-slot=\"autocomplete-group\"\n      className={cn(\"text-foreground block\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteGroupLabel({\n  className,\n  ...props\n}: BaseAutocomplete.GroupLabel.Props) {\n  return (\n    <BaseAutocomplete.GroupLabel\n      data-slot=\"autocomplete-group-label\"\n      className={cn(\n        \"text-muted-foreground bg-(--popup-surface,var(--popover)) px-3.5 py-1.5 pt-2.5 text-xs font-semibold\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteSeparator({\n  className,\n  ...props\n}: BaseAutocomplete.Separator.Props) {\n  return (\n    <BaseAutocomplete.Separator\n      data-slot=\"autocomplete-separator\"\n      className={cn(\"bg-border mx-1 my-1 h-px min-h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nexport const Autocomplete = {\n  Root: AutocompleteRoot,\n  Input: AutocompleteInput,\n  Trigger: AutocompleteTrigger,\n  Icon: AutocompleteIcon,\n  Clear: AutocompleteClear,\n  Value: AutocompleteValue,\n  Portal: AutocompletePortal,\n  Backdrop: AutocompleteBackdrop,\n  Positioner: AutocompletePositioner,\n  Popup: AutocompletePopup,\n  Arrow: AutocompleteArrow,\n  Status: AutocompleteStatus,\n  Empty: AutocompleteEmpty,\n  List: AutocompleteList,\n  VirtualizedList: AutocompleteVirtualizedList,\n  Collection: AutocompleteCollection,\n  Row: AutocompleteRow,\n  Item: AutocompleteItem,\n  Group: AutocompleteGroup,\n  GroupLabel: AutocompleteGroupLabel,\n  Separator: AutocompleteSeparator,\n};\n\nconst useAutocompleteFilter = BaseAutocomplete.useFilter;\nconst useAutocompleteFilteredItems = BaseAutocomplete.useFilteredItems;\n\nexport {\n  AutocompleteRoot,\n  AutocompleteInput,\n  AutocompleteTrigger,\n  AutocompleteIcon,\n  AutocompleteClear,\n  AutocompleteValue,\n  AutocompletePortal,\n  AutocompleteBackdrop,\n  AutocompletePositioner,\n  AutocompletePopup,\n  AutocompleteArrow,\n  AutocompleteStatus,\n  AutocompleteEmpty,\n  AutocompleteList,\n  AutocompleteVirtualizedList,\n  AutocompleteCollection,\n  AutocompleteRow,\n  AutocompleteItem,\n  AutocompleteGroup,\n  AutocompleteGroupLabel,\n  AutocompleteSeparator,\n  useAutocompleteFilter,\n  useAutocompleteFilteredItems,\n};\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/autocomplete.tsx"
    }
  ],
  "type": "registry:ui"
}