Skip to main content

Autocomplete

Please refer to MUI's official docs for more details on component's usage guide and API documentation.

Variants

Use variant={'filled' | 'standard'} prop with TextField component in renderInput prop with Autocomplete component for different variants of input. Use disabled prop with Autocomplete component for disabled autocomplete.


// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteVariants = () => {
return (
<div className='flex gap-4 flex-col'>
<Autocomplete
options={top100Films}
id='autocomplete-outlined'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Combo box' />}
/>
<Autocomplete
options={top100Films}
id='autocomplete-filled'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Combo box' variant='filled' />}
/>
<Autocomplete
options={top100Films}
id='autocomplete-default'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Combo box' variant='standard' />}
/>
<Autocomplete
disabled
options={top100Films}
id='autocomplete-disabled'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Disabled' />}
/>
</div>
)
}

export default AutocompleteVariants
Controlled and Uncontrolled

Use value prop with Autocomplete component for controlled autocomplete input.


// React Imports
import { useState } from 'react'
import type { SyntheticEvent } from 'react'

// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

type FilmOptionType = {
year: number
title: string
}

const AutocompleteControlledUncontrolled = () => {
// States
const [value, setValue] = useState<FilmOptionType | null>(null)

const handleChange = (event: SyntheticEvent, newValue: FilmOptionType | null) => {
setValue(newValue)
}

return (
<div className='flex gap-4 flex-col'>
<Autocomplete
value={value}
options={top100Films}
onChange={handleChange}
id='autocomplete-controlled'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Controlled' />}
/>
<Autocomplete
options={top100Films}
id='autocomplete-uncontrolled'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Uncontrolled' />}
/>
</div>
)
}

export default AutocompleteControlledUncontrolled
Free Solo

Use freeSolo prop so the textbox can contain any arbitrary value.


// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteFreeSolo = () => {
return (
<Autocomplete
freeSolo
id='autocomplete-free-solo'
options={top100Films.map(option => option.title)}
renderInput={params => <TextField {...params} label='Free Solo' />}
/>
)
}

export default AutocompleteFreeSolo
Autocomplete Props

Each of the following examples demonstrate one feature of Autocomplete component.


// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteProps = () => {
return (
<div className='flex gap-4 flex-col'>
<Autocomplete
disableCloseOnSelect
options={top100Films}
id='autocomplete-disableCloseOnSelect'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='disableCloseOnSelect' />}
/>
<Autocomplete
clearOnEscape
options={top100Films}
id='autocomplete-clearOnEscape'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='clearOnEscape' />}
/>
<Autocomplete
disableClearable
options={top100Films}
id='autocomplete-disableClearable'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='disableClearable' />}
/>
<Autocomplete
openOnFocus
options={top100Films}
id='autocomplete-openOnFocus'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='openOnFocus' />}
/>
<Autocomplete
autoHighlight
options={top100Films}
id='autocomplete-autoHighlight'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='autoHighlight' />}
/>
<Autocomplete
autoSelect
options={top100Films}
id='autocomplete-autoSelect'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='autoSelect' />}
/>
<Autocomplete
blurOnSelect
options={top100Films}
id='autocomplete-blurOnSelect'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='blurOnSelect' />}
/>
<Autocomplete
clearOnBlur
options={top100Films}
id='autocomplete-clearOnBlur'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='clearOnBlur' />}
/>
</div>
)
}

export default AutocompleteProps
Country Select

Choose one of the countries.


// MUI Imports
import Box from '@mui/material/Box'
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { countries } from '../../../data/countries'

type CountryType = {
code: string
label: string
phone: string
}

const AutocompleteCountry = () => {
return (
<Autocomplete
autoHighlight
id='autocomplete-country-select'
options={countries as CountryType[]}
getOptionLabel={option => option.label || ''}
renderOption={(props, option) => (
<Box component='li' {...props} key={option.label}>
<img
className='mie-4 flex-shrink-0'
alt=''
width='20'
loading='lazy'
src={`https://flagcdn.com/w20/${option.code.toLowerCase()}.png`}
srcSet={`https://flagcdn.com/w40/${option.code.toLowerCase()}.png 2x`}
/>
{option.label} ({option.code}) +{option.phone}
</Box>
)}
renderInput={params => (
<TextField
{...params}
key={params.id}
label='Choose a country'
inputProps={{
...params.inputProps,
autoComplete: 'new-password'
}}
/>
)}
/>
)
}

export default AutocompleteCountry
Creatable

You can create an option other than from the list.


// React Imports
import { useState } from 'react'

// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

type FilmOptionType = {
year?: number
title: string
inputValue?: string
}

const filter = createFilterOptions<FilmOptionType>()

const AutocompleteCreatable = () => {
// States
const [value, setValue] = useState<FilmOptionType | null>(null)

return (
<Autocomplete
freeSolo
clearOnBlur
value={value}
handleHomeEndKeys
options={top100Films}
id='autocomplete-free-solo-with-text'
renderOption={(props, option) => <li {...props}>{option.title}</li>}
renderInput={params => <TextField {...params} label='Free solo with text demo' />}
getOptionLabel={option => {
if (typeof option === 'string') {
return option || ''
}
if ((option as FilmOptionType).inputValue as string) {
return ((option as FilmOptionType).inputValue as string) || ''
}

return (option.title as string) || ''
}}
onChange={(event, newValue) => {
if (typeof newValue === 'string') {
setValue({
title: newValue
})
} else if (newValue && (newValue as any).inputValue) {
setValue({
title: (newValue as any).inputValue
})
} else {
setValue(newValue)
}
}}
filterOptions={(options: FilmOptionType[], params: any) => {
const filtered = filter(options, params)
const { inputValue } = params
const isExisting = options.some((option: FilmOptionType) => inputValue === option.title)

if (inputValue !== '' && !isExisting) {
filtered.push({
inputValue,
title: `Add "${inputValue}"`
})
}

return filtered
}}
/>
)
}

export default AutocompleteCreatable
Multiple Values

Use multiple prop to select multiple options from the list.

Inception
Inception
Inception

// MUI Imports
import Chip from '@mui/material/Chip'
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteMultipleValues = () => {
return (
<div className='flex gap-4 flex-col'>
<Autocomplete
multiple
options={top100Films}
filterSelectedOptions
defaultValue={[top100Films[13]]}
id='autocomplete-multiple-outlined'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='filterSelectedOptions' placeholder='Favorites' />}
/>
<Autocomplete
freeSolo
multiple
id='autocomplete-multiple-filled'
defaultValue={[top100Films[13].title]}
options={top100Films.map(option => option.title)}
renderInput={params => <TextField {...params} variant='filled' label='freeSolo' placeholder='Favorites' />}
renderTags={(value: string[], getTagProps) =>
value.map((option: string, index: number) => (
<Chip variant='outlined' label={option} size='small' {...(getTagProps({ index }) as {})} key={index} />
))
}
/>
<Autocomplete
multiple
options={top100Films}
defaultValue={[top100Films[13]]}
id='autocomplete-multiple-standard'
getOptionLabel={option => option.title || ''}
renderInput={params => (
<TextField {...params} label='Multiple values' placeholder='Favorites' variant='standard' />
)}
/>
</div>
)
}

export default AutocompleteMultipleValues
Disabled Options

Use getOptionDisabled prop to disable some options from the list.


// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

const timeSlots = Array.from(new Array(24 * 2)).map(
(_, index) => `${index < 20 ? '0' : ''}${Math.floor(index / 2)}:${index % 2 === 0 ? '00' : '30'}`
)

const AutocompleteDisabledOptions = () => {
return (
<Autocomplete
options={timeSlots}
id='autocomplete-disabled-options'
renderInput={params => <TextField {...params} label='Disabled options' />}
getOptionDisabled={option => option === timeSlots[0] || option === timeSlots[2]}
/>
)
}

export default AutocompleteDisabledOptions
Grouped

Use groupBy prop to group the list according to your needs.


// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteGrouped = () => {
const options = top100Films.map(option => {
const firstLetter = option.title[0].toUpperCase()

return {
firstLetter: /[0-9]/.test(firstLetter) ? '0-9' : firstLetter,
...option
}
})

return (
<Autocomplete
id='autocomplete-grouped'
groupBy={option => option.firstLetter}
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='With categories' />}
options={options.sort((a, b) => -b.firstLetter.localeCompare(a.firstLetter))}
/>
)
}

export default AutocompleteGrouped
Checkboxes

Use Checkbox component in renderOption prop to render checkbox in options.


// MUI Imports
import Checkbox from '@mui/material/Checkbox'
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteCheckboxes = () => {
return (
<Autocomplete
multiple
disableCloseOnSelect
options={top100Films}
id='autocomplete-checkboxes'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} key={params.id} label='Checkboxes' placeholder='Favorites' />}
renderOption={(props, option, { selected }) => (
<li {...props} key={option.title}>
<Checkbox checked={selected} className='mie-2' />
{option.title}
</li>
)}
/>
)
}

export default AutocompleteCheckboxes
Fixed Options

You can fix an option in the input and add any other option as well.

Pulp Fiction
Inception

// React Imports
import { useState } from 'react'

// MUI Imports
import Chip from '@mui/material/Chip'
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

// Type
type DataType = {
year: number
title: string
}

const fixedOptions = [top100Films[6]]

const AutocompleteFixedOptions = () => {
// States
const [value, setValue] = useState<DataType[]>([...fixedOptions, top100Films[13]])

return (
<Autocomplete
multiple
value={value}
options={top100Films}
id='autocomplete-fixed-option'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Fixed tag' placeholder='Favorites' />}
onChange={(event, newValue) => {
setValue([...fixedOptions, ...newValue.filter(option => fixedOptions.indexOf(option) === -1)])
}}
renderTags={(tagValue, getTagProps) =>
tagValue.map((option, index) => (
<Chip
label={option.title}
{...(getTagProps({ index }) as {})}
disabled={fixedOptions.indexOf(option) !== -1}
key={index}
size='small'
/>
))
}
/>
)
}

export default AutocompleteFixedOptions
Small Size

Use size='small' prop for small sized input.

Inception

// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteSmallSize = () => {
return (
<div>
<Autocomplete
size='small'
options={top100Films}
id='autocomplete-size-small'
defaultValue={top100Films[13]}
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Size small' placeholder='Favorites' />}
/>
<Autocomplete
multiple
size='small'
className='mbs-5'
options={top100Films}
defaultValue={[top100Films[13]]}
id='autocomplete-size-small-multi'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Size small' placeholder='Favorites' />}
/>
</div>
)
}

export default AutocompleteSmallSize
Limit Tags

Use limitTags prop to limit tags in the input.

Inception
Forrest Gump
+1

// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

const AutocompleteLimitTags = () => {
return (
<Autocomplete
multiple
limitTags={2}
options={top100Films}
id='autocomplete-limit-tags'
getOptionLabel={option => option.title || ''}
defaultValue={[top100Films[13], top100Films[12], top100Films[11]]}
renderInput={params => <TextField {...params} label='limitTags' placeholder='Favorites' />}
/>
)
}

export default AutocompleteLimitTags
Custom Filter

Use filterOptions prop to filter the search according to your needs.


// MUI Imports
import TextField from '@mui/material/TextField'
import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete'

// Data Imports
import { top100Films } from '../../../data/top100films'

type FilmOptionType = {
year: number
title: string
}

const filterOptions = createFilterOptions({
matchFrom: 'start',
stringify: (option: FilmOptionType) => option.title
})

const AutocompleteCustomFilter = () => {
return (
<Autocomplete
options={top100Films}
filterOptions={filterOptions}
id='autocomplete-custom-filter'
getOptionLabel={option => option.title || ''}
renderInput={params => <TextField {...params} label='Custom filter' />}
/>
)
}

export default AutocompleteCustomFilter
Custom Input

Use renderInput prop to customize the rendered input.


// MUI Imports
import Autocomplete from '@mui/material/Autocomplete'

const options = ['Option 1', 'Option 2']

const AutocompleteCustomInput = () => {
return (
<Autocomplete
options={options}
id='autocomplete-custom-input'
renderInput={params => (
<div ref={params.InputProps.ref}>
<input type='text' {...params.inputProps} />
</div>
)}
sx={{
display: 'inline-block',
'& input': {
width: 200,
borderWidth: 2,
backgroundColor: 'background.paper',
color: theme => theme.palette.getContrastText(theme.palette.background.paper)
}
}}
/>
)
}

export default AutocompleteCustomInput