1- import React , { memo , forwardRef , useId } from "react" ;
1+ import React , { memo , forwardRef , useId , ReactNode } from "react" ;
22import { symToStr } from "tsafe/symToStr" ;
3+ import { assert } from "tsafe/assert" ;
4+ import type { Equals } from "tsafe" ;
5+
36import { RegisteredLinkProps , useLink } from "./lib/routing" ;
7+ import { createComponentI18nApi } from "./lib/i18n" ;
48import { fr } from "./lib" ;
59import { cx } from "./lib/tools/cx" ;
610
7- // We make users import dsfr.css, so we don't need to import the scoped CSS
8- // but in the future if we have a complete component coverage it
9- // we could stop requiring users to import the hole CSS and only import on a
10- // per component basis.
1111import "./dsfr/component/breadcrumb/breadcrumb.css" ;
1212
1313export type BreadcrumbProps = {
1414 className ?: string ;
1515 links : BreadcrumbProps . Link [ ] ;
16+ classes ?: Partial < Record < "root" | "button" | "collapse" | "list" | "link" | "text" , string > > ;
1617} ;
1718
1819export namespace BreadcrumbProps {
1920 export type Link = {
20- text : string ;
21+ text : ReactNode ;
2122 linkProps : RegisteredLinkProps ;
2223 isActive ?: boolean ;
2324 } ;
2425}
2526
26- //Longueur et lisibilité : Afin qu’il reste lisible, évitez que le fil d’Ariane soit trop long et passe sur plusieurs lignes.
27- // Si les titres de page de votre site sont longs, nous conseillons de n’afficher que les 4 premiers mots du nom de la page courante et d’indiquer que l’élément est tronqué par l’affichage de “…”
28- const trimText = ( label : string ) => {
29- if ( label && label . split ( " " ) . length > 4 ) {
30- return label . split ( " " ) . slice ( 0 , 4 ) . join ( " " ) + "..." ;
31- }
32- return label ;
33- } ;
34-
3527/** @see <https://react-dsfr-components.etalab.studio/?path=/docs/components-breadcrumb> */
3628export const Breadcrumb = memo (
3729 forwardRef < HTMLDivElement , BreadcrumbProps > ( ( props , ref ) => {
38- const { links, className, ...rest } = props ;
30+ const { links, className, classes = { } , ...rest } = props ;
31+
32+ assert < Equals < keyof typeof rest , never > > ( ) ;
33+
34+ const { t } = useTranslation ( ) ;
3935
4036 const { Link } = useLink ( ) ;
4137 const breadcrumbId = useId ( ) ;
38+
4239 return (
4340 < nav
4441 ref = { ref }
4542 role = "navigation"
46- className = { cx ( fr . cx ( "fr-breadcrumb" ) , className ) }
47- aria-label = "vous êtes ici :"
43+ className = { cx ( fr . cx ( "fr-breadcrumb" ) , classes . root , className ) }
44+ aria-label = { ` ${ t ( "navigation label" ) } :` }
4845 { ...rest }
4946 >
5047 < button
51- className = "fr-breadcrumb__button"
48+ className = { cx ( fr . cx ( "fr-breadcrumb__button" ) , classes . button ) }
5249 aria-expanded = "false"
5350 aria-controls = { breadcrumbId }
5451 >
55- Voir le fil d’Ariane
52+ { t ( "show breadcrumb" ) }
5653 </ button >
57- < div className = "fr-collapse" id = { breadcrumbId } >
58- < ol className = "fr-breadcrumb__list" >
54+ < div className = { cx ( fr . cx ( "fr-collapse" ) , classes . collapse ) } id = { breadcrumbId } >
55+ < ol className = { cx ( fr . cx ( "fr-breadcrumb__list" ) , classes . list ) } >
5956 < >
6057 { links . map ( link => (
6158 < li key = { link . linkProps . href } >
6259 < Link
6360 { ...link . linkProps }
6461 className = { cx (
6562 fr . cx ( "fr-breadcrumb__link" ) ,
63+ classes . link ,
6664 link . linkProps . className
6765 ) }
6866 aria-current = { link . isActive ? "page" : undefined }
6967 >
70- { trimText ( link . text ) }
68+ { link . text }
7169 </ Link >
7270 </ li >
7371 ) ) }
@@ -81,4 +79,22 @@ export const Breadcrumb = memo(
8179
8280Breadcrumb . displayName = symToStr ( { Breadcrumb } ) ;
8381
82+ const { useTranslation, addBreadcrumbTranslations } = createComponentI18nApi ( {
83+ "componentName" : symToStr ( { Breadcrumb } ) ,
84+ "frMessages" : {
85+ "show breadcrumb" : "Voir le fil d’Ariane" ,
86+ "navigation label" : "vous êtes ici"
87+ }
88+ } ) ;
89+
90+ addBreadcrumbTranslations ( {
91+ "lang" : "en" ,
92+ "messages" : {
93+ "show breadcrumb" : "Show navigation" ,
94+ "navigation label" : "you are here"
95+ }
96+ } ) ;
97+
98+ export { addBreadcrumbTranslations } ;
99+
84100export default Breadcrumb ;
0 commit comments