Select

Select lets merchants choose one option from an options menu. Consider select when you have 4 or more options, to avoid cluttering the interface.

Presents a classic dropdown menu or equivalent picker as determined by merchants’ browsers.

import {Select} from '@shopify/polaris';
import {useState, useCallback} from 'react';

function SelectExample() {
  const [selected, setSelected] = useState('today');

  const handleSelectChange = useCallback((value) => setSelected(value), []);

  const options = [
    {label: 'Today', value: 'today'},
    {label: 'Yesterday', value: 'yesterday'},
    {label: 'Last 7 days', value: 'lastWeek'},
  ];

  return (
    <Select
      label="Date range"
      options={options}
      onChange={handleSelectChange}
      value={selected}
    />
  );
}

Use only for cases where the select must fit on a single line, such as in a toolbar.

import {Select} from '@shopify/polaris';
import {useState, useCallback} from 'react';

function InlineLabelExample() {
  const [selected, setSelected] = useState('newestUpdate');

  const handleSelectChange = useCallback((value) => setSelected(value), []);

  const options = [
    {label: 'Newest update', value: 'newestUpdate'},
    {label: 'Oldest update', value: 'oldestUpdate'},
    {label: 'Most spent', value: 'mostSpent'},
    {label: 'Most orders', value: 'mostOrders'},
    {label: 'Last name A–Z', value: 'lastNameAlpha'},
    {label: 'Last name Z–A', value: 'lastNameReverseAlpha'},
  ];

  return (
    <Select
      label="Sort by"
      labelInline
      options={options}
      onChange={handleSelectChange}
      value={selected}
    />
  );
}

Use for selections that aren’t currently available. The surrounding interface should make it clear why the select box is disabled and how to activate it.

import {Select} from '@shopify/polaris';
import React from 'react';

function SelectExample() {
  return (
    <Select
      label="Date range"
      disabled
      options={[
        {label: 'Today', value: 'today'},
        {label: 'Yesterday', value: 'yesterday'},
        {label: 'Last 7 days', value: 'lastWeek'},
      ]}
    />
  );
}

Renders any React element to the left of individual select options. Does not show in the dropdown.

import {Icon, Select} from '@shopify/polaris';
import {CaretUpMinor, CaretDownMinor} from '@shopify/polaris-icons';
import {useState, useCallback} from 'react';

function PrefixExample() {
  const [selected, setSelected] = useState('enabled');

  const handleSelectChange = useCallback((value) => setSelected(value), []);

  const options = [
    {
      label: 'Increase',
      value: 'Increase',
      prefix: <Icon source={CaretUpMinor} />,
    },
    {
      label: 'Decrease',
      value: 'Decrease',
      prefix: <Icon source={CaretDownMinor} />,
    },
  ];

  return (
    <Select
      label="Permission"
      options={options}
      onChange={handleSelectChange}
      value={selected}
    />
  );
}

Use to let merchants know if there’s a problem with their selection. For selects, a selection is typically invalid only when using a placeholder option (“Select”) and no other selection has been made.

import {Select} from '@shopify/polaris';
import {useState, useCallback} from 'react';

function ValidationErrorExample() {
  const [selected, setSelected] = useState('');

  const handleSelectChange = useCallback((value) => setSelected(value), []);

  return (
    <Select
      label="Province"
      options={['Alberta']}
      value={selected}
      onChange={handleSelectChange}
      error="Province is required"
    />
  );
}

Use to let merchants know when their select input is invalid in the context of a group of form inputs that the select depends on.

import {
  Stack,
  FormLayout,
  TextField,
  Select,
  InlineError,
  Card,
  TextStyle,
  Link,
} from '@shopify/polaris';
import {useState, useCallback} from 'react';

function SeparateValidationErrorExample() {
  const [weight, setWeight] = useState('12');
  const [unit, setUnit] = useState('');

  const handleWeightChange = useCallback((value) => setWeight(value), []);
  const handleUnitChange = useCallback((value) => setUnit(value), []);

  const unitSelectID = 'unit';
  const errorMessage = generateErrorMessage();
  const formGroupMarkup = (
    <Stack vertical spacing="extraTight">
      <FormLayout>
        <FormLayout.Group condensed>
          <TextField
            label="Product weight"
            type="number"
            value={weight}
            onChange={handleWeightChange}
            error={Boolean(!weight && unit)}
            autoComplete="off"
          />
          <Select
            id={unitSelectID}
            label="Unit of measure"
            placeholder="Select"
            options={['oz', 'g', 'kg', 'lb']}
            value={unit}
            onChange={handleUnitChange}
            error={Boolean(!unit && weight)}
          />
        </FormLayout.Group>
      </FormLayout>
      <InlineError message={errorMessage} fieldID={unitSelectID} />
    </Stack>
  );

  return <Card sectioned>{formGroupMarkup}</Card>;

  function generateErrorMessage() {
    const weightError =
      !weight && unit ? 'The numeric weight of the product ' : '';
    const unitError =
      !unit && weight ? 'The unit of measure for the product weight' : '';

    if (!weightError && !unitError) {
      return '';
    }

    return (
      <span>
        <TextStyle variation="negative">
          <p>
            {`${weightError}${unitError} is required when weight based shipping rates are enabled. `}
            <Link>Manage shipping</Link>
          </p>
        </TextStyle>
      </span>
    );
  }
}

Props

Want to help make this feature better? Please share your feedback.

interface SelectProps
options?((string | ) | )[]

List of options or option groups to choose from.

labelReact.ReactNode

Label for the select.

labelAction?

Adds an action to the label.

labelHidden?boolean

Visually hide the label.

labelInline?boolean

Show the label to the left of the value, inside the control.

disabled?boolean

Disable input.

helpText?React.ReactNode

Additional text to aide in use.

placeholder?string

Example text to display as placeholder.

id?string

ID for form input.

name?string

Name for form input.

value?string

Value for form input.

error?any

Display an error state.

onChange?(selected: string, id: string) => void

Callback when selection is changed.

onFocus?() => void

Callback when select is focused.

onBlur?() => void

Callback when focus is removed.

requiredIndicator?boolean

Visual required indicator, add an asterisk to label.

Best practices

The select component should:

  • Be used for selecting between 4 or more pre-defined options
  • Have a default option selected whenever possible
  • Use “Select” as a placeholder option only if there’s no logical default option

Content guidelines

Select label

Labels should:

  • Give a short description (1–3 words) of the requested input.
  • Be written in sentence case (the first word capitalized, the rest lowercase).
  • Avoid punctuation and articles (“the”, “an”, “a”).
  • Be independent sentences. To support internationalization, they should not act as the first part of a sentence that is finished by the component’s options.
  • Be descriptive, not instructional. If the selection needs more explanation, use help text below the field.

Do

  • Email address

Don’t

  • What is your email address?

Do

  • Phone number

Don’t

  • My phone number is:

Select options

Options should:

  • Start with “Select” as a placeholder if there isn’t a default option
  • Be listed alphabetically or in another logical order so merchants can easily find the option they need
  • Be written in sentence case (the first word capitalized, the rest lowercase) and avoid using commas or semicolons at the end of each option
  • Be clearly labelled based on what the option will do

  • To let merchants select one option from a list with less than 4 options, use the choice list component
  • To create a select where merchants can make multiple selections, or to allow advanced formatting of option text, use an option list inside a popover