AdminKitDocs
Forms

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.

When the list is long, or people need more than one value, use Select. It is built on React Select 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>.

<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

Pro

This component is only available in AdminKit PRO. Learn more.

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.

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. AdminKit sets the defaults below, and any prop you pass replaces its default:

PropDefault in AdminKitEffect
unstyledtrueReact Select's own colors are off; the Sass styles the react-select__ classes
classNamePrefix"react-select"The class prefix the Sass expects
isClearablefalseNo clear button
closeMenuOnSelect!isMultiA 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
instanceIdfrom 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.

<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.

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.

Last updated on

On this page