Marble UI
← Components

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>

PropTypeDefaultDescription
options *requiredCascaderOption[]—
classNamestring—
labelstring—
onChange(path: string[]) => void—
placeholderstring'Select…'
valuestring[]—

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)} />
  • onChange gets the path of values (['eu', 'nl', 'ams']); the trigger shows the labels joined with “ / “. Only a leaf completes the choice and closes the popover.
  • value sets 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 label plus the current path or placeholder.
Example source · show
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