Cascader
Boîte de sélection en cascade pour les données hiérarchiques comme les emplacements ou les catégories.
import { Cascader } from 'asterui'Exemples
Section intitulée « Exemples »Basique
Sélection hiérarchique simple.
Select location
import { Cascader } from 'asterui'
function App() {
const options = [
{
value: 'usa',
label: 'United States',
children: [
{
value: 'ca',
label: 'California',
children: [
{ value: 'sf', label: 'San Francisco' },
{ value: 'la', label: 'Los Angeles' },
],
},
{
value: 'ny',
label: 'New York',
children: [
{ value: 'nyc', label: 'New York City' },
{ value: 'buf', label: 'Buffalo' },
],
},
],
},
]
return (
<Cascader options={options} placeholder="Select location" />
)
}
export default App Expansion au survol
Développer les sous-menus au survol.
Select category
import { Cascader } from 'asterui'
function App() {
const options = [
{
value: 'electronics',
label: 'Electronics',
children: [
{
value: 'phones',
label: 'Phones',
children: [
{ value: 'iphone', label: 'iPhone' },
{ value: 'android', label: 'Android' },
],
},
{
value: 'computers',
label: 'Computers',
children: [
{ value: 'laptop', label: 'Laptop' },
{ value: 'desktop', label: 'Desktop' },
],
},
],
},
]
return (
<Cascader options={options} expandTrigger="hover" placeholder="Select category" />
)
}
export default App Tailles
Différentes tailles de cascader.
Extra small
Small
Medium
Large
import { Cascader } from 'asterui'
function App() {
const options = [
{ value: 'opt1', label: 'Option 1' },
{ value: 'opt2', label: 'Option 2' },
]
return (
<div className="flex flex-col gap-2">
<Cascader size="xs" options={options} placeholder="Extra small" />
<Cascader size="sm" options={options} placeholder="Small" />
<Cascader size="md" options={options} placeholder="Medium" />
<Cascader size="lg" options={options} placeholder="Large" />
</div>
)
}
export default App Désactivé
État désactivé du cascader.
Option 1
import { Cascader } from 'asterui'
function App() {
const options = [
{ value: 'opt1', label: 'Option 1' },
{ value: 'opt2', label: 'Option 2' },
]
return (
<Cascader options={options} disabled value={['opt1']} />
)
}
export default App Recherche
Activer la fonctionnalité de recherche/filtre.
Search locations
import { Cascader } from 'asterui'
function App() {
const options = [
{
value: 'usa',
label: 'United States',
children: [
{
value: 'ca',
label: 'California',
children: [
{ value: 'sf', label: 'San Francisco' },
{ value: 'la', label: 'Los Angeles' },
],
},
],
},
]
return (
<Cascader options={options} showSearch placeholder="Search locations" />
)
}
export default App Changement à la sélection
Autoriser la sélection de n'importe quel niveau, pas seulement les nœuds feuilles.
Select any level
Selected: None
import { Cascader } from 'asterui'
import { useState } from 'react'
function App() {
const [value, setValue] = useState<string[]>([])
const options = [
{
value: 'usa',
label: 'United States',
children: [
{ value: 'ca', label: 'California' },
{ value: 'ny', label: 'New York' },
],
},
]
return (
<div>
<Cascader
options={options}
changeOnSelect
value={value}
onChange={setValue}
placeholder="Select any level"
/>
<p className="mt-2 text-sm">Selected: {value.join(' / ') || 'None'}</p>
</div>
)
}
export default App Chargement asynchrone
Charger les options dynamiquement lors de l'expansion.
Load on expand
import { Cascader } from 'asterui'
import { useState } from 'react'
function App() {
const [options, setOptions] = useState<CascaderOption[]>([
{ value: 'region1', label: 'Region 1' },
{ value: 'region2', label: 'Region 2' },
])
const loadData = async (selectedOptions: CascaderOption[]) => {
const targetOption = selectedOptions[selectedOptions.length - 1]
await new Promise(resolve => setTimeout(resolve, 1000))
setOptions(prev => {
const update = (opts: CascaderOption[]): CascaderOption[] =>
opts.map(opt =>
opt.value === targetOption.value
? {
...opt,
children: [
{ value: `${opt.value}-1`, label: 'Child 1', isLeaf: true },
{ value: `${opt.value}-2`, label: 'Child 2', isLeaf: true },
],
}
: { ...opt, children: opt.children ? update(opt.children) : undefined }
)
return update(prev)
})
}
return (
<Cascader options={options} loadData={loadData} placeholder="Load on expand" />
)
}
export default App État de validation
Afficher l'état de validation d'erreur ou d'avertissement.
Error state
Warning state
import { Cascader } from 'asterui'
function App() {
const options = [
{ value: 'opt1', label: 'Option 1' },
{ value: 'opt2', label: 'Option 2' },
]
return (
<div className="flex flex-col gap-2">
<Cascader options={options} status="error" placeholder="Error state" />
<Cascader options={options} status="warning" placeholder="Warning state" />
</div>
)
}
export default App Sélection multiple
Sélectionner plusieurs valeurs feuilles.
Select multiple
import { Cascader } from 'asterui'
function App() {
const options = [
{
value: 'fruits',
label: 'Fruits',
children: [
{ value: 'apple', label: 'Apple' },
{ value: 'banana', label: 'Banana' },
],
},
{
value: 'vegetables',
label: 'Vegetables',
children: [
{ value: 'carrot', label: 'Carrot' },
{ value: 'lettuce', label: 'Lettuce' },
],
},
]
return (
<Cascader options={options} multiple placeholder="Select multiple" />
)
}
export default App Cascader
Section intitulée « Cascader »| Propriété | Description | Type | Défaut |
|---|---|---|---|
options | Données d’options hiérarchiques | CascaderOption[] | [] |
value | Chemin de valeur sélectionnée contrôlée | string[] | - |
defaultValue | Valeur sélectionnée par défaut (non contrôlée) | string[] | [] |
onChange | Callback lors du changement de sélection | (value: string[], selectedOptions: CascaderOption[]) => void | - |
placeholder | Texte de l’espace réservé d’entrée | string | 'Please select' |
disabled | Désactiver le cascader | boolean | false |
allowClear | Afficher le bouton d’effacement | boolean | true |
expandTrigger | Comment développer les sous-menus | 'click' | 'hover' | 'click' |
changeOnSelect | Autoriser la sélection de n’importe quel niveau, pas seulement les feuilles | boolean | false |
displayRender | Fonction de rendu d’affichage personnalisée | (labels: ReactNode[], selectedOptions: CascaderOption[]) => ReactNode | - |
size | Taille d’entrée | 'xs' | 'sm' | 'md' | 'lg' | 'md' |
color | Couleur de l’anneau de focus | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | - |
status | État de validation | 'error' | 'warning' | - |
showSearch | Activer la fonctionnalité de recherche | boolean | { filter?, render?, matchInputWidth? } | false |
notFoundContent | Contenu lorsqu’aucun résultat de recherche | ReactNode | 'No results found' |
loadData | Fonction de chargement de données asynchrone | (selectedOptions: CascaderOption[]) => Promise<void> | - |
fieldNames | Noms de champs personnalisés pour le mappage de données | { label?: string; value?: string; children?: string } | - |
open | État d’ouverture contrôlée du menu déroulant | boolean | - |
onDropdownVisibleChange | Callback lors du changement de visibilité du menu déroulant | (open: boolean) => void | - |
popupClassName | Nom de classe pour le menu déroulant | string | - |
dropdownRender | Rendu d’enveloppe de menu déroulant personnalisé | (menu: ReactNode) => ReactNode | - |
multiple | Activer le mode de sélection multiple | boolean | false |
maxTagCount | Nombre maximum d’étiquettes à afficher en mode multiple | number | 'responsive' | - |
className | Classes CSS supplémentaires | string | - |
CascaderOption
Section intitulée « CascaderOption »| Propriété | Description | Type | Défaut |
|---|---|---|---|
value | Identifiant unique | string | - |
label | Libellé d’affichage | ReactNode | - |
children | Options enfants | CascaderOption[] | - |
disabled | Désactiver cette option | boolean | false |
isLeaf | Forcer comme nœud feuille (pas d’expansion, pas de chargement asynchrone) | boolean | - |
Accessibilité
Section intitulée « Accessibilité »Le composant Cascader suit le modèle de combobox WAI-ARIA :
- Utilise
role="combobox"sur le déclencheur avecaria-expanded,aria-haspopup aria-activedescendantsuit l’option focalisée pour les lecteurs d’écranaria-selectedindique l’état sélectionné sur les optionsaria-disabledindique l’état désactivé- Le bouton d’effacement a
aria-label="Clear selection"
Navigation au clavier
Section intitulée « Navigation au clavier »| Touche | Action |
|---|---|
| Bas | Ouvrir le menu déroulant ou passer à l’option suivante |
| Haut | Passer à l’option précédente |
| Droite | Passer à la colonne suivante (développer) |
| Gauche | Passer à la colonne précédente |
| Entrée | Sélectionner l’option focalisée ou ouvrir le menu déroulant |
| Espace | Basculer le menu déroulant (lorsque non en recherche) |
| Échap | Fermer le menu déroulant |
| Début | Passer à la première option |
| Fin | Passer à la dernière option |
Le composant inclut des attributs de données pour les tests :
data-testid="cascader"sur le conteneur racinedata-testid="cascader-dropdown"sur le menu déroulantdata-testid="cascader-option-{value}"sur chaque optiondata-testid="cascader-clear"sur le bouton d’effacementdata-state="open|closed"sur la racine indique l’état du menu déroulantdata-state="selected|hovered"sur les options indique l’étatdata-value="{value}"sur les options fournit la valeur