Select

Import
import { Select } from "reshaped";
import type { SelectProps } from "reshaped";
Related components
Full keyboard navigation
Can be controlled and uncontrolled
Automatic integration with FormControl utility


Form fields have a required name property, so that's the only property you have to pass to Select to start using it. If you need to handle its change events - add an onChange property to it.

<Select
  name="animal"
  placeholder="Select an animal"
  onChange={(args) => console.log(args)}
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
/>

Same as when using native inputs in React, Select can be used as a controlled or uncontrolled component. By default, Select is uncontrolled and lets you define its default value using the defaultValue property. In this case, all change events are handled automatically. This approach is helpful when you're populating the field default value from a data source, but you don't need to control it manually afterward.

<Select
  name="animal2"
  placeholder="Select an animal"
  defaultValue="dog"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
/>

If you need to control the state of the field manually, you can use the value property. That will give you complete control of the component value and will stop handling the value automatically. You will have to update the state using the onChange handler and will be able to add custom logic before that happens.

<Select
  name="animal3"
  placeholder="Select an animal"
  onChange={({ value }) => {
    /* Update your state here */
  }}
  value="dog"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
/>

Select supports a content slot on the left side, which you can use for displaying text or other components.

<Select
  name="animal6"
  placeholder="Select account"
  options={[
    { label: "hello@reshaped.so", value: "1" },
    { label: "updates@reshaped.so", value: "2" },
  ]}
  startSlot={<Avatar src="/img/examples/avatar-3.png" initials="P" size={5} />}
/>

For consistent Icon usage in text fields, you can use the icon property instead of startSlot and pass the icon SVG component.

<Select
  name="animal"
  placeholder="Select an animal"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
  icon={IconZap}
/>

Select comes in 3 sizes, with the medium size used by default. All sizes are aligned with sizes of other related components like Button or TextField.

<View gap={3}>
  <Select
    size="medium"
    name="animal"
    placeholder="Select an animal"
    options={[
      { label: "Dog", value: "dog" },
      { label: "Turtle", value: "turtle" },
    ]}
    icon={IconZap}
  />
  <Select
    size="large"
    name="animal"
    placeholder="Select an animal"
    options={[
      { label: "Dog", value: "dog" },
      { label: "Turtle", value: "turtle" },
    ]}
    icon={IconZap}
  />
  <Select
    size="xlarge"
    name="animal"
    placeholder="Select an animal"
    options={[
      { label: "Dog", value: "dog" },
      { label: "Turtle", value: "turtle" },
    ]}
    icon={IconZap}
  />
</View>

Select supports responsive syntax for its size property, which means you can change its size based on the viewport.

<Select
  size={{ s: "medium", l: "xlarge" }}
  name="animal"
  placeholder="Select an animal"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
  icon={IconZap}
/>

If you want to alternate the styles of the select, you can use its faded variant.

<Select
  variant="faded"
  name="animal"
  placeholder="Select an animal"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
  icon={IconZap}
/>

Otherwise, you can also use the headless variant which removes most of the styles from the select and lets you use it for custom layouts.

<Select
  variant="headless"
  name="animal"
  placeholder="Select an animal"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
  icon={IconZap}
/>
  • Since headless variant removes the horizontal padding, you might want to add it yourself with a custom wrapper for the select that would expand the clickable area.
  • headless variant removes the focused and error outline since most of the time you would want to display them in a different place. You can use :focus-within selector in your css to implement the focus state.

You can use hasError property to show the user that Select is not passing the form validation.

<Select
  name="animal4"
  placeholder="Select an animal"
  hasError
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
/>

Select can be disabled with the disabled flag. Remember that disabling the field will remove it from the form submit query.

<Select
  disabled
  name="animal5"
  placeholder="Select an animal"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
/>

You can use Select without passing options to only render the trigger as a button and combine it with other components, like DropdownMenu or Modal.

<DropdownMenu width="trigger">
  <DropdownMenu.Trigger>
    {(attributes) => (
      <Select
        name="animal"
        placeholder="Select an animal"
        inputAttributes={attributes}
      />
    )}
  </DropdownMenu.Trigger>
  <DropdownMenu.Content>
    <DropdownMenu.Item>Turtle</DropdownMenu.Item>
    <DropdownMenu.Item>Cat</DropdownMenu.Item>
  </DropdownMenu.Content>
</DropdownMenu>

To let the user know what data you expect them to type in, add labels or status messages to your fields with the help of the FormControl utility. In case you're using xlarge Select size, you can also combine it with the large FormControl size for better visual alignment.

Note: Don't use placeholders as labels for the fields as users won't see the placeholder when input contains a value.

<FormControl>
  <FormControl.Label>Email</FormControl.Label>
  <Select
    name="animal7"
    placeholder="Select an animal"
    options={[
      { label: "Dog", value: "dog" },
      { label: "Turtle", value: "turtle" },
    ]}
  />
</FormControl>
  • When using Select - make sure to provide a text description for it. You can either provide the label by using the FormControl utility or by passing inputAttributes={{ 'aria-label': 'Your label' }} to the component if you don't want to display it visually.
<Select
  name="animal8"
  placeholder="Select an animal"
  options={[
    { label: "Dog", value: "dog" },
    { label: "Turtle", value: "turtle" },
  ]}
  inputAttributes={{ "aria-label": "Animal" }}
/>