JGuang

Select

Select · Material UI

Preview
npm install @mui/material@9.4.0 @emotion/react@11.14.0 @emotion/styled@11.14.1

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.propPractical roleDeclaration source
Select.valueControlled native value; its scalar/array/nullable type is owner-specific.Select
Select.multipleNative multiple-selection mode; value and callback types change with the owner.Select
Select.onChangeOwning control's native callback; preserve its exact event/value/nullable signature.Select
Select.labelIdID of the element naming the native Select; do not invent a missing label.Select
Select.renderValueNative selected-value presentation callback; it does not change selection data.Select
Select.nativeRender 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.

PropRequiredUpstream metadata type / constraintMetadata default
autoWidthnoboolfalse
childrennonode—
classesnoobject{}
defaultOpennoboolfalse
defaultValuenoany—
displayEmptynoboolfalse
IconComponentnoelementTypeArrowDropDownIcon
idnostring—
inputnoelement—
inputPropsnoobject—
labelnonode—
labelIdnostring—
MenuPropsnoobject—
multiplenoboolfalse
nativenoboolfalse
onChangenofunc—
onClosenofunc—
onOpennofunc—
opennobool—
renderValuenofunc—
SelectDisplayPropsnoobject—
sxnoArray<func | object | bool> | func | object—
valueno'' | any—
variantno'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.

PropRequiredUpstream metadata type / constraintMetadata default
childrennonode—
classesnoobject{}
IconComponentnoelementTypeArrowDropDownIcon
inputnoelement<Input />
inputPropsnoobject—
onChangenofunc—
sxnoArray<func | object | bool> | func | object—
valuenoany—
variantno'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.