React UI
Edit page
Home
Getting Started
Customize
Foundation
Components: UI
Alert Badge Button ButtonGroup Card CheckboxField Modal Radio ScrollView SelectField
Basic Usage General Guidelines Design Variants Sizes Invisible Label Horizontal Layout Help Text States API Table TextArea TextField Toggle
Components: Layouts
CSS Helpers
Readme

# SelectField

SelectField allows users to select one option from a set.

##
Basic Usage

To implement the SelectField component, you need to import it first:

    import { SelectField } from '@react-ui-org/react-ui';

And use it:

Your favourite fruit
() => { const [fruit, setFruit] = React.useState('apple') return ( <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field" label="Your favourite fruit" options={[ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ]} value={fruit} /> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  return (    <SelectField      changeHandler={e => setFruit(e.target.value)}      id="my-select-field"      label="Your favourite fruit"      options={[        {          label: 'Apple',          value: 'apple',        },        {          label: 'Banana',          value: 'banana',        },        {          label: 'Grapefruit',          value: 'grapefruit',        },      ]}      value={fruit}    />  )}

See
API for all available options.

## General Guidelines

- Use SelectField for
  many options. For sets of just a few options (say 3 at maximum) consider using the Radio component. This will help keep your UI clean and uncluttered and prevent your users from being overwhelmed by too many options.

- Don't use for boolean (true/false) selection or to toggle things on and off. CheckboxField and Toggle are more suitable for such cases.

- Use short and descriptive labels, ideally nouns rather than seemingly polite phrases like Please select your favourite fruit. Short labels will help your users accomplish their task faster.

- Only make the SelectField's label invisible when there is another visual clue to guide users through filling the input. Using the first option as label is not recommended either — it disappears once user makes their choice.

- When a short label is not enough, use help texts to guide users before they enter anything.

- Use clear, calm error messages when there's a problem with what they entered.

- In case of a large amount of options, consider grouping related items together by nesting them (implements the
  `optgroup` HTML element).

👉 We use the native `select` HTML element to improve user experience on mobile devices by using the native select of the platform.

## Design Variants

To satisfy the design requirements of your project, all input fields in React UI come in two design variants to choose from: outline and filled. Both can be further customized with CSS custom properties.

Your favourite fruit
Your favourite fruit
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-outline" label="Your favourite fruit" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-filled" label="Your favourite fruit" options={options} variant="filled" value={fruit} /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-outline"        label="Your favourite fruit"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-filled"        label="Your favourite fruit"        options={options}        variant="filled"        value={fruit}      />    </>  )}

## Sizes

Aside from the default (medium) size, two additional sizes are available: small and large.

Your favourite fruit
Your favourite fruit
Your favourite fruit
Your favourite fruit
Your favourite fruit
Your favourite fruit
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-outline-small" label="Your favourite fruit" options={options} size="small" value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-outline-medium" label="Your favourite fruit" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-outline-large" label="Your favourite fruit" options={options} size="large" value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-filled-small" label="Your favourite fruit" options={options} size="small" value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-filled-medium" label="Your favourite fruit" options={options} value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-filled-large" label="Your favourite fruit" options={options} size="large" value={fruit} variant="filled" /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-outline-small"        label="Your favourite fruit"        options={options}        size="small"        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-outline-medium"        label="Your favourite fruit"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-outline-large"        label="Your favourite fruit"        options={options}        size="large"        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-filled-small"        label="Your favourite fruit"        options={options}        size="small"        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-filled-medium"        label="Your favourite fruit"        options={options}        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-filled-large"        label="Your favourite fruit"        options={options}        size="large"        value={fruit}        variant="filled"      />    </>  )}

Full-width fields span the full width of a parent:

Your favourite fruit
Your favourite fruit
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth id="my-select-field-outline-full-width" label="Your favourite fruit" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth id="my-select-field-filled-full-width" label="Your favourite fruit" options={options} value={fruit} variant="filled" /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        id="my-select-field-outline-full-width"        label="Your favourite fruit"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        id="my-select-field-filled-full-width"        label="Your favourite fruit"        options={options}        value={fruit}        variant="filled"      />    </>  )}

## Invisible Label

While it may be acceptable for login screens with just a few fields or for other simple forms, it's dangerous to hide labels from users in most cases. Keep in mind you should provide another visual clue so users know what to fill into the input.

Your favourite fruit
Your favourite fruit
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-outline-hidden-label" isLabelVisible={false} label="Your favourite fruit" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-filled-hidden-label" isLabelVisible={false} label="Your favourite fruit" options={options} value={fruit} variant="filled" /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-outline-hidden-label"        isLabelVisible={false}        label="Your favourite fruit"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-filled-hidden-label"        isLabelVisible={false}        label="Your favourite fruit"        options={options}        value={fruit}        variant="filled"      />    </>  )}

## Horizontal Layout

The default vertical layout is very easy to use and work with. However, there are situations where horizontal layout suits better — and that's why React UI supports this kind of layout as well.

Your favourite fruit
Your favourite fruit
Your favourite fruit
Your favourite fruit
Your favourite fruit
Your favourite fruit
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-outline-horizontal" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-filled-horizontal" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth id="my-select-field-outline-horizontal-full-width" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth id="my-select-field-filled-horizontal-full-width" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth id="my-select-field-outline-horizontal-full-width-invisible-label" isLabelVisible={false} label="Your favourite fruit" layout="horizontal" value={fruit} options={options} /> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth id="my-select-field-filled-horizontal-full-width-invisible-label" isLabelVisible={false} label="Your favourite fruit" layout="horizontal" options={options} value={fruit} variant="filled" /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-outline-horizontal"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-filled-horizontal"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        id="my-select-field-outline-horizontal-full-width"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        id="my-select-field-filled-horizontal-full-width"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        id="my-select-field-outline-horizontal-full-width-invisible-label"        isLabelVisible={false}        label="Your favourite fruit"        layout="horizontal"        value={fruit}        options={options}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        id="my-select-field-filled-horizontal-full-width-invisible-label"        isLabelVisible={false}        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}        variant="filled"      />    </>  )}

## Help Text

You may provide an additional help text to clarify how the input should be filled.

Your favourite fruit
Choose one or more kinds of fruit to feel happy.
Your favourite fruit
Choose one or more kinds of fruit to feel happy.
Your favourite fruit
Choose one or more kinds of fruit to feel happy.
Your favourite fruit
Choose one or more kinds of fruit to feel happy.
Your favourite fruit
Choose one or more kinds of fruit to feel happy.
Your favourite fruit
Choose one or more kinds of fruit to feel happy.
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Choose one or more kinds of fruit to feel happy." id="my-select-field-outline-help-text" label="Your favourite fruit" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Choose one or more kinds of fruit to feel happy." id="my-select-field-filled-help-text" label="Your favourite fruit" options={options} value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Choose one or more kinds of fruit to feel happy." id="my-select-field-outline-help-text-horizontal" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Choose one or more kinds of fruit to feel happy." id="my-select-field-filled-help-text-horizontal" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth helperText="Choose one or more kinds of fruit to feel happy." id="my-select-field-outline-help-text-horizontal-full-width" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} fullWidth helperText="Choose one or more kinds of fruit to feel happy." id="my-select-field-filled-help-text-horizontal-full-width" label="Your favourite fruit" layout="horizontal" options={options} value={fruit} variant="filled" /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Choose one or more kinds of fruit to feel happy."        id="my-select-field-outline-help-text"        label="Your favourite fruit"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Choose one or more kinds of fruit to feel happy."        id="my-select-field-filled-help-text"        label="Your favourite fruit"        options={options}        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Choose one or more kinds of fruit to feel happy."        id="my-select-field-outline-help-text-horizontal"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Choose one or more kinds of fruit to feel happy."        id="my-select-field-filled-help-text-horizontal"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        helperText="Choose one or more kinds of fruit to feel happy."        id="my-select-field-outline-help-text-horizontal-full-width"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        fullWidth        helperText="Choose one or more kinds of fruit to feel happy."        id="my-select-field-filled-help-text-horizontal-full-width"        label="Your favourite fruit"        layout="horizontal"        options={options}        value={fruit}        variant="filled"      />    </>  )}

## States

### Validation States

Validation states visually present the result of validation of the input. You should always provide a help text for states other than valid so users know what happened and what action they should take or what options they have.

Your favourite fruit
Great, they're in stock!
Your favourite fruit
Oh, really?
Your favourite fruit
You must select at least one kind of fruit.
Your favourite fruit
Great, they're in stock!
Your favourite fruit
Oh, really?
Your favourite fruit
You must select at least one kind of fruit.
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Great, they're in stock!" id="my-select-field-outline-success" label="Your favourite fruit" options={options} required validationState="valid" value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Oh, really?" id="my-select-field-outline-warning" label="Your favourite fruit" options={options} required validationState="warning" value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="You must select at least one kind of fruit." id="my-select-field-outline-error" label="Your favourite fruit" options={options} required validationState="invalid" value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Great, they're in stock!" id="my-select-field-filled-success" label="Your favourite fruit" options={options} required validationState="valid" value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="Oh, really?" id="my-select-field-filled-warning" label="Your favourite fruit" options={options} required validationState="warning" value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} helperText="You must select at least one kind of fruit." id="my-select-field-filled-error" label="Your favourite fruit" options={options} required value={fruit} validationState="invalid" variant="filled" /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Great, they're in stock!"        id="my-select-field-outline-success"        label="Your favourite fruit"        options={options}        required        validationState="valid"        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Oh, really?"        id="my-select-field-outline-warning"        label="Your favourite fruit"        options={options}        required        validationState="warning"        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="You must select at least one kind of fruit."        id="my-select-field-outline-error"        label="Your favourite fruit"        options={options}        required        validationState="invalid"        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Great, they're in stock!"        id="my-select-field-filled-success"        label="Your favourite fruit"        options={options}        required        validationState="valid"        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="Oh, really?"        id="my-select-field-filled-warning"        label="Your favourite fruit"        options={options}        required        validationState="warning"        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        helperText="You must select at least one kind of fruit."        id="my-select-field-filled-error"        label="Your favourite fruit"        options={options}        required        value={fruit}        validationState="invalid"        variant="filled"      />    </>  )}

### Disabled State

It's possible to disable just some options or the whole input.

Your favourite fruit
Your favourite fruit
Your favourite fruit
Your favourite fruit
() => { const [fruit, setFruit] = React.useState('apple') const options = [ { label: 'Apple', value: 'apple', }, { disabled: true, label: 'Banana', value: 'banana', }, { label: 'Grapefruit', value: 'grapefruit', }, ] return ( <> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-outline-disabled-option" label="Your favourite fruit" options={options} value={fruit} /> <SelectField changeHandler={e => setFruit(e.target.value)} id="my-select-field-filled-disabled-option" label="Your favourite fruit" options={options} value={fruit} variant="filled" /> <SelectField changeHandler={e => setFruit(e.target.value)} disabled id="my-select-field-outline-disabled" label="Your favourite fruit" options={options} value="apple" /> <SelectField changeHandler={e => setFruit(e.target.value)} disabled id="my-select-field-filled-disabled" label="Your favourite fruit" options={options} value="apple" variant="filled" /> </> ) }

    () => {  const [fruit, setFruit] = React.useState('apple')  const options = [    {      label: 'Apple',      value: 'apple',    },    {      disabled: true,      label: 'Banana',      value: 'banana',    },    {      label: 'Grapefruit',      value: 'grapefruit',    },  ]  return (    <>      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-outline-disabled-option"        label="Your favourite fruit"        options={options}        value={fruit}      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        id="my-select-field-filled-disabled-option"        label="Your favourite fruit"        options={options}        value={fruit}        variant="filled"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        disabled        id="my-select-field-outline-disabled"        label="Your favourite fruit"        options={options}        value="apple"      />      <SelectField        changeHandler={e => setFruit(e.target.value)}        disabled        id="my-select-field-filled-disabled"        label="Your favourite fruit"        options={options}        value="apple"        variant="filled"      />    </>  )}

## API

In addition to the options below, you can add any custom attributes that do not interfere with the API, and they will be passed to the `select` HTML element. This is useful mainly to improve component's accessibility.

changeHandler
func
null
disabled
bool
false
forwardedRef
Function │ { "current": "any" }
undefined
fullWidth
bool
false
helperText
string
null
id
string
required
inFormLayout
bool
false
isLabelVisible
bool
true
label
string
required
layout
'horizontal' │ 'vertical'
'vertical'
options
Array<{ "disabled": "Boolean", "label": "string", "value": "string │ number" }>
required
required
bool
false
size
'small' │ 'medium' │ 'large'
'medium'
validationState
'invalid' │ 'valid' │ 'warning'
null
value
string │ number
undefined
variant
'filled' │ 'outline'
'outline'

Next: Table →