Listbox
listboxPresents a keyboard-navigable single or multiple selection list.
Usage
Single choice
selectionMode="single", click/arrow keys to roam, and check the selected item.
<Listbox
items={items}
selectionMode="single"
defaultSelectedKeys={["profile"]}
onSelectionChange={setKeys}
/>Multiple choice
selectionMode="multiple", multiple selections are allowed, aria-multiselectable is automatically turned on.
<Listbox
items={items}
selectionMode="multiple"
defaultSelectedKeys={["profile", "settings"]}
onSelectionChange={setKeys}
/>Pure action list
selectionMode="none" does not hold the selected state, and only relies on onAction to trigger the command.
<Listbox
items={items}
selectionMode="none"
onAction={(key) => console.log(key)}
aria-label="Action List"
/>Slot and description
startContent icon, description secondary copy, endContent shortcut key, disabled deactivated.
const items = [
{ key: "profile", label: "Personal Information", description: "View and Edit Account", startContent: <User className="size-4" /> },
{ key: "shortcut", label: "Shortcut key", endContent: <kbd className="font-mono text-xs">⌘K</kbd> },
{ key: "disabled", label: "Disabled Item", disabled: true },
];
<Listbox items={items} selectionMode="single" />When to use
Use Listbox for an always-visible, keyboard-accessible collection of options such as settings, commands, or menu items. Use selectionMode="single" or "multiple" when selection state matters, and selectionMode="none" with onAction for commands that should not remain selected. Unlike Combobox, Listbox has no input or popup and is best for a modest, flat set of visible options.
Import
import { Listbox } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| items* | ListboxItemData[] | — | List items; each item contains key/label, and can contain description/startContent/endContent/disabled |
| selectionMode | "none" | "single" | "multiple" | "single" | none creates an action-only list; single and multiple retain selection. |
| selectedKeys | string[] | — | Controlled selected keys. |
| defaultSelectedKeys | string[] | [] | Initial selected keys when uncontrolled. |
| disabledKeys | string[] | [] | Extra disabled keys, merged with item.disabled. |
| className | string | — | Container class name |
| style | CSSProperties | — | Inline styles, placed on the root element of the list. Used to express dynamic values that cannot be given by the Tailwind class (such as maxHeight determined at runtime) |
| aria-label | string | "\u9009\u9879\u5217\u8868" | Accessible name; the built-in Chinese copy means “Option list.” |
Events
| Event | Type | Description |
|---|---|---|
| onSelectionChange | (keys: string[]) => void | Called when selection changes. |
| onAction | (key: string) => void | Triggered when any item is activated (including none mode), used for imperative actions |
Example
const [keys, setKeys] = useState<string[]>(["profile"]);
<Listbox
items={items}
selectionMode="single"
selectedKeys={keys}
onSelectionChange={setKeys}
/>Action-only list (no selected state):
<Listbox items={items} selectionMode="none" onAction={(key) => run(key)} aria-label="Actions" />Usage guidelines
- With
selectionMode="none", the component retains no selection. Handle activations withonAction;onSelectionChangehas no meaningful value in this mode. - Provide
aria-labelwhen the list has no visible heading so assistive technology can identify its purpose.
Related
SecretField · Combobox · Mentions · InputOTP · Rating · Upload
Playground
<Listbox
items={items}
selectionMode="single"
selectedKeys={keys}
onSelectionChange={setKeys}
/>