Guides approfondis
Angular Aria

Tree

Vue d'ensemble

Un tree affiche des données hiérarchiques dont les éléments peuvent se déplier pour révéler leurs enfants ou se replier pour les masquer. Les utilisateurs naviguent avec les touches fléchées, déplient et replient les nœuds et, éventuellement, sélectionnent des éléments dans des scénarios de navigation ou de sélection de données.

Utilisation

Les trees conviennent bien pour afficher des données hiérarchiques dans lesquelles les utilisateurs doivent parcourir des structures imbriquées.

Utilisez des trees lorsque vous :

  • Construisez une navigation dans un système de fichiers
  • Affichez des hiérarchies de dossiers et de documents
  • Créez des structures de menus imbriqués
  • Affichez des organigrammes
  • Parcourez des données hiérarchiques
  • Implémentez une navigation de site avec des sections imbriquées

Évitez les trees lorsque vous :

  • Affichez des listes plates (utilisez plutôt Listbox)
  • Affichez des tableaux de données (utilisez plutôt Grid)
  • Créez des listes déroulantes simples (utilisez plutôt Select)
  • Construisez un fil d'Ariane (utilisez des patterns breadcrumb)

Fonctionnalités

  • Navigation hiérarchique - Structure arborescente imbriquée, avec dépliage et repliage
  • Modes de sélection - Sélection unique ou multiple, avec un comportement explicite ou qui suit le focus
  • La sélection suit le focus - Sélection automatique facultative lorsque le focus change
  • Navigation au clavier - Touches fléchées, Début, Fin et recherche par saisie (type-ahead)
  • Déplier/replier - Flèches Droite/Gauche ou Entrée pour basculer les nœuds parents
  • Éléments désactivés - Désactivez des nœuds spécifiques avec gestion du focus
  • Modes de focus - Stratégies de focus roving tabindex ou activedescendant
  • Prise en charge RTL - Navigation pour les langues de droite à gauche

Exemples

Utilisez un tree pour la navigation lorsque le clic sur les éléments déclenche des actions plutôt que de les sélectionner.

Définissez [nav]="true" pour activer le mode navigation. Celui-ci utilise aria-current pour indiquer la page courante au lieu de la sélection.

Sélection unique

Activez la sélection unique pour les scénarios où les utilisateurs choisissent un seul élément du tree.

Laissez [multi]="false" (la valeur par défaut) pour une sélection unique. Les utilisateurs appuient sur Espace pour sélectionner l'élément qui a le focus.

Sélection multiple

Permettez aux utilisateurs de sélectionner plusieurs éléments du tree.

Définissez [multi]="true" sur le tree. Les utilisateurs sélectionnent les éléments un par un avec Espace, ou des plages avec Maj+touches fléchées.

La sélection suit le focus

Lorsque la sélection suit le focus, l'élément qui a le focus est automatiquement sélectionné. Cela simplifie l'interaction dans les scénarios de navigation.

Définissez [selectionMode]="'follow'" sur le tree. La sélection se met à jour automatiquement à mesure que les utilisateurs naviguent avec les touches fléchées.

Éléments de tree désactivés

Désactivez des nœuds spécifiques du tree pour empêcher toute interaction. Vous contrôlez si les éléments désactivés peuvent recevoir le focus.

Lorsque [softDisabled]="true" est défini sur le tree, les éléments désactivés peuvent recevoir le focus mais ne peuvent être ni activés ni sélectionnés. Lorsque [softDisabled]="false", les éléments désactivés sont ignorés lors de la navigation au clavier.

Tests

Angular Aria fournit des harnais de composant pour tester les composants de tree. Voici un exemple d'utilisation des harnais dans un test de composant :

import {ComponentFixture, TestBed} from '@angular/core/testing';
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {TreeHarness} from '@angular/aria/tree/testing';
import {MyTreeComponent} from './my-tree'; // Your component

describe('MyTreeComponent', () => {
  let fixture: ComponentFixture<MyTreeComponent>;
  let loader: HarnessLoader;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [MyTreeComponent],
    });

    fixture = TestBed.createComponent(MyTreeComponent);
    await fixture.whenStable();
    loader = TestbedHarnessEnvironment.loader(fixture);
  });

  it('should navigate and expand tree items', async () => {
    const tree = await loader.getHarness(TreeHarness);

    // Get top-level structure representation
    expect(await tree.getTreeStructure()).toEqual({
      children: [{text: 'public'}, {text: 'src'}, {text: 'package.json'}],
    });

    // Get all items (currently visible)
    const items = await tree.getItems();
    expect(items.length).toBe(3);

    // Expand the first item ('public')
    expect(await items[0].isExpanded()).toBe(false);
    await items[0].click();
    expect(await items[0].isExpanded()).toBe(true);

    // Verifying tree structure updates after expansion
    expect(await tree.getTreeStructure()).toEqual({
      children: [
        {
          text: 'public',
          children: [{text: 'index.html'}, {text: 'styles.css'}],
        },
        {text: 'src'},
        {text: 'package.json'},
      ],
    });
  });
});

Référence de l'API

Pour une documentation détaillée de l'API, consultez les références d'API suivantes :