Listbox

7 parts

A list of selectable options that supports single or multiple selection, full keyboard navigation (arrows, Home/End, PageUp/PageDown, type-ahead), Shift-range selection, and optional hover highlighting. Use it when you need an always-visible selection list — picking from a set of values, building a custom multi-select, or as the options surface inside a larger widget. The root owns selection state (controlled via v-model or uncontrolled via defaultValue), the highlighted item, orientation/direction, optional native-form integration (name/required), and provides context to every descendant part.

Demo

Loading demo…

Anatomy

Import the parts and compose them. Each part forwards attributes to its underlying element.

vue
import {
  ListboxRoot,
  ListboxContent,
  ListboxItem,
  ListboxItemIndicator,
  ListboxGroup,
  ListboxGroupLabel,
  ListboxFilter,
} from '@robonen/primitives/selection/listbox';

<ListboxRoot>
  <ListboxContent />
  <ListboxItem />
  <ListboxItemIndicator />
  <ListboxGroup />
  <ListboxGroupLabel />
  <ListboxFilter />
</ListboxRoot>

API Reference

ListboxRoot

Root

A list of selectable options that supports single or multiple selection, full keyboard navigation (arrows, Home/End, PageUp/PageDown, type-ahead), Shift-range selection, and optional hover highlighting. Use it when you need an always-visible selection list — picking from a set of values, building a custom multi-select, or as the options surface inside a larger widget. The root owns selection state (controlled via `v-model` or uncontrolled via `defaultValue`), the highlighted item, orientation/direction, optional native-form integration (`name`/`required`), and provides context to every descendant part.

PropTypeDescription
defaultValue?U | U[]Uncontrolled initial value.
multiple?booleanAllow multiple selection.
orientation?ListboxOrientationNavigation orientation.
dir?ListboxDirectionReading direction. Falls back to ConfigProvider.
disabled?booleanDisable the whole listbox.
selectionBehavior?ListboxSelectionBehaviorHow selection behaves in multiple mode.
highlightOnHover?booleanHighlight items on hover.
by?string | ((a: U, b: U) => boolean)Compare objects by key or custom comparator.
name?stringNative input name for form submission. When set, a hidden input mirrors the value.
required?booleanMark as required for native form validation.
modelValue?T | T[] | undefinedTwo-way bound value (v-model).
Emits
EventPayload
update:modelValue[value: T | T[] | undefined]

ListboxContent

Content

The scrollable list container (`role="listbox"`) that wraps the items. It receives focus, owns the keyboard handlers (navigation, enter, type-ahead), and exposes the collection of items to the root.

No props or events — renders its element and forwards attributes.

ListboxItem

Item

A single selectable option (`role="option"`). Clicking, pressing Space, or pressing Enter while highlighted toggles its selection and emits `select`. Exposes `isSelected` / `isHighlighted` to its default slot.

PropTypeDescription
valueUThe value of the item.
disabled?booleanDisable this item.
textValue?stringText used for type-ahead matching. Defaults to the item's textContent. Provide this when the visible text differs from what users will type (e.g. an item rendered with icons/markup).

ListboxItemIndicator

ItemIndicator

Renders its content only when the parent `ListboxItem` is selected. Use it to show a checkmark or other selected-state marker; it is `aria-hidden`.

No props or events — renders its element and forwards attributes.

ListboxGroup

Group

Groups related items under a shared label (`role="group"`). Wraps a set of `ListboxItem`s and is labelled by its `ListboxGroupLabel` via `aria-labelledby`.

No props or events — renders its element and forwards attributes.

ListboxGroupLabel

GroupLabel

The accessible label for a `ListboxGroup`. Its id is wired to the group's `aria-labelledby`, so place it inside the group to name the set of items.

No props or events — renders its element and forwards attributes.

ListboxFilter

Filter

An optional text input for filtering the list. While mounted it takes over focus from the content (driving the list via `aria-activedescendant`), resets the highlight to the first item on each keystroke, and forwards Enter / arrow / Home / End keys to the listbox. Filtering of the items themselves is left to the consumer via `v-model`.

PropTypeDescription
modelValue?stringControlled input value.
autoFocus?booleanFocus on mount.
disabled?booleanDisable input.