Autocomplete
Item | Name | Description |
---|---|---|
A | <TextField /> | <AutocompleteField /> uses a <TextField /> under the hood. |
B | <Search /> | The <Search /> icon is used when implementing a search box using <AutocompleteField /> . |
C | Value | The 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. |
Item | Name | Description |
---|---|---|
A | Container | The 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. |
C | Group label | A <span> generated by the label prop when grouping options. |
D | <AutocompleteOptionGroup /> | A group of <AutocompleteOptions /> using a required label . |
Item | Name | Description |
---|---|---|
A | <Check /> | The <Check /> icon is used to indicate that the <AutocompleteOption /> is selected. The icon is omitted when using the search behavior. |
B | Option content | Contains any other children passed to the <AutocompleteOption /> such as a text string or image. |
- Autocomplete supports two modes
- Learn more about filtering vs searching
- 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.
Name | Type | Default | Description |
---|---|---|---|
after | ReactNode | Content 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 | ReactNode | Content 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 | ReactNode | Content of the field; typically an AutocompleteSelect and AutocompleteListbox | |
component | ReactNode | Component override for the input element | |
counter | ReactNode | Indicator of a limit placed on a field, e.g. maximum character count or remaining hours; most commonly using CharacterCount | |
fit | ReactNode | Determines 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 | ReactNode | A brief description or hint for the input ; can be used to link to an external resource. | |
invalid | boolean | If true , the field will be shown in an invalid state. | |
label Required | string | Label associated with the input . | |
loading | string | If true , the loading Spinner is displayed. | |
optionalText | string | Text used to indicate that a field is not required. | |
validationText | ReactNode | Validation message associated with the input . |
Name | Type | Default | Description |
---|---|---|---|
children | ReactNode | Content of the component, typically an Option |
Name | Type | Default | Description |
---|---|---|---|
children | ReactNode | Content of the component, typically a series of AutocompleteOption |
Name | Type | Default | Description |
---|---|---|---|
children | ReactNode | Content of the component | |
label Required | string | The text entered into the input element when the option is selected | |
value Required | string number | The value for the option. |
Name | Type | Default | Description |
---|---|---|---|
label Required | string | The group label |
- All included icons meet the minimum requirement of 3:1 contrast ratio for non-text content For more information, see footnote 1,For more information, see footnote 2
- The focus indicators meet the minimum requirements for focus appearance and focus visibility For more information, see footnote 3, For more information, see footnote 4
- The touch-target areas for the input and options meet the minimum requirement for target size For more information, see footnote 5
- This component uses visuallyHidden with
role="alert"
to announce to the screen reader how many options are available For more information, see footnote 6,For more information, see footnote 7,For more information, see footnote 8,For more information, see footnote 9 aria-busy
is set based on the value of theloading
attribute to indicate loading content For more information, see footnote 10- Autocomplete Listbox is portaled and positioned using Popper. This comes with the benefit of flexibility, but is not a standard pattern and requires certain accommodations to communicate to the user that they are in a special navigation mode and provide instructions on how to exit. We follow a pattern similar to the Spectrum Design System in which all content outside the control is hidden using aria-hidden. For more information, see footnote 11
- We have divided escape key presses to allow for both keyboard and screen reader users. The first press closes the Autocomplete Listbox and the second will clear the selected value as well as the value of the
input
. This allows screen readers to close the Autocomplete Listbox and navigate forward. For more information, see footnote 12, For more information, see footnote 13
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 managedconst 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 (<AutocompleteFieldlabel="Country"value={inputValue}onChange={e => setInputValue(e.target.value)}><AutocompleteSelectname="country"value={selectedCountry.code}onChange={e => {const newCountry = countries.find(country => country.code === e.target.value) ?? null;setSelectedCountry(newCountry);}}>{selectedCountry ? (<Optionlabel={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