OptionList
role="listbox" with aria-activedescendant. Options are strings. Keyboard is Arrow, Home, End, Enter, and Space. Escape is not handled so it can close a parent Popover.
Single value is string | null. Multiple value is string[]. Selected options stay font-weight: 400 and use an accent-soft row fill (color.bg.selected, 12% accent). Highlighted selected is 20% (color.accent.soft-strong). Rows are 2px apart. Hover is gated with @media (hover: hover).
Multiple keeps a check gutter on every row. Selected fills the box and draws a CSS check.
Options are OptionList.Option parts inside OptionList.Root.
A combobox can pass id, activeValue, onActiveValueChange, and tabIndex={-1} so the input owns focus and aria-activedescendant. Uncontrolled lists keep tabIndex={0}.
When to use
When: Overlay listbox inside Popover or BottomSheet. Single or multiple string options. Keyboard listbox pattern.
When not: Choices that stay on the page → Radio or Checkbox. Do not dual-wire the same value to Radio/Checkbox.
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| selectionMode | "single" | "multiple" | no | "single" | Single fires onValueChange(string). Multiple fires onValueChange(string[]). |
| value | string | null | readonly string[] | yes | — | Selected value, or values when selectionMode is multiple. |
| onValueChange | (value: string | string[]) => void | yes | — | Selection change. Single passes a string. Multiple passes the next array. |
| id | string | no | — | Listbox id. Auto-generated when omitted. Option ids derive from it. |
| tabIndex | number | no | 0 | Listbox tabIndex. Pass -1 when a combobox input owns focus. |
| activeValue | string | null | no | — | Controlled highlighted value. Omit to keep highlight inside the list. |
| onActiveValueChange | (value: string | null) => void | no | — | Fires when keyboard or pointer moves the highlight. |
| aria-label | string | no | — | Name when no visible label is present. |
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| value | string | yes | — | Selection value. |
| children | string | yes | — | Visible label. Text only. |
| disabled | boolean | no | false | Skips pointer and keyboard selection. |