Skip to content

Autocomplete

Autocomplete provides fast filtering of large datasets through live search results based on user input.
Figma logo
A points to TextField; B points to a Search icon; C points to a text value; D points to a Spinner; E points to a clear button
Illustrating the pieces that make up an Autocomplete Field
Explaining the pieces that make up an Autocomplete Field
ItemNameDescription
A<TextField /><AutocompleteField /> uses a <TextField /> under the hood.
B<Search />The <Search /> icon is used when implementing a search box using <AutocompleteField />.
CValueThe placeholder or typed text string.
D<Spinner />Rendered when loading is true to give a visual cue that content is loading.
E<IconButton />The <Close /> icon is used within <IconButton /> to clear the entered or selected text string.
Showing the dimensions of an autocomplete field: 44px in height with width determined by its container
Showing a dotted line that outlines a clickable region
Illustrating the spacing within an Autocomplete Field
A points to the Autocomplete Listbox container; B points to an Autocomplete Option; C points to a group label; D points to an Autocomplete Option Group
Illustrating the pieces that make up an Autocomplete Listbox
Explaining the pieces that make up an Autocomplete Listbox
ItemNameDescription
AContainerThe parent component–rendered as a <ul>—that wraps <AutocompleteOption /> children components.
B<AutocompleteOption />The child component—rendered as an <li>—that contains the main content for a given step.
CGroup labelA <span> generated by the label prop when grouping options.
D<AutocompleteOptionGroup />A group of <AutocompleteOptions /> using a required label.
Autocomplete Listbox has a maximum height of 400px and its width is automatically determined by its container
Illustrating the dimensions of an Autocomplete Listbox
A points to the Autocomplete Listbox container; B points to an Autocomplete Option; C points to a group label; D points to an Autocomplete Option Group
Illustrating the pieces that make up an Autocomplete Option
Explaining the pieces that make up an Autocomplete Listbox
ItemNameDescription
A<Check />The <Check /> icon is used to indicate that the <AutocompleteOption /> is selected. The icon is omitted when using the search behavior.
BOption contentContains any other children passed to the <AutocompleteOption /> such as a text string or image.
The height and width of an Autocomplete Option is determined by its container
Showing a dotted line that outlines a clickable region
Illustrating the dimensions of an Autocomplete Option
  • Autocomplete supports two modes
  • The presence of <AutocompleteSelect /> is used to swap modes

This example implements filtering functionality in which options are limited to a specific dataset.

This example implements search functionality in which options are presented and selectable, but any input is considered valid.

This example illustrates an asynchronous Autocomplete filter.

This example illustrates the use of <AutocompleteOptionGroup /> to group related options. <AutocompleteSeparator /> is also available to distinguish between options.

A basic Autocomplete filter implementation using Formik and Yup to require selection.

A basic Autocomplete search implementation using Formik and Yup to require input.

React props
NameTypeDefaultDescription
after  ReactNodeContent shown after the input value. By default this content is not interactive and will ignore pointer events. Any interactive elements must be styled with pointer-events: auto;.
before  ReactNodeContent shown before the input value. By default this content is not interactive and will ignore pointer events. Any interactive elements must be styled with pointer-events: auto;.
children  ReactNodeContent of the field; typically an AutocompleteSelect and AutocompleteListbox
component  ReactNodeComponent override for the input element
counter  ReactNodeIndicator of a limit placed on a field, e.g. maximum character count or remaining hours; most commonly using CharacterCount
fit  ReactNodeDetermines the point of reference for the width of the component. If set to content, the size will be set by the size of the input. If set to container, the size will expand to fit the containing element.
helperText  ReactNodeA brief description or hint for the input; can be used to link to an external resource.
invalid  booleanIf true, the field will be shown in an invalid state.
label  RequiredstringLabel associated with the input.
loading  stringIf true, the loading Spinner is displayed.
optionalText  stringText used to indicate that a field is not required.
validationText  ReactNodeValidation message associated with the input.
React props
NameTypeDefaultDescription
children  ReactNodeContent of the component, typically an Option
React props
NameTypeDefaultDescription
children  ReactNodeContent of the component, typically a series of AutocompleteOption
React props
NameTypeDefaultDescription
children  ReactNodeContent of the component
label  RequiredstringThe text entered into the input element when the option is selected
value  RequiredstringnumberThe value for the option.
React props
NameTypeDefaultDescription
label  RequiredstringThe group label

The following testing snippet(s) offer suggestions for testing the component using React Testing Library with occasional help from Jest.

const countries = [
{ code: 'af', name: 'Afghanistan' },
// ...continued
];
// Tested component where state is being managed
const TestedComponent = () => {
const [inputValue, setInputValue] = useState('');
const [selectedCountry, setSelectedCountry] = useState<Country | null>(null);
const options = useMemo(() => {
const searchValue = inputValue.toLowerCase();
return countries
.filter(country => country.name.startsWith('A'))
.filter(country => country.name.toLowerCase().startsWith(searchValue))
.slice(0, 6);
}, [inputValue]);
return (
<AutocompleteField
label="Country"
value={inputValue}
onChange={e => setInputValue(e.target.value)}
>
<AutocompleteSelect
name="country"
value={selectedCountry.code}
onChange={e => {
const newCountry = countries.find(country => country.code === e.target.value) ?? null;
setSelectedCountry(newCountry);
}}
>
{selectedCountry ? (
<Option
label={selectedCountry.name}
value={selectedCountry.code} />
) : null}
</AutocompleteSelect>
<AutocompleteListbox aria-label="Country suggestions">
<AutocompleteOptionGroup label="A">
{options.map(option => (
<AutocompleteOption key={option.code} label={option.name} value={option.code}>
{option.name}
</AutocompleteOption>
))}
</AutocompleteOptionGroup>
</AutocompleteListbox>
</AutocompleteField>
};
render(<TestedComponent />);
const combobox = screen.getByRole('combobox', {
name: 'Country',
});
// The listbox, clear button, and the options elements will all be hidden
// on first render. To unhide them, search for something:
userEvent.type(combobox, 'a');
expect(combobox).toHaveDisplayValue('a');
expect(listbox).toBeVisible();
const clearButton = screen.getByRole('button', {
name: 'Clear',
});
const listbox = screen.getByRole('listbox', {
name: 'Country suggestions',
});
const group = within(listbox).getByRole('group', {
name: 'A',
});
const afghanistanOption = within(group).getByRole('option', {
name: 'Afghanistan',
});
// To select an option:
userEvent.click(afghanistanOption);
// To clear the selected option:
userEvent.click(clearButton);
// Note: we recommend that you do not directly assert the selected value.
// Instead, assert displayed values and things you can see. If the selected
// value changes something else in the UI, assert on that instead