Cascade Select
Choose a leaf value by moving through progressive hierarchy columns.
Usage
Location
Choose a location progressively from country to city.
Choose a location progressively from country to city.
<!-- Cascade Select / Location -->
<script setup lang="ts">
import { CascadeSelectColumn, CascadeSelectContent, CascadeSelectItem, CascadeSelectRoot, CascadeSelectTrigger, CascadeSelectValue } from '@sectile/vue/cascade-select'
const nodes = [{ id: 'asia', parentID: null }, { id: 'kr', parentID: 'asia' }, { id: 'seoul', parentID: 'kr' }]
</script>
<template>
<CascadeSelectRoot :nodes="nodes" default-value="seoul" v-slot="{ columns }">
<CascadeSelectTrigger><CascadeSelectValue placeholder="Choose a destination" /></CascadeSelectTrigger>
<CascadeSelectContent>
<CascadeSelectColumn v-for="(_, depth) in columns" :key="depth" :depth="depth" v-slot="{ items }">
<CascadeSelectItem v-for="item in items" :key="item" :value="item">{{ item }}</CascadeSelectItem>
</CascadeSelectColumn>
</CascadeSelectContent>
</CascadeSelectRoot>
</template>Disabled
Remove the control from keyboard and pointer interaction.
Remove the control from keyboard and pointer interaction.
<!-- Cascade Select / Disabled -->
<script setup lang="ts">
import { CascadeSelectColumn, CascadeSelectContent, CascadeSelectItem, CascadeSelectRoot, CascadeSelectTrigger, CascadeSelectValue } from '@sectile/vue/cascade-select'
const nodes = [{ id: 'asia', parentID: null }, { id: 'kr', parentID: 'asia' }, { id: 'seoul', parentID: 'kr' }]
</script>
<template>
<CascadeSelectRoot :nodes="nodes" default-value="seoul" v-slot="{ columns }">
<CascadeSelectTrigger><CascadeSelectValue placeholder="Choose a destination" /></CascadeSelectTrigger>
<CascadeSelectContent>
<CascadeSelectColumn v-for="(_, depth) in columns" :key="depth" :depth="depth" v-slot="{ items }">
<CascadeSelectItem v-for="item in items" :key="item" :value="item">{{ item }}</CascadeSelectItem>
</CascadeSelectColumn>
</CascadeSelectContent>
</CascadeSelectRoot>
</template>Controlled
Let the parent own the current value and apply accepted changes back to the component.
Let the parent own the current value and apply accepted changes back to the component.
<!-- Cascade Select / Controlled -->
<script setup lang="ts">
import { CascadeSelectColumn, CascadeSelectContent, CascadeSelectItem, CascadeSelectRoot, CascadeSelectTrigger, CascadeSelectValue } from '@sectile/vue/cascade-select'
const nodes = [{ id: 'asia', parentID: null }, { id: 'kr', parentID: 'asia' }, { id: 'seoul', parentID: 'kr' }]
</script>
<template>
<CascadeSelectRoot :nodes="nodes" default-value="seoul" v-slot="{ columns }">
<CascadeSelectTrigger><CascadeSelectValue placeholder="Choose a destination" /></CascadeSelectTrigger>
<CascadeSelectContent>
<CascadeSelectColumn v-for="(_, depth) in columns" :key="depth" :depth="depth" v-slot="{ items }">
<CascadeSelectItem v-for="item in items" :key="item" :value="item">{{ item }}</CascadeSelectItem>
</CascadeSelectColumn>
</CascadeSelectContent>
</CascadeSelectRoot>
</template>Floating positioning
This component uses the shared positioning engine. Use the live positioning example to change side, align, offsets, collision boundaries, strategy, and tracking while inspecting the resolved placement.
API
Vue package: @sectile/vue/cascade-select
CascadeSelectRootCascadeSelectTriggerCascadeSelectValueCascadeSelectContentCascadeSelectColumnCascadeSelectItemCascadeSelectItemIndicatorCascadeSelectItemChevron
Props
CascadeSelectRootProps
alignAlignment of positioned content relative to its anchor.
asElement or component rendered for this part.
asChildWhether to merge this part into its single child instead of rendering a wrapper.
avoidCollisionsWhether positioned content may flip or shift to remain visible.
collisionBoundaryBoundary used to keep positioned content visible.
collisionPaddingSpace kept between positioned content and its collision boundary.
defaultOpenInitial uncontrolled open state.
defaultValueInitial value used when the component owns its state.
disabledWhether interaction is unavailable.
disabledItemsItem values excluded from focus and selection.
formID of the native form associated with the control.
hideWhenDetachedWhether positioned content hides when its anchor leaves the layout.
labelAccessible name announced for the control.
modelValueCurrent value when state is controlled by the parent.
nameName used for native form submission.
nodesFlat hierarchy used to build the tree.
openWhether the associated popup or disclosure is open.
policiesBehavior policies that customize validation, movement, or selection.
positionWhether the popup is positioned relative to its trigger.
readonlyWhether the value can be inspected but not changed.
requiredWhether the control must contain a valid value before submission.
sidePreferred side of the anchor for positioned content.
sideOffsetDistance between positioned content and its anchor.
strategyCSS positioning strategy used for anchored content.
textValueReturns searchable or presentational text for an item value.
trackingUpdate strategy used while anchored content is open.
CascadeSelectColumnProps
asElement or component rendered for this part.
asChildWhether to merge this part into its single child instead of rendering a wrapper.
depthZero-based depth of this column in a cascading selection.
labelAccessible name announced for the control.
CascadeSelectItemProps
asElement or component rendered for this part.
asChildWhether to merge this part into its single child instead of rendering a wrapper.
disabledWhether interaction is unavailable.
valueCurrent value exposed by this contract.
CascadeSelectPartProps
asElement or component rendered for this part.
asChildWhether to merge this part into its single child instead of rendering a wrapper.
Slots
CascadeSelectRootSlotProps
columnsVisible cascade hierarchy columns.
disabledWhether interaction is unavailable.
highlightedValueValue currently highlighted for interaction.
openWhether the associated popup or disclosure is open.
pathCurrent selected path.
readonlyWhether the value can be inspected but not changed.
valueCurrent value exposed by this contract.
valuePathCurrent selected values from root to leaf.
CascadeSelectColumnSlotProps
depthDepth of the current hierarchical item.
itemsCurrent derived item collection.
parentValueValue that owns the current cascade column.
CascadeSelectItemSlotProps
branchWhether this item owns descendants.
disabledWhether interaction is unavailable.
expandedWhether descendants are visible.
highlightedWhether this item is highlighted for interaction.
selectedWhether this item is selected.
valueCurrent value exposed by this contract.
Events
CascadeSelectRoot
highlightEmitted when the highlighted item changes.
update:modelValueEmitted when the component requests a new controlled value.
update:openEmitted when the component requests a new open state.
Other types
CascadeSelectTextValueResolver
type CascadeSelectTextValueResolver = NonNullable<CascadeSelectRootProps['textValue']>CascadeSelectValueChangeHandler
type CascadeSelectValueChangeHandler = (value: string | null) => voidCascadeSelectOpenChangeHandler
type CascadeSelectOpenChangeHandler = (value: boolean) => voidCascadeSelectHighlightHandler
type CascadeSelectHighlightHandler = (value: string | null) => voidParts
Shared scope: [data-scope="cascade-select"]. Combine it with a part selector to keep styles local to this component.
| Part | Selector | Role | Extra attributes |
|---|---|---|---|
root | [data-part="root"] | Defines the component boundary and owns its composed parts. | — |
trigger | [data-part="trigger"] | Opens, closes, or activates the associated content. | — |
value | [data-part="value"] | Displays the current committed value. | — |
content | [data-part="content"] | Contains the component content shown for the active state. | — |
column | [data-part="column"] | Groups one level of hierarchical choices. | — |
item | [data-part="item"] | Represents one selectable or actionable item. | — |
item-indicator | [data-part="item-indicator"] | Shows the item selection state. | — |
item-chevron | [data-part="item-chevron"] | Shows that an item opens a deeper level. | — |
Keyboard interaction
| Key | Behavior |
|---|---|
| Arrow keys | Move the active option in the visible orientation. |
| Home / End | Move to the first or last eligible option. |
| Enter / Space | Select or activate the current option. |
| Printable text | Move to the next matching option when typeahead is available. |
Accessibility
Each visible column is a labeled listbox; options expose selection, branch, and disabled state.
