Listbox

Alpha

A persistent listbox (always visible, not a dropdown) with single and multi-select modes, option groups, and full keyboard navigation.

Import

import { Listbox } from "@compa11y/react";

Usage

Example.tsx
import { useState } from "react";
import { Listbox } from "@compa11y/react";

// Single select
function SingleExample() {
  const [fruit, setFruit] = useState("apple");

  return (
    <Listbox value={fruit} onValueChange={setFruit} aria-label="Favorite fruit">
      <Listbox.Option value="apple">Apple</Listbox.Option>
      <Listbox.Option value="banana">Banana</Listbox.Option>
      <Listbox.Option value="cherry">Cherry</Listbox.Option>
    </Listbox>
  );
}

// Multi-select with groups
function MultiExample() {
  const [selected, setSelected] = useState<string[]>([]);

  return (
    <Listbox multiple value={selected} onValueChange={setSelected} aria-label="Toppings">
      <Listbox.Group label="Meats">
        <Listbox.Option value="pepperoni">Pepperoni</Listbox.Option>
        <Listbox.Option value="sausage">Sausage</Listbox.Option>
      </Listbox.Group>
      <Listbox.Group label="Vegetables">
        <Listbox.Option value="peppers">Peppers</Listbox.Option>
        <Listbox.Option value="olives">Olives</Listbox.Option>
      </Listbox.Group>
    </Listbox>
  );
}

Features

  • Single and multi-select modes
  • Option groups with visible labels
  • Roving tabindex via aria-activedescendant
  • Type-ahead character search
  • Shift+Arrow range selection (multi-select)
  • Ctrl+A to select/deselect all (multi-select)
  • Scroll-into-view on focus change
  • Screen reader announcements for selection, range counts, and select/deselect all

Props

Listbox component props
PropTypeDefaultDescription
valuestring | string[]-Controlled selected value(s)
onValueChange(value: string | string[]) => void-Called when selection changes
multiplebooleanfalseEnable multi-select mode
orientation'horizontal' | 'vertical''vertical'Layout orientation
disabledbooleanfalseDisables the entire listbox
aria-labelstring-Accessible label for the listbox

Sub-components

Listbox.Option

Listbox.Option props
PropTypeDefaultDescription
value*string-Option value
disabledbooleanfalseDisables this option
children*ReactNode-Option label content

Listbox.Group

Listbox.Group props
PropTypeDefaultDescription
label*string-Visible group label (used for aria-labelledby)
children*ReactNode-Listbox.Option elements

Keyboard Interactions

Accessibility
All keyboard interactions follow WAI-ARIA best practices and work without any additional configuration.
Keyboard shortcuts for Listbox
KeyAction
ArrowDown / ArrowUpMove focus (single: also selects; multi: focus only)
Home / EndMove to first/last option (single: also selects)
SpaceToggle selection (multi-select)
Shift+ArrowDown / Shift+ArrowUpExtend selection (multi-select)
Ctrl+Shift+Home / Ctrl+Shift+EndRange select to first/last (multi-select)
Ctrl+ASelect or deselect all options (multi-select)
Type charactersType-ahead to jump to matching option