Autocomplete
A text input that suggests matching options as you type, with variant and color token support.
'use client', so importing it into a server component tree is fine, but the file itself cannot be rendered on the server. Because it draws its own list instead of using a native dropdown, the color tokens apply in every browser — unlike Select, whose open list is drawn by the OS.Usage
import { Autocomplete } from 'trivela-ui';
export function Example() {
return (
<Autocomplete
options={['Next.js', 'Remix', 'Astro']}
placeholder="Search framework…"
/>
);
}Examples
Basic
Pass plain strings and the component filters them as you type. Focus the field to see every option, or use ↑ ↓ and Enter.
Colors
The color token drives the highlighted option as well as the input focus ring. Open each one to compare.
Variants
The input reuses Input's variants, so an Autocomplete sits cleanly next to the rest of a form.
Separate value and label
Pass objects when the stored value differs from the text shown, and mark any option disabled. onSelect fires on commit and reports the value, not the label.
Controlled
Pass value and onValueChange to own the text yourself. onSelect fires only on commit — a click or Enter — not on every keystroke.
Typed: — · Selected: —
Custom filter
The default match is a case-insensitive substring. Pass filter to change it — here to a prefix match.
Empty state
When nothing matches, the list shows emptyMessage instead of collapsing — so the field never looks broken.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| options | (string | { value: string; label?: string; disabled?: boolean })[] | — | Required. Strings are used as both value and label; label falls back to value. |
| value / onValueChange | string / (value: string) => void | — | Controls the input text. Omit both to let the component own it. |
| onSelect | (option: { value, label }) => void | — | Fires on commit — click or Enter — not on every keystroke. |
| filter | (option, query) => boolean | substring match | Case-insensitive substring match on the label by default. |
| emptyMessage | string | 'No results found.' | Shown when no option matches the query. |
| variant | 'solid' | 'ghost' | 'outline' | 'subtle' | 'solid' | Style variant for the text input. |
| color | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'neutral' | 'primary' | Color scale for the highlighted option and focus ring. |
| className | string | — | Merged onto the input, not the wrapper. |
| ...props | InputHTMLAttributes<HTMLInputElement> | — | Forwarded to the input. value, defaultValue, onChange and onSelect are owned by the component. |