{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "b-autocomplete",
  "type": "registry:ui",
  "registryDependencies": [],
  "dependencies": ["@base-ui/react", "motion", "lucide-react"],
  "devDependencies": [],
  "files": [
    {
      "path": "b-autocomplete.tsx",
      "content": "\"use client\";\n\nimport { Autocomplete as AutocompletePrimitive } from \"@base-ui/react/autocomplete\";\nimport { Input as InputPrimitive } from \"@base-ui/react/input\";\nimport { ScrollArea as ScrollAreaPrimitive } from \"@base-ui/react/scroll-area\";\nimport { ChevronsUpDown, X } from \"lucide-react\";\nimport { motion, useReducedMotion } from \"motion/react\";\nimport * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst controlCornerClassName =\n  \"rounded-lg supports-[corner-shape:squircle]:corner-squircle supports-[corner-shape:squircle]:rounded-[11px]\";\n\nconst controlCornerInheritClassName =\n  \"rounded-[inherit] supports-[corner-shape:squircle]:[corner-shape:inherit]\";\n\nconst componentThemeClassName =\n  \"[--ic-background:#ffffff] [--ic-foreground:#111111] [--ic-primary:#111111] [--ic-secondary:#646b75] [--ic-surface-border:#e9edf2] [--ic-border:#e3e7ec] [--ic-card:#ffffff] [--ic-card-foreground:#111111] [--ic-muted:#f5f7fa] [--ic-muted-foreground:#6d7480] [--ic-accent:#f3f5f8] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] [--ic-accent-foreground:#111111] [--ic-input:#e3e7ec] [--ic-ring:rgba(17,17,17,0.16)] [--ic-destructive:#dc2626] [--ic-paper:#fcfcfd] [--ic-popover-foreground:#111111] [--ic-brand:#0ea5e9] [--ic-brand-soft:#bae6fd] [--ic-shadow-soft:0_18px_38px_-24px_rgba(15,23,42,0.35)] [--ic-chart-1:oklch(0.52_0.19_254)] [--ic-chart-2:oklch(0.74_0.11_232)] [--ic-chart-3:oklch(0.42_0.16_262)] [--ic-chart-4:oklch(0.84_0.07_228)] [--ic-chart-5:oklch(0.62_0.14_240)] [--color-background:var(--ic-background)] [--color-foreground:var(--ic-foreground)] [--color-primary:var(--ic-primary)] [--color-secondary:var(--ic-secondary)] [--color-border:var(--ic-border)] [--color-card:var(--ic-card)] [--color-card-foreground:var(--ic-card-foreground)] [--color-muted:var(--ic-muted)] [--color-muted-foreground:var(--ic-muted-foreground)] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] [--color-input:var(--ic-input)] [--color-ring:var(--ic-ring)] [--color-destructive:var(--ic-destructive)] [--color-paper:var(--ic-paper)] [--color-popover-foreground:var(--ic-popover-foreground)] [--color-brand:var(--ic-brand)] [--color-brand-soft:var(--ic-brand-soft)] [--color-chart-1:var(--ic-chart-1)] [--color-chart-2:var(--ic-chart-2)] [--color-chart-3:var(--ic-chart-3)] [--color-chart-4:var(--ic-chart-4)] [--color-chart-5:var(--ic-chart-5)] dark:[--ic-background:#111111] dark:[--ic-foreground:#f6f3ec] dark:[--ic-primary:#f6f3ec] dark:[--ic-secondary:#cbc6bb] dark:[--ic-surface-border:#2a2a25] dark:[--ic-border:#2b2a25] dark:[--ic-card:#111111] dark:[--ic-card-foreground:#f6f3ec] dark:[--ic-muted:#171716] dark:[--ic-muted-foreground:#9a958a] dark:[--ic-accent:#1a1a18] [--color-accent:var(--ic-accent)] [--color-accent-foreground:var(--ic-accent-foreground)] dark:[--ic-accent-foreground:#f6f3ec] dark:[--ic-input:#2b2a25] dark:[--ic-ring:rgba(246,243,236,0.18)] dark:[--ic-destructive:#f87171] dark:[--ic-paper:#171716] dark:[--ic-popover-foreground:#f6f3ec] dark:[--ic-brand:#38bdf8] dark:[--ic-brand-soft:#0c4a6e] dark:[--ic-shadow-soft:0_20px_44px_-28px_rgba(0,0,0,0.6)] dark:[--ic-chart-1:oklch(0.68_0.17_250)] dark:[--ic-chart-2:oklch(0.82_0.09_225)] dark:[--ic-chart-3:oklch(0.58_0.15_260)] dark:[--ic-chart-4:oklch(0.75_0.12_235)] dark:[--ic-chart-5:oklch(0.88_0.06_220)]\";\n\ntype AutocompleteRootProps<Value> = Omit<\n  AutocompletePrimitive.Root.Props<Value>,\n  \"items\"\n> & {\n  items: readonly Value[];\n};\n\nconst INSTANT_TRANSITION = { duration: 0 } as const;\n\ntype AutocompleteContextValue = {\n  actionsRef: React.RefObject<AutocompletePrimitive.Root.Actions | null>;\n  activeHighlightId: string;\n  activeValue: unknown;\n  open: boolean;\n  prefersReducedMotion: boolean;\n  setActiveValue: React.Dispatch<React.SetStateAction<unknown>>;\n  setOpen: (open: boolean) => void;\n  skipExitAnimationRef: React.MutableRefObject<boolean>;\n};\n\ntype DivRenderProps = React.HTMLAttributes<HTMLDivElement> & {\n  children?: React.ReactNode;\n  className?: string;\n  ref?: React.Ref<HTMLDivElement>;\n  style?: React.CSSProperties;\n};\n\ntype InputRenderProps = React.InputHTMLAttributes<HTMLInputElement> & {\n  className?: string;\n  ref?: React.Ref<HTMLInputElement>;\n  style?: React.CSSProperties;\n};\n\nconst AutocompleteContext =\n  React.createContext<AutocompleteContextValue | null>(null);\n\nfunction useAutocompleteContext(componentName: string) {\n  const context = React.useContext(AutocompleteContext);\n\n  if (!context) {\n    throw new Error(`${componentName} must be used inside Autocomplete`);\n  }\n\n  return context;\n}\n\nfunction setRef<T>(ref: React.Ref<T> | undefined, value: T | null) {\n  if (typeof ref === \"function\") {\n    ref(value);\n    return;\n  }\n\n  if (ref) {\n    (ref as React.MutableRefObject<T | null>).current = value;\n  }\n}\n\nfunction composeEventHandlers<Event extends React.SyntheticEvent>(\n  originalEventHandler: ((event: Event) => void) | undefined,\n  eventHandler: (event: Event) => void\n) {\n  return (event: Event) => {\n    originalEventHandler?.(event);\n\n    if (!event.defaultPrevented) {\n      eventHandler(event);\n    }\n  };\n}\n\nfunction resolveStateClassName<State>(\n  className: string | ((state: State) => string | undefined) | undefined,\n  state: State\n) {\n  return typeof className === \"function\" ? className(state) : className;\n}\n\nfunction resolvePopupProps(popupProps: DivRenderProps) {\n  const {\n    children: _popupChildren,\n    className: popupClassName,\n    onAnimationEnd: _onAnimationEnd,\n    onAnimationIteration: _onAnimationIteration,\n    onAnimationStart: _onAnimationStart,\n    onDrag: _onDrag,\n    onDragEnd: _onDragEnd,\n    onDragEnter: _onDragEnter,\n    onDragExit: _onDragExit,\n    onDragLeave: _onDragLeave,\n    onDragOver: _onDragOver,\n    onDragStart: _onDragStart,\n    onDrop: _onDrop,\n    ref: popupRef,\n    style: popupStyle,\n    ...resolvedPopupProps\n  } = popupProps;\n\n  return {\n    popupClassName,\n    popupRef,\n    popupStyle,\n    resolvedPopupProps,\n  };\n}\n\nfunction resolveItemProps(itemProps: DivRenderProps) {\n  const {\n    children: _itemChildren,\n    className: itemClassName,\n    onAnimationEnd: _onAnimationEnd,\n    onAnimationIteration: _onAnimationIteration,\n    onAnimationStart: _onAnimationStart,\n    onDrag: _onDrag,\n    onDragEnd: _onDragEnd,\n    onDragEnter: _onDragEnter,\n    onDragExit: _onDragExit,\n    onDragLeave: _onDragLeave,\n    onDragOver: _onDragOver,\n    onDragStart: _onDragStart,\n    onDrop: _onDrop,\n    ref: itemRef,\n    style: itemStyle,\n    ...resolvedItemProps\n  } = itemProps;\n\n  return {\n    itemClassName,\n    itemRef,\n    itemStyle,\n    resolvedItemProps,\n  };\n}\n\nconst FLUID_EASE = [0.16, 1, 0.3, 1] as const;\nconst EXIT_EASE = [0.4, 0, 0.6, 1] as const;\n\nconst POPUP_SPRING = {\n  type: \"spring\" as const,\n  stiffness: 260,\n  damping: 32,\n  mass: 0.95,\n};\n\nconst HIGHLIGHT_SPRING = {\n  type: \"spring\" as const,\n  stiffness: 460,\n  damping: 40,\n  mass: 0.82,\n};\n\nconst popupMotion = {\n  animate: { opacity: 1, scale: 1, y: 0 },\n  closed: { opacity: 0, scale: 0.985, y: -5 },\n  initial: { opacity: 0, scale: 0.985, y: -5 },\n  openTransition: {\n    opacity: { duration: 0.34, ease: FLUID_EASE },\n    scale: POPUP_SPRING,\n    y: POPUP_SPRING,\n  },\n  closedTransition: {\n    opacity: { duration: 0.22, ease: EXIT_EASE },\n    scale: { duration: 0.22, ease: EXIT_EASE },\n    y: { duration: 0.22, ease: EXIT_EASE },\n  },\n};\n\nconst autocompleteListScrollbarClassName =\n  \"z-10 my-1.5 mr-0.5 w-1 shrink-0 touch-none select-none opacity-0 transition-opacity duration-150 before:absolute before:left-1/2 before:h-full before:w-5 before:-translate-x-1/2 before:content-[''] data-hovering:pointer-events-auto data-hovering:opacity-100 data-scrolling:pointer-events-auto data-scrolling:opacity-100 data-scrolling:duration-0\";\n\nconst autocompleteListThumbClassName =\n  \"relative rounded-full bg-muted-foreground/50 bg-[color:color-mix(in_oklch,var(--ic-muted-foreground),transparent_35%)]\";\n\nconst autocompleteInputShellClassName =\n  \"group flex h-11 w-full items-center gap-1 border border-input bg-background pl-3 pr-2 text-base transition-[border-color,box-shadow] sm:text-sm hover:border-ring/40 focus-within:border-ring focus-within:ring-1 focus-within:ring-ring/25 [&:has(input[aria-invalid=true])]:border-destructive [&:has(input[aria-invalid=true])]:ring-1 [&:has(input[aria-invalid=true])]:ring-destructive/20 dark:[&:has(input[aria-invalid=true])]:border-destructive/50 dark:[&:has(input[aria-invalid=true])]:ring-destructive/40\";\n\nconst autocompleteInputClassName =\n  \"h-full w-full min-w-0 flex-1 bg-transparent text-[16px] text-foreground placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed sm:text-sm\";\n\nconst autocompletePopupPanelClassName =\n  \"w-[var(--anchor-width)] max-w-[var(--available-width)] transform-gpu overflow-hidden border border-neutral-200/60 bg-white text-neutral-900 shadow-none dark:border-neutral-700/60 dark:bg-neutral-950 dark:text-neutral-100\";\n\nconst MAX_MENU_HEIGHT = 256;\nconst VIEWPORT_PADDING = 12;\n\nconst autocompleteCollisionAvoidance = {\n  align: \"shift\" as const,\n  fallbackAxisSide: \"none\" as const,\n  side: \"none\" as const,\n};\n\nconst chevronTransition = {\n  type: \"spring\" as const,\n  stiffness: 380,\n  damping: 30,\n  mass: 0.8,\n};\n\nfunction Autocomplete<Value>({\n  actionsRef: actionsRefProp,\n  autoHighlight = true,\n  children,\n  defaultOpen = false,\n  highlightItemOnHover = true,\n  items,\n  modal = false,\n  onItemHighlighted,\n  onOpenChange,\n  open: openProp,\n  openOnInputClick = false,\n  ...props\n}: AutocompleteRootProps<Value>) {\n  const internalActionsRef =\n    React.useRef<AutocompletePrimitive.Root.Actions | null>(null);\n  const actionsRef = actionsRefProp ?? internalActionsRef;\n  const isOpenControlled = openProp !== undefined;\n  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n  const [activeValue, setActiveValue] = React.useState<unknown>();\n  const open = isOpenControlled ? openProp : uncontrolledOpen;\n  const activeHighlightId = React.useId();\n  const skipExitAnimationRef = React.useRef(false);\n  const prefersReducedMotion = useReducedMotion() === true;\n\n  const setOpen = React.useCallback(\n    (nextOpen: boolean) => {\n      if (!isOpenControlled) {\n        setUncontrolledOpen(nextOpen);\n      }\n\n      if (!nextOpen) {\n        setActiveValue(undefined);\n      }\n    },\n    [isOpenControlled]\n  );\n\n  const handleItemHighlighted = React.useCallback<\n    NonNullable<AutocompletePrimitive.Root.Props<Value>[\"onItemHighlighted\"]>\n  >(\n    (highlightedValue, eventDetails) => {\n      setActiveValue(highlightedValue);\n      onItemHighlighted?.(highlightedValue, eventDetails);\n    },\n    [onItemHighlighted]\n  );\n\n  const handleOpenChange = React.useCallback<\n    NonNullable<AutocompletePrimitive.Root.Props<Value>[\"onOpenChange\"]>\n  >(\n    (nextOpen, eventDetails) => {\n      if (!nextOpen && eventDetails.reason === \"item-press\") {\n        skipExitAnimationRef.current = true;\n      } else if (nextOpen) {\n        skipExitAnimationRef.current = false;\n      }\n\n      if (!eventDetails.isCanceled) {\n        setOpen(nextOpen);\n      }\n\n      onOpenChange?.(nextOpen, eventDetails);\n    },\n    [onOpenChange, setOpen]\n  );\n\n  return (\n    <AutocompleteContext.Provider\n      value={{\n        actionsRef,\n        activeHighlightId,\n        activeValue,\n        open,\n        prefersReducedMotion,\n        setActiveValue,\n        setOpen,\n        skipExitAnimationRef,\n      }}\n    >\n      <AutocompletePrimitive.Root\n        {...props}\n        actionsRef={actionsRef}\n        autoHighlight={autoHighlight}\n        highlightItemOnHover={highlightItemOnHover}\n        items={items}\n        modal={modal}\n        onItemHighlighted={handleItemHighlighted}\n        onOpenChange={handleOpenChange}\n        open={open}\n        openOnInputClick={openOnInputClick}\n      >\n        {children}\n      </AutocompletePrimitive.Root>\n    </AutocompleteContext.Provider>\n  );\n}\n\nfunction AutocompleteValue({ ...props }: AutocompletePrimitive.Value.Props) {\n  return (\n    <AutocompletePrimitive.Value data-slot=\"autocomplete-value\" {...props} />\n  );\n}\n\nfunction AutocompleteIcon({\n  className,\n  ...props\n}: AutocompletePrimitive.Icon.Props) {\n  return (\n    <AutocompletePrimitive.Icon\n      className={cn(\n        \"pointer-events-none flex shrink-0 items-center text-muted-foreground\",\n        className\n      )}\n      data-slot=\"autocomplete-icon\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteClear({\n  className,\n  disabled: disabledProp,\n  ...props\n}: AutocompletePrimitive.Clear.Props) {\n  return (\n    <AutocompletePrimitive.Clear\n      disabled={disabledProp}\n      {...props}\n      render={(clearProps) => {\n        const {\n          className: _clearClassName,\n          ref: clearRef,\n          style: _clearStyle,\n          ...resolvedClearProps\n        } = clearProps as React.ComponentProps<\"button\"> & {\n          ref?: React.Ref<HTMLButtonElement>;\n        };\n\n        return (\n          <button\n            {...resolvedClearProps}\n            aria-label=\"Clear input\"\n            className={cn(\n              \"flex size-8 shrink-0 items-center justify-center overflow-hidden rounded-md text-muted-foreground/70 transition-colors hover:bg-accent/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 disabled:cursor-not-allowed disabled:opacity-50\",\n              className\n            )}\n            data-slot=\"autocomplete-clear\"\n            ref={clearRef}\n            type=\"button\"\n          >\n            <X className=\"h-3.5 w-3.5\" />\n          </button>\n        );\n      }}\n    />\n  );\n}\n\nfunction AutocompleteTrigger({\n  className,\n  children,\n  disabled = false,\n  ...props\n}: AutocompletePrimitive.Trigger.Props) {\n  const { open, prefersReducedMotion } = useAutocompleteContext(\n    \"AutocompleteTrigger\"\n  );\n\n  return (\n    <AutocompletePrimitive.Trigger\n      aria-expanded={open}\n      aria-label={open ? \"Collapse suggestions\" : \"Open suggestions\"}\n      className={cn(\n        \"flex size-8 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30 disabled:cursor-not-allowed disabled:opacity-50\",\n        controlCornerClassName,\n        className\n      )}\n      data-slot=\"autocomplete-trigger\"\n      disabled={disabled}\n      type=\"button\"\n      {...props}\n    >\n      {children}\n      <motion.span\n        animate={{ rotate: open ? 180 : 0 }}\n        transition={\n          prefersReducedMotion ? INSTANT_TRANSITION : chevronTransition\n        }\n      >\n        <ChevronsUpDown className=\"h-4 w-4\" />\n      </motion.span>\n    </AutocompletePrimitive.Trigger>\n  );\n}\n\nfunction AutocompleteInput({\n  className,\n  children,\n  disabled = false,\n  id: idProp,\n  label,\n  labelClassName,\n  ref: refProp,\n  render: userRender,\n  showClear = true,\n  showTrigger = false,\n  ...props\n}: AutocompletePrimitive.Input.Props & {\n  label?: React.ReactNode;\n  labelClassName?: string;\n  showClear?: boolean;\n  showTrigger?: boolean;\n}) {\n  const { open, setOpen } = useAutocompleteContext(\"AutocompleteInput\");\n  const inputRef = React.useRef<HTMLInputElement | null>(null);\n  const generatedId = React.useId();\n  const inputId = idProp ?? generatedId;\n\n  const inputGroup = (\n    <AutocompletePrimitive.InputGroup\n      className={cn(\n        componentThemeClassName,\n        controlCornerClassName,\n        autocompleteInputShellClassName,\n        disabled && \"cursor-not-allowed opacity-50\",\n        open && \"border-ring ring-1 ring-ring/25\",\n        label ? undefined : className\n      )}\n      data-slot=\"autocomplete-input\"\n      onClick={(event) => {\n        if (disabled) return;\n\n        const target = event.target as HTMLElement;\n\n        if (\n          target.closest(\n            '[data-slot=\"autocomplete-clear\"], [data-slot=\"autocomplete-trigger\"]'\n          )\n        ) {\n          return;\n        }\n\n        inputRef.current?.focus();\n      }}\n    >\n      <AutocompletePrimitive.Input\n        {...props}\n        disabled={disabled}\n        id={inputId}\n        onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n          if (event.key === \"Tab\") {\n            setOpen(false);\n          }\n        })}\n        render={(inputProps, inputState) => {\n          if (userRender) {\n            return typeof userRender === \"function\"\n              ? userRender(inputProps, inputState)\n              : userRender;\n          }\n\n          const {\n            className: primitiveClassName,\n            ref: primitiveRef,\n            style: primitiveStyle,\n            ...resolvedInputProps\n          } = inputProps as InputRenderProps;\n\n          return (\n            <InputPrimitive\n              {...resolvedInputProps}\n              disabled={disabled}\n              id={inputId}\n              render={(baseInputProps) => {\n                const {\n                  className: baseClassName,\n                  ref: baseRef,\n                  style: baseStyle,\n                  ...baseResolvedProps\n                } = baseInputProps as InputRenderProps;\n\n                return (\n                  <input\n                    {...baseResolvedProps}\n                    autoComplete=\"off\"\n                    className={cn(\n                      autocompleteInputClassName,\n                      primitiveClassName,\n                      baseClassName\n                    )}\n                    data-slot=\"autocomplete-input-control\"\n                    ref={(node) => {\n                      inputRef.current = node;\n                      setRef(primitiveRef, node);\n                      setRef(baseRef, node);\n                      setRef(refProp, node);\n                    }}\n                    style={{ ...primitiveStyle, ...baseStyle }}\n                  />\n                );\n              }}\n            />\n          );\n        }}\n      />\n      {(showClear || showTrigger) && (\n        <div className=\"ml-1.5 flex shrink-0 items-center gap-0.5\">\n          {showClear ? <AutocompleteClear disabled={disabled} /> : null}\n          {showTrigger ? <AutocompleteTrigger disabled={disabled} /> : null}\n        </div>\n      )}\n      {children}\n    </AutocompletePrimitive.InputGroup>\n  );\n\n  if (!label) {\n    return inputGroup;\n  }\n\n  return (\n    <div className={cn(\"flex w-full flex-col gap-2\", className)}>\n      <label\n        className={cn(\"font-medium text-foreground text-sm\", labelClassName)}\n        htmlFor={inputId}\n      >\n        {label}\n      </label>\n      {inputGroup}\n    </div>\n  );\n}\n\nfunction AutocompleteContentPanel({\n  children,\n  className,\n  popupClassName,\n  popupRef,\n  popupState,\n  popupStyle,\n  resolvedPopupProps,\n}: {\n  children: React.ReactNode;\n  className?:\n    | string\n    | ((state: AutocompletePrimitive.Popup.State) => string | undefined);\n  popupClassName?: string;\n  popupRef?: React.Ref<HTMLDivElement>;\n  popupState: AutocompletePrimitive.Popup.State;\n  popupStyle?: React.CSSProperties;\n  resolvedPopupProps: Omit<\n    DivRenderProps,\n    \"children\" | \"className\" | \"ref\" | \"style\"\n  >;\n}) {\n  const { actionsRef, prefersReducedMotion, skipExitAnimationRef } =\n    useAutocompleteContext(\"AutocompleteContentPanel\");\n  const isPopupVisible = popupState.open;\n  const skipExitAnimation = !popupState.open && skipExitAnimationRef.current;\n\n  return (\n    <div\n      {...resolvedPopupProps}\n      ref={(node) => {\n        setRef(popupRef, node);\n      }}\n      role=\"presentation\"\n      style={{\n        ...popupStyle,\n        transformOrigin: \"var(--transform-origin)\",\n      }}\n    >\n      <motion.div\n        animate={isPopupVisible ? popupMotion.animate : popupMotion.closed}\n        className={cn(\n          componentThemeClassName,\n          controlCornerClassName,\n          autocompletePopupPanelClassName,\n          popupClassName,\n          resolveStateClassName(className, popupState)\n        )}\n        initial={\n          popupState.transitionStatus === \"starting\"\n            ? popupMotion.initial\n            : false\n        }\n        onAnimationComplete={() => {\n          if (!popupState.open) {\n            skipExitAnimationRef.current = false;\n            actionsRef.current?.unmount();\n          }\n        }}\n        style={{\n          pointerEvents: isPopupVisible ? undefined : \"none\",\n          transformOrigin: \"var(--transform-origin)\",\n        }}\n        transition={\n          prefersReducedMotion\n            ? INSTANT_TRANSITION\n            : isPopupVisible\n              ? popupMotion.openTransition\n              : skipExitAnimation\n                ? INSTANT_TRANSITION\n                : popupMotion.closedTransition\n        }\n      >\n        {children}\n      </motion.div>\n    </div>\n  );\n}\n\nfunction AutocompleteBackdrop({\n  className,\n  ...props\n}: AutocompletePrimitive.Backdrop.Props) {\n  return (\n    <AutocompletePrimitive.Backdrop\n      className={cn(\n        \"fixed inset-0 z-[9998] bg-black/20 dark:bg-black/40\",\n        className\n      )}\n      data-slot=\"autocomplete-backdrop\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteContent({\n  align = \"start\",\n  alignOffset = 0,\n  anchor,\n  children,\n  className,\n  collisionAvoidance = autocompleteCollisionAvoidance,\n  collisionPadding = VIEWPORT_PADDING,\n  side = \"bottom\",\n  sideOffset = 6,\n  ...props\n}: AutocompletePrimitive.Popup.Props &\n  Pick<\n    AutocompletePrimitive.Positioner.Props,\n    | \"align\"\n    | \"alignOffset\"\n    | \"anchor\"\n    | \"collisionAvoidance\"\n    | \"collisionPadding\"\n    | \"side\"\n    | \"sideOffset\"\n  >) {\n  return (\n    <AutocompletePrimitive.Portal keepMounted>\n      <AutocompletePrimitive.Positioner\n        align={align}\n        alignOffset={alignOffset}\n        anchor={anchor}\n        className=\"z-[9999] outline-none\"\n        collisionAvoidance={collisionAvoidance}\n        collisionPadding={collisionPadding}\n        side={side}\n        sideOffset={sideOffset}\n      >\n        <AutocompletePrimitive.Popup\n          data-slot=\"autocomplete-content\"\n          initialFocus={false}\n          {...props}\n          render={(popupProps, popupState) => {\n            const { popupClassName, popupRef, popupStyle, resolvedPopupProps } =\n              resolvePopupProps(popupProps as DivRenderProps);\n\n            return (\n              <AutocompleteContentPanel\n                className={className}\n                popupClassName={popupClassName}\n                popupRef={popupRef}\n                popupState={popupState}\n                popupStyle={popupStyle}\n                resolvedPopupProps={resolvedPopupProps}\n              >\n                {children}\n              </AutocompleteContentPanel>\n            );\n          }}\n        />\n      </AutocompletePrimitive.Positioner>\n    </AutocompletePrimitive.Portal>\n  );\n}\n\nfunction AutocompleteList({\n  className,\n  onPointerLeave,\n  ...props\n}: AutocompletePrimitive.List.Props) {\n  const { setActiveValue } = useAutocompleteContext(\"AutocompleteList\");\n\n  return (\n    <ScrollAreaPrimitive.Root\n      className={cn(\"relative min-h-0 overflow-hidden\", className)}\n      style={{\n        maxHeight: `min(var(--available-height, ${MAX_MENU_HEIGHT}px), ${MAX_MENU_HEIGHT}px)`,\n      }}\n    >\n      <AutocompletePrimitive.List\n        data-slot=\"autocomplete-list\"\n        onPointerLeave={composeEventHandlers(onPointerLeave, () => {\n          setActiveValue(undefined);\n        })}\n        {...props}\n        render={(listProps) => {\n          const {\n            children: listChildren,\n            className: listClassName,\n            ref: listRef,\n            style: listStyle,\n            ...resolvedListProps\n          } = listProps as DivRenderProps;\n\n          return (\n            <ScrollAreaPrimitive.Viewport\n              {...resolvedListProps}\n              className={cn(\n                \"max-h-[inherit] min-h-0 overscroll-contain p-1 outline-none\",\n                listClassName\n              )}\n              ref={(node) => {\n                setRef(listRef, node);\n              }}\n              style={listStyle}\n            >\n              {listChildren}\n            </ScrollAreaPrimitive.Viewport>\n          );\n        }}\n      />\n      <ScrollAreaPrimitive.Scrollbar\n        className={autocompleteListScrollbarClassName}\n        orientation=\"vertical\"\n      >\n        <ScrollAreaPrimitive.Thumb className={autocompleteListThumbClassName} />\n      </ScrollAreaPrimitive.Scrollbar>\n    </ScrollAreaPrimitive.Root>\n  );\n}\n\nfunction AutocompleteItem({\n  className,\n  children,\n  description,\n  value,\n  ...props\n}: AutocompletePrimitive.Item.Props & {\n  description?: React.ReactNode;\n}) {\n  const {\n    activeHighlightId,\n    activeValue,\n    prefersReducedMotion,\n    setActiveValue,\n  } = useAutocompleteContext(\"AutocompleteItem\");\n\n  return (\n    <AutocompletePrimitive.Item\n      data-slot=\"autocomplete-item\"\n      value={value}\n      {...props}\n      render={(itemProps, itemState) => {\n        const { itemClassName, itemRef, itemStyle, resolvedItemProps } =\n          resolveItemProps(itemProps as DivRenderProps);\n        const showHighlight =\n          itemState.highlighted || Object.is(activeValue, value);\n\n        return (\n          <motion.div\n            {...resolvedItemProps}\n            animate={{ opacity: 1, y: 0 }}\n            className={cn(\n              \"relative flex cursor-pointer select-none items-start px-2.5 py-2 text-foreground text-sm\",\n              controlCornerClassName,\n              itemClassName,\n              resolveStateClassName(className, itemState)\n            )}\n            initial={prefersReducedMotion ? false : { opacity: 0, y: 2 }}\n            onMouseEnter={composeEventHandlers(\n              resolvedItemProps.onMouseEnter,\n              () => {\n                setActiveValue(value);\n              }\n            )}\n            onPointerMove={composeEventHandlers(\n              resolvedItemProps.onPointerMove,\n              () => {\n                setActiveValue(value);\n              }\n            )}\n            ref={(node) => {\n              setRef(itemRef, node);\n            }}\n            style={itemStyle}\n            transition={\n              prefersReducedMotion\n                ? INSTANT_TRANSITION\n                : { duration: 0.12, ease: \"easeOut\" }\n            }\n          >\n            {showHighlight ? (\n              <motion.div\n                className={cn(\n                  \"absolute inset-0 bg-accent\",\n                  controlCornerInheritClassName\n                )}\n                layoutId={activeHighlightId}\n                transition={\n                  prefersReducedMotion ? INSTANT_TRANSITION : HIGHLIGHT_SPRING\n                }\n              />\n            ) : null}\n\n            <span className=\"relative z-10 flex flex-col\">\n              <span className=\"font-medium leading-tight\">{children}</span>\n              {description ? (\n                <span className=\"text-muted-foreground text-xs\">\n                  {description}\n                </span>\n              ) : null}\n            </span>\n          </motion.div>\n        );\n      }}\n    />\n  );\n}\n\nfunction AutocompleteEmpty({\n  className,\n  children = \"No results found.\",\n  ...props\n}: AutocompletePrimitive.Empty.Props) {\n  const { prefersReducedMotion } = useAutocompleteContext(\"AutocompleteEmpty\");\n\n  return (\n    <AutocompletePrimitive.Empty\n      className={cn(\"text-center text-muted-foreground text-sm\", className)}\n      data-slot=\"autocomplete-empty\"\n      {...props}\n    >\n      <motion.span\n        animate={{ opacity: 1 }}\n        className=\"block px-3 py-6\"\n        initial={prefersReducedMotion ? false : { opacity: 0 }}\n        transition={\n          prefersReducedMotion ? INSTANT_TRANSITION : { duration: 0.18 }\n        }\n      >\n        {children}\n      </motion.span>\n    </AutocompletePrimitive.Empty>\n  );\n}\n\nfunction AutocompleteStatus({\n  className,\n  ...props\n}: AutocompletePrimitive.Status.Props) {\n  return (\n    <AutocompletePrimitive.Status\n      className={cn(\"px-3 py-2 text-muted-foreground text-xs\", className)}\n      data-slot=\"autocomplete-status\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteRow({\n  className,\n  ...props\n}: AutocompletePrimitive.Row.Props) {\n  return (\n    <AutocompletePrimitive.Row\n      className={cn(className)}\n      data-slot=\"autocomplete-row\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteGroup({\n  className,\n  ...props\n}: AutocompletePrimitive.Group.Props) {\n  return (\n    <AutocompletePrimitive.Group\n      className={cn(className)}\n      data-slot=\"autocomplete-group\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteLabel({\n  className,\n  ...props\n}: AutocompletePrimitive.GroupLabel.Props) {\n  return (\n    <AutocompletePrimitive.GroupLabel\n      className={cn(\"px-2 py-1.5 text-muted-foreground text-xs\", className)}\n      data-slot=\"autocomplete-label\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteCollection({\n  ...props\n}: AutocompletePrimitive.Collection.Props) {\n  return (\n    <AutocompletePrimitive.Collection\n      data-slot=\"autocomplete-collection\"\n      {...props}\n    />\n  );\n}\n\nfunction AutocompleteSeparator({\n  className,\n  ...props\n}: AutocompletePrimitive.Separator.Props) {\n  return (\n    <AutocompletePrimitive.Separator\n      className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n      data-slot=\"autocomplete-separator\"\n      {...props}\n    />\n  );\n}\n\nfunction useAutocompleteAnchor() {\n  return React.useRef<HTMLDivElement | null>(null);\n}\n\nconst useAutocompleteFilter = AutocompletePrimitive.useFilter;\nconst useFilteredAutocompleteItems = AutocompletePrimitive.useFilteredItems;\n\nexport {\n  Autocomplete,\n  AutocompleteBackdrop,\n  AutocompleteClear,\n  AutocompleteCollection,\n  AutocompleteContent,\n  AutocompleteEmpty,\n  AutocompleteGroup,\n  AutocompleteIcon,\n  AutocompleteInput,\n  AutocompleteItem,\n  AutocompleteLabel,\n  AutocompleteList,\n  AutocompleteRow,\n  AutocompleteSeparator,\n  AutocompleteStatus,\n  AutocompleteTrigger,\n  AutocompleteValue,\n  useAutocompleteAnchor,\n  useAutocompleteFilter,\n  useFilteredAutocompleteItems,\n};\n",
      "type": "registry:ui"
    }
  ],
  "title": "Autocomplete (Base UI)",
  "description": "Base UI autocomplete with list filtering, suggestion highlight motion, and the same Iconiq input shell as the combobox install."
}
