Free text with suggestions, wrapping the Base UI Autocomplete. The value is the input text itself: picking a suggestion fills it in, and anything typed stays valid. When the answer must come from the list, use the Combobox instead.

Playground

Type a letter or two and arrow through what's left; Borderless and Compact restyle the input and the list together, and the Code tab shows the markup for exactly what you've configured.

Variants

mode decides what arrowing through the list does to the input. The default, list, only filters as you type; both also writes the highlighted suggestion into the input; inline writes but never filters, for short lists you want to keep whole; none does neither, for lists you filter yourself.

States

Open and highlighted are live (type to see them); disabled and invalid are yours to set, and invalid turns the border to the danger color, which a surrounding Field does for you on failed validation.

Styling states

The autocomplete shares the Combobox's classes, so the two restyle together; items carry data-highlighted and the popup the usual data-starting-style/data-ending-style transitions:

.ub-autocomplete-popup .ub-combobox-item[data-highlighted] {
  background: var(--ub-accent);
  color: var(--ub-accent-contrast);
}

Props

Everything the Base UI Autocomplete accepts passes through (openOnInputClick, autoHighlight, itemToStringValue for object items, ...). The essentials:

PropTypeDefaultDescription
AutocompleteRoot.itemsValue[]The suggestions; typing filters them and powers the empty state.
AutocompleteRoot.valuestringThe input text (also defaultValue, onValueChange); suggestions fill it.
AutocompleteRoot.mode"list" | "both" | "inline" | "none""list"Whether arrowing writes into the input and whether typing filters; see Variants above.
AutocompleteRoot.size"default" | "compact""default"Sizes the input and the list together: 36px tall with 16px text by default, 28px with 14px text compact.
AutocompleteInput.clearablebooleantrueShows the clear button while something is typed.
AutocompleteInput.variant"default" | "borderless""default"Bordered, or a muted fill with no border.
AutocompleteInput.placeholderstringHint text while the input is empty.
AutocompleteInput.invalidbooleanfalseDanger border and ring, plus aria-invalid; a surrounding Field sets it automatically.
AutocompleteContent.empty / statusReactNodeEmpty state, and a politely announced status line for async searches.
AutocompleteContent.sideOffsetnumber4Gap between the input and the popup, in pixels. Also side and align.

Agent instructions

Working with a coding agent? Paste this into its context, or point it at llms.txt for the whole library.

AutocompleteRoot, AutocompleteInput, AutocompleteContent, AutocompleteItem, from @usebones/react.
- Structure: AutocompleteRoot (pass items; size "default" | "compact"; mode "list" default) wraps AutocompleteInput (placeholder, variant "default" | "borderless", clearable default true, invalid; no chevron, typing-first) + AutocompleteContent (empty="...", status for async, function children rendering an AutocompleteItem per suggestion).
- The value is the input string (value/defaultValue/onValueChange); selecting a suggestion fills it and free text stays valid. Use Combobox when the value must come from the list.
- mode: "list" (default) filters as you type; "both" also writes the highlighted suggestion into the input while arrowing; "inline" writes without filtering; "none" does neither.
- Async: fetch in onValueChange (it fires per keystroke, since the value is the text), pass results as items, and put status="Searching..." on the content.
- Inside FieldRoot, drop invalid and use FieldLabel and FieldError instead; the Field wires the name and validation.
- Restyle in CSS via the shared Combobox classes (.ub-combobox-input, .ub-combobox-popup, .ub-combobox-item) plus .ub-autocomplete-* hooks; restyling one restyles both. Tokens only.