cascader

A headless React cascader component for selecting values from hierarchical option trees, with search, multi-select, and async loading built in.

Library
npm
v1.25.0
233stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
81/100Excellent
Development Activity84
Maintenance84
Community76
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
74/100Good
Architecture82
Code Quality85
Innovation55
Learning Curve75

@rc-component/cascader is the React component behind Ant Design’s Cascader control, built for picking values out of nested option trees like region/city/district or category/subcategory/product hierarchies. It renders a column-based popup where selecting an option in one level reveals the next, and supports single selection, change-on-select, and full multi-select with a checkbox UI that conducts checked/half-checked state across parent and child nodes.

Beyond basic selection, it ships controllable search across the whole option tree (with custom filter, sort, and render hooks), asynchronous loadData for lazily fetching child options, custom field name mapping so it can consume data shaped however the host application already has it, and semantic classNames/styles props for styling individual parts of the selector and popup without fighting a monolithic class name.

It is built on top of @rc-component/select’s BaseSelect for the trigger/popup/positioning plumbing and @rc-component/tree-style entity utilities for path/key bookkeeping, which keeps the cascader’s own code focused on tree-specific selection logic (path resolution, checked-value deduplication, strategy-based display of checked nodes) rather than reimplementing popup and input behavior from scratch.

What You Get

  • A Cascader component plus a standalone Cascader.Panel for embedding the option-tree UI without the trigger/popup shell
  • Single-select, change-on-select, and checkable multi-select modes, with checkStrictly to disable parent/child checked-state conduction
  • Built-in controllable search (showSearch) with custom filter, sort, render, and result limit across the full option path
  • Async loadData hook for fetching child options on demand as a user drills into the tree
  • Custom fieldNames mapping so options can use any label/value/children key names
  • Semantic classNames/styles props for styling the selector and popup pieces independently, plus optionRender for fully custom option content

Common Use Cases

  • Region/address pickers (province -> city -> district) driven by a static or server-fed option tree
  • Category or taxonomy selectors where choosing a leaf node requires drilling through parent categories
  • Multi-select filters (e.g. product category checklists) that need parent/child checked-state conduction
  • Admin or dashboard forms where child options must be lazily fetched per level instead of loaded all at once
  • Building a fully custom-styled cascading select as the visual foundation for a design system’s own Cascader component (as Ant Design itself does)

Under The Hood

Architecture The component is a thin, hook-driven layer over @rc-component/select’s BaseSelect: src/Cascader.tsx composes useOptions, useSearchConfig, useSearchOptions, useValues, useSelect, useMissingValues, and useDisplayValues to turn a raw options tree plus controlled/uncontrolled value into the derived state BaseSelect needs (displayValues, searchOptions, onDisplayValuesChange), then hands rendering of the popup itself to OptionList (src/OptionList/index.tsx -> List.tsx -> Column.tsx) via BaseSelect’s OptionList injection point and a CascaderContext provider carrying shared config (fieldNames, checkable state, expand/loading icons, render overrides) down to the column renderers. Path/key bookkeeping (which internal “path key” maps to which chain of raw values) is centralized in useEntities/commonUtil/treeUtil, so the one piece of real complexity in the codebase — reconciling checked/half-checked conduction with deduplication strategies (SHOW_PARENT/SHOW_CHILD) — lives in a small number of well-named utility functions rather than being spread across the component tree. Swapping the underlying BaseSelect popup/positioning behavior would be the one change that ripples widest, since nearly every other module treats it as a fixed foundation.

Tech Stack TypeScript React library targeting React 19-compatible peer dependencies, built on @rc-component/select for the trigger/popup/positioning shell, @rc-component/util for shared hooks (useControlledState, useEvent, useId) and KeyCode handling, and @rc-component/trigger for popup placement types. It’s compiled for distribution with father (producing both lib CommonJS and es ESM output plus assets/*.css/*.less) and documented/demoed with dumi, the same toolchain used across the rest of the react-component/Ant Design ecosystem. Release automation runs through @rc-component/np.

Code Quality The repo has an extensive Jest + Testing Library test suite (11 spec files covering basics, checkable mode, field-name remapping, keyboard navigation, async loadData, search with limits, the standalone Panel, and “semantic” className/style props), run via the shared rc-test runner and covered by Codecov, with a CodeQL security-and-quality workflow and a dedicated main.yml CI test workflow on every push and PR. ESLint (via eslint.config.mjs) and strict tsc --noEmit type-checking are wired into lint/lint:tsc scripts, and Husky runs pre-commit checks. Naming and prop typing are consistent and precise throughout (deprecated props are explicitly annotated with @deprecated JSDoc pointing at their replacement), reflecting the discipline typical of a widely-consumed Ant Design ecosystem package.

API Design The public API is a single default export (Cascader, with a Panel static and SHOW_PARENT/SHOW_CHILD constants) that mirrors familiar <select>-like ergonomics — pass options and a children trigger element, get value/onChange. Getting started requires no boilerplate beyond an options array, while advanced behavior (search, async loading, multi-select, custom rendering) is opt-in through clearly named, individually documented props rather than a large configuration object, and deprecated single-purpose props (searchValue, onSearch, autoClearSearchValue) are being consolidated into a single showSearch config object, showing active API cleanup rather than accretion.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search