# ReactSelect

Source: https://payloadcms.com/docs/beta/ui-components/react-select

The `ReactSelect` component adapts `react-select` to Payload's styles and interaction patterns. It is also exported as `Select`.

## Import

Inside a Payload Admin Panel Custom Component:

```tsx
import { ReactSelect } from '@payloadcms/ui'
```

You can also import the component directly:

```tsx
import { ReactSelect } from '@payloadcms/ui/elements/ReactSelect'
```

## Basic usage

**Implementation**

```tsx
import type { ReactSelectOption } from '@payloadcms/ui'

const options: ReactSelectOption[] = [
  { label: 'Draft', value: 'draft' },
  { label: 'Published', value: 'published' },
  { label: 'Archived', value: 'archived' },
]

const [value, setValue] = useState<ReactSelectOption | null>(options[0] ?? null)

const handleChange = (
  nextValue: ReactSelectOption | ReactSelectOption[] | null,
) => {
  setValue(Array.isArray(nextValue) ? null : nextValue)
}

<ReactSelect
  aria-label="Status"
  isClearable={false}
  onChange={handleChange}
  options={options}
  placeholder="Select a status"
  value={value}
/>
```

**Styling**

Override field tokens within ReactSelect, then target its portalled menu to customize the control, focus state, and options without changing other Admin fields.

```css
@layer payload {
  .react-select {
    --field-color-bg: #ffffff;
    --field-color-border: #b8b2d8;
    --field-color-border-focus: #6d5dfc;
    --field-border-radius: 0.5rem;
  }

  .rs__floating-menu-portal .rs__option--is-focused {
    --color-bg-secondary: #f2efff;
  }

  .rs__floating-menu-portal .rs__option--is-selected {
    --color-bg-selected: #e4dfff;
  }
}
```

- `--field-color-bg`: Select control background.
- `--field-color-border`: Select control border.
- `--field-color-border-focus`: Select control border while focused.
- `--field-border-radius`: Select control corner radius.
- `--color-bg-secondary`: Focused option background.
- `--color-bg-selected`: Selected option background.

Store the selected option object rather than only its value. Use `isMulti` when users can select more than one option.

By default, the options menu is rendered in a portal so it can escape drawers and other containers without being clipped.

## Multiple values

**Implementation**

```tsx
import type { ReactSelectOption } from '@payloadcms/ui'

const options: ReactSelectOption[] = [
  { label: 'Posts', value: 'posts' },
  { label: 'Media', value: 'media' },
  { label: 'Pages', value: 'pages' },
  { label: 'Users', value: 'users' },
]

const [value, setValue] = useState<ReactSelectOption[]>(options.slice(0, 2))

const handleChange = (
  nextValue: ReactSelectOption | ReactSelectOption[] | null,
) => {
  setValue(Array.isArray(nextValue) ? nextValue : nextValue ? [nextValue] : [])
}

<ReactSelect
  aria-label="Collections"
  isMulti
  isSortable
  onChange={handleChange}
  options={options}
  placeholder="Select collections"
  value={value}
/>
```

**Styling**

Override field tokens within ReactSelect, then target its portalled menu to customize the control, focus state, and options without changing other Admin fields.

```css
@layer payload {
  .react-select {
    --field-color-bg: #ffffff;
    --field-color-border: #b8b2d8;
    --field-color-border-focus: #6d5dfc;
    --field-border-radius: 0.5rem;
  }

  .rs__floating-menu-portal .rs__option--is-focused {
    --color-bg-secondary: #f2efff;
  }

  .rs__floating-menu-portal .rs__option--is-selected {
    --color-bg-selected: #e4dfff;
  }
}
```

- `--field-color-bg`: Select control background.
- `--field-color-border`: Select control border.
- `--field-color-border-focus`: Select control border while focused.
- `--field-border-radius`: Select control corner radius.
- `--color-bg-secondary`: Focused option background.
- `--color-bg-selected`: Selected option background.

Enable `isMulti` to store an array of selected options. Add `isSortable` when users should also be able to reorder those values by dragging them.

## Accessibility

- Add `aria-label` or associate the select with a visible field label when its purpose is not clear from nearby text.
- Keep option labels unique and concise.
- Preserve keyboard search and selection behavior when supplying custom `components`.

## Common props

These are the props most commonly used with this component. See its exported types in `@payloadcms/ui` for the complete list.

| Prop           | Type                                          | Default   | Description                                        |
| -------------- | --------------------------------------------- | --------- | -------------------------------------------------- |
| `options` \*   | `Option[] \| OptionGroup[]`                   | —         | Options displayed in the menu.                     |
| `value`        | `Option \| Option[]`                          | —         | Selected option or options.                        |
| `onChange`     | `(value: Option \| Option[] \| null) => void` | —         | Runs when the selection changes or is cleared.     |
| `placeholder`  | `string \| LabelFunction`                     | Localized | Sets the empty-state label.                        |
| `isMulti`      | `boolean`                                     | `false`   | Allows multiple selected values.                   |
| `isSortable`   | `boolean`                                     | `false`   | Allows selected multi-value items to be reordered. |
| `isClearable`  | `boolean`                                     | `true`    | Displays a control for clearing the value.         |
| `isSearchable` | `boolean`                                     | `true`    | Allows options to be filtered by typing.           |
| `isCreatable`  | `boolean`                                     | `false`   | Allows users to create values not in `options`.    |
| `disabled`     | `boolean`                                     | `false`   | Prevents interaction.                              |
| `isLoading`    | `boolean`                                     | `false`   | Displays the loading state.                        |
| `showError`    | `boolean`                                     | `false`   | Applies the validation error style.                |

_\* An asterisk denotes that a prop is required._
