From c168959e12357e5eff19f50fd7852dfb1360c253 Mon Sep 17 00:00:00 2001 From: mathieu Date: Sat, 22 Aug 2026 01:39:28 +0200 Subject: [PATCH] =?UTF-8?q?Fait=20dire=20aux=20boutons=20repliables=20s'il?= =?UTF-8?q?s=20sont=20ouverts=20ou=20ferm=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit « aria-expanded="@_ouvert" » ne rend pas « true » ou « false » : Blazor y voit un attribut de présence, comme disabled. Vrai donnait aria-expanded="", faux retirait l'attribut — dans les deux cas, un lecteur d'écran n'apprenait rien, et un bouton replié ne s'annonçait plus comme repliable. Le défaut valait pour les six boutons de l'application. Une fonction nommée remplace le booléen nu, qui se relisait comme correct. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 18 ++++++++++----- MaBibli.Client/Composants/ArbreSerie.razor | 2 +- .../Composants/GroupeCatalogue.razor | 5 ++--- MaBibli.Client/Layout/MainLayout.razor | 2 +- MaBibli.Client/Pages/Bibliographie.razor | 4 ++-- MaBibli.Client/Pages/Catalogue.razor | 2 +- MaBibli.Client/Services/Aria.cs | 22 +++++++++++++++++++ MaBibli.Tests/AriaTests.cs | 21 ++++++++++++++++++ 8 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 MaBibli.Client/Services/Aria.cs create mode 100644 MaBibli.Tests/AriaTests.cs diff --git a/CLAUDE.md b/CLAUDE.md index 735aa35..2bd63a5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3353,16 +3353,24 @@ un cran trop haut qu'un catalogue qui ne s'affiche plus. Un test le verrouille. reste un vrai lien vers `/series/{id}`. ⚠️ **`aria-expanded="@Deplie"` ne fait pas ce qu'on croit** : Blazor traite un booléen comme un -attribut de *présence* et rend `aria-expanded=""`, que les lecteurs d'écran ne savent pas lire. -L'état doit être écrit en toutes lettres (`@(Deplie ? "true" : "false")`). Constaté ici, mesuré -dans le navigateur — **le même défaut subsiste ailleurs** (`ArbreSerie`, le bouton « Filtrer » du -catalogue), non corrigé faute d'être dans la demande. +attribut de *présence*, à la manière de `disabled` — vrai rend `aria-expanded=""`, faux **retire +l'attribut**. Or ARIA attend les chaînes « true » et « false », et un lecteur d'écran ne sait lire +aucune des deux formes produites : replié, le bouton ne s'annonce plus comme repliable du tout. + +Le défaut était passé inaperçu **six fois** — il ne se voit pas à l'écran, et aucun test ne rend +de balisage. `Services/Aria.cs` porte donc la mise en garde et la conversion +(`aria-expanded="@Aria.Etat(_ouvert)"`), appliquée partout : bascule du menu, bouton « Filtrer » +du catalogue et de la bibliographie, dépli d'une œuvre bibliographique, arbre des séries, blocs +du catalogue. ⚠️ **Une fonction plutôt qu'un ternaire recopié** : un booléen nu se lit comme +correct à la relecture, un appel nommé se remarque quand il manque. + +Vérifié en exécution sur les six : « false » à l'état replié, « true » une fois ouvert. **Vérifié en exécution** (375 px puis 320 px) : le cycle *La Légende de Drizzt* coiffe ses deux sous-séries, chaque niveau se replie et se déplie indépendamment, l'état d'un sous-niveau survit au repli de son cycle, le compteur reste « 6 livres » dans tous les cas, le repli survit à une recherche (« salvatore ») et à son effacement, le nom mène toujours à `/series/6`, aucun -débordement horizontal (`scrollWidth` = 320) et aucune erreur de console. 627 tests au vert. +débordement horizontal (`scrollWidth` = 320) et aucune erreur de console. 628 tests au vert. **Vérifié en exécution** (320 px puis 1280 px, base de développement garnie de trois tomes et d'un livre hors série) : blocs « L'Elfe noir » (2 tomes, dans l'ordre de **lecture** — l'inverse diff --git a/MaBibli.Client/Composants/ArbreSerie.razor b/MaBibli.Client/Composants/ArbreSerie.razor index 7ea119f..0292e7e 100644 --- a/MaBibli.Client/Composants/ArbreSerie.razor +++ b/MaBibli.Client/Composants/ArbreSerie.razor @@ -16,7 +16,7 @@
@if (Enfants.Count > 0) { - diff --git a/MaBibli.Client/Pages/Bibliographie.razor b/MaBibli.Client/Pages/Bibliographie.razor index d547494..23f405d 100644 --- a/MaBibli.Client/Pages/Bibliographie.razor +++ b/MaBibli.Client/Pages/Bibliographie.razor @@ -165,7 +165,7 @@ else if (_bibliographie is { } biblio)
@@ -302,7 +302,7 @@ else if (_bibliographie is { } biblio) { } diff --git a/MaBibli.Client/Pages/Catalogue.razor b/MaBibli.Client/Pages/Catalogue.razor index 9b06c12..74340e8 100644 --- a/MaBibli.Client/Pages/Catalogue.razor +++ b/MaBibli.Client/Pages/Catalogue.razor @@ -15,7 +15,7 @@

Catalogue

diff --git a/MaBibli.Client/Services/Aria.cs b/MaBibli.Client/Services/Aria.cs new file mode 100644 index 0000000..b4a7132 --- /dev/null +++ b/MaBibli.Client/Services/Aria.cs @@ -0,0 +1,22 @@ +namespace MaBibli.Client.Services; + +/// +/// Les états ARIA, écrits en toutes lettres. +/// +/// +/// ⚠️ aria-expanded="@_ouvert" ne fait pas ce qu'on croit. Blazor traite un booléen +/// comme un attribut de présence — à la manière de disabled ou hidden : vrai +/// rend aria-expanded="", faux retire l'attribut. Or ARIA attend les chaînes +/// « true » et « false », et un lecteur d'écran ne sait lire ni l'une ni l'autre de ces deux +/// formes : replié, le bouton ne s'annonce plus comme repliable du tout. +/// +/// Le défaut est passé inaperçu cinq fois (2026-08-22) parce qu'il ne se voit pas à l'écran et +/// qu'aucun test ne rend de balisage. D'où cette fonction : elle se remarque à la relecture là +/// où un booléen nu se lit comme correct. +/// +/// +public static class Aria +{ + /// « true » ou « false », jamais un attribut de présence. + public static string Etat(bool valeur) => valeur ? "true" : "false"; +} diff --git a/MaBibli.Tests/AriaTests.cs b/MaBibli.Tests/AriaTests.cs new file mode 100644 index 0000000..f3caa6e --- /dev/null +++ b/MaBibli.Tests/AriaTests.cs @@ -0,0 +1,21 @@ +using MaBibli.Client.Services; + +namespace MaBibli.Tests; + +/// +/// L'état ARIA s'écrit en toutes lettres (2026-08-22). +/// +/// +/// ⚠️ Ce que ce test verrouille n'est pas la fonction — elle tient en une ligne — mais le +/// contrat : « false » est une valeur, et non l'absence d'attribut. C'est exactement ce +/// que Blazor faisait à sa place, et ce qui rendait un bouton replié muet aux lecteurs d'écran. +/// +public class AriaTests +{ + [Fact] + public void L_etat_est_toujours_une_chaine() + { + Assert.Equal("true", Aria.Etat(true)); + Assert.Equal("false", Aria.Etat(false)); + } +}