Skip to content

Commit 96102f2

Browse files
committed
Enable header navigation to be a custom node for RSC
1 parent 05b399b commit 96102f2

File tree

13 files changed

+110
-62
lines changed

13 files changed

+110
-62
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@
138138
"./Quote": "./dist/Quote.js",
139139
"./Pagination": "./dist/Pagination.js",
140140
"./Notice": "./dist/Notice.js",
141+
"./MainNavigation": "./dist/MainNavigation/index.js",
141142
"./Highlight": "./dist/Highlight.js",
142-
"./Header": "./dist/Header/index.js",
143+
"./Header": "./dist/Header.js",
143144
"./Footer": "./dist/Footer.js",
144145
"./Display": "./dist/Display.js",
145146
"./Card": "./dist/Card.js",

src/Header/Header.tsx renamed to src/Header.tsx

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import React, { memo, forwardRef, useId } from "react";
22
import type { ReactNode } from "react";
3-
import { fr } from "../fr";
4-
import { createComponentI18nApi } from "../i18n";
3+
import { fr } from "./fr";
4+
import { createComponentI18nApi } from "./i18n";
55
import { symToStr } from "tsafe/symToStr";
6-
import { cx } from "../tools/cx";
7-
import { getLink } from "../link";
8-
import type { RegisteredLinkProps } from "../link";
9-
import type { MainNavigationProps } from "./MainNavigation";
10-
import { MainNavigation } from "./MainNavigation";
6+
import { cx } from "./tools/cx";
7+
import { getLink } from "./link";
8+
import type { RegisteredLinkProps } from "./link";
119
import { assert } from "tsafe/assert";
1210
import type { Equals } from "tsafe";
13-
import type { FrIconClassName, RiIconClassName } from "../fr/generatedFromCss/classNames";
11+
import type { FrIconClassName, RiIconClassName } from "./fr/generatedFromCss/classNames";
12+
import type { MainNavigationProps } from "./MainNavigation";
13+
import { MainNavigation } from "./MainNavigation";
1414

1515
export type HeaderProps = {
1616
className?: string;
1717
brandTop: ReactNode;
1818
serviceTitle?: ReactNode;
1919
serviceTagline?: ReactNode;
2020
homeLinkProps: RegisteredLinkProps & { title: string };
21-
navItems?: MainNavigationProps.Item[];
21+
navigation?: MainNavigationProps.Item[] | ReactNode;
2222
/** There should be at most three of them */
2323
quickAccessItems?: HeaderProps.QuickAccessItem[];
2424
operatorLogo?: {
@@ -59,14 +59,7 @@ export type HeaderProps = {
5959
| "serviceTitle"
6060
| "serviceTagline"
6161
| "menu"
62-
| "menuLinks"
63-
| "nav"
64-
| "navList"
65-
| "navItem"
66-
| "navLink"
67-
| "navBtn"
68-
| "navMenu"
69-
| "navMenuList",
62+
| "menuLinks",
7063
string
7164
>
7265
>;
@@ -105,7 +98,7 @@ export const Header = memo(
10598
serviceTitle,
10699
serviceTagline,
107100
homeLinkProps,
108-
navItems = [],
101+
navigation = undefined,
109102
quickAccessItems = [],
110103
operatorLogo,
111104
renderSearchInput,
@@ -180,7 +173,7 @@ export const Header = memo(
180173
)}
181174

182175
{(quickAccessItems.length > 0 ||
183-
navItems.length > 0 ||
176+
navigation !== undefined ||
184177
renderSearchInput !== undefined) && (
185178
<div
186179
className={cx(
@@ -328,7 +321,7 @@ export const Header = memo(
328321
</div>
329322
</div>
330323
</div>
331-
{(navItems.length !== 0 || quickAccessItems.length !== 0) && (
324+
{(navigation !== undefined || quickAccessItems.length !== 0) && (
332325
<div
333326
className={cx(fr.cx("fr-header__menu", "fr-modal"), classes.menu)}
334327
id={menuModalId}
@@ -345,20 +338,12 @@ export const Header = memo(
345338
<div
346339
className={cx(fr.cx("fr-header__menu-links"), classes.menuLinks)}
347340
/>
348-
{navItems.length !== 0 && (
349-
<MainNavigation
350-
items={navItems}
351-
classes={{
352-
"root": classes.nav,
353-
"list": classes.navList,
354-
"item": classes.navItem,
355-
"link": classes.navLink,
356-
"btn": classes.navBtn,
357-
"menu": classes.navMenu,
358-
"menuList": classes.navMenuList
359-
}}
360-
/>
361-
)}
341+
{navigation !== undefined &&
342+
(navigation instanceof Array ? (
343+
<MainNavigation items={navigation} />
344+
) : (
345+
navigation
346+
))}
362347
</div>
363348
</div>
364349
)}

src/Header/index.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/Header/MainNavigation/MainNavigation.tsx renamed to src/MainNavigation/MainNavigation.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React, { memo, forwardRef, useId } from "react";
22
import type { ReactNode } from "react";
3-
import { createComponentI18nApi } from "../../i18n";
3+
import { createComponentI18nApi } from "../i18n";
44
import { symToStr } from "tsafe/symToStr";
55
import { assert } from "tsafe/assert";
66
import type { Equals } from "tsafe";
7-
import type { RegisteredLinkProps } from "../../link";
8-
import { getLink } from "../../link";
9-
import { fr } from "../../fr";
10-
import { cx } from "../../tools/cx";
7+
import type { RegisteredLinkProps } from "../link";
8+
import { getLink } from "../link";
9+
import { fr } from "../fr";
10+
import { cx } from "../tools/cx";
1111
import type { MenuProps } from "./Menu";
1212
import { Menu } from "./Menu";
1313
import type { MegaMenuProps } from "./MegaMenu";

src/Header/MainNavigation/MegaMenu.tsx renamed to src/MainNavigation/MegaMenu.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React, { memo, forwardRef } from "react";
22
import type { ReactNode } from "react";
33
import { symToStr } from "tsafe/symToStr";
4-
import { createComponentI18nApi } from "../../i18n";
5-
import { fr } from "../../fr";
6-
import { cx } from "../../tools/cx";
4+
import { createComponentI18nApi } from "../i18n";
5+
import { fr } from "../fr";
6+
import { cx } from "../tools/cx";
77
import { assert } from "tsafe/assert";
88
import type { Equals } from "tsafe";
9-
import { getLink } from "../../link";
10-
import type { RegisteredLinkProps } from "../../link";
9+
import { getLink } from "../link";
10+
import type { RegisteredLinkProps } from "../link";
1111

1212
export type MegaMenuProps = {
1313
classes?: Partial<Record<"root" | "leader" | "category" | "list", string>>;
@@ -157,4 +157,6 @@ addMegaMenuTranslations({
157157
}
158158
});
159159

160+
export { addMegaMenuTranslations };
161+
160162
export default MegaMenu;

src/Header/MainNavigation/Menu.tsx renamed to src/MainNavigation/Menu.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import React, { memo, forwardRef } from "react";
44
import type { ReactNode } from "react";
55
import { symToStr } from "tsafe/symToStr";
6-
import { fr } from "../../fr";
7-
import { cx } from "../../tools/cx";
6+
import { fr } from "../fr";
7+
import { cx } from "../tools/cx";
88
import { assert } from "tsafe/assert";
99
import type { Equals } from "tsafe";
10-
import type { RegisteredLinkProps } from "../../link";
11-
import { getLink } from "../../link";
10+
import type { RegisteredLinkProps } from "../link";
11+
import { getLink } from "../link";
1212

1313
export type MenuProps = {
1414
classes?: Partial<Record<"root" | "list", string>>;

src/Header/MainNavigation/index.ts renamed to src/MainNavigation/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from "./MainNavigation";
2+
export { addMegaMenuTranslations } from "./MegaMenu";
23

34
import { MainNavigation } from "./MainNavigation";
45

src/scripts/list-exports.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as fs from "fs";
22
import { join as pathJoin } from "path";
33
import { getProjectRoot } from "../bin/tools/getProjectRoot";
44
import { exclude } from "tsafe/exclude";
5-
import { execSync } from "child_process";
5+
//import { execSync } from "child_process";
66
import { same } from "evt/tools/inDepth/same";
77
import { capitalize } from "tsafe/capitalize";
88

@@ -65,6 +65,7 @@ const newExports = {
6565
return undefined;
6666
})
6767
.filter(exclude(undefined))
68+
/*
6869
.filter(([, relativePath]) => {
6970
try {
7071
execSync(`git ls-files --error-unmatch ${pathJoin(srcDirPath, relativePath)}`, {
@@ -76,6 +77,7 @@ const newExports = {
7677
7778
return true;
7879
})
80+
*/
7981
.filter(exclude(undefined))
8082
.sort()
8183
.reverse()

stories/Header.stories.tsx

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react";
22
import { Header } from "../dist/Header";
3+
import { MainNavigation } from "../dist/MainNavigation";
34
import { sectionName } from "./sectionName";
45
import { getStoryFactory } from "./getStory";
56
import placeholder_9x16ImgUrl from "./assets/placeholder.9x16.png";
@@ -38,7 +39,7 @@ export const SimpleHeader = getStory({
3839
"href": "/",
3940
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
4041
},
41-
"navItems": [
42+
"navigation": [
4243
{
4344
"text": "accès direct",
4445
"linkProps": {
@@ -182,7 +183,7 @@ export const HeaderWithQuickAccessItemsNavItemsAndSearchEngine = getStory({
182183
}
183184
}
184185
],
185-
"navItems": [
186+
"navigation": [
186187
{
187188
"text": "accès direct",
188189
"linkProps": {
@@ -287,3 +288,66 @@ export const WithHorizontalOperatorLogo = getStory({
287288
"alt": "[À MODIFIER - texte alternatif de l’image]"
288289
}
289290
});
291+
292+
export const NavigationAsCustomNode = getStory(
293+
{
294+
"brandTop": (
295+
<>
296+
INTITULE
297+
<br />
298+
OFFICIEL
299+
</>
300+
),
301+
"homeLinkProps": {
302+
"href": "/",
303+
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
304+
},
305+
"navigation": (
306+
<MainNavigation
307+
items={[
308+
{
309+
"text": "accès direct",
310+
"linkProps": {
311+
"href": "#",
312+
"target": "_self"
313+
}
314+
},
315+
{
316+
"text": "accès direct",
317+
"linkProps": {
318+
"href": "#",
319+
"target": "_self"
320+
},
321+
"isActive": true
322+
},
323+
{
324+
"text": "accès direct",
325+
"linkProps": {
326+
"href": "#",
327+
"target": "_self"
328+
}
329+
},
330+
{
331+
"text": "accès direct",
332+
"linkProps": {
333+
"href": "#",
334+
"target": "_self"
335+
}
336+
}
337+
]}
338+
/>
339+
)
340+
},
341+
{
342+
"description": `You can provide a custom \`ReactNode\` as \`navigation\` prop.
343+
It is useful to keep the Header as a server component in Next 13 AppDir.
344+
345+
\`\`\`tsx
346+
347+
import { MainNavigation } from "@codegouvfr/react-dsfr/MainNavigation";
348+
349+
\`\`\`
350+
351+
`
352+
}
353+
);

test/integration/cra/src/Home.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ export function Home() {
77

88
return (
99
<>
10-
1110
<Alert
1211
closable
1312
severity="success"

0 commit comments

Comments
 (0)