# React Select Bootstrap

React Select Bootstrap styling in AdminKit PRO: a searchable select and multiselect with option groups, next to the native form-select in JSX.

AdminKit for React has two kinds of select. For a short, fixed list, use the native `<select>` with Bootstrap's `.form-select` class. It is plain markup in JSX, and it is in the free and PRO versions of [AdminKit for React](/react/).

When the list is long, or people need more than one value, use `Select`. It is built on [React Select](https://react-select.com/) 5: people search as they type, browse grouped options and pick several values. AdminKit styles it to look like the other Bootstrap form controls. `Select` is part of AdminKit PRO.

## Example

The native select needs no JavaScript. To preselect an option in React, set `defaultValue` on the `<select>`, or `value` and `onChange` for a controlled select. Don't put `selected` on an `<option>`.

```html
<label class="form-label" for="nativeSelect">Status</label>
<select class="form-select" id="nativeSelect">
  <option value="active" selected>Active</option>
  <option value="paused">Paused</option>
  <option value="archived">Archived</option>
</select>
```
```tsx code
<label className="form-label" htmlFor="nativeSelect">Status</label>
<select className="form-select" id="nativeSelect" defaultValue="active">
  <option value="active">Active</option>
  <option value="paused">Paused</option>
  <option value="archived">Archived</option>
</select>
```

`form-select-lg` and `form-select-sm` change the size, `multiple` turns it into a list box, and `disabled` grays it out.

## React Select

> This component is only available in **AdminKit PRO**. [Learn more](/pricing/#react).

Pass the choices in `options`: a list of `{ value, label }` objects, or groups of them. The `SelectOption` and `SelectGroup` types describe these shapes, and you can import them from the component. The control has no `id` of its own, so connect the label with `aria-labelledby`.

```html
<label class="form-label" id="stateLabel" for="stateSelect">State</label>
<select class="form-control" id="stateSelect">
  <optgroup label="Mountain Time Zone">
    <option value="AZ" selected>Arizona</option>
    <option value="CO">Colorado</option>
    <option value="UT">Utah</option>
  </optgroup>
  <optgroup label="Pacific Time Zone">
    <option value="CA">California</option>
    <option value="OR">Oregon</option>
    <option value="WA">Washington</option>
  </optgroup>
</select>

<script>
new Choices(document.querySelector("#stateSelect"));
</script>
```
```tsx code
import { Select, type SelectGroup } from "@/components/plugins/select";

const states: SelectGroup[] = [
  {
    label: "Mountain Time Zone",
    options: [
      { value: "AZ", label: "Arizona" },
      { value: "CO", label: "Colorado" },
      { value: "UT", label: "Utah" },
    ],
  },
  {
    label: "Pacific Time Zone",
    options: [
      { value: "CA", label: "California" },
      { value: "OR", label: "Oregon" },
      { value: "WA", label: "Washington" },
    ],
  },
];

export function StateSelect() {
  return (
    <>
      <label className="form-label" id="state-label">State</label>
      <Select
        options={states}
        defaultValue={states[0]?.options[0]}
        aria-labelledby="state-label"
      />
    </>
  );
}
```

The preview shows the select of the HTML version. `_react-select.scss` gives React Select the same look.

## Props

`Select` takes the [props of React Select](https://react-select.com/props). AdminKit sets the defaults below, and any prop you pass replaces its default:

| Prop | Default in AdminKit | Effect |
| --- | --- | --- |
| `unstyled` | `true` | React Select's own colors are off; the Sass styles the `react-select__` classes |
| `classNamePrefix` | `"react-select"` | The class prefix the Sass expects |
| `isClearable` | `false` | No clear button |
| `closeMenuOnSelect` | `!isMulti` | A multiple select stays open while you pick |
| `menuPlacement` | `"auto"` | The menu opens upward when there is no room below |
| `noOptionsMessage` | | "No results found" after a search, "No choices to choose from" otherwise |
| `instanceId` | from `useId()` | Stable ids for the generated elements |

`className` goes to the container, next to `react-select` and `react-select--single` or `react-select--multi`. The separator between the value and the arrow is removed, and a multiple select has no arrow.

The component is in `src/components/plugins/select.tsx`. It renders React Select unstyled, with the `react-select__` class prefix, and `src/scss/5-vendor/_react-select.scss` styles those classes like a Bootstrap form control.

## Multiple values

When people should pick more than one value, set `isMulti`. The picked values show as tags with a remove button. The demo passes `placeholder=""` for an empty field.

```html
<label class="form-label" for="statesSelect">States</label>
<select class="form-control" id="statesSelect" multiple>
  <option value="AZ">Arizona</option>
  <option value="CA">California</option>
  <option value="CO">Colorado</option>
  <option value="OR">Oregon</option>
  <option value="UT">Utah</option>
  <option value="WA">Washington</option>
</select>

<script>
new Choices(document.querySelector("#statesSelect"), { removeItemButton: true });
</script>
```
```tsx code
<label className="form-label" id="states-label">States</label>
<Select options={states} isMulti placeholder="" aria-labelledby="states-label" />
```

## Controlled value

Without `value`, React Select keeps track of the selection itself. When your component needs to read or set the selection, pass `value` and `onChange`. If the form submits with `FormData`, give the select a `name`. React Select then adds hidden inputs with the selected values.

```tsx
import { useState } from "react";
import { Select, type SelectOption } from "@/components/plugins/select";

export function StatesFilter({ options }: { options: SelectOption[] }) {
  const [selected, setSelected] = useState<readonly SelectOption[]>([]);

  return (
    <>
      <label className="form-label" id="filter-label">States</label>
      <Select
        options={options}
        isMulti
        value={selected}
        onChange={(values) => setSelected(values)}
        name="states"
        aria-labelledby="filter-label"
      />
    </>
  );
}
```

React Select only loads with the pages that use it. React Router loads each page when it is opened, so the library is not in the bundle of the other pages.

## Accessibility

- Name the select: `aria-labelledby` with the `id` of a visible label, or `inputId` with a `<label htmlFor>` that points at the search field, as the tags field of the Prompts app does.
- React Select is keyboard operable: type to search, the arrow keys move through the options, Enter picks one and Escape closes the menu.
- For a short, fixed list, the native `<select>` is the simpler choice: the browser and the screen reader handle it fully.

## Related

- [Next.js React Select](/nextjs/docs/forms/select/): the same select in AdminKit for Next.js
- [Bootstrap 5 select](/bootstrap/docs/forms/select/) and [multiselect](/bootstrap/docs/forms/multiselect/): the select of the HTML version
- [Form controls](/react/docs/forms/form-control/): inputs and textareas
- [Advanced Inputs demo](https://react-demo.adminkit.io/forms-advanced-inputs)

---

Canonical HTML page: https://adminkit.io/react/docs/forms/select/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
