Skip to content

Listbox ​

SListbox is an always-visible list of options: what a select shows inside its dropdown, usable on its own. It fits a picker in a settings panel, a command list, a filter column next to a table — any place where the choices should stay on screen instead of hiding behind a trigger.

Use SSelect when the value belongs in a form field: it has a labelled frame, a placeholder, a floating label and validation. SListbox is the bare surface — no frame chrome, no trigger — so it also composes inside popovers, drawers and command palettes.

Options come from the options array, the value is bound with v-model: a single value by default, an array of them with multiple.

Reka UI owns the interaction. Tab moves onto the list (focus lands on the active option, not on the whole list), the arrow keys and Home/End move between options and skip the disabled ones, typing the first letters of a label jumps to it, and Space or Enter picks the highlighted option. The list reports itself as role="listbox" with role="option" rows, so it needs an accessible name: pass label, or point your own aria-labelledby at a visible heading.

Single selection ​

Picking the selected option clears it, the way a checkbox does. Set selection-behavior="replace" to keep exactly one option picked at all times. With multiple, replace also gives the keyboard a range: Shift with the arrow keys, Home or End extends the selection from the last pick. The range is a keyboard gesture — Shift with a click is an ordinary click.

Multiple selection ​

With multiple the model becomes an array, every pick toggles its own option, and the list announces itself as multi-selectable.

Option content ​

An option takes an icon — a name from the icon registry or a raw path. For anything richer, the option slot replaces the whole row and receives the option itself along with its selected and disabled state.

Long lists (max-height) ​

max-height is the height the list may grow to before it starts scrolling; a number means pixels. The list scrolls inside a scroll area, and moving the highlight with the keyboard keeps the active option in view.

Empty state ​

With an empty options array the list shows a message from the locale dictionary — the listboxEmpty key, "No options". Override it with empty-text, or replace it entirely with the empty slot.

Sizes and shape ​

size sets the option row height — sm (32px), md (40px) or lg (48px) — and square removes the rounding of the frame.

API ​

Props

NameTypeDefaultDescription
options*{ label: string; value: string; disabled?: boolean; icon?: string }[]requiredList of options.
size"md" | "sm" | "lg""md"Option row size: sm (32px), md (40px), or lg (48px).
multiplebooleanfalseMultiple selection. modelValue becomes string[], and the list reports itself as multi-selectable to assistive technology.
selection-behavior"replace" | "toggle""toggle"How picking an option changes the selection. toggle (the default) flips the option: picking a selected one clears it, which is how checkbox-like lists behave. replace keeps exactly one pick per action — a click always wins over the previous selection, and with multiple Shift with the arrow keys, Home or End extends the range from the last pick. The range is a keyboard gesture only: a Shift-click is an ordinary click.
labelstringundefinedAccessible name of the list. A listbox has no visible label of its own, so either set this or point aria-labelledby at your own heading.
empty-textstringundefinedText shown when options is empty (taken from the locale dictionary by default).
max-heightstring | numberundefinedHeight the list is allowed to grow to before it starts scrolling; a number means pixels. Without it the list is as tall as its options.
squarebooleanfalseSquare corners: removes the list border rounding (rounded by default).
disabledbooleanfalseDisables the whole list: no option can be picked or focused.
model-valuestring | string[]undefinedSelection: the option value (string), or an array of them with multiple (string[]). Two-way binding via v-model.

Events

NameSignatureDescription
update:modelValue( value: | string | string[] | undefined ) => voidEmitted when modelValue changes. Used for two-way binding (v-model).

Slots

NameDescription
optionOption row: replaces the icon, the label and the selected indicator.
emptyMessage shown when there are no options.