Skip to content

SelectBox

A single-select dropdown built on reka-ui. Set autocomplete to turn it into a filterable single-select combobox: type to narrow the options, just like MultiSelect but bound to a single string.

Examples

vue
<script setup>
import { ref } from "vue";
const interval = ref("weekly");
</script>

<SelectBox
  v-model="interval"
  label="Interval"
  :options="[
    { value: 'daily', label: 'Daily' },
    { value: 'weekly', label: 'Weekly' },
    { value: 'monthly', label: 'Monthly' },
  ]"
/>

Hidden label

Use hide-label to visually hide the label while keeping it available to screen readers. Prefer this over aria-label whenever you have label text, since a real <label> is translated by browsers and keeps the naming in the DOM.

vue
<SelectBox
  v-model="interval"
  label="Interval"
  hide-label
  :options="[
    { value: 'daily', label: 'Daily' },
    { value: 'weekly', label: 'Weekly' },
    { value: 'monthly', label: 'Monthly' },
  ]"
/>

Autocomplete

Add autocomplete to make the field filterable. Type to narrow the list; the selected option's label fills the input. v-model is still a single string.

vue
<script setup>
import { ref } from "vue";
const state = ref("");
</script>

<SelectBox
  v-model="state"
  autocomplete
  label="State"
  placeholder="Search states…"
  :options="[
    { value: 'ca', label: 'California' },
    { value: 'ny', label: 'New York' },
    { value: 'tx', label: 'Texas' },
    { value: 'wa', label: 'Washington' },
    { value: 'fl', label: 'Florida' },
  ]"
/>

Accessibility

In the default mode the field is a reka-ui Select; with autocomplete it's a reka-ui Combobox following the ARIA combobox pattern:

  • The input has role="combobox" with aria-expanded, aria-controls, and aria-autocomplete="list"; the popup is a role="listbox" and each option a role="option" that reflects its state via aria-selected.
  • Keyboard support is handled for you: type to filter, ↑/↓ to move through the list, Enter to select the highlighted option, and Escape to close.
  • Pass label so the field is named by a real <label>. In autocomplete mode the label is also wired to the input via for/id, so clicking it focuses the field; use hide-label to keep the label for screen readers while hiding it visually, or aria-label when there's no visible label text.
  • The chevron is a labelled toggle (aria-label="Toggle options") kept out of the tab order, and native browser autofill is disabled so it can't cover the option list.

Model

NameType
v-modelstring

Props

PropTypeRequiredDefault
labelstringNo
hideLabelbooleanNo
ariaLabelstringNo
hintstringNo
optionsSelectOption[]Yes
placeholderstringNo
autocompletebooleanNo

SelectOption

ts
interface SelectOption {
  value: string;
  label: string;
}