Cascader
Preview: Default
Hierarchical picker: one listbox column per level; choosing a leaf closes and shows the full path. `value` follows later changes.
Import
import { Cascader } from '@marbleui/ui'Props
<Cascader>
| Prop | Type | Default | Description |
|---|---|---|---|
| options *required | CascaderOption[] | — | |
| className | string | — | |
| label | string | — | |
| onChange | (path: string[]) => void | — | |
| placeholder | string | 'Select…' | |
| value | string[] | — |
Accessibility
Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria Button · React Aria Dialog · React Aria DialogTrigger · React Aria ListBox · React Aria ListBoxItem. Follow the primitive's docs for the full keyboard map.
Usage notes
Pick one leaf from a hierarchy a level at a time (region → country → office), one column per level. To allow picking parents use TreeSelect; for a flat list use Select.
const offices: CascaderOption[] = [
{ value: 'eu', label: 'Europe', children: [{ value: 'nl', label: 'Netherlands', children: [{ value: 'ams', label: 'Amsterdam' }] }] },
]
<Cascader label="Office" options={offices} onChange={(path) => setOffice(path)} />
onChangegets the path ofvalues (['eu', 'nl', 'ams']); the trigger shows the labels joined with “ / “. Only a leaf completes the choice and closes the popover.valuesets the path and follows later changes; the user can still change it from the popover.- Pressing the option that’s already chosen keeps it: on a leaf that confirms the choice and closes the popover.
- The trigger is named by the
labelplus the current path or placeholder.
Example source · show· hide
import { Cascader, type CascaderOption } from './cascader'
const regions: CascaderOption[] = [
{ value: 'eu', label: 'Europe', children: [{ value: 'nl', label: 'Netherlands', children: [{ value: 'ams', label: 'Amsterdam' }, { value: 'rtm', label: 'Rotterdam' }] }, { value: 'de', label: 'Germany', children: [{ value: 'ber', label: 'Berlin' }, { value: 'muc', label: 'Munich' }] }] },
{ value: 'na', label: 'North America', children: [{ value: 'us', label: 'United States', children: [{ value: 'sf', label: 'San Francisco' }, { value: 'ny', label: 'New York' }] }, { value: 'ca', label: 'Canada', children: [{ value: 'tor', label: 'Toronto' }] }] },
{ value: 'ap', label: 'Asia Pacific', children: [{ value: 'sg', label: 'Singapore' }, { value: 'jp', label: 'Japan', children: [{ value: 'tyo', label: 'Tokyo' }] }] },
]
export const styles = { Default: () => <Cascader className="w-72" label="Office" options={regions} />, Preselected: () => <Cascader className="w-72" label="Office" options={regions} value={['eu', 'nl', 'ams']} /> }Source: packages/ui/src/cascader/cascader.tsx
Catalog
- Category
- selection
- Priority
- Extra
- Primitive
- composed
- React Aria
- Menu + SubmenuTrigger