Refined UI

An opinionated, customizable superset of shadcn/ui

AgentsPrimitivesSkillsSkins
Guides
  • Overview
  • Get started
  • Shadcn compatibility
  • Architecture
  • Agent surface
Primitives
  • Accordion
  • Alert
  • Alert dialog
  • Aspect ratio
  • Autocomplete
  • Avatar
  • Badge
  • Button
  • Button group
  • Calendar
  • Card
  • Checkbox
  • Checkbox Group
  • Code
  • Code Diff
  • Collapsible
  • Color Picker
  • Combobox
  • Command
  • Date Picker
  • Dialog
  • Drawer
  • Empty
  • Field
  • Form
  • Gradient Editor
  • Hover card
  • Input
  • Input group
  • Input OTP
  • Item
  • Kbd
  • Markdown
  • Menu
  • Menubar
  • Meter
  • Native select
  • Navigation menu
  • Number Field
  • Pagination
  • Popover
  • Progress
  • Radio group
  • Resizable
  • Scroll area
  • Select
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Table
  • Table of contents
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • Toolbar
  • Tooltip
  • Tree
  • Trigger Menu
  • Typography
Hooks
  • Use Chat Message
  • Use Chat Input
  • Use User Ask
  • Use Audio Recorder
  • Use Environment Variables
  • Use Copy To Clipboard
  • Use Tool Call
  • Use Sidebar Resize
Utils
  • cn
  • Skin
  • Contracts
  • Serialize
Extensions
  • Control Effects
  • View Transition
  • Send Aurora
  1. Primitives
  2. Autocomplete
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
└── AutocompleteItem

The 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.

Registry command
npx shadcn@latest add http://127.0.0.1:3000/r/refined/autocomplete.json
See registry manifest

Installed dependencies

Installed with this primitive because the slot depends on them; they are support files, not standalone sidebar items.

Control variantssrc/registry/sources/refined/control-variants.tsSupport
Surface variantssrc/registry/sources/refined/surface-variants.tsSupport
Scroll areasrc/registry/sources/refined/ui/scroll-area.tsxSupport

Raw 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>
);
}
​

On this page

  • Preview
  • Composition
  • Installation
  • Dependencies
  • Source
Country
Type to filter countries