Guides approfondis
Angular Aria

Menu

Vue d'ensemble

Un menu propose une liste d'actions ou d'options aux utilisateurs et apparaît généralement en réponse à un clic sur un bouton ou à un clic droit. Les menus prennent en charge la navigation au clavier avec les touches fléchées, les sous-menus, les cases à cocher, les boutons radio et les éléments désactivés.

Utilisation

Les menus conviennent bien pour présenter des listes d'actions ou de commandes parmi lesquelles les utilisateurs peuvent choisir.

Utilisez un menu pour :

  • Construire des menus de commandes d'application (Fichier, Édition, Affichage)
  • Créer des menus contextuels (actions au clic droit)
  • Afficher des listes d'actions déroulantes
  • Implémenter des listes déroulantes dans une toolbar
  • Organiser des paramètres ou des options

Évitez les menus pour :

  • Construire la navigation d'un site (utilisez plutôt des landmarks de navigation)
  • Créer des listes de sélection dans un formulaire (utilisez le composant Select)
  • Basculer entre des panneaux de contenu (utilisez des tabs)
  • Afficher du contenu repliable (utilisez un accordion)

Fonctionnalités

  • Navigation au clavier - Touches fléchées, Home/End et recherche par caractère pour une navigation efficace
  • Sous-menus - Prise en charge des menus imbriqués avec positionnement automatique
  • Types de menus - Menus standalone, menus avec déclencheur et menubars
  • Cases à cocher et boutons radio - Éléments de menu à bascule et de sélection
  • Éléments désactivés - États désactivés souples ou stricts avec gestion du focus
  • Fermeture automatique - Fermeture configurable lors de la sélection
  • Prise en charge du RTL - Navigation pour les langues de droite à gauche

Exemples

Créez un menu déroulant en associant un bouton déclencheur à un menu. Le déclencheur ouvre et ferme le menu.

Le menu se ferme automatiquement lorsque l'utilisateur sélectionne un élément ou appuie sur Échap.

Menu contextuel

Les menus contextuels apparaissent à la position du curseur lorsque les utilisateurs font un clic droit sur un élément.

Positionnez le menu à l'aide des coordonnées de l'événement contextmenu.

Menu standalone

Un menu standalone ne nécessite pas de déclencheur et reste visible dans l'interface.

Les menus standalone conviennent bien aux listes d'actions ou à une navigation toujours visibles.

Éléments de menu désactivés

Désactivez des éléments de menu spécifiques avec l'input disabled. Contrôlez le comportement du focus avec softDisabled.

Avec [softDisabled]="true", les éléments désactivés peuvent recevoir le focus mais ne peuvent pas être activés. Avec [softDisabled]="false", les éléments désactivés sont ignorés pendant la navigation au clavier.

Tests

Angular Aria fournit des harnais de composant pour tester les composants menu. 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 {MenuHarness, MenuItemHarness} from '@angular/aria/menu/testing';
import {MyMenuComponent} from './my-menu'; // Your component

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

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

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

  it('should open menu and click item', async () => {
    // Load the menu harness by its trigger text
    const menu = await loader.getHarness(MenuHarness.with({triggerText: 'Open Menu'}));

    // Verify initial state
    expect(await menu.isOpen()).toBe(false);

    // Open the menu
    await menu.open();
    expect(await menu.isOpen()).toBe(true);

    // Get items
    const items = await menu.getItems();
    expect(items.length).toBe(3);
    expect(await items[0].getText()).toBe('Item 1');

    // Click first item
    await items[0].click();

    // Menu should close after selection (depending on your implementation)
    expect(await menu.isOpen()).toBe(false);
  });

  it('should interact with submenus', async () => {
    const menu = await loader.getHarness(MenuHarness.with({triggerText: 'Open Menu'}));
    await menu.open();

    // Get the item that triggers a submenu
    const subItem = await loader.getHarness(MenuItemHarness.with({text: 'Submenu'}));
    expect(await subItem.hasSubmenu()).toBe(true);

    // Open submenu
    await subItem.click();
    const submenu = await subItem.getSubmenu();
    expect(submenu).toBeTruthy();
    expect(await submenu!.isOpen()).toBe(true);

    // Interact with submenu items
    const subItems = await submenu!.getItems();
    expect(subItems.length).toBe(1);
  });
});

Référence de l'API

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