Autocomplete
The autocomplete is a normal text input enhanced by a panel of suggested options.
The widget is useful for setting the value of a single-line textbox in one of two types of scenarios:
- The value for the textbox must be chosen from a predefined set of allowed values, e.g., a location field must contain a valid location name: combo box.
- The textbox may contain any arbitrary value, but it is advantageous to suggest possible values to the user, e.g., a search field may suggest similar or previous searches to save the user time: free solo.
Combo box
The value must be chosen from a predefined set of allowed values.
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={option => option.title}
style={{ width: 300 }}
renderInput={params => (
<TextField {...params} label="Combo box" variant="outlined" fullWidth />
)}
/>
Free solo
Set freeSolo
to true so the textbox can contain any arbitrary value. The prop is designed to cover the primary use case of a search box with suggestions, e.g. Google search.
However, if you intend to use it for a combo box like experience (an enhanced version of a select element) we recommend setting selectOnFocus
.
<Autocomplete
id="grouped-demo"
options={options.sort((a, b) => -b.firstLetter.localeCompare(a.firstLetter))}
groupBy={option => option.firstLetter}
getOptionLabel={option => option.title}
style={{ width: 300 }}
renderInput={params => (
<TextField {...params} label="With categories" variant="outlined" fullWidth />
)}
/>
<Autocomplete
id="disabled-options-demo"
options={timeSlots}
getOptionDisabled={option => option === timeSlots[0] || option === timeSlots[2]}
style={{ width: 300 }}
renderInput={params => (
<TextField {...params} label="Disabled options" variant="outlined" fullWidth />
)}
/>
useAutocomplete
For advanced customization use cases, we expose a useAutocomplete()
hook.
It accepts almost the same options as the Autocomplete component minus all the props
related to the rendering of JSX.
The Autocomplete component uses this hook internally.
import useAutocomplete from '@material-ui/lab/useAutocomplete';
Head to the Customized Autocomplete section for a customization example with the Autocomplete
component instead of the hook.
Asynchronous requests
For this demo, we need to load the Google Maps JavaScript API.
⚠️ Before you can start using the Google Maps JavaScript API, you must sign up and create a billing account.
Multiple values
Also known as tags, the user is allowed to enter more than one value.
Fixed options
In the event that you need to lock certain tag so that they can't be removed in the interface, you can set the chips disabled.
Head to the Customized hook section for a customization example with the useAutocomplete
hook instead of the component.
Highlights
The following demo relies on autosuggest-highlight, a small (1 kB) utility for highlighting text in autosuggest and autocomplete components.
Custom filter
The component exposes a factory to create a filter method that can provided to the filerOption
prop.
You can use it to change the default option filter behavior.
import { createFilterOptions } from '@material-ui/lab/Autocomplete';
It supports the following options:
config
(Object [optional]):config.ignoreAccents
(Boolean [optional]): Defaults totrue
. Remove diacritics.config.ignoreCase
(Boolean [optional]): Defaults totrue
. Lowercase everything.config.matchFrom
('any' | 'start' [optional]): Defaults to'any'
.config.stringify
(Func [optional]): Defaults toJSON.stringify
.config.trim
(Boolean [optional]): Defaults tofalse
. Remove trailing spaces.
In the following demo, the options need to start with the query prefix:
const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: option => option.title,
});
<Autocomplete filterOptions={filterOptions} />
Advanced
For richer filtering mechanisms, like fuzzy matching, it's recommended to look at match-sorter. For instance:
import matchSorter from 'match-sorter';
const filterOptions = (options, { inputValue }) =>
matchSorter(options, inputValue);
<Autocomplete filterOptions={filterOptions} />
Virtualization
Search within 10,000 randomly generated options. The list is virtualized thanks to react-window.
<Autocomplete
id="virtualize-demo"
style={{ width: 300 }}
disableListWrap
classes={classes}
ListboxComponent={ListboxComponent}
renderGroup={renderGroup}
options={OPTIONS}
groupBy={option => option[0].toUpperCase()}
renderInput={params => (
<TextField {...params} variant="outlined" label="10,000 options" fullWidth />
)}
renderOption={option => <Typography noWrap>{option}</Typography>}
/>
Limitations
autocomplete/autofill
The browsers have heuristics to help the users fill the form inputs. However, it can harm the UX of the component.
By default, the component disable the autocomplete feature (remembering what the user has typed for a given field in a previous session) with the autoComplete="off"
attribute.
However, in addition to remembering past entered values, the browser might also propose autofill suggestions (saved login, address, or payment details). In the event you want the avoid autofill, you can try the following:
- Name the input without leaking any information the browser can use. e.g.
id="field1"
instead ofid="country"
. If you leave the id empty, the component uses a random id. - Set
autoComplete="new-password"
:<TextField {...params} inputProps={{ ...params.inputProps, autoComplete: 'new-password', }} />
iOS VoiceOver
VoiceOver on iOS Safari doesn't support the aria-owns
attribute very well.
You can work around the issue with the disablePortal
prop.
TypeScript
To fully take advantage of type inference, you need to set the multiple
prop to undefined
, false
or true
.
See this discussion for more details.
TypeScript might solve this bug in the future.
Accessibility
(WAI-ARIA: https://www.w3.org/TR/wai-aria-practices/#combobox)
We encourage the usage of a label for the textbox. The component implements the WAI-ARIA authoring practices.