Selection List
betaA multi-select list of people with a liquid tick and an action that springs out from under it once someone is picked.
- Forms
- 2 files
- 1 npm package
- Accessibility notes
Loading the example…
pnpm dlx @dowel-ui/cli add selection-listnpm packages installed: class-variance-authority.
import { SelectionList } from "@/components/ui/selection-list";Default
Preselected
Photos
Async Action
Custom Labels
Controlled
Gallery
<SelectionList>
| Prop | Type | Default |
|---|---|---|
items (required) | SelectionListItem[] | — |
actionClassName | string | — |
actionLabelThe action's label for a selection count. | string | ((count: number) => string) | defaultActionLabel |
bounceOvershoot of the action's spring, 0–1. | number | 0.35 |
cornerRadius of the box in pixels; the pill and action radii derive from it. | number | 20 |
defaultValue | string[] | — |
doneLabelShown on the action, and announced, once it has run. | string | "Requests sent" |
listClassName | string | — |
onActionRuns with the selected ids. Return a promise to show a busy state until it settles. | (ids: string[]) => unknown | — |
onValueChange | (value: string[]) => void | — |
resetAfterMilliseconds the done label shows before the action tucks away. | number | 1600 |
stroke | boolean | — |
tone | "default" | "inverted" | "default" |
valueControlled selection, as item ids. | string[] | — |
Plus every attribute of <div> except defaultValue, onChange, children.
The list is a role="listbox" aria-multiselectable="true" with a single tab stop; name it with aria-label (default "Select people") or aria-labelledby. Rows are role="option" with aria-selected. ArrowUp/ArrowDown rove with wrap-around, Home/End jump, Space/Enter toggle and Ctrl/Cmd+A selects or clears everything. The hover highlight follows keyboard focus as well as the pointer. The action button is disabled, inert and aria-hidden while tucked away (nothing selected); a pending action shows aria-busy, and the done label is announced through a polite live region. When the action tucks away again focus returns to the list. The tick, avatars and highlight are aria-hidden; under reduced motion the goo fill becomes a plain fill.
10/10
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — passes
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — passes
- className merged — passes
- Visible focus — passes
- No fixed widths — passes