Listbox
AlphaA 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
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | string[] | - | Controlled selected value(s) |
onValueChange | (value: string | string[]) => void | - | Called when selection changes |
multiple | boolean | false | Enable multi-select mode |
orientation | 'horizontal' | 'vertical' | 'vertical' | Layout orientation |
disabled | boolean | false | Disables the entire listbox |
aria-label | string | - | Accessible label for the listbox |
Sub-components
Listbox.Option
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | - | Option value |
disabled | boolean | false | Disables this option |
children* | ReactNode | - | Option label content |
Listbox.Group
| Prop | Type | Default | Description |
|---|---|---|---|
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.
| Key | Action |
|---|---|
| ArrowDown / ArrowUp | Move focus (single: also selects; multi: focus only) |
| Home / End | Move to first/last option (single: also selects) |
| Space | Toggle selection (multi-select) |
| Shift+ArrowDown / Shift+ArrowUp | Extend selection (multi-select) |
| Ctrl+Shift+Home / Ctrl+Shift+End | Range select to first/last (multi-select) |
| Ctrl+A | Select or deselect all options (multi-select) |
| Type characters | Type-ahead to jump to matching option |