Adaptive Select

Adaptiveness

  • Desktop: doesn't block interaction with other page elements when open
  • Android & iOS: uses the native device select
  • iOS: native styling
import AdaptiveModeDemo from "@/shared/adaptiveModeDemo";
import {
  AdaptiveSelect,
  AdaptiveSelectItem,
} from "adaptive-material-ui/components/select";

export default function () {
  return (
    <AdaptiveModeDemo>
      <AdaptiveSelect defaultValue={1}>
        <AdaptiveSelectItem value={1}>One</AdaptiveSelectItem>
        <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
      </AdaptiveSelect>
    </AdaptiveModeDemo>
  );
}

Variations

Variant
Label
Multiple Values
Grouping
import AdaptiveModeDemo from "@/shared/adaptiveModeDemo";
import { DemoList, DemoListItem } from "@/shared/demoList";
import FormControl from "@mui/material/FormControl";
import InputLabel from "@mui/material/InputLabel";
import {
  AdaptiveSelect,
  AdaptiveSelectItem,
  AdaptiveSelectItemGroup,
} from "adaptive-material-ui/components/select";

export default function () {
  return (
    <AdaptiveModeDemo>
      <DemoList>
        <DemoListItem title="Variant">
          <AdaptiveSelect
            defaultValue={1}
            variant="standard"
            sx={{ width: 120 }}
          >
            <AdaptiveSelectItem value={1}>Standard</AdaptiveSelectItem>
            <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
          </AdaptiveSelect>
          <AdaptiveSelect
            defaultValue={1}
            variant="outlined"
            sx={{ width: 120 }}
          >
            <AdaptiveSelectItem value={1}>Outlined</AdaptiveSelectItem>
            <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
          </AdaptiveSelect>
          <AdaptiveSelect
            defaultValue={1}
            hiddenLabel
            variant="filled"
            sx={{ width: 120 }}
          >
            <AdaptiveSelectItem value={1}>Filled</AdaptiveSelectItem>
            <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
          </AdaptiveSelect>
        </DemoListItem>
        <DemoListItem title="Label">
          <FormControl sx={{ width: 120 }}>
            {/* https://mui.com/material-ui/react-select/#accessibility */}
            <InputLabel focused={false} htmlFor="label-select">
              Label
            </InputLabel>
            <AdaptiveSelect defaultValue={1} id="label-select" label="Label">
              <AdaptiveSelectItem value={1}>One</AdaptiveSelectItem>
              <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
            </AdaptiveSelect>
          </FormControl>
        </DemoListItem>
        <DemoListItem title="Multiple Values">
          <AdaptiveSelect multiple defaultValue={[1]}>
            <AdaptiveSelectItem value={1}>One</AdaptiveSelectItem>
            <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
            <AdaptiveSelectItem value={3}>Three</AdaptiveSelectItem>
          </AdaptiveSelect>
        </DemoListItem>
        <DemoListItem title="Grouping">
          <AdaptiveSelect defaultValue={1}>
            <AdaptiveSelectItem value={1}>One</AdaptiveSelectItem>
            <AdaptiveSelectItemGroup label="Category 1">
              <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
              <AdaptiveSelectItem value={3}>Three</AdaptiveSelectItem>
            </AdaptiveSelectItemGroup>
          </AdaptiveSelect>
        </DemoListItem>
      </DemoList>
    </AdaptiveModeDemo>
  );
}

Native Limitations

  • The event.target.value for the native onChange event is always a string
  • The option element browser support & React support for content other than text is currently limited MDN

No Selected Value

The first value is auto selected if there's no specified selected value on a native select. To compensate for this the AdaptiveSelect adds a hidden option with a empty value, which can be removed using the nativeEmptyValueOption prop if needed.

Default
Disabled
import AdaptiveModeDemo from "@/shared/adaptiveModeDemo";
import { DemoList, DemoListItem } from "@/shared/demoList";
import {
  AdaptiveSelect,
  AdaptiveSelectItem,
} from "adaptive-material-ui/components/select";

export default function () {
  return (
    <AdaptiveModeDemo adaptiveMode="ios">
      <DemoList>
        <DemoListItem title="Default">
          <AdaptiveSelect defaultValue="">
            <AdaptiveSelectItem value={1}>One</AdaptiveSelectItem>
            <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
          </AdaptiveSelect>
        </DemoListItem>
        <DemoListItem title="Disabled">
          <AdaptiveSelect defaultValue="" nativeEmptyValueOption={false}>
            <AdaptiveSelectItem value={1}>One</AdaptiveSelectItem>
            <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
          </AdaptiveSelect>
        </DemoListItem>
      </DemoList>
    </AdaptiveModeDemo>
  );
}

Disable Native

To disable the native select for all environments, native={false} can be added to the component or theme

import AdaptiveModeDemo from "@/shared/adaptiveModeDemo";
import { createTheme } from "@mui/material/styles";
import {
  AdaptiveSelect,
  AdaptiveSelectItem,
} from "adaptive-material-ui/components/select";
import { AdaptiveThemeProvider } from "adaptive-material-ui/theme/adaptiveThemeProvider";
// 👇 Note the type import required for TypeScript
import type {} from "adaptive-material-ui/theme/themeAugmentation";

const theme = createTheme({
  colorSchemes: { dark: true },
  components: {
    AdaptiveSelect: {
      defaultProps: {
        native: false,
      },
    },
  },
});

export default function () {
  return (
    <AdaptiveModeDemo>
      <AdaptiveThemeProvider theme={theme}>
        <AdaptiveSelect defaultValue={1}>
          <AdaptiveSelectItem value={1}>One</AdaptiveSelectItem>
          <AdaptiveSelectItem value={2}>Two</AdaptiveSelectItem>
        </AdaptiveSelect>
      </AdaptiveThemeProvider>
    </AdaptiveModeDemo>
  );
}

API

MUI Select API with the following changes:

  • input defaults to AdaptiveInput, AdaptiveFilledInput, or AdaptiveOutlinedInput
  • Desktop: MenuProps.disableScrollLock defaults to true
  • Desktop: MenuProps.slots.root defaults to ModalNonBlocking
  • Android & iOS: native defaults to true

nativeEmptyValueOption

Adds a hidden empty value option element when native

  • Type: boolean
  • Default: true

AdaptiveSelectItem

MUI MenuItem API with the following changes:

  • Props not applicable to a <option> element are ignored on native. See the source for the full list of ignored props.

AdaptiveSelectItemGroup

MUI ListSubheader API with the following changes:

  • Props not applicable to a <optgroup> element are ignored on native. See the source for the full list of ignored props.