Component

Cascader

Multi-level select. Drills through hierarchical categories one column at a time; picking a leaf commits the full path. A signal-forms native control — it implements FormValueControl, so [formField] binds straight to its value model (readonly T[]). [(value)] works standalone, and [(ngModel)] / reactive forms keep working through Angular's bridge.

Import

import { WrCascader, type WrCascaderOption } from 'ngwr/cascader';

Basic

<wr-cascader [options]="locations" [(value)]="picked" placeholder="Pick a location" />

locations: WrCascaderOption[] = [
  {
    value: 'us', label: 'United States', children: [
      { value: 'ca', label: 'California', children: [
        { value: 'la', label: 'Los Angeles' },
        { value: 'sf', label: 'San Francisco' },
      ] },
    ],
  },
  // ...
];
Value: [ "us", "ca", "sf" ]

changeOnSelect

Commit a path on every click, including parent nodes. Useful for filters where any level is meaningful.

<wr-cascader
  [options]="locations"
  [(value)]="picked"
  changeOnSelect
  placeholder="Pick any level"
/>
Value: []

API

NameDescriptionTypeDefault
clearLabelAccessible name. Falls back to select.clearSelection, then 'Clear selection'.string | nullnull
optionsrequiredRoot-level options. Each may have children for deeper levels.readonly WrCascaderOption<T>[]
placeholderPlaceholder shown when no path is selected.string''
ariaLabelAccessible name of the trigger. Falls back to the placeholder, then to select.label — a role="combobox" with nothing selected and no placeholder otherwise has no name at all.string | nullnull
disabledDisable the cascader. Bound automatically from the field's disabled state when used with [formField].booleanfalse
readonlyRefuse changes while the trigger stays focusable and the path still submits. Bound automatically from the field's readonly state when used with [formField]. The panel is where every edit happens, so a read-only cascader simply does not open — there is nothing to browse that is not already on the trigger — and the clear button goes away with it. Mirrored as aria-readonly, which role combobox supports.booleanfalse
sizeControl size — shares the --wr-control-* contract.WrCascaderSize'md'
clearableShow a clear-all (×) button on the trigger when a path is selected.booleantrue
changeOnSelectAllow selecting non-leaf (parent) nodes. When false, only leaves (nodes without children) commit a selection.booleanfalse
separatorSeparator between labels in the trigger display.string'/'
valueCommitted selection path (full array from root to leaf). Bound by [formField], or two-way via [(value)].unknown[]
(touch)Emitted on blur / commit so a bound field can mark itself touched.void

Types

NameDescriptionTypeDefault
WrCascaderOption<T>{ value: T, label: string, disabled?: boolean, children?: WrCascaderOption<T>[] }. A node without children is a leaf.interface

CSS custom properties

NameDescriptionTypeDefault
--wr-cascader-col-widthWidth of each column in the panel.length12rem
--wr-cascader-max-heightMax height per column before scrolling.length16rem

CSS variables

Custom properties ngwr/cascader publishes. Each default below is declared on the component's own selector, so a :root override is shadowed by it — set them on that selector, on a wrapper you scope yourself, or inline on the element. Unlike the BEM class names, these are the supported way to restyle the component.

VariableDefaultDeclared on
--wr-cascader-bgvar(--wr-color-surface).wr-cascader +1 variant override
--wr-cascader-bordervar(--wr-color-outline).wr-cascader
--wr-cascader-col-width12rem.wr-cascader
--wr-cascader-colorvar(--wr-color-on-surface).wr-cascader +1 variant override
--wr-cascader-font-sizevar(--wr-control-font-size-md).wr-cascader +2 variant overrides
--wr-cascader-line-heightvar(--wr-control-line-height-md).wr-cascader +2 variant overrides
--wr-cascader-max-height16rem.wr-cascader
--wr-cascader-min-width12rem.wr-cascader
--wr-cascader-opt-fontvar(--wr-control-font-size-md).wr-cascader-panel +2 variant overrides
--wr-cascader-opt-py0.5rem.wr-cascader-panel +2 variant overrides
--wr-cascader-padding-xvar(--wr-control-padding-x-md).wr-cascader +2 variant overrides
--wr-cascader-padding-yvar(--wr-control-padding-y-md).wr-cascader +2 variant overrides
--wr-cascader-radiusvar(--wr-control-radius-md).wr-cascader +2 variant overrides