Skip to content

Commit 464d2dd

Browse files
committed
Prevent having to pass the homeLink and the brandTop to both the header and the footer
1 parent b29d981 commit 464d2dd

File tree

5 files changed

+52
-107
lines changed

5 files changed

+52
-107
lines changed

src/Footer.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import { createComponentI18nApi } from "./i18n";
1010
import type { FrIconClassName, RiIconClassName } from "./fr/generatedFromCss/classNames";
1111
import { id } from "tsafe/id";
1212
import { ModalProps } from "./Modal";
13+
import { getBrandTopAndHomeLinkProps } from "./zz_internal/brandTopAndHomeLinkProps";
1314

1415
export type FooterProps = {
1516
className?: string;
16-
brandTop: ReactNode;
1717
accessibility: "non compliant" | "partially compliant" | "fully compliant";
1818
contentDescription?: ReactNode;
1919
websiteMapLinkProps?: RegisteredLinkProps;
@@ -22,7 +22,6 @@ export type FooterProps = {
2222
personalDataLinkProps?: RegisteredLinkProps;
2323
cookiesManagementLinkProps?: RegisteredLinkProps;
2424
cookiesManagementButtonProps?: ModalProps.ModalButtonProps;
25-
homeLinkProps: RegisteredLinkProps & { title: string };
2625
bottomItems?: FooterProps.BottomItem[];
2726
partnersLogos?: FooterProps.PartnersLogos;
2827
operatorLogo?: {
@@ -139,9 +138,7 @@ export const Footer = memo(
139138
const {
140139
className,
141140
classes = {},
142-
brandTop,
143141
contentDescription,
144-
homeLinkProps,
145142
websiteMapLinkProps,
146143
accessibilityLinkProps,
147144
accessibility,
@@ -160,6 +157,8 @@ export const Footer = memo(
160157

161158
assert<Equals<keyof typeof rest, never>>();
162159

160+
const { brandTop, homeLinkProps } = getBrandTopAndHomeLinkProps();
161+
163162
const { Link } = getLink();
164163

165164
const { t } = useTranslation();

src/Header.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ import type { FrIconClassName, RiIconClassName } from "./fr/generatedFromCss/cla
1111
import type { MainNavigationProps } from "./MainNavigation";
1212
import { MainNavigation } from "./MainNavigation";
1313
import { Display } from "./Display/Display";
14+
import { setBrandTopAndHomeLinkProps } from "./zz_internal/brandTopAndHomeLinkProps";
1415

1516
export type HeaderProps = {
1617
className?: string;
1718
brandTop: ReactNode;
19+
homeLinkProps: RegisteredLinkProps & { title: string };
1820
serviceTitle?: ReactNode;
1921
serviceTagline?: ReactNode;
20-
homeLinkProps: RegisteredLinkProps & { title: string };
2122
navigation?: MainNavigationProps.Item[] | ReactNode;
2223
/** There should be at most three of them */
2324
quickAccessItems?: HeaderProps.QuickAccessItem[];
@@ -91,6 +92,8 @@ export namespace HeaderProps {
9192
}
9293
}
9394

95+
96+
9497
/** @see <https://react-dsfr-components.etalab.studio/?path=/docs/components-header> */
9598
export const Header = memo(
9699
forwardRef<HTMLDivElement, HeaderProps>((props, ref) => {
@@ -111,6 +114,8 @@ export const Header = memo(
111114

112115
assert<Equals<keyof typeof rest, never>>();
113116

117+
setBrandTopAndHomeLinkProps({ brandTop, homeLinkProps });
118+
114119
const menuButtonId = `button-${useId()}`;
115120
const menuModalId = `modal-${useId()}`;
116121
const searchModalId = `modal-${useId()}`;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
import type { ReactNode } from "react";
3+
import type { RegisteredLinkProps } from "../link";
4+
5+
6+
let wrap: {
7+
brandTop: ReactNode;
8+
homeLinkProps: RegisteredLinkProps & { title: string };
9+
} | undefined = undefined;
10+
11+
export function setBrandTopAndHomeLinkProps(params: {
12+
brandTop: ReactNode;
13+
homeLinkProps: RegisteredLinkProps & { title: string }
14+
}) {
15+
wrap = params;
16+
}
17+
18+
export function getBrandTopAndHomeLinkProps() {
19+
20+
if (wrap === undefined) {
21+
throw new Error("The footer should be used in conjunction with the header.");
22+
}
23+
24+
return wrap;
25+
}

stories/Footer.stories.tsx

Lines changed: 13 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ import { assert } from "tsafe/assert";
66
import type { Equals } from "tsafe";
77
import placeholder_9x16ImgUrl from "./assets/placeholder.9x16.png";
88
import placeholder_16x9ImgUrl from "./assets/placeholder.16x9.png";
9+
import { setBrandTopAndHomeLinkProps } from "../dist/zz_internal/brandTopAndHomeLinkProps";
10+
11+
setBrandTopAndHomeLinkProps({
12+
"brandTop": <>
13+
INTITULE
14+
<br />
15+
OFFICIEL
16+
</>,
17+
"homeLinkProps": {
18+
"href": "/",
19+
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
20+
}
21+
});
922

1023
const { meta, getStory } = getStoryFactory({
1124
sectionName,
@@ -14,9 +27,6 @@ const { meta, getStory } = getStoryFactory({
1427
- [See DSFR documentation](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/pied-de-page)
1528
- [See source code](https://github.com/codegouvfr/react-dsfr/blob/main/src/Footer.tsx)`,
1629
"argTypes": {
17-
"brandTop": {
18-
"control": { "type": null }
19-
},
2030
"accessibility": {
2131
"options": (() => {
2232
const accessibility = [
@@ -46,9 +56,6 @@ const { meta, getStory } = getStoryFactory({
4656
"cookiesManagementLinkProps": {
4757
"control": { "type": null }
4858
},
49-
"homeLinkProps": {
50-
"control": { "type": null }
51-
},
5259
"bottomItems": {
5360
"description":
5461
"To integrate the Dark mode switch head over to the documentation of the [Display component](https://react-dsfr-components.etalab.studio/?path=/docs/components-display)"
@@ -66,13 +73,6 @@ const { meta, getStory } = getStoryFactory({
6673
export default meta;
6774

6875
export const Default = getStory({
69-
"brandTop": (
70-
<>
71-
INTITULE
72-
<br />
73-
OFFICIEL
74-
</>
75-
),
7676
"accessibility": "fully compliant",
7777
"contentDescription": `
7878
Ce message est à remplacer par les informations de votre site.
@@ -94,20 +94,9 @@ export const Default = getStory({
9494
"cookiesManagementLinkProps": {
9595
"href": "#"
9696
},
97-
"homeLinkProps": {
98-
"href": "/",
99-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
100-
}
10197
});
10298

10399
export const FooterWithVerticalOperatorLogo = getStory({
104-
"brandTop": (
105-
<>
106-
INTITULE
107-
<br />
108-
OFFICIEL
109-
</>
110-
),
111100
"accessibility": "fully compliant",
112101
"contentDescription": `
113102
Ce message est à remplacer par les informations de votre site.
@@ -117,10 +106,6 @@ export const FooterWithVerticalOperatorLogo = getStory({
117106
Retrouvez toutes les informations et démarches administratives nécessaires à la création,
118107
à la gestion et au développement de votre entreprise.
119108
`,
120-
"homeLinkProps": {
121-
"href": "/",
122-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
123-
},
124109
"operatorLogo": {
125110
"orientation": "vertical",
126111
"imgUrl": placeholder_9x16ImgUrl,
@@ -129,13 +114,6 @@ export const FooterWithVerticalOperatorLogo = getStory({
129114
});
130115

131116
export const FooterWithHorizontalOperatorLogo = getStory({
132-
"brandTop": (
133-
<>
134-
INTITULE
135-
<br />
136-
OFFICIEL
137-
</>
138-
),
139117
"accessibility": "fully compliant",
140118
"contentDescription": `
141119
Ce message est à remplacer par les informations de votre site.
@@ -145,10 +123,6 @@ export const FooterWithHorizontalOperatorLogo = getStory({
145123
Retrouvez toutes les informations et démarches administratives nécessaires à la création,
146124
à la gestion et au développement de votre entreprise.
147125
`,
148-
"homeLinkProps": {
149-
"href": "/",
150-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
151-
},
152126
"operatorLogo": {
153127
"orientation": "horizontal",
154128
"imgUrl": placeholder_16x9ImgUrl,
@@ -157,13 +131,6 @@ export const FooterWithHorizontalOperatorLogo = getStory({
157131
});
158132

159133
export const WithCustomLicense = getStory({
160-
"brandTop": (
161-
<>
162-
INTITULE
163-
<br />
164-
OFFICIEL
165-
</>
166-
),
167134
"accessibility": "fully compliant",
168135
"contentDescription": `
169136
Ce message est à remplacer par les informations de votre site.
@@ -173,10 +140,6 @@ export const WithCustomLicense = getStory({
173140
Retrouvez toutes les informations et démarches administratives nécessaires à la création,
174141
à la gestion et au développement de votre entreprise.
175142
`,
176-
"homeLinkProps": {
177-
"href": "/",
178-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
179-
},
180143
"license": (
181144
<>
182145
Unless stated otherwise all content of this website are under{" "}
@@ -188,13 +151,6 @@ export const WithCustomLicense = getStory({
188151
});
189152

190153
export const WithPartners = getStory({
191-
"brandTop": (
192-
<>
193-
INTITULE
194-
<br />
195-
OFFICIEL
196-
</>
197-
),
198154
"accessibility": "fully compliant",
199155
"contentDescription": `
200156
Ce message est à remplacer par les informations de votre site.
@@ -204,10 +160,6 @@ export const WithPartners = getStory({
204160
Retrouvez toutes les informations et démarches administratives nécessaires à la création,
205161
à la gestion et au développement de votre entreprise.
206162
`,
207-
"homeLinkProps": {
208-
"href": "/",
209-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
210-
},
211163
"partnersLogos": {
212164
"main": {
213165
"href": "#",
@@ -230,13 +182,6 @@ export const WithPartners = getStory({
230182
});
231183

232184
export const WithMainPartnerOnly = getStory({
233-
"brandTop": (
234-
<>
235-
INTITULE
236-
<br />
237-
OFFICIEL
238-
</>
239-
),
240185
"accessibility": "fully compliant",
241186
"contentDescription": `
242187
Ce message est à remplacer par les informations de votre site.
@@ -246,10 +191,6 @@ export const WithMainPartnerOnly = getStory({
246191
Retrouvez toutes les informations et démarches administratives nécessaires à la création,
247192
à la gestion et au développement de votre entreprise.
248193
`,
249-
"homeLinkProps": {
250-
"href": "/",
251-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
252-
},
253194
"partnersLogos": {
254195
"main": {
255196
"href": "#",
@@ -260,13 +201,6 @@ export const WithMainPartnerOnly = getStory({
260201
});
261202

262203
export const WithSubPartnersOnly = getStory({
263-
"brandTop": (
264-
<>
265-
INTITULE
266-
<br />
267-
OFFICIEL
268-
</>
269-
),
270204
"accessibility": "fully compliant",
271205
"contentDescription": `
272206
Ce message est à remplacer par les informations de votre site.
@@ -276,10 +210,6 @@ export const WithSubPartnersOnly = getStory({
276210
Retrouvez toutes les informations et démarches administratives nécessaires à la création,
277211
à la gestion et au développement de votre entreprise.
278212
`,
279-
"homeLinkProps": {
280-
"href": "/",
281-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
282-
},
283213
"partnersLogos": {
284214
"sub": [
285215
{
@@ -306,13 +236,6 @@ const linkList = new Array(6).fill({
306236
}) as FooterProps.LinkList.List;
307237

308238
export const WithLinkList = getStory({
309-
"brandTop": (
310-
<>
311-
INTITULE
312-
<br />
313-
OFFICIEL
314-
</>
315-
),
316239
"accessibility": "fully compliant",
317240
"contentDescription": `
318241
Ce message est à remplacer par les informations de votre site.
@@ -322,9 +245,5 @@ export const WithLinkList = getStory({
322245
Retrouvez toutes les informations et démarches administratives nécessaires à la création,
323246
à la gestion et au développement de votre entreprise.
324247
`,
325-
"homeLinkProps": {
326-
"href": "/",
327-
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
328-
},
329248
linkList
330249
});

test/integration/next-appdir/app/layout.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ import { headerFooterDisplayItem } from "@codegouvfr/react-dsfr/Display";
1212
import { fr } from "@codegouvfr/react-dsfr";
1313
import { Navigation } from "./Navigation";
1414

15-
const brandTop = <>INTITULE<br />OFFICIEL</>;
16-
17-
const homeLinkPops = { "href": "/", "title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)" };
18-
1915
declare module "@codegouvfr/react-dsfr/gdpr" {
2016
interface RegisterGdprServices {
2117
matomo: never;
@@ -69,9 +65,12 @@ export default function RootLayout({ children }: { children: JSX.Element; }) {
6965
<NextAppDirEmotionCacheProvider options={{ "key": "css" }}>
7066
<MuiDsfrThemeProvider>
7167
<Header
72-
brandTop={brandTop}
68+
brandTop={<>INTITULE<br />OFFICIEL</>}
7369
serviceTitle="Nom du site / service"
74-
homeLinkProps={homeLinkPops}
70+
homeLinkProps={{
71+
"href": "/",
72+
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
73+
}}
7574
quickAccessItems={[
7675
headerFooterDisplayItem,
7776
{
@@ -95,7 +94,6 @@ export default function RootLayout({ children }: { children: JSX.Element; }) {
9594
{children}
9695
</div>
9796
<Footer
98-
brandTop={brandTop}
9997
accessibility="fully compliant"
10098
contentDescription={`
10199
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
@@ -104,7 +102,6 @@ export default function RootLayout({ children }: { children: JSX.Element; }) {
104102
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
105103
eu fugiat nulla pariatur.
106104
`}
107-
homeLinkProps={homeLinkPops}
108105
bottomItems={[headerFooterDisplayItem]}
109106
/>
110107
</MuiDsfrThemeProvider>

0 commit comments

Comments
 (0)