Accessibilité
@lh-ui/react partage avec les autres bibliothèques de la famille un même contrat d'accessibilité : balises sémantiques, attributs ARIA et interactions clavier sont tous définis dans @lh-ui/share/core, et chaque plateforme les implémente de manière identique. Cette bibliothèque garantit en outre l'absence des pièges a11y courants de l'écosystème React.
Sémantique et ARIA
LhSwitchrend<div role="switch" aria-checked>au lieu d'une checkbox déguisée visuellementLhSelect: le déclencheur estrole="combobox", le panneau déroulantrole="listbox", les optionsrole="option", et le surlignage clavier est synchronisé viaaria-activedescendantLhDialog:role="dialog" aria-modal, le titre bénéficiant à la fois d'un repliaria-labelet d'une association précise viaaria-labelledbyLhTooltipassocie l'infobulle au déclencheur viaaria-describedbyLhTag, lorsqu'il est cliquable, est promurole="button"et répond à Enter / SpaceLhFormItemrend, en cas d'échec de validation, un message d'erreurrole="alert"et définitaria-invalid
Interaction clavier
| Composant | Touches |
|---|---|
LhButton / LhTag | Enter / Space déclenche le clic |
LhSwitch | Enter / Space bascule l'état |
LhSelect | ArrowUp / ArrowDown surligne les options, Enter sélectionne, Échap referme |
LhDialog | Échap ferme (seule la couche au sommet de la pile répond) |
LhTooltip | Échap ferme |
Lors de la superposition de plusieurs couches, useLhOverlayStack maintient une pile d'ouverture : Échap ne ferme que le sommet de la pile, afin qu'une seule frappe n'emmène pas toutes les couches.
Gestion du focus
LhDialog, à l'ouverture, utiliseuseLhFocusTrappour enfermer le focus dans la boîte de dialogue (Tab / Shift+Tab ne s'en échappe pas) et le restitue au déclencheur à la fermetureLhFormItem, au clic sur le label, place le focus sur le premier élément focalisable de la zone de contenu (focusControl) : le comportement natif d'enveloppement du label n'est pas fiable sur les contrôles composites
Icônes décoratives
LhIcon est decorative par défaut : il émet aria-hidden="true", invisible pour les lecteurs d'écran. Pour véhiculer du sens, passer decorative={false} + ariaLabel :
<LhIcon name="search" decorative={false} ariaLabel="Rechercher" />
Le rendu est alors <svg role="img" aria-label="Rechercher">.
Sécurité en StrictMode
Tous les composants sont sûrs sous React StrictMode : le nettoyage des effects et les remontages sont traités de manière idempotente (inscription / démontage de la pile de couches, contrôle du détenteur du verrou de défilement, libération du focus trap).
Cohérence de la famille
Les comportements d'accessibilité sont consignés dans docs/设计语言基线.md ; ils constituent le contrat unifié des deux lignées (web / native). Chaque plateforme les implémente à partir de la même logique @lh-ui/share/core, avec des attributs ARIA et des sémantiques de touches identiques.