Autocomplete
The autocomplete is a text input enhanced by a panel of suggested options when users start typing.
Introduction
Autocomplete
is an enhanced version of text input that shows suggested options as the users type and also let them select an option from the list.
Flags
- The completion string, appears inline after the input cursor in the textbox. The inline completion string is visually highlighted and has a selected state.
- The first option is automatically highlighted.
- The selected option becomes the value of the input when the Autocomplete loses focus unless the user chooses a different option or changes the character string in the input.
- The input is always blurred.
- The input's text is cleared on blur if no value is selected.
- Clear all values when the user presses escape and the popup is closed.
- The component is disabled.
- The input can't be cleared
- The popup won't close when a value is selected.
- The list box in the popup will not wrap focus.
- Hide the selected option from the list box.
- The user input is not bound to the provided options.
- The highlight can move to the input.
- The popup will open on input focus.
- The popup will be under the DOM hierarchy of the parent component.
- The component becomes read-only. It is also supported in multiple tags where the tag cannot be deleted.
- The input's text is selected on focus. It helps the user clear the selected value.
Usage
After installation, you can start building with this component using the following basic elements:
import Autocomplete from '@mui/joy/Autocomplete';
import Input from '@mui/joy/Input';
export default function App() {
return <Autocomplete options={['Option 1', 'Option 2']} />;
}
Basics
The Autocomplete component requires a list of options
to be displayed after the textbox is focused. The value must be chosen from a predefined set of allowed values.
Customization
Options structure
By default, the options
accepts an array of string
or { label: string }
:
const options = [
{ label: 'The Godfather', id: 1 },
{ label: 'Pulp Fiction', id: 2 },
];
// or
const options = ['The Godfather', 'Pulp Fiction'];
However, you can use different structures by providing a getOptionLabel
prop:
const options = [
{ title: 'Pulp Fiction', id: 2 },
// ...
];
<Autocomplete getOptionLabel={option => option.title}>
Option appearance
To customize the appearance of the options, use renderOption
prop in combination with the AutocompleteOption
component as an option container.
Variants
The autocomplete component supports the four global variants: outlined
(default), soft
, solid
, and plain
.
Label
Put an Autocomplete
, a FormLabel
and a FormHelperText
(optional) under a FormControl
component to create an accessible autocomplete.
Controlled states
The component has two states that can be controlled:
- the "value" state with the
value
/onChange
props combination. This state represents the value selected by the user, for instance when pressing Enter. - the "input value" state with the
inputValue
/onInputChange
props combination. This state represents the value displayed in the textbox.
value:
'Option 1'
inputValue:
''
Grouped options
You can group the options with the groupBy
prop.
If you do so, make sure that the options are also sorted with the same dimension that they are grouped by,
otherwise, you will notice duplicate headers.
Search input
Use freeSolo
to create a search input with suggestions experience, e.g. Google search or react-autowhatever.
User's created option
If you intend to use freeSolo
mode for a combo box like experience (an enhanced version of a select element) we recommend setting:
selectOnFocus
to help the user clear the selected value.clearOnBlur
to help the user enter a new value.handleHomeEndKeys
to move focus inside the popup with the Home and End keys.- A last option, for instance:
Add "YOUR SEARCH"
.
You could also display a dialog when the user wants to add a new value.
Multiple selection
By default, the autocomplete uses Chip
component to render the user's selected options.
When the autocomplete is focused, the user can press the backspace to remove the latest selected option from the list.
Limit the selected options to be displayed
You can use the limitTags
prop to limit the number of displayed options when not focused.
Sizes
The autocomplete component comes with three sizes out of the box: sm
, md
(the default), and lg
. The size is propagated to internal components, including Input
, Chip
, and List
.
The size
can also be controlled at the FormControl
.
Custom filter
The component exposes a factory to create a filter method that can be provided to the filterOptions
prop.
You can use it to change the default option filter behavior.
import { createFilterOptions } from '@mui/material/Autocomplete';
Arguments
config
(object [optional]):
config.ignoreAccents
(bool [optional]): Defaults totrue
. Remove diacritics.config.ignoreCase
(bool [optional]): Defaults totrue
. Lowercase everything.config.limit
(number [optional]): Default to null. Limit the number of suggested options to be shown. For example, ifconfig.limit
is100
, only the first100
matching options are shown. It can be useful if a lot of options match and virtualization wasn't set up.config.matchFrom
('any' | 'start' [optional]): Defaults to'any'
.config.stringify
(func [optional]): Controls how an option is converted into a string so that it can be matched against the input text fragment.config.trim
(bool [optional]): Defaults tofalse
. Remove trailing spaces.
Returns
filterOptions
: the returned filter method can be provided directly to the filterOptions
prop of the Autocomplete
component, or the parameter of the same name for the hook.
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 filter
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} />;
Common examples
Highlighting options
The following demo relies on autosuggest-highlight, a small (1 kB) utility for highlighting text in autosuggest and autocomplete components.
GitHub's picker
To reproduce GitHub's label picker, the Autocomplete
is rendered inside a PopperUnstyled
. To remove the popup behavior from the autocomplete, replace the listbox slot with the AutocompleteListbox
component.
- help wanted
- type: bug
Virtualization
Search within 10,000 randomly generated options. The list is virtualized thanks to react-window.
Events
If you would like to prevent the default key handler behavior, you can set the event's defaultMuiPrevented
property to true
:
<Autocomplete
onKeyDown={(event) => {
if (event.key === 'Enter') {
// Prevent's default 'Enter' behavior.
event.defaultMuiPrevented = true;
// your handler code
}
}}
/>
CSS Variables
The Autocomplete component reuses CSS variables from the Input component to give you the consistent customization experience.
<Autocomplete />
CSS Variables
px
px
px
Limitations
autocomplete/autofill
By default, the component disables the input autocomplete feature (remembering what the user has typed for a given field in a previous session) with the autoComplete="off"
attribute.
Google Chrome does not currently support this attribute setting (Issue 587466).
A possible workaround is to remove the id
to have the component generate a random one.
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"
(some browsers will suggest a strong password for inputs with this attribute setting):<Autocomplete slotProps={{ input: { autoComplete: 'new-password', }, }} />
Read the guide on MDN for more details.
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.
<Autocomplete
slotProps={{
listbox: {
disablePortal: true,
},
}}
/>
Accessibility
(WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/)
We encourage the usage of a label for the textbox. The component implements the WAI-ARIA authoring practices.