Select
Choose one or multiple values with native or Material selection surfaces.
This guide covers Material UI Core with the default Emotion engine; extensions and additional demos are explicitly classified.
Use case and business boundary
Multiple values require the right array type; native options and MenuItems are different child structures, not interchangeable.
Native composition and scope
Select, NativeSelect
Preserve native Material UI composition and types; do not substitute JGuang UI/Base UI/Radix APIs. Example entries are not extra components.
Native installation and initialization
npm install @mui/material@9.4.0 @emotion/react@11.14.0 @emotion/styled@11.14.1
Use native npm and Emotion, not an invented JGuang UI Registry URL. Place examples inside native ThemeProvider; choose CssBaseline or ScopedCssBaseline for the project. Inspect React, existing providers, lockfile and SSR first. Never overwrite files or conceal peer conflicts. This batch verified React 19.2.8; React 18 and below require matching react-is. See the included bilingual setup guide.
Practical native parameters
These selected parameters are not a flattened universal API. Preserve the native declaring owner, slot structure, nullable values and generics.
| Owner.prop | Practical role | Declaration source |
|---|---|---|
Select.value | Controlled native value; its scalar/array/nullable type is owner-specific. | Select |
Select.multiple | Native multiple-selection mode; value and callback types change with the owner. | Select |
Select.onChange | Owning control's native callback; preserve its exact event/value/nullable signature. | Select |
Select.labelId | ID of the element naming the native Select; do not invent a missing label. | Select |
Select.renderValue | Native selected-value presentation callback; it does not change selection data. | Select |
Select.native | Render a browser-native Select child structure, not MenuItems. | Select |
Runnable native examples
Machine keys select example entries, not universal variant props. Native demo JSX/data stay unchanged; JGuang-authored acceptance fixtures are explicitly labelled.
- Basic select ·
BasicSelect· upstream native demo - Variants ·
SelectVariants· upstream native demo - Labels and helper text ·
SelectLabels· upstream native demo - Auto width ·
SelectAutoWidth· upstream native demo - Small Size ·
SelectSmall· upstream native demo - Other props ·
SelectOtherProps· upstream native demo - Native select ·
NativeSelectDemo· upstream native demo - Customization ·
CustomizedSelects· upstream native demo - Default ·
MultipleSelect· upstream native demo - Selection indicators ·
MultipleSelectCheckmarks· upstream native demo - Chip ·
MultipleSelectChip· upstream native demo - Placeholder ·
MultipleSelectPlaceholder· upstream native demo - Native ·
MultipleSelectNative· upstream native demo - Controlling the open state ·
ControlledOpenSelect· upstream native demo - With a dialog ·
DialogSelect· upstream native demo - Grouping ·
GroupedSelect· upstream native demo
Actual usage example
Unmodified pinned native demo; copy its required local helper files together.
import * as React from 'react';
import Box from '@mui/material/Box';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import Select, { SelectChangeEvent } from '@mui/material/Select';
export default function BasicSelect() {
const [age, setAge] = React.useState('');
const handleChange = (event: SelectChangeEvent) => {
setAge(event.target.value as string);
};
return (
<Box sx={{ minWidth: 120 }}>
<FormControl fullWidth>
<InputLabel id="demo-simple-select-label">Age</InputLabel>
<Select
labelId="demo-simple-select-label"
id="demo-simple-select"
value={age}
label="Age"
onChange={handleChange}
>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</Select>
</FormControl>
</Box>
);
}
Example dependency boundaries
react, @mui/material/Box, @mui/material/InputLabel, @mui/material/MenuItem, @mui/material/FormControl, @mui/material/Select, @mui/material/FormHelperText, @mui/material/NativeSelect, @mui/material/styles, @mui/material/InputBase, @mui/material/OutlinedInput, @mui/material/ListItemText, @mui/icons-material/CheckBoxOutlineBlank, @mui/icons-material/CheckBox, @mui/material/Chip, @mui/material/Button, @mui/material/Dialog, @mui/material/DialogActions, @mui/material/DialogContent, @mui/material/DialogTitle, @mui/material/ListSubheader
Direct Icons/System/Utils example imports require their matching 9.4.0 packages. Relative data/helpers are part of the example closure, not extra components. Remote images and simulated operations do not supply a backend.
Pinned upstream API metadata reference
These tables retain the upstream metadata, not a newly inferred generic type system. Conditional generics, inherited props and callback details are defined by the source declarations below. Theme defaults may override metadata defaults.
Select
import Select from '@mui/material/Select';
import { Select } from '@mui/material';
Native inheritance: OutlinedInput. Parent/DOM props are not fabricated as additional own props.
| Prop | Required | Upstream metadata type / constraint | Metadata default |
|---|---|---|---|
autoWidth | no | bool | false |
children | no | node | — |
classes | no | object | {} |
defaultOpen | no | bool | false |
defaultValue | no | any | — |
displayEmpty | no | bool | false |
IconComponent | no | elementType | ArrowDropDownIcon |
id | no | string | — |
input | no | element | — |
inputProps | no | object | — |
label | no | node | — |
labelId | no | string | — |
MenuProps | no | object | — |
multiple | no | bool | false |
native | no | bool | false |
onChange | no | func | — |
onClose | no | func | — |
onOpen | no | func | — |
open | no | bool | — |
renderValue | no | func | — |
SelectDisplayProps | no | object | — |
sx | no | Array<func | object | bool> | func | object | — |
value | no | '' | any | — |
variant | no | 'filled' | 'outlined' | 'standard' | 'outlined' |
NativeSelect
import NativeSelect from '@mui/material/NativeSelect';
import { NativeSelect } from '@mui/material';
Native inheritance: Input. Parent/DOM props are not fabricated as additional own props.
| Prop | Required | Upstream metadata type / constraint | Metadata default |
|---|---|---|---|
children | no | node | — |
classes | no | object | {} |
IconComponent | no | elementType | ArrowDropDownIcon |
input | no | element | <Input /> |
inputProps | no | object | — |
onChange | no | func | — |
sx | no | Array<func | object | bool> | func | object | — |
value | no | any | — |
variant | no | 'filled' | 'outlined' | 'standard' | — |
Native source declarations
Declarations/imports are extracted from pinned source without flattening unions or external inheritance. Original English comments/types are source reference, not a claim of translated upstream prose. Shared types stay in their native packages.
vendor/src/Select/Select.d.ts
import * as React from 'react';
import { SxProps } from '@mui/system';
import { Theme } from '../styles';
import { InternalStandardProps as StandardProps } from '../internal';
import { InputProps } from '../Input';
import { MenuProps } from '../Menu';
import { SelectChangeEvent, SelectInputProps } from './SelectInput';
import { SelectClasses } from './selectClasses';
import { OutlinedInputProps } from '../OutlinedInput';
import { FilledInputProps } from '../FilledInput';
export interface BaseSelectProps<Value = unknown> extends StandardProps<
InputProps,
'value' | 'onChange' | 'placeholder'
> {
/**
* If `true`, the width of the popover will automatically be set according to the items inside the
* menu, otherwise it will be at least the width of the select input.
* @default false
*/
autoWidth?: boolean | undefined;
/**
* The option elements to populate the select with.
* Can be some `MenuItem` when `native` is false and `option` when `native` is true.
*
* ⚠️The `MenuItem` elements **must** be direct descendants when `native` is false.
*/
children?: React.ReactNode;
/**
* Override or extend the styles applied to the component.
* @default {}
*/
classes?: Partial<SelectClasses> | undefined;
/**
* If `true`, the component is initially open. Use when the component open state is not controlled (i.e. the `open` prop is not defined).
* You can only use it when the `native` prop is `false` (default).
* @default false
*/
defaultOpen?: boolean | undefined;
/**
* The default value. Use when the component is not controlled.
*/
defaultValue?: Value | undefined;
/**
* If `true`, a value is displayed even if no items are selected.
*
* In order to display a meaningful value, a function can be passed to the `renderValue` prop which
* returns the value to be displayed when no items are selected.
*
* ⚠️ When using this prop, make sure the label doesn't overlap with the empty displayed value.
* The label should either be hidden or forced to a shrunk state.
* @default false
*/
displayEmpty?: boolean | undefined;
/**
* The icon that displays the arrow.
* @default ArrowDropDownIcon
*/
IconComponent?: React.ElementType | undefined;
/**
* The `id` of the wrapper element or the `select` element when `native`.
*/
id?: string | undefined;
/**
* An `Input` element; does not have to be a material-ui specific `Input`.
*/
input?: React.ReactElement<unknown, any> | undefined;
/**
* [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input#attributes) applied to the `input` element.
* When `native` is `true`, the attributes are applied on the `select` element.
*/
inputProps?: InputProps['inputProps'] | undefined;
/**
* See [OutlinedInput#label](https://mui.com/material-ui/api/outlined-input/#props)
*/
label?: React.ReactNode;
/**
* The ID of an element that acts as an additional label. The Select will
* be labelled by the additional label and the selected value.
*/
labelId?: string | undefined;
/**
* Props applied to the [`Menu`](https://mui.com/material-ui/api/menu/) element.
*/
MenuProps?: Partial<MenuProps> | undefined;
/**
* If `true`, `value` must be an array and the menu will support multiple selections.
* @default false
*/
multiple?: boolean | undefined;
/**
* If `true`, the component uses a native `select` element.
* @default false
*/
native?: boolean | undefined;
/**
* Callback fired when a menu item is selected.
*
* @param {SelectChangeEvent<Value>} event The event source of the callback.
* You can pull out the new value by accessing `event.target.value` (any).
* **Warning**: This is a generic event, not a change event, unless the change event is caused by browser autofill.
* @param {object} [child] The react element that was selected when `native` is `false` (default).
*/
onChange?: SelectInputProps<Value>['onChange'] | undefined;
/**
* Callback fired when the component requests to be closed.
* Use it in either controlled (see the `open` prop), or uncontrolled mode (to detect when the Select collapses).
*
* @param {object} event The event source of the callback.
*/
onClose?: ((event: React.SyntheticEvent) => void) | undefined;
/**
* Callback fired when the component requests to be opened.
* Use it in either controlled (see the `open` prop), or uncontrolled mode (to detect when the Select expands).
*
* @param {object} event The event source of the callback.
*/
onOpen?: ((event: React.SyntheticEvent) => void) | undefined;
/**
* If `true`, the component is shown.
* You can only use it when the `native` prop is `false` (default).
*/
open?: boolean | undefined;
/**
* Render the selected value.
* You can only use it when the `native` prop is `false` (default).
*
* @param {any} value The `value` provided to the component.
* @returns {ReactNode}
*/
renderValue?: ((value: Value) => React.ReactNode) | undefined;
/**
* Props applied to the clickable div element.
*/
SelectDisplayProps?: React.HTMLAttributes<HTMLDivElement> | undefined;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme> | undefined;
/**
* The `input` value. Providing an empty string will select no options.
* Set to an empty string `''` if you don't want any of the available options to be selected.
*
* If the value is an object it must have reference equality with the option in order to be selected.
* If the value is not an object, the string representation must match with the string representation of the option in order to be selected.
*/
value?: Value | '' | undefined;
/**
* The variant to use.
* @default 'outlined'
*/
variant?: SelectVariants | undefined;
}
export interface FilledSelectProps extends Omit<
FilledInputProps,
'value' | 'onChange' | 'id' | 'classes' | 'inputProps' | 'placeholder' | 'label'
> {
/**
* The variant to use.
* @default 'outlined'
*/
variant: 'filled';
}
export interface StandardSelectProps extends Omit<
InputProps,
'value' | 'onChange' | 'id' | 'classes' | 'inputProps' | 'placeholder' | 'label'
> {
/**
* The variant to use.
* @default 'outlined'
*/
variant: 'standard';
}
export interface OutlinedSelectProps extends Omit<
OutlinedInputProps,
'value' | 'onChange' | 'id' | 'classes' | 'inputProps' | 'placeholder' | 'label'
> {
/**
* The variant to use.
* @default 'outlined'
*/
variant?: 'outlined' | undefined;
}
export type SelectVariants = 'outlined' | 'standard' | 'filled';
export type SelectProps<Value = unknown> =
| (FilledSelectProps & BaseSelectProps<Value>)
| (StandardSelectProps & BaseSelectProps<Value>)
| (OutlinedSelectProps & BaseSelectProps<Value>);
declare const Select: (<Value = unknown>(props: SelectProps<Value>) => React.JSX.Element) & {
muiName: string;
};
vendor/src/NativeSelect/NativeSelect.d.ts
import * as React from 'react';
import { SxProps } from '@mui/system';
import { Theme } from '../styles';
import { InternalStandardProps as StandardProps } from '../internal';
import { InputProps } from '../Input';
import { NativeSelectInputProps } from './NativeSelectInput';
import { NativeSelectClasses } from './nativeSelectClasses';
export interface NativeSelectProps extends StandardProps<
InputProps,
'inputProps' | 'value' | 'onChange'
> {
/**
* The option elements to populate the select with.
* Can be some `<option>` elements.
*/
children?: React.ReactNode;
/**
* Override or extend the styles applied to the component.
* @default {}
*/
classes?: Partial<NativeSelectClasses> | undefined;
/**
* The icon that displays the arrow.
* @default ArrowDropDownIcon
*/
IconComponent?: React.ElementType | undefined;
/**
* An `Input` element; does not have to be a material-ui specific `Input`.
* @default <Input />
*/
input?: React.ReactElement<unknown, any> | undefined;
/**
* [Attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/select#attributes) applied to the `select` element.
*/
inputProps?: Partial<NativeSelectInputProps> | undefined;
/**
* Callback fired when a menu item is selected.
*
* @param {React.ChangeEvent<HTMLSelectElement>} event The event source of the callback.
* You can pull out the new value by accessing `event.target.value` (string).
*/
onChange?: NativeSelectInputProps['onChange'] | undefined;
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
sx?: SxProps<Theme> | undefined;
/**
* The `input` value. The DOM API casts this to a string.
*/
value?: unknown;
/**
* The variant to use.
*/
variant?: 'standard' | 'outlined' | 'filled' | undefined;
}
declare const NativeSelect: ((props: NativeSelectProps) => React.JSX.Element) & { muiName: string };
Post-install acceptance
Run strict types, production build and real interactions. Check keyboard labels/focus, disabled/error/read-only semantics where natively supported, both themes, narrow screens and reduced motion. Verify callbacks against the real host data; do not declare installation complete from copying a prompt. Initialization fixtures also require server HTML and warning-free hydration.
Source and license
https://github.com/mui/material-ui/tree/809a7717b4c050ba3f69b75300689f07c050a16e
MIT · @mui/material@9.4.0. Vendor originals and license are preserved. Full original upstream prose remains in vendor/docs and is not represented as fully translated.