Home

Autocomplete

A text field that suggests values as you type and keeps whatever is typed, suggestion or not.

ui.autocompletecomponents/ui/autocomplete.tsx

Use case

For the AI

Use it for a text value where suggestions help but are not the only answer: the city on a client's address, a job title, a supplier that may be new. The value is the input's text (a string), so a new entry is kept as typed; picking a suggestion only fills the text in.

Use it when

  • Free text with suggestions (a city, a street, a tag that may be new)
  • The value saved is the text, not a record's id
  • Speeding up the typing of common values

Use something else when

  • The value must be an existing record (a client, a product): Combobox
  • Searching the whole tool for pages, records and actions: Command bar
  • Filtering the list on the page as you type: Search field
  • A short fixed list: Select

Examples

Suggestions as you type; what is typed is kept

Code

Import

import { Autocomplete, AutocompleteEmpty, AutocompleteInput, AutocompleteItem, AutocompleteList, AutocompletePopup } from "@/components/ui/autocomplete"

Usage

const CITIES = ["Montréal", "Laval", "Longueuil", "Québec", "Gatineau", "Sherbrooke"].map((c) => ({ value: c, label: c }))

<Autocomplete items={CITIES}>
  <AutocompleteInput name="city" placeholder="City" aria-label="City" />
  <AutocompletePopup>
    <AutocompleteEmpty>Keep typing, any city works.</AutocompleteEmpty>
    <AutocompleteList>
      {(item: (typeof CITIES)[number]) => (
        <AutocompleteItem key={item.value} value={item}>
          {item.label}
        </AutocompleteItem>
      )}
    </AutocompleteList>
  </AutocompletePopup>
</Autocomplete>

Rules

  • The value is a string (`value`, `onValueChange`), never limited to the suggestions.
  • `AutocompleteEmpty` says the typed text is still fine ("Keep typing, any city works."), not that it is wrong.
  • Name the input: a `FieldLabel` in a form, or `aria-label`; pass `name` so a form submits the text.
  • Keep `AutocompleteList`: it scrolls inside a `ScrollArea` that fades at its edges.
  • The list glides to its new height as you type, its top fixed (useGlide on the popup, built in).