fix(my-space): rendre explicites les intitulés des CTA du panneau (RGAA 6.1.1) — #4137 - #4670
Conversation
…AA 6.1.1) Complète le nom accessible des CTA start/continuer/lecture-seule via des spans fr-sr-only, sans changer le texte visible imposé par le Figma.
Audit d'accessibilité ultra11y — RGAA✅ Aucune non-conformité relevée par le moteur statique.
Rapport complet (HTML, captures annotées) : artefact ultra11y-pr-static du run. |
There was a problem hiding this comment.
Revi — aucun problème détecté dans le périmètre revu.
Écarts au ticket
- #4137: covered. The start variant and all four 'Continuer' variants (plus lockedByOther) get an fr-sr-only accessible-name suffix and the Figma visible label is unchanged. The anchored assertions were redesigned to check visible text and exact accessible name separately. aria-describedby was re-assessed and kept for the campaign year. The ref comes from the PR title/body and branch name, because GitHub reports no closingIssuesReferences for PR 4670.
Détails du run IA · Iterion
Run : 01a0f126-196e-7a44-88f9-a4b07bd3f82c
Tokens du run au moment de publier : 33 263.
Périmètre revu : correctness: packages/app/src/modules/my-space/DeclarationProcessPanel.tsx — CtaLabel / getCtaAccessibleSuffix for all 6 variants plus lockedByOther; accessible name built from separate ' ' text node + fr-sr-only span (dom-accessibility-api trimming and browser block-boundary spacing both give 'Commencer la déclaration'); visible label unchanged in the inline-flex .fr-btn (trailing space collapses, sr-only span is out of flow) ; accessibility (RGAA 6.1.1 / 6.1.5, WCAG 2.5.3): packages/app/src/modules/my-space/DeclarationProcessPanel.tsx — visible label is a contiguous prefix of every new accessible name; closed variant unchanged; aria-describedby kept ; rendering/hydration: packages/app/src/modules/my-space/DeclarationProcessPanel.tsx — SSR/client text-node output identical, no hydration mismatch ; maintainability/project rules: packages/app/src/modules/my-space/DeclarationProcessPanel.tsx — the added one-line comments are the non-obvious WHY that code-quality.md explicitly allows ; tests: packages/app/src/modules/my-space/tests/DeclarationProcessPanel.test.tsx — visibleText helper, exact getByRole name assertions, describe.each over 4 'Continuer' variants, lockedByOther and closed coverage; PanelVariant type import present ; regression blast radius: src/e2e/** and src/modules/** — no Playwright/testing-library locator, toHaveText or snapshot depends on the old exact CTA names (declaration-representation.e2e.ts 'Commencer' targets the separate representation panel; the 'Voir la déclaration' locators are unchanged) ; requirements: issue #4137 against the diff
Revue mono (single model family).
| Étape | Modèle | Harness | Effort demandé | Tokens |
|---|---|---|---|---|
| Revue Claude | claude-opus-5-5 | claude_code | high | 32 374 |
| Synthèse · Claude | claude-opus-5-5 | claude_code | medium | 889 |
Tokens cumulés des appels IA, pas la taille du contexte. L’effort indiqué est le réglage demandé au modèle.
🧪 Recette E2E — grille 185 coordonnées
➡️ Grille complète dans le résumé du run · Rapport Playwright et traces |
|
|
||
| // jsdom applies no real stylesheet, so an `fr-sr-only` span stays part of `textContent`; strip it to isolate the visible label from its accessible-name suffix. | ||
| function visibleText(element: Element): string { | ||
| const clone = element.cloneNode(true) as Element; | ||
| for (const hidden of clone.querySelectorAll(".fr-sr-only")) { | ||
| hidden.remove(); | ||
| } | ||
| return (clone.textContent ?? "").replace(/\s+/g, " ").trim(); | ||
| } |
There was a problem hiding this comment.
C'est un peu bizarre ça, on a pas une autre approche plus simple ? Le probleme il vient du fr-sr-only ?
|
🎉 Deployment for commit 5098143 : Ingresses
Docker images
|
Viczei
left a comment
There was a problem hiding this comment.
Avis favorable sur le commit revu. Les compléments masqués précisent les noms accessibles des CTA, y compris en lecture seule, tout en conservant les libellés visibles et les destinations. Les variantes sont couvertes par les tests. Aucun défaut bloquant identifié dans ce périmètre.
|
🎉 This PR is included in version 4.0.0-alpha.5 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Closes #4137
Résumé
Les CTA du panneau latéral de démarche (
DeclarationProcessPanel) portaient des intitulés visibles génériques (« Commencer », « Continuer », « Consulter en lecture seule ») qui ne permettent pas, lus isolément, de comprendre leur fonction et leur destination (RGAA 6.1.1).aria-describedby(ajouté par #3520) reste un gain UX mais ne referme pas le critère : le glossaire RGAA définit le « contexte du lien » comme une liste fermée qui n'inclut pasaria-describedby.Le correctif complète le nom accessible (pas le contexte) via des
<span className="fr-sr-only">, sans changer le texte visible imposé par le Figma :startcompliance_choice/compliance/evaluation/cselockedByOtherclosedaria-describedby={PANEL_TITLE_ID}est conservé (apporte l'année de campagne, absente du nom accessible).Point d'attention corrigé en cours de revue
Le premier jet plaçait le span masqué au milieu du libellé
lockedByOther(« Consulter [masqué] en lecture seule »), ce qui cassait WCAG 2.5.3 Label in Name : le texte visible n'était plus une sous-chaîne contiguë du nom accessible (un utilisateur de commande vocale disant « clique sur Consulter en lecture seule » n'aurait pas pu matcher l'élément). Trouvé par le gatergaa-auditor, corrigé en déplaçant le span en fin de libellé (nom accessible : « Consulter en lecture seule la démarche des indicateurs de rémunération »).Tests
toHaveTextContent(/^Commencer$/), cassées par l'ajout des spans (jsdom n'applique pas de vraie feuille de style, doncfr-sr-onlyreste danstextContent), remplacées par un helpervisibleText()(isolant le texte visible) et des assertionsgetByRole("link", { hidden: true, name: ... })sur le nom accessible exact.lockedByOther) et declosed.pnpm typecheck,pnpm lint:check,pnpm test(515 fichiers, 7134 tests).Test plan
pnpm typecheckpnpm lint:check/pnpm check:writepnpm test(suite complète)rgaa-auditor(skill ultra11yreview-a11y) — PASS après correctifstructural-auditor— MINOR non bloquant (fichier de test déjà au-dessus du seuil de 400 lignes avant ce ticket, alourdi de 57 lignes ; pas une régression introduite ici, à envisager pour un futur découpage par variante)functional-validator