Select components are used for collecting user provided information from a list of options.
Menus are positioned under their emitting elements, unless they are close to the bottom of the viewport.
{{ādemoā: āBasicSelect.jsā}}
The Select component is meant to be interchangeable with a native <select>
element.
If you are looking for more advanced features, like combobox, multiselect, autocomplete, async or creatable support, head to the Autocomplete
component.
Itās meant to be an improved version of the āreact-selectā and ādownshiftā packages.
The Select component is implemented as a custom <input>
element of the InputBase.
It extends the text field components subcomponents, either the OutlinedInput, Input, or FilledInput, depending on the variant selected.
It shares the same styles and many of the same props. Refer to the respective componentās API page for details.
{{ādemoā: āSelectVariants.jsā}}
{{ādemoā: āSelectLabels.jsā}}
Note that when using FormControl with the outlined variant of the Select, you need to provide a label in two places: in the InputLabel component and in the
label
prop of the Select component (see the above demo).
{{ādemoā: āSelectAutoWidth.jsā}}
{{ādemoā: āSelectSmall.jsā}}
{{ādemoā: āSelectOtherProps.jsā}}
As the user experience can be improved on mobile using the native select of the platform, we allow such pattern.
{{ādemoā: āNativeSelectDemo.jsā}}
The TextField
wrapper component is a complete form control including a label, input and help text.
You can find an example with the select mode in this section.
Here are some examples of customizing the component. You can learn more about this in the overrides documentation page.
The first step is to style the InputBase
component.
Once itās styled, you can either use it directly as a text field or provide it to the select input
prop to have a select
field.
Notice that the "standard"
variant is easier to customize, since it does not wrap the contents in a fieldset
/legend
markup.
{{ādemoā: āCustomizedSelects.jsā}}
šØ If you are looking for inspiration, you can check MUI Treasuryās customization examples.
The Select
component can handle multiple selections.
Itās enabled with the multiple
prop.
Like with the single selection, you can pull out the new value by accessing event.target.value
in the onChange
callback. Itās always an array.
{{ādemoā: āMultipleSelect.jsā}}
{{ādemoā: āMultipleSelectCheckmarks.jsā}}
{{ādemoā: āMultipleSelectChip.jsā}}
{{ādemoā: āMultipleSelectPlaceholder.jsā}}
{{ādemoā: āMultipleSelectNative.jsā}}
You can control the open state of the select with the open
prop. Alternatively, it is also possible to set the initial (uncontrolled) open state of the component with the defaultOpen
prop.
- A component is controlled when itās managed by its parent using props.
- A component is uncontrolled when itās managed by its own local state.
Learn more about controlled and uncontrolled components in the React documentation.
{{ādemoā: āControlledOpenSelect.jsā}}
While itās discouraged by the Material Design guidelines, you can use a select inside a dialog.
{{ādemoā: āDialogSelect.jsā}}
Display categories with the ListSubheader
component or the native <optgroup>
element.
{{ādemoā: āGroupedSelect.jsā}}
If you wish to wrap the ListSubheader in a custom component, youāll have to annotate it so MaterialĀ UI can handle it properly when determining focusable elements.
You have two options for solving this: Option 1: Define a static boolean field called
muiSkipListHighlight
on your component function, and set it totrue
:
function MyListSubheader(props: ListSubheaderProps) { return <ListSubheader {...props} />; } MyListSubheader.muiSkipListHighlight = true; export default MyListSubheader; // elsewhere: return ( <Select> <MyListSubheader>Group 1</MyListSubheader> <MenuItem value={1}>Option 1</MenuItem> <MenuItem value={2}>Option 2</MenuItem> <MyListSubheader>Group 2</MyListSubheader> <MenuItem value={3}>Option 3</MenuItem> <MenuItem value={4}>Option 4</MenuItem> {/* ... */} </Select>
Option 2: Place a
muiSkipListHighlight
prop on each instance of your component. The prop doesnāt have to be forwarded to the ListSubheader, nor present in the underlying DOM element. It just has to be placed on a component thatās used as a subheader.
export default function MyListSubheader( props: ListSubheaderProps & { muiSkipListHighlight: boolean }, ) { const { muiSkipListHighlight, ...other } = props; return <ListSubheader {...other} />; } // elsewhere: return ( <Select> <MyListSubheader muiSkipListHighlight>Group 1</MyListSubheader> <MenuItem value={1}>Option 1</MenuItem> <MenuItem value={2}>Option 2</MenuItem> <MyListSubheader muiSkipListHighlight>Group 2</MyListSubheader> <MenuItem value={3}>Option 3</MenuItem> <MenuItem value={4}>Option 4</MenuItem> {/* ... */} </Select> );
We recommend the first option as it doesnāt require updating all the usage sites of the component.
Keep in mind this is only necessary if you wrap the ListSubheader in a custom component. If you use the ListSubheader directly, no additional code is required.
To properly label your Select
input you need an extra element with an id
that contains a label.
That id
needs to match the labelId
of the Select
, for example:
<InputLabel id="label">Age</InputLabel>
<Select labelId="label" id="select" value="20">
<MenuItem value="10">Ten</MenuItem>
<MenuItem value="20">Twenty</MenuItem>
</Select>
Alternatively a TextField
with an id
and label
creates the proper markup and
ids for you:
<TextField id="select" label="Age" value="20" select>
<MenuItem value="10">Ten</MenuItem>
<MenuItem value="20">Twenty</MenuItem>
</TextField>
For a native select, you should mention a label by giving the value of the id
attribute of the select element to the InputLabel
ās htmlFor
attribute:
<InputLabel htmlFor="select">Age</InputLabel>
<NativeSelect id="select">
<option value="10">Ten</option>
<option value="20">Twenty</option>
</NativeSelect>