Skip to content
EspañolEnglish
All components (204)

Cascading selector

Fields · Cascader · .amset-cascader

What it is and when to use it

Country > province > city in a single field, with one column per level. It is what until now was built with several chained Selects, which do not share state or keyboard. The value is the path: the keys of each level, from the root to the leaf.

When to use it

  • Hierarchical data where a leaf is chosen (or a branch with changeOnSelect): locations, product categories, org chart.

When not to

  • A flat list: Select. With a tree you want to see in full and pick several from: Tree.

Keyboard: Down Arrow or Up Arrow open the field; inside, the up and down arrows move through the column, Right Arrow enters the inner level, Left Arrow goes back to the outer one, Home and End go to the ends, Enter or Space chooses (or opens, if it has children) and Escape closes, returning focus to the field.

Accessibility: each column is a list with its level name (levelLabels); options with children say "with sublevels" in addition to carrying the arrow. Dimmed ones cannot be chosen.

Lazy loading: an option with isLeaf: false and no children requests its children with loadData(path) (the path to it) the first time it is opened, and the column says "Loading…".

Fine-tuning: the field's --amset-field-* variables and --amset-cascader-column-width and --amset-cascader-height.

What it looks like

Spain, has sub-levels
Portugal, has sub-levels

<Cascader
  label="Shipping destination"
  placeholder="Choose a destination"
  options={[
    { key: 'es', label: 'Spain', children: [
      { key: 'cadiz', label: 'Cadiz', children: [{ key: 'jerez', label: 'Jerez de la Frontera' }] },
    ] },
  ]}
  levelLabels={['Country', 'Province', 'City']}
  defaultValue={['es', 'cadiz', 'jerez']}
/>

Props

Import it with import { Cascader } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
labelrequiredstring—
optionsrequiredreadonly CascaderOption[]The tree of options: country > province > city.
changeOnSelectbooleanYou can choose an option that has children, not only the leaves: "Spain" on its own without going down to a province. By default, leaves only.
classNamestringMerged with the library classes; it does not replace them.
defaultValueCascaderPathThe route chosen at the start, without controlling it from outside.
disabledboolean—
displayRender(labels: readonly string[]) => ReactNodeHow the chosen value is shown in the closed field. It receives the names of the path. By default, "Spain / Madrid".
errorstring—
hiddenLabelbooleanThe label for the screen reader only.
hintstring—
idstring—
invalidboolean—
levelLabelsreadonly string[]The name of each level for the screen reader: `['País', 'Provincia', 'Ciudad']`.
loadData(path: CascaderPath) => Promise<readonly CascaderOption[]>Asks for the children of an option the first time it is opened (lazy loading). The option carries `isLeaf: false` and has no `children`; it is called with its path.
loadingTextstringWhat the column says while the children arrive. "Loading…" by default.
namestringSo that the chosen value travels in a native form: the KEY of the leaf (or of the last option chosen).
offsetnumber—
onBlur() => voidOn leaving the field. The form uses it to mark that it has been touched.
onChange(path: CascaderPath) => voidNotifies the chosen path. Each key is that of a level.
placeholderstring—
placementPlacement—
readOnlyboolean—
requiredboolean—
size"sm" | "md" | "lg"—
valueCascaderPathThe chosen path, from root to leaf, controlled from outside. `[]` is "nothing chosen".
variantFieldVariant—

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

CSS variables

These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.

VariableDefault
--amset-cascader-column-width11rem
--amset-cascader-height16rem

How to change it

.amset-cascader {
  --amset-cascader-column-width: ...;
  --amset-cascader-height: ...;
}

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: