Cascader
Only leaves are selected by default. Set
changeOnSelect to allow intermediate levels.Source
LLM docs
Package
Examples
15
Properties
88
Basics
Drill through columns to select a city, or search the full path.
Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" placeholder="Choose a city" data={data} searchable />
</Block>
);
}Flat Paths
withColumns={false} lists full paths in one column.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" data={data} withColumns={false} />
</Block>
);
}Variants
Compare the default, filled, outline, and unstyled field shells on Cascader.
Loading demo…
import { Column, Cascader } from '@plocks/ui';
const options = [{ value: 'us', label: 'United States', children: [{ value: 'nyc', label: 'New York' }] }];
const variants = ['default', 'filled', 'outline', 'unstyled'] as const;
export function Demo() {
return (
<Column gap="md" fullWidth>
{variants.map(variant => (
<Cascader key={variant} variant={variant} label={`${variant} variant`} data={options} placeholder="Choose a city" />
))}
</Column>
);
}Select Intermediate Levels
changeOnSelect allows a parent path to be selected.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" data={data} changeOnSelect />
</Block>
);
}Hover Expansion
expandTrigger="hover" opens the next column on hover. safeAreaPolygon keeps that column open during diagonal pointer travel.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" data={data} expandTrigger="hover" />
</Block>
);
}Maximum Displayed Levels
maxDisplayedLevels limits the simultaneous columns.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader
label="Location"
data={data}
maxDisplayedLevels={2}
defaultValue={['europe', 'france', 'paris']}
/>
</Block>
);
}Search Paths
Search switches to a list of matching full paths.
Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" data={data} searchable />
</Block>
);
}Nothing Found
Search displays a fallback when there are no matches.
Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader
label="Location"
data={data}
searchable
nothingFoundMessage="No matching locations"
/>
</Block>
);
}Formatted Value
formatValue customizes the selected path shown in the trigger.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader
label="Location"
data={data}
defaultValue={['europe', 'france', 'paris']}
formatValue={(path) => path.map((item) => item.label).join(' → ')}
/>
</Block>
);
}Column Width
columnWidth changes the width of each level.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" data={data} columnWidth={220} />
</Block>
);
}Clearable
clearable adds a control to remove the selected path.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader
label="Location"
data={data}
defaultValue={['europe', 'france', 'paris']}
clearable
/>
</Block>
);
}Disabled Options
Disabled options stay visible but cannot be selected.
Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{ value: 'france', label: 'France', disabled: true },
{ value: 'germany', label: 'Germany' },
],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" data={data} />
</Block>
);
}Custom Option
renderOption customizes each column entry.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader
label="Location"
data={data}
renderOption={(option) => `${option.label ?? option.value} →`}
/>
</Block>
);
}Read Only
A read-only field displays its path without opening.
Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader
label="Location"
data={data}
readOnly
defaultValue={['europe', 'france', 'paris']}
/>
</Block>
);
}Error State
error links validation feedback to the field.Loading demo…
import { Block, Cascader } from '@plocks/ui';
const data = [
{
value: 'europe',
label: 'Europe',
children: [
{
value: 'france',
label: 'France',
children: [
{ value: 'paris', label: 'Paris' },
{ value: 'lyon', label: 'Lyon' },
],
},
],
},
{
value: 'asia',
label: 'Asia',
children: [{ value: 'japan', label: 'Japan', children: [{ value: 'tokyo', label: 'Tokyo' }] }],
},
];
export function Demo() {
return (
<Block fullWidth>
<Cascader label="Location" data={data} error="Choose a location" />
</Block>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources