Contexte
Le fil d'Ariane (breadcrumb) est actuellement dupliqué dans 9 fichiers avec ~60 lignes de markup DSFR copié-collé à chaque fois, et deux patterns incohérents coexistent dans le codebase.
État actuel
| Fichier |
Pattern lien |
Page courante |
Home |
SitemapPage.tsx |
<a> |
<a aria-current> |
/ |
CookiesPage.tsx |
<a> |
<a aria-current> |
/ |
LegalNoticePage.tsx |
<a> |
<a aria-current> |
/ |
PrivacyPolicyPage/index.tsx |
<a> |
<a aria-current> |
/ |
AccessibilityPage/index.tsx |
<a> |
<a aria-current> |
/ |
AidePage.tsx |
<a> |
<a aria-current> |
/ |
FaqPage.tsx |
<Link> |
<span aria-current> |
/ |
CompanyBanner.tsx |
<Link> |
<span aria-current> |
/ |
CompanyInfoBanner.tsx |
<Link> |
<span aria-current> |
/mon-espace/mes-entreprises |
Problèmes identifiés
- ~500 lignes de code dupliqué (60 lignes × 9 fichiers)
- Incohérence sémantique : la page courante est parfois un
<a> (lien vers soi-même), parfois un <span> (correct selon DSFR)
- Incohérence technique : mix de
<a> natifs et de <Link> Next.js pour la navigation interne
- Nommage des IDs non standardisé (
breadcrumb-sitemap, breadcrumb-cookies, etc.)
- Maintenance difficile : un changement de structure DSFR devrait être fait à 9 endroits
Spécification
API proposée
type BreadcrumbItem = {
label: string;
href?: string; // absent = page courante
};
type BreadcrumbProps = {
items: BreadcrumbItem[];
id?: string; // auto-généré si absent
};
Exemple d'utilisation
<Breadcrumb
items={[
{ label: "Accueil", href: "/" },
{ label: "Mon espace", href: "/mon-espace/mes-entreprises" },
{ label: "Ma déclaration" },
]}
/>
Règles d'implémentation
- Emplacement :
src/modules/layout/Breadcrumb.tsx (module layout, exporté via barrel)
- Navigation : utiliser
Link de Next.js pour tous les liens internes
- Page courante :
<a> avec aria-current="page" sans href (conformité DSFR)
- Structure HTML : respecter exactement le markup DSFR (documentation)
- ID : auto-généré via
useId() si non fourni
- Accessibilité :
aria-label="vous êtes ici :", aria-expanded, aria-controls
Tests
- Test unitaire du composant avec différentes configurations (1 niveau, 3 niveaux, avec/sans ID custom)
- Vérifier la structure HTML DSFR (
nav > button + div > ol > li)
- Vérifier
aria-current="page" sur le dernier élément
- Vérifier que
Link est utilisé pour les href internes
Tâches
Contexte
Le fil d'Ariane (breadcrumb) est actuellement dupliqué dans 9 fichiers avec ~60 lignes de markup DSFR copié-collé à chaque fois, et deux patterns incohérents coexistent dans le codebase.
État actuel
SitemapPage.tsx<a><a aria-current>/CookiesPage.tsx<a><a aria-current>/LegalNoticePage.tsx<a><a aria-current>/PrivacyPolicyPage/index.tsx<a><a aria-current>/AccessibilityPage/index.tsx<a><a aria-current>/AidePage.tsx<a><a aria-current>/FaqPage.tsx<Link><span aria-current>/CompanyBanner.tsx<Link><span aria-current>/CompanyInfoBanner.tsx<Link><span aria-current>/mon-espace/mes-entreprisesProblèmes identifiés
<a>(lien vers soi-même), parfois un<span>(correct selon DSFR)<a>natifs et de<Link>Next.js pour la navigation internebreadcrumb-sitemap,breadcrumb-cookies, etc.)Spécification
API proposée
Exemple d'utilisation
Règles d'implémentation
src/modules/layout/Breadcrumb.tsx(module layout, exporté via barrel)Linkde Next.js pour tous les liens internes<a>avecaria-current="page"sanshref(conformité DSFR)useId()si non fourniaria-label="vous êtes ici :",aria-expanded,aria-controlsTests
nav > button + div > ol > li)aria-current="page"sur le dernier élémentLinkest utilisé pour les href internesTâches
Breadcrumbdanssrc/modules/layout/src/modules/layout/index.ts