SelectList displays a list of actions or options using the browser’s native select.

also known as Picklist, Picker

Figma:

Responsive:

Adaptive:

Props

Component props
Name
Type
Default
children
Required
React.Node
-

One or more SelectList.Option components, which may be grouped using SelectList.Group.

id
Required
string
-

A unique identifier to connect the underlying <select> with the associated label.

onChange
Required
({
  event: SyntheticInputEvent<HTMLSelectElement>,
  value: string,
}) => void
-

Callback triggered when the user selects a new option. See the controlled component variant to learn more.

dataTestId
string
-

Available for testing purposes, if needed. Consider better queries before using this prop.

disabled
boolean
false

Used to disable the entire SelectList.

errorMessage
string
-

Used to communicate error information to the user. Be sure to localize the text. See the error message variant to learn more.

helperText
string
-

Used to provide more information about the form field. Be sure to localize the text. See the helper text variant to learn more.

label
string
-

The label shown above the input. Be sure to localize the label.

labelDisplay
"visible" | "hidden"
"visible"

Whether the legend should be visible or not. If hidden, the legend is still available for screen reader users, but does not appear visually. See the label visibility variant for more info.

name
string
-

Used to specify the name of the control.

placeholder
string
-

If not provided, the first item in the list will be shown. Be sure to localize the text. See the controlled component variant to learn more.

size
"md" | "lg"
"md"

md: 40px, lg: 48px. See the size variant to learn more.

value
?string
-

The currently-selected value. See the controlled component variant to learn more.

Usage guidelines

When to use
  • When presenting users with a list of options that utilizes the native select functionality of the browser or device.
  • When presenting users with a list of options to choose from, like display settings.
When not to use
  • When more than 10 options are presented and the ability to filter the list would be beneficial. Use ComboBox instead.
  • When extra functionality, like groups, subtext or badges, is needed. Use Dropdown instead.
  • When the options are links and navigate users to different places. Use Dropdown instead.

Best practices

Do

Use SelectList when the user needs to select from a simple list of items.

Don't

Use SelectList when additional functionality such as subtext or images are needed. Use Dropdown instead.

Do

Order the list items in SelectList either alphabetically or by usage.

Don't

Use SelectList if there are fewer than 4 items in the list and there is space to display all options. Use RadioGroup instead.

Do

Keep the same type of selection for a group of items. An example of this might be a filter bar. If some items could use SelectList and some items need to use Dropdown, use Dropdown for all the items in the group.

Don't

Mix Dropdown and SelectList in a group of items.

Accessibility

Labels

SelectList comes with Label built-in: just use the label prop. We strongly encourage always supplying a label. Be sure to provide a unique id so the Label is associated with the correct SelectList.

If SelectList is labeled by content elsewhere on the page, or a more complex label is needed, the labelDisplay prop can be used to visually hide the label. In this case, it is still available to screen reader users, but will not appear visually on the screen.

import { Box, Flex, IconButton, SelectList, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Flex gap={{ column: 0, row: 6 }}>
        <SelectList
          id="selectlistexampleA11yVisible"
          label="Date range"
          onChange={() => {}}
          size="lg"
        >
          {[
            { label: 'Last 5 days', value: '5' },
            { label: 'Last week', value: '7' },
            { label: 'Last 30 days', value: '30' },
            { label: 'Last sixth months', value: '6m' },
            { label: 'Last year', value: '365' },
          ].map(({ label, value }) => (
            <SelectList.Option key={label} label={label} value={value} />
          ))}
        </SelectList>

        <Flex direction="column" gap={2}>
          <Flex alignItems="center" gap={1}>
            <Text size="300">Date range</Text>
            <IconButton
              accessibilityLabel="Info"
              icon="info-circle"
              size="sm"
              tooltip={{
                text: 'Options available are based on your usage.',
                idealDirection: 'right',
              }}
            />
          </Flex>
          <SelectList
            id="selectlistexampleA11yHiddenLabel"
            label="Date range"
            labelDisplay="hidden"
            onChange={() => {}}
            size="lg"
          >
            {[
              { label: 'Last 5 days', value: '5' },
              { label: 'Last week', value: '7' },
              { label: 'Last 30 days', value: '30' },
              { label: 'Last sixth months', value: '6m' },
              { label: 'Last year', value: '365' },
            ].map(({ label, value }) => (
              <SelectList.Option key={label} label={label} value={value} />
            ))}
          </SelectList>
        </Flex>
      </Flex>
    </Box>
  );
}

Subcomponents

SelectList.Option

Use SelectList.Option to define the available options within SelectList.

SelectList.Option Props

SelectList.Option subcomponent props
Name
Type
Default
label
Required
string
-

The visible label for the option. Don't forget to localize!

value
Required
string
-

The underlying value of the option.

disabled
boolean
-

Used to disable the option.

SelectList.Group

Use SelectList.Group to group a subset of the options within SelectList.

SelectList.Group Props

SelectList.Group subcomponent props
Name
Type
Default
children
Required
React.Node
-

One or more SelectList.Option components.

label
Required
string
-

The label for the group. Don't forget to localize!

disabled
boolean
-

Used to disable the entire group of options.

Variants

Size

import { Box, SelectList } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <SelectList
        id="selectlistexample10"
        label="Country"
        onChange={() => {}}
        size="lg"
      >
        {[
          { label: 'Algeria', value: 'algeria' },
          { label: 'Belgium', value: 'belgium' },
          { label: 'Canada', value: 'canada' },
          { label: 'Denmark', value: 'denmark' },
          { label: 'Egypt', value: 'egypt' },
          { label: 'France', value: 'france' },
        ].map(({ label, value }) => (
          <SelectList.Option key={label} label={label} value={value} />
        ))}
      </SelectList>
    </Box>
  );
}

Large

Use lg as the recommended size within Pinterest products.

import { Box, SelectList } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <SelectList
        id="selectlistexample11"
        label="Country"
        onChange={() => {}}
        size="md"
      >
        {[
          { label: 'Algeria', value: 'algeria' },
          { label: 'Belgium', value: 'belgium' },
          { label: 'Canada', value: 'canada' },
          { label: 'Denmark', value: 'denmark' },
          { label: 'Egypt', value: 'egypt' },
          { label: 'France', value: 'france' },
        ].map(({ label, value }) => (
          <SelectList.Option key={label} label={label} value={value} />
        ))}
      </SelectList>
    </Box>
  );
}

Medium

Use md on denser surfaces, such as business products or internal tools.

Label visibility

In some cases, the label for a SelectList is represented in a different way visually, as demonstrated below. In these instances, you can set labelDisplay="hidden" to ensure SelectList is properly labeled for screen readers while using a different element to represent the label visually.

import { Box, Flex, IconButton, SelectList, Text } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Flex direction="column" gap={2}>
        <Flex alignItems="center" gap={1}>
          <Text size="300" weight="bold">
            Date range
          </Text>
          <IconButton
            accessibilityLabel="Info"
            icon="info-circle"
            size="sm"
            tooltip={{
              text: 'Options available are based on your usage.',
              idealDirection: 'right',
            }}
          />
        </Flex>

        <SelectList
          id="selectlistexampleHiddenLabel"
          label="Date range"
          labelDisplay="hidden"
          onChange={() => {}}
          size="lg"
        >
          {[
            { label: 'Last 5 days', value: '5' },
            { label: 'Last week', value: '7' },
            { label: 'Last 30 days', value: '30' },
            { label: 'Last sixth months', value: '6m' },
            { label: 'Last year', value: '365' },
          ].map(({ label, value }) => (
            <SelectList.Option key={label} label={label} value={value} />
          ))}
        </SelectList>
      </Flex>
    </Box>
  );
}

Helper text

Helper text should be used when additional description may be required to understand the SelectList. Common examples include text that is legally required to be displayed, or instructions to fill out a form (e.g. proper formatting). If the text is optional, Tooltip could be used instead.

import { Box, SelectList } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <SelectList
        helperText="Product prices in your data source without an ISO currency code will default to this currency"
        id="selectlistexample12"
        label="Default currency"
        onChange={() => {}}
        size="lg"
      >
        {[
          { label: 'ARS - Argentine peso', value: 'ars' },
          { label: 'AUD - Australian dollar', value: 'aud' },
          { label: 'ERN - Eritrean nakfa', value: 'ern' },
          { label: 'EUR - Euro', value: 'eur' },
          { label: 'GBP - British pound', value: 'gbp' },
          { label: 'JPY - Japanese yen', value: 'jpy' },
          { label: 'USD - United States Dollar', value: 'usd' },
        ].map(({ label, value }) => (
          <SelectList.Option key={label} label={label} value={value} />
        ))}
      </SelectList>
    </Box>
  );
}

Controlled component

SelectList must be used as a controlled component when the placeholder or value props are needed. When used in this manner, onChange and value are required, while placeholder is optional.

import { useState } from 'react';
import { Box, SelectList } from 'gestalt';

export default function Example() {
  const [country, setCountry] = useState('');
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <SelectList
        id="selectlistexample13"
        label="Country"
        name="country"
        onChange={({ value }) => setCountry(value)}
        placeholder="Select a country"
        value={country}
      >
        {[
          { label: 'Algeria', value: 'algeria' },
          { label: 'Belgium', value: 'belgium' },
          { label: 'Canada', value: 'canada' },
          { label: 'Denmark', value: 'denmark' },
          { label: 'Egypt', value: 'egypt' },
          { label: 'France', value: 'france' },
        ].map(({ label, value }) => (
          <SelectList.Option key={label} label={label} value={value} />
        ))}
      </SelectList>
    </Box>
  );
}

Error message

errorMessage should be used to denote an error state in SelectList and to provide a message for how the user can fix it.

import { Box, SelectList } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <SelectList
        errorMessage="You must select a country"
        id="selectlistexample14"
        label="Country"
        onChange={() => {}}
        placeholder="Select a country"
        size="lg"
      >
        {[
          { label: 'Algeria', value: 'algeria' },
          { label: 'Belgium', value: 'belgium' },
          { label: 'Canada', value: 'canada' },
          { label: 'Denmark', value: 'denmark' },
          { label: 'Egypt', value: 'egypt' },
          { label: 'France', value: 'france' },
        ].map(({ label, value }) => (
          <SelectList.Option key={label} label={label} value={value} />
        ))}
      </SelectList>
    </Box>
  );
}

Groups

SelectList.Group can be used to group related options. Note that disabling a group disables all of its options.

import { Box, SelectList } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <SelectList
        helperText="Note that the family members aren't secondary!"
        id="selectlistexample15"
        label="Choose your favorite secondary character"
        onChange={() => {}}
        placeholder="Select a character"
        size="lg"
      >
        <SelectList.Group disabled label="Family">
          {['Bart', 'Lisa', 'Homer', 'Marge', 'Maggie'].map((name) => (
            <SelectList.Option key={name} label={name} value={name} />
          ))}
        </SelectList.Group>
        <SelectList.Group label="Neighbors">
          {['Ned', 'Maude', 'Rod', 'Todd'].map((name) => (
            <SelectList.Option key={name} label={name} value={name} />
          ))}
        </SelectList.Group>
        <SelectList.Group label="Cartoons">
          {['Itchy', 'Scratchy', 'Poochie'].map((name) => (
            <SelectList.Option key={name} label={name} value={name} />
          ))}
        </SelectList.Group>
      </SelectList>
    </Box>
  );
}

Component quality checklist

Component quality checklist
Quality item
Status
Status description
Figma Library
Ready
Component is available in Figma for web and mobile web.
Responsive Web
Ready
Component responds to changing viewport sizes in web and mobile web.

Dropdown
If additional functionality is needed in the menu, such as subtext, headers or custom styling, use Dropdown.

ComboBox
If users need the ability to choose an option by entering text to filter a long list of options, use ComboBox.

RadioGroup
If users need the ability to choose between fewer than 4 options, use RadioButton.

Checkbox
If users need the ability to choose between a yes/no option, use Checkbox.