Cascader

The Cascader component provides a multi-panel cascading selection interface for hierarchical data like locations, categories, and organizational structures.

Installation

npm install @duskmoon-dev/el-cascader

Usage

import '@duskmoon-dev/el-cascader/register';
<el-dm-cascader
  placeholder="Select location..."
></el-dm-cascader>

Live Demo

Basic Cascader

Empty Cascader (No Options)

Properties

PropertyTypeDefaultDescription
valuestring''Selected path as JSON array
placeholderstring''Placeholder text
disabledbooleanfalseDisables the cascader
multiplebooleanfalseEnable multi-path selection
searchablebooleanfalseEnable search filtering
clearablebooleanfalseShow clear button
change-on-selectbooleanfalseEmit change on each level selection
expand-trigger'click' | 'hover''click'How to expand panels
separatorstring' / 'Display path separator
show-all-levelsbooleantrueShow full path or only leaf label
size'sm' | 'md' | 'lg''md'Size variant
optionsstring''JSON string of cascader options

Option Format

Options can be set via HTML attribute or JavaScript:

Via Attribute (JSON string)

<el-dm-cascader
  options='[{"value":"usa","label":"United States","children":[{"value":"ca","label":"California"}]}]'
></el-dm-cascader>

Via JavaScript

interface CascaderOption {
  value: string;              // Unique value
  label: string;              // Display text
  disabled?: boolean;         // Disable this option
  children?: CascaderOption[]; // Child options
  leaf?: boolean;             // Force as leaf (no async loading)
}
const cascader = document.querySelector('el-dm-cascader');
cascader.setOptions([
  {
    value: 'usa',
    label: 'United States',
    children: [
      {
        value: 'california',
        label: 'California',
        children: [
          { value: 'sf', label: 'San Francisco' },
          { value: 'la', label: 'Los Angeles' }
        ]
      }
    ]
  }
]);

With Clearable

Clearable Cascader

<el-dm-cascader clearable placeholder="Select and clear..."></el-dm-cascader>

Searchable

Searchable Cascader

<el-dm-cascader searchable clearable placeholder="Search locations..."></el-dm-cascader>

Change on Select

Allow selecting non-leaf nodes:

Change on Select

<el-dm-cascader change-on-select clearable placeholder="Select any level..."></el-dm-cascader>

Hover to Expand

Hover to Expand

<el-dm-cascader expand-trigger="hover" placeholder="Hover to expand..."></el-dm-cascader>

Multiple Selection

Multiple Selection

<el-dm-cascader multiple clearable placeholder="Select multiple paths..."></el-dm-cascader>

Async Loading

For large datasets, load children dynamically:

const cascader = document.querySelector('el-dm-cascader');

// Set initial options
cascader.setOptions([
  { value: 'category1', label: 'Category 1', leaf: false },
  { value: 'category2', label: 'Category 2', leaf: false }
]);

// Set async loader
cascader.setLoadData(async (option) => {
  // Simulate API call
  await new Promise(resolve => setTimeout(resolve, 500));

  return [
    { value: `${option.value}-sub1`, label: `${option.label} - Sub 1` },
    { value: `${option.value}-sub2`, label: `${option.label} - Sub 2` }
  ];
});

Note: searchable cannot be used with async loading since the full tree is not available for searching.

Custom Separator

Custom Separator

<el-dm-cascader separator=" > " placeholder="Custom separator..."></el-dm-cascader>

Show Only Leaf Label

Show Only Leaf Label

<el-dm-cascader show-all-levels="false" placeholder="Shows only last level..."></el-dm-cascader>

Sizes

Cascader Sizes

<el-dm-cascader size="sm" placeholder="Small..."></el-dm-cascader>
<el-dm-cascader size="md" placeholder="Medium..."></el-dm-cascader>
<el-dm-cascader size="lg" placeholder="Large..."></el-dm-cascader>

Disabled

Disabled

<el-dm-cascader disabled placeholder="Disabled..."></el-dm-cascader>

Events

EventDescription
changeFired when selection changes
expandFired when a panel expands
searchFired when search text changes

Event Handling

const cascader = document.querySelector('el-dm-cascader');

cascader.addEventListener('change', (event) => {
  console.log('Selected path:', event.detail.value);
  console.log('Selected options:', event.detail.selectedOptions);
  console.log('Path array:', event.detail.path);
});

cascader.addEventListener('expand', (event) => {
  console.log('Expanded option:', event.detail.option);
  console.log('Level:', event.detail.level);
});

Keyboard Navigation

  • Arrow Down/Up: Navigate within panel
  • Arrow Right: Expand to next panel
  • Arrow Left: Go back to previous panel
  • Enter: Select current option
  • Escape: Close dropdown
  • Backspace: Remove last tag (in multiple mode)

Accessibility

  • Uses role="combobox" with proper ARIA attributes
  • aria-expanded indicates dropdown state
  • Panel options have role="option" with aria-selected
  • Loading states announced via aria-busy
  • Full keyboard navigation support