Primitives
Autocomplete
Free-text input with search-as-you-type suggestions.
Composition
The preferred shape for composing the installed primitive from its exported parts.
Free-text suggestions
The field value remains text; choosing an item fills the input instead of locking selection state.
Autocomplete├── AutocompleteInput│ └── AutocompleteClear└── AutocompleteContent ├── AutocompleteEmpty └── AutocompleteList ├── AutocompleteGroup │ ├── AutocompleteGroupLabel │ └── AutocompleteItem └── AutocompleteItemThe refined source installs this primitive from src/registry/sources/refined/ui/autocomplete.tsx. Install it on its own with the command above, or inspect the source below.
npx shadcn@latest add http://127.0.0.1:3000/r/refined/autocomplete.jsonInstalled dependencies
Installed with this primitive because the slot depends on them; they are support files, not standalone sidebar items.
Control variants
src/registry/sources/refined/control-variants.tsSupportSurface variants
src/registry/sources/refined/surface-variants.tsSupportScroll area
src/registry/sources/refined/ui/scroll-area.tsxSupportRaw code
Primary installed primitive source
Base UI Autocomplete slot
src/registry/sources/refined/ui/autocomplete.tsx
"use client";import { Autocomplete as AutocompletePrimitive } from "@base-ui/react/autocomplete";import type { AutocompleteClearProps, AutocompleteContentProps, AutocompleteEmptyProps, AutocompleteGroupLabelProps, AutocompleteGroupProps, AutocompleteInputProps, AutocompleteItemProps, AutocompleteListProps, AutocompleteProps,} from "@/components/refined-ui/contracts";import { controlSize, controlSurfaceClasses } from "@/components/refined-ui/control-variants";import { cn } from "@/components/refined-ui/lib/cn";import { skinEffects, skinId, skinSlot } from "@/components/refined-ui/skin";import { floatingListContentClasses, floatingListItemClasses } from "@/components/refined-ui/surface-variants";import { ScrollArea } from "@/components/refined-ui/ui/scroll-area";// Unlike Combobox, input is FREE TEXT: value/onValueChange is the filter string, picking an item just// fills the field — never locks to a discrete value, no per-row ItemIndicator (Base UI has none).export function Autocomplete<Value = string>({ children, ...props }: AutocompleteProps<Value>) { return <AutocompletePrimitive.Root {...props}>{children}</AutocompletePrimitive.Root>;}export function AutocompleteClear({ className, children, ...props }: AutocompleteClearProps) { return ( <AutocompletePrimitive.Clear data-ui="agent" data-slot="autocomplete-clear" aria-label="Clear search" className={cn( "inline-flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-[var(--radius-control)] text-muted-foreground outline-none transition hover:text-foreground focus-visible:ring-2 focus-visible:ring-foreground/20 disabled:cursor-not-allowed disabled:opacity-45", skinSlot("autocomplete-clear", {}), className, )} {...props} > {children ?? ( <svg viewBox="0 0 12 12" className="size-3" aria-hidden="true" fill="none"> <path d="M3 3 9 9M9 3 3 9" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" /> </svg> )} </AutocompletePrimitive.Clear> );}export function AutocompleteInput({ size = "md", className, ...props }: AutocompleteInputProps) { return ( <AutocompletePrimitive.InputGroup data-ui="agent" data-slot="autocomplete" className={cn("relative flex w-full items-center", skinSlot("autocomplete", {}))} > <AutocompletePrimitive.Input data-ui="agent" data-slot="autocomplete-input" data-control="true" data-size={size} className={cn( "w-full min-w-0 rounded-[var(--radius-control)] pr-9 font-medium outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-foreground/20 disabled:cursor-not-allowed disabled:opacity-45", controlSurfaceClasses, controlSize({ size }), skinSlot("autocomplete-input", { size }), className, )} {...props} /> <AutocompleteClear className="absolute right-1.5 top-1/2 -translate-y-1/2" /> </AutocompletePrimitive.InputGroup> );}export function AutocompleteContent({ className, children, sideOffset = 6, ...props }: AutocompleteContentProps) { return ( <AutocompletePrimitive.Portal> {/* Portals land outside container-scoped skin root; positioner re-asserts token scope on itself. */} <AutocompletePrimitive.Positioner data-skin={skinId()} data-effects={skinEffects()} side="bottom" align="start" sideOffset={sideOffset} className="z-[80] outline-none" > <AutocompletePrimitive.Popup data-ui="agent" data-slot="autocomplete-content" className={cn( "w-[var(--anchor-width)] max-w-[var(--available-width)] origin-[var(--transform-origin)]", floatingListContentClasses, skinSlot("autocomplete-content", {}), className, )} {...props} > {children} </AutocompletePrimitive.Popup> </AutocompletePrimitive.Positioner> </AutocompletePrimitive.Portal> );}export function AutocompleteList<Value = unknown>({ className, children, ...props }: AutocompleteListProps<Value>) { return ( <ScrollArea className="w-full" maxHeight="min(18rem, var(--available-height))"> <AutocompletePrimitive.List data-ui="agent" data-slot="autocomplete-list" className={cn("outline-none", skinSlot("autocomplete-list", {}), className)} {...props} > {children} </AutocompletePrimitive.List> </ScrollArea> );}export function AutocompleteEmpty({ className, children, ...props }: AutocompleteEmptyProps) { return ( <AutocompletePrimitive.Empty data-ui="agent" data-slot="autocomplete-empty" className={cn( "px-[calc(var(--padding-x)*0.5)] py-6 text-center text-body text-muted-foreground empty:h-0 empty:overflow-hidden empty:p-0", skinSlot("autocomplete-empty", {}), className, )} {...props} > {children} </AutocompletePrimitive.Empty> );}export function AutocompleteItem<Value = unknown>({ className, children, disabled, ...props }: AutocompleteItemProps<Value>) { return ( <AutocompletePrimitive.Item data-ui="agent" data-slot="autocomplete-item" disabled={disabled} className={cn(floatingListItemClasses, skinSlot("autocomplete-item", { disabled: Boolean(disabled) }), className)} {...props} > <span className="flex min-w-0 flex-1 items-center gap-2 truncate">{children}</span> </AutocompletePrimitive.Item> );}export function AutocompleteGroup({ className, children, ...props }: AutocompleteGroupProps) { return ( <AutocompletePrimitive.Group data-ui="agent" data-slot="autocomplete-group" className={cn("py-1", skinSlot("autocomplete-group", {}), className)} {...props} > {children} </AutocompletePrimitive.Group> );}export function AutocompleteGroupLabel({ className, children, ...props }: AutocompleteGroupLabelProps) { return ( <AutocompletePrimitive.GroupLabel data-ui="agent" data-slot="autocomplete-group-label" className={cn( "px-[calc(var(--padding-x)*0.5)] py-1 text-meta font-medium text-muted-foreground", skinSlot("autocomplete-group-label", {}), className, )} {...props} > {children} </AutocompletePrimitive.GroupLabel> );}