Select a path from hierarchical data with cascading columns
Cascader lets users select a value from hierarchical data by drilling down through cascading columns: picking an option in one column reveals its children in a new column to the right. The value is an ordered path from the root option to the selected node, for example ['asia', 'jp', 'tokyo'] .
Cascader is useful for large hierarchical datasets where a nested dropdown would be hard to navigate – locations (continent → country → city), categories, organization structures, etc.
All demos on this page switch to the flat list layout on small screens, so the cascading columns and interactions like hover expand and keyboard navigation cannot be fully tested on mobile devices – open the demos on a larger screen to try them out.
Data passed to the data prop is an array of CascaderOption objects:
Cascader value is an ordered array of option values (a path from root to node) or null when nothing is selected. The onChange callback is called with the selected path and the resolved chain of CascaderOption objects:
By default, only leaf options (options without children) can be selected. Clicking a parent option only expands the next column.
Set the changeOnSelect prop to allow selecting any option, not only leaves. When enabled, clicking a parent option both selects its path and expands the next column, so any intermediate level is a valid value:
closeOnSelect controls whether the dropdown is closed after a value is selected. When it is not set, it defaults to the opposite of allowDeselect : the dropdown stays open by default (so the selection can be toggled off), unless allowDeselect={false} is set. Set closeOnSelect explicitly to override this behavior:
By default, clicking the selected option again removes the value. Set allowDeselect={false} to disable this behavior:
By default, the next column is opened when an option is clicked. Set expandTrigger="hover" to open the next column on hover instead – selecting a leaf still requires a click:
With expandTrigger="hover" , the open column stays in place while the cursor moves diagonally toward it – options that the cursor passes over on the way do not replace it. Set safeAreaPolygon={false} to expand on every hover immediately, or pass an object to configure Floating UI safePolygon options:
Cascading columns require horizontal space and are not ideal for narrow screens, which makes them a poor fit for mobile layouts. Set withColumns={false} to render options as a flat list of full paths (the same way as search results) instead of columns – this layout works well on mobile:
The most common use case is to render columns on desktop and the flat list on mobile. Combine withColumns with the use-matches hook to switch between the two layouts depending on the screen size. All demos on this page use this technique – resize the window to see the layout change:
Deep hierarchies can produce many columns. Use the maxDisplayedLevels prop ( 3 by default) to limit how many columns are displayed next to each other. When you drill deeper than the limit, the earliest columns are replaced by the deeper ones and a control is displayed on the left. Click it to reveal the previous levels; a control on the right then lets you return to the deeper levels:
Set the searchable prop to allow filtering options. In search mode, the columns are replaced with a flat list of full paths that match the query:
Use the filter prop to customize how paths are matched and renderSearchOption to customize how search results are rendered:
Use searchValue and onSearchChange props to control the search value:
Set the nothingFoundMessage prop to display a message when no options match the search query:
By default, the selected path is displayed in the input as option labels joined by the separator ( / by default). Use the separator prop to change the divider and the formatValue prop to fully customize the input label:
Use the columnWidth prop to set a fixed width for every column and maxDropdownHeight to control the height of a column before it becomes scrollable ( 260 by default):
Use the renderOption prop to customize how options are rendered in columns. The function receives the option and its column level:
Use the withCheckIcon prop to toggle the check icon on the selected option and checkIconPosition to change its position ( left or right ):
Set the disabled property on an option to prevent it from being selected or expanded. Disabled options are skipped during keyboard navigation:
Cascader supports leftSection and rightSection props the same way as other inputs. These sections are usually used to add icons:
Set the clearable prop to display the clear button when a value is selected:
Use the clearSectionMode prop to control how the clear button and rightSection are rendered:
Each column is scrollable. Use the maxDropdownHeight prop to control the height of a column before it becomes scrollable and scrollAreaProps to pass props down to the ScrollArea in each column:
Use dropdownOpened , defaultDropdownOpened , onDropdownOpen and onDropdownClose props to control the dropdown opened state:
Use comboboxProps to pass props down to the underlying Combobox and Popover . For example, set position to change the dropdown position:
In flat list mode ( withColumns={false} ) the dropdown width can be controlled with comboboxProps={{ width }} . In columns mode the dropdown is sized to the columns:
To use Cascader inside a Popover , set comboboxProps={{ withinPortal: false }} :
You can override Combobox props with comboboxProps . This is useful when you need to change some of the props that are not exposed by Cascader , for example withinPortal :
Use the Styles API to customize Cascader styles:
Component Styles API
Hover over selectors to highlight corresponding elements
Cascader supports leftSection and rightSection props. These sections are rendered with absolute positioning inside the input wrapper. You can use them to display icons, input controls, or any other elements.
You can use the following props to control sections styles and content:
Cascader component supports Input and Input.Wrapper component features and all input element props. The Cascader documentation does not include all features supported by the component – see the Input documentation to learn about all available features.
Set readOnly to make the input read only. When readOnly is set, Cascader will not open the dropdown and will not call the onChange function.
Set disabled to disable the input. When disabled is set, the user cannot interact with the input and Cascader will not open the dropdown.
Pick a valid location
Set the loading prop to display a loader in the right section instead of the chevron:
Cascader columns are rendered as nested listboxes with option elements. To make the component accessible, set the label prop or pass aria-label to the component: