Menu
À quoi il sert
Menu ouvre une liste d’actions depuis un bouton, selon le motif APG Menu Button. Il ne sert pas à la navigation du site.
Quand l’utiliser
- Regrouper des actions sur un objet : copier, renommer, supprimer.
- Fermer le menu après le choix d’une entrée : le composant le fait.
Quand ne pas l’utiliser
- Pour la navigation du site : une liste de liens dans nav suffit et se lit mieux.
- Pour un choix de formulaire : utiliser un champ select ou des boutons radio.
- Pour une seule action : un bouton simple suffit.
Exemples
<Menu
id="actions"
label="Actions"
items={[
{ label: 'Copier le lien', action: 'copy-link' },
{ label: 'Ouvrir le dépôt', href: '/depot' },
{ label: 'Supprimer', action: 'delete', disabled: true },
]}
/>Accessibilité
Clavier
- Entrée, Espace et Flèche bas ouvrent le menu et placent le focus sur la première entrée.
- Flèche haut ouvre le menu et place le focus sur la dernière entrée.
- Les flèches haut et bas bouclent ; Début et Fin vont aux extrémités.
- Une lettre tapée va à la première entrée dont le libellé commence par elle.
- Échap ferme le menu et rend le focus au bouton ; Tab ferme le menu.
Lecteur d’écran
- Le bouton annonce aria-haspopup="menu" et son état aria-expanded (APG Menu Button).
- Le panneau a role="menu", nommé par le bouton ; chaque entrée a role="menuitem".
- Une entrée désactivée porte aria-disabled="true" et reste focalisable, comme l’APG le recommande.
Garanti par le composant
- Sans JavaScript, le bouton ouvre le panneau (popover) et les liens fonctionnent.
- Le bouton et les entrées font au moins la taille du jeton --pp-size-target-min (WCAG 2.5.8).
- Le focus est visible sur le bouton et les entrées (WCAG 2.4.7). Le texte garde la couleur de premier plan.
- Une entrée désactivée est aussi barrée : la couleur n’est pas seule (WCAG 1.4.1).
À la charge de l’intégrateur
- Fournir un id unique par menu et un libellé de bouton explicite.
- Écouter l’évènement pp-menu-action (detail.action) sur le panneau pour les entrées à action.
- Non testé avec VoiceOver, NVDA ou JAWS : à vérifier sur les cibles du site.
- Le repli de position sans ancrage CSS suppose une écriture de gauche à droite : non vérifié en RTL.
Propriétés
| Propriété | Type | Défaut | Description |
|---|---|---|---|
| label (obligatoire) | string | — | Texte du bouton, qui sert aussi de nom accessible au menu. |
| id (obligatoire) | string | — | Identifiant du panneau ; le bouton a pour id `<id>-button`. Unique dans la page. |
| items (obligatoire) | Item[] | — | Entrées du menu, dans l'ordre d'affichage. |
| class | string | — | Réservé au placement du composant dans son parent. |
Jetons utilisés
--pp-color-accent--pp-color-bg--pp-color-fg--pp-color-focus--pp-color-line--pp-color-muted--pp-color-surface--pp-radius-control--pp-radius-surface--pp-size-focus-offset--pp-size-focus-width--pp-size-rule--pp-size-target-min--pp-space-2xs--pp-space-3xs--pp-space-s
Preuves et décisions
- APG : motif Menu Button
- WCAG 2.1.1 Clavier
- WCAG 2.5.8 Taille de la cible (minimum)
- Tests : packages/astro/test/Menu.test.ts, menu.behavior.test.ts