Skip to main content

Select

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 FormControl component for different variants of select and use MenuItem component as children of Select component.


// MUI Imports
import Select from '@mui/material/Select'
import MenuItem from '@mui/material/MenuItem'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'

const SelectVariants = () => {
return (
<div className='flex gap-4 flex-col'>
<FormControl fullWidth>
<InputLabel id='demo-basic-select-outlined-label'>Age</InputLabel>
<Select label='Age' defaultValue='' id='demo-basic-select-outlined' labelId='demo-basic-select-outlined-label'>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl variant='filled' fullWidth>
<InputLabel id='demo-basic-select-filled-label'>Age</InputLabel>
<Select label='Age' labelId='demo-basic-select-filled-label' id='demo-basic-select-filled' defaultValue=''>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl variant='standard' fullWidth>
<InputLabel id='demo-basic-select-label'>Age</InputLabel>
<Select label='Age' labelId='demo-basic-select-label' id='demo-basic-select' defaultValue=''>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</div>
)
}

export default SelectVariants
Native Select

Use native prop with Select component and <option> element inside Select component for native select.


// MUI Imports
import Select from '@mui/material/Select'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'

const SelectNative = () => {
return (
<div className='flex gap-4 flex-col'>
<FormControl fullWidth>
<InputLabel htmlFor='outlined-age-native-basic'>Age</InputLabel>
<Select
native
label='Age'
defaultValue=''
inputProps={{
name: 'age',
id: 'outlined-age-native-basic'
}}
>
<option aria-label='None' value='' />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
<FormControl variant='filled' fullWidth>
<InputLabel htmlFor='filled-age-native-basic'>Age</InputLabel>
<Select
native
label='Age'
defaultValue=''
inputProps={{
name: 'age',
id: 'filled-age-native-basic'
}}
>
<option aria-label='None' value='' />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
<FormControl variant='standard' fullWidth>
<InputLabel htmlFor='age-native-basic'>Age</InputLabel>
<Select
native
label='Age'
defaultValue=''
inputProps={{
name: 'age',
id: 'age-native-basic'
}}
>
<option aria-label='None' value='' />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
</div>
)
}

export default SelectNative
Select Props

Use displayEmpty, disabled, error, renderValue, autoWidth, required & inputProps props and FormHelperText component for different types of selects.

With label + helper text

Without label

Auto width

Disabled

Error

Read only

Required


// MUI Imports
import Select from '@mui/material/Select'
import MenuItem from '@mui/material/MenuItem'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'
import FormHelperText from '@mui/material/FormHelperText'

const SelectProps = () => {
return (
<div className='flex gap-4 flex-col'>
<FormControl fullWidth>
<InputLabel id='demo-basic-select-helper-label'>Age</InputLabel>
<Select label='Age' defaultValue='' id='demo-basic-select-helper' labelId='demo-basic-select-helper-label'>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>With label + helper text</FormHelperText>
</FormControl>
<FormControl fullWidth>
<Select defaultValue='' displayEmpty inputProps={{ 'aria-label': 'Without label' }}>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Without label</FormHelperText>
</FormControl>
<FormControl fullWidth>
<InputLabel id='demo-basic-select-autoWidth-label'>Age</InputLabel>
<Select
autoWidth
label='Age'
defaultValue=''
id='demo-basic-select-autoWidth'
labelId='demo-basic-select-autoWidth-label'
>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Auto width</FormHelperText>
</FormControl>
<FormControl disabled fullWidth>
<InputLabel id='demo-basic-select-disabled-label'>Age</InputLabel>
<Select label='Age' defaultValue='' id='demo-basic-select-disabled' labelId='demo-basic-select-disabled-label'>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Disabled</FormHelperText>
</FormControl>
<FormControl error fullWidth>
<InputLabel id='demo-basic-select-error-label'>Age</InputLabel>
<Select
label='Age'
defaultValue=''
id='demo-basic-select-error'
renderValue={value => `⚠️ - ${value}`}
labelId='demo-basic-select-error-label'
>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Error</FormHelperText>
</FormControl>
<FormControl fullWidth>
<InputLabel id='demo-basic-select-readonly-label'>Age</InputLabel>
<Select
label='Age'
defaultValue=''
inputProps={{ readOnly: true }}
id='demo-basic-select-readonly'
labelId='demo-basic-select-readonly-label'
>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Read only</FormHelperText>
</FormControl>
<FormControl required fullWidth>
<InputLabel id='demo-basic-select-required-label'>Age</InputLabel>
<Select
label='Age *'
defaultValue=''
id='demo-basic-select-required'
labelId='demo-basic-select-required-label'
>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
<FormHelperText>Required</FormHelperText>
</FormControl>
</div>
)
}

export default SelectProps
Multiple Select

Use multiple prop for multiple selections.

Default

Checkmarks

Chip

Placeholder

Native


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

// MUI Imports
import Box from '@mui/material/Box'
import Chip from '@mui/material/Chip'
import MenuItem from '@mui/material/MenuItem'
import Checkbox from '@mui/material/Checkbox'
import Typography from '@mui/material/Typography'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'
import ListItemText from '@mui/material/ListItemText'
import Select from '@mui/material/Select'
import type { SelectChangeEvent } from '@mui/material/Select'

const ITEM_HEIGHT = 48
const ITEM_PADDING_TOP = 8
const MenuProps = {
PaperProps: {
style: {
width: 250,
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP
}
}
}

const names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
'Ralph Hubbard',
'Omar Alexander',
'Carlos Abbott',
'Miriam Wagner',
'Bradley Wilkerson',
'Virginia Andrews',
'Kelly Snyder'
]

const SelectMultiple = () => {
// States
const [personName, setPersonName] = useState<string[]>([])
const [personNameNative, setPersonNameNative] = useState<string[]>([])

const handleChange = (event: SelectChangeEvent<string[]>) => {
setPersonName(event.target.value as string[])
}

const handleChangeMultipleNative = (event: ChangeEvent<HTMLSelectElement>) => {
const { options } = event.target
const value: string[] = []

for (let i = 0, l = options.length; i < l; i += 1) {
if (options[i].selected) {
value.push(options[i].value)
}
}
setPersonNameNative(value)
}

return (
<div className='flex gap-4 flex-col'>
<div>
<Typography className='mbe-2 font-medium' color='text.primary'>
Default
</Typography>
<FormControl fullWidth>
<InputLabel id='demo-multiple-name-label'>Name</InputLabel>
<Select
multiple
label='Name'
value={personName}
MenuProps={MenuProps}
id='demo-multiple-name'
onChange={handleChange}
labelId='demo-multiple-name-label'
>
{names.map(name => (
<MenuItem key={name} value={name}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
</div>
<div>
<Typography className='mbe-2 font-medium' color='text.primary'>
Checkmarks
</Typography>
<FormControl fullWidth>
<InputLabel id='demo-multiple-checkbox-label'>Tag</InputLabel>
<Select
multiple
label='Tag'
value={personName}
MenuProps={MenuProps}
onChange={handleChange}
id='demo-multiple-checkbox'
labelId='demo-multiple-checkbox-label'
renderValue={selected => (selected as unknown as string[]).join(', ')}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
<div>
<Typography className='mbe-2 font-medium' color='text.primary'>
Chip
</Typography>
<FormControl fullWidth>
<InputLabel id='demo-multiple-chip-label'>Chip</InputLabel>
<Select
multiple
label='Chip'
value={personName}
MenuProps={MenuProps}
id='demo-multiple-chip'
onChange={handleChange}
labelId='demo-multiple-chip-label'
renderValue={selected => (
<div className='flex flex-wrap gap-1'>
{(selected as unknown as string[]).map(value => (
<Chip key={value} label={value} size='small' />
))}
</div>
)}
>
{names.map(name => (
<MenuItem key={name} value={name}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
</div>
<div>
<Typography className='mbe-2 font-medium' color='text.primary'>
Placeholder
</Typography>
<FormControl fullWidth>
<Select
multiple
displayEmpty
value={personName}
MenuProps={MenuProps}
onChange={handleChange}
inputProps={{ 'aria-label': 'Without label' }}
renderValue={selected => {
if ((selected as unknown as string[]).length === 0) {
return <em>Placeholder</em>
}

return (selected as unknown as string[]).join(', ')
}}
>
<MenuItem disabled value=''>
<em>Placeholder</em>
</MenuItem>
{names.map(name => (
<MenuItem key={name} value={name}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
</div>
<div>
<Typography className='mbe-2 font-medium' color='text.primary'>
Native
</Typography>
<FormControl fullWidth>
<InputLabel shrink htmlFor='select-multiple-native'>
Native
</InputLabel>
<Select
native
multiple
label='Native'
value={personNameNative} // @ts-ignore
onChange={handleChangeMultipleNative}
inputProps={{ id: 'select-multiple-native' }}
>
{names.map(name => (
<option key={name} value={name}>
{name}
</option>
))}
</Select>
</FormControl>
</div>
</div>
)
}

export default SelectMultiple
Controlled and Uncontrolled

Manage value prop with the help of a state for controlled Select and use defaultValue prop for uncontrolled Select.


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

// MUI Imports
import MenuItem from '@mui/material/MenuItem'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'
import Select from '@mui/material/Select'
import type { SelectChangeEvent } from '@mui/material/Select'

const SelectControlledUncontrolled = () => {
// States
const [value, setValue] = useState<string>('')

const handleChange = (event: SelectChangeEvent) => {
setValue(event.target.value as string)
}

return (
<div className='flex gap-4 flex-col'>
<FormControl fullWidth>
<InputLabel id='controlled-select-label'>Controlled</InputLabel>
<Select
value={value}
label='Controlled'
id='controlled-select'
onChange={handleChange}
labelId='controlled-select-label'
>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth>
<InputLabel id='uncontrolled-select-label'>Uncontrolled</InputLabel>
<Select defaultValue='' label='Uncontrolled' id='uncontrolled-select' labelId='uncontrolled-select-label'>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</div>
)
}

export default SelectControlledUncontrolled
Customized Select

Use styled hook to customize your select.


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

// MUI Imports
import MenuItem from '@mui/material/MenuItem'
import { styled } from '@mui/material/styles'
import InputBase from '@mui/material/InputBase'
import InputLabel from '@mui/material/InputLabel'
import Select from '@mui/material/Select'
import MuiFormControl from '@mui/material/FormControl'
import type { SelectChangeEvent } from '@mui/material/Select'
import type { FormControlProps } from '@mui/material/FormControl'

// Styled FormControl component
const FormControl = styled(MuiFormControl)<FormControlProps>(({ theme }) => ({
'& .MuiFormLabel-root.Mui-focused': {
color: '#80BDFF'
},
'& .MuiInputLabel-root': {
left: -14,
zIndex: 0
},
'& > .MuiInputBase-root': {
marginTop: theme.spacing(4),
'&.MuiInput-root:before, &.MuiInput-root:after': {
border: 0
}
},
'& .MuiInputBase-input': {
fontSize: 16,
borderRadius: 4,
position: 'relative',
padding: '10px 26px 10px 12px',
backgroundColor: theme.palette.background.paper,
transition: theme.transitions.create(['border-color', 'box-shadow']),
border: theme.palette.mode === 'light' ? '1px solid #ced4da' : `1px solid ${theme.palette.divider}`,
fontFamily: [
'-apple-system',
'BlinkMacSystemFont',
'"Segoe UI"',
'Roboto',
'"Helvetica Neue"',
'Arial',
'sans-serif',
'"Apple Color Emoji"',
'"Segoe UI Emoji"',
'"Segoe UI Symbol"'
].join(','),
'&:focus': {
borderRadius: 4,
borderColor: '#80BDFF',
boxShadow: '0 0 0 0.2rem rgba(0,123,255,0.25)'
}
}
}))

const SelectCustomized = () => {
// States
const [value, setValue] = useState<string>('')

const handleChange = (event: SelectChangeEvent) => {
setValue(event.target.value as string)
}

return (
<div className='flex gap-4 flex-col'>
<FormControl fullWidth>
<InputLabel id='demo-customized-select-label'>Age</InputLabel>
<Select
value={value}
input={<InputBase />}
onChange={handleChange}
id='demo-customized-select'
labelId='demo-customized-select-label'
>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth>
<InputLabel htmlFor='demo-customized-select-native'>Age</InputLabel>
<Select native input={<InputBase />} id='demo-customized-select-native' value={value} onChange={handleChange}>
<option aria-label='None' value='' />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
</div>
)
}

export default SelectCustomized
Grouping

Display categories with the ListSubheader component or the native <optgroup> element.


// MUI Imports
import Select from '@mui/material/Select'
import MenuItem from '@mui/material/MenuItem'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'
import ListSubheader from '@mui/material/ListSubheader'

const SelectGrouping = () => {
return (
<div className='flex gap-4 flex-col'>
<FormControl fullWidth>
<InputLabel htmlFor='grouped-select'>Grouping</InputLabel>
<Select label='Grouping' defaultValue='' id='grouped-select'>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<ListSubheader>Category 1</ListSubheader>
<MenuItem value={1}>Option 1</MenuItem>
<MenuItem value={2}>Option 2</MenuItem>
<ListSubheader>Category 2</ListSubheader>
<MenuItem value={3}>Option 3</MenuItem>
<MenuItem value={4}>Option 4</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth>
<InputLabel htmlFor='grouped-native-select'>Grouping</InputLabel>
<Select native label='Grouping' defaultValue='' id='grouped-native-select'>
<option aria-label='None' value='' />
<optgroup label='Category 1'>
<option value={1}>Option 1</option>
<option value={2}>Option 2</option>
</optgroup>
<optgroup label='Category 2'>
<option value={3}>Option 3</option>
<option value={4}>Option 4</option>
</optgroup>
</Select>
</FormControl>
</div>
)
}

export default SelectGrouping
Select with Dialog

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

// MUI Imports
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Dialog from '@mui/material/Dialog'
import Select from '@mui/material/Select'
import MenuItem from '@mui/material/MenuItem'
import InputLabel from '@mui/material/InputLabel'
import DialogTitle from '@mui/material/DialogTitle'
import FormControl from '@mui/material/FormControl'
import DialogContent from '@mui/material/DialogContent'
import DialogActions from '@mui/material/DialogActions'

const SelectWithDialog = () => {
// States
const [open, setOpen] = useState<boolean>(false)

const handleClickOpen = () => {
setOpen(true)
}

const handleClose = () => {
setOpen(false)
}

return (
<div>
<Button variant='outlined' onClick={handleClickOpen}>
Open select dialog
</Button>
<Dialog maxWidth='xs' fullWidth open={open} onClose={handleClose}>
<DialogTitle>Fill the form</DialogTitle>
<DialogContent className='!pbs-2'>
<Box component='form' className='flex gap-4'>
<FormControl className='mie-4 mbe-4' fullWidth>
<InputLabel id='demo-dialog-select-label'>Age</InputLabel>
<Select label='Age' labelId='demo-dialog-select-label' id='demo-dialog-select' defaultValue=''>
<MenuItem value=''>
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
<FormControl fullWidth>
<InputLabel htmlFor='outlined-age-native-basic'>Age</InputLabel>
<Select
native
label='Age'
defaultValue=''
inputProps={{
name: 'age',
id: 'outlined-age-native-basic'
}}
>
<option aria-label='None' value='' />
<option value={10}>Ten</option>
<option value={20}>Twenty</option>
<option value={30}>Thirty</option>
</Select>
</FormControl>
</Box>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} variant='outlined'>
Cancel
</Button>
<Button onClick={handleClose} variant='outlined'>
Ok
</Button>
</DialogActions>
</Dialog>
</div>
)
}

export default SelectWithDialog