Skip to content

Commit 241656b

Browse files
committed
Add story for main navigation menu
1 parent fe95fd6 commit 241656b

File tree

9 files changed

+258
-33
lines changed

9 files changed

+258
-33
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
"devDependencies": {
7373
"@babel/core": "^7.20.2",
7474
"@emotion/react": "^11.10.4",
75-
"tss-react": "^4.4.4",
7675
"@emotion/styled": "^11.10.4",
7776
"@gouvfr/dsfr": "1.8.4",
7877
"@mui/material": "^5.10.7",
@@ -112,6 +111,7 @@
112111
"remixicon": "^2.5.0",
113112
"storybook-dark-mode": "^1.1.2",
114113
"ts-node": "^10.9.1",
114+
"tss-react": "^4.4.4",
115115
"typescript": "^4.9.1-beta",
116116
"vitest": "^0.24.3"
117117
},

src/Header/Header.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ export type HeaderProps = {
5959
| "serviceTagline"
6060
| "menu"
6161
| "menuLinks"
62-
| "navRoot"
62+
| "nav"
6363
| "navList"
6464
| "navItem"
6565
| "navLink"
66-
| "navBtn",
66+
| "navBtn"
67+
| "navMenu"
68+
| "navMenuList",
6769
string
6870
>
6971
>;
@@ -342,11 +344,13 @@ export const Header = memo(
342344
<MainNavigation
343345
items={navItems}
344346
classes={{
345-
"root": classes.navRoot,
347+
"root": classes.nav,
346348
"list": classes.navList,
347349
"item": classes.navItem,
348350
"link": classes.navLink,
349-
"btn": classes.navBtn
351+
"btn": classes.navBtn,
352+
"menu": classes.navMenu,
353+
"menuList": classes.navMenuList
350354
}}
351355
/>
352356
)}

src/Header/MainNavigation/MainNavigation.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import { MegaMenu } from "./MegaMenu";
1616
export type MainNavigationProps = {
1717
className?: string;
1818
items: MainNavigationProps.Item[];
19-
classes?: Partial<Record<"root" | "list" | "item" | "link" | "btn", string>>;
19+
classes?: Partial<
20+
Record<"root" | "list" | "item" | "link" | "btn" | "menu" | "menuList", string>
21+
>;
2022
};
2123

2224
export namespace MainNavigationProps {
@@ -31,19 +33,19 @@ export namespace MainNavigationProps {
3133

3234
export type Link = Common & {
3335
linkProps: RegisteredLinkProps;
34-
menuProps?: undefined;
36+
menuLinks?: undefined;
3537
megaMenuProps?: undefined;
3638
};
3739

3840
export type Menu = Common & {
3941
linkProps?: undefined;
40-
menuProps: MenuProps;
42+
menuLinks: MenuProps.Link[];
4143
megaMenuProps?: undefined;
4244
};
4345

4446
export type MegaMenu = Common & {
4547
linkProps?: undefined;
46-
menuProps?: undefined;
48+
menuLinks?: undefined;
4749
megaMenuProps: MegaMenuProps;
4850
};
4951
}
@@ -83,7 +85,7 @@ export const MainNavigation = memo(
8385
text,
8486
isActive = false,
8587
linkProps,
86-
menuProps,
88+
menuLinks = [],
8789
megaMenuProps
8890
},
8991
i
@@ -114,13 +116,13 @@ export const MainNavigation = memo(
114116
>
115117
{text}
116118
</button>
117-
{menuProps !== undefined && (
119+
{menuLinks.length !== 0 && (
118120
<Menu
119-
{...menuProps}
120-
className={cx(
121-
fr.cx("fr-collapse"),
122-
menuProps.className
123-
)}
121+
classes={{
122+
"root": cx(fr.cx("fr-collapse"), classes.root),
123+
"list": classes.menuList
124+
}}
125+
links={menuLinks}
124126
id={getMenuId(i)}
125127
/>
126128
)}

src/Header/MainNavigation/Menu.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,30 @@ import type { RegisteredLinkProps } from "../../lib/routing";
99
import { useLink } from "../../lib/routing";
1010

1111
export type MenuProps = {
12-
className?: string;
1312
classes?: Partial<Record<"root" | "list", string>>;
14-
items: {
13+
links: MenuProps.Link[];
14+
};
15+
16+
export namespace MenuProps {
17+
export type Link = {
1518
text: ReactNode;
1619
linkProps: RegisteredLinkProps;
1720
isActive?: boolean;
18-
}[];
19-
};
21+
};
22+
}
2023

2124
export const Menu = memo(
2225
forwardRef<HTMLDivElement, MenuProps & { id: string }>((props, ref) => {
23-
const { className, id, classes = {}, items, ...rest } = props;
26+
const { id, classes = {}, links, ...rest } = props;
2427

2528
assert<Equals<keyof typeof rest, never>>();
2629

2730
const { Link } = useLink();
2831

2932
return (
30-
<div
31-
className={cx(fr.cx("fr-menu"), classes.root, className)}
32-
id={id}
33-
ref={ref}
34-
{...rest}
35-
>
33+
<div className={cx(fr.cx("fr-menu"), classes.root)} id={id} ref={ref} {...rest}>
3634
<ul className={cx(fr.cx("fr-menu__list"), classes.list)}>
37-
{items.map(({ text, linkProps, isActive = false }, i) => (
35+
{links.map(({ text, linkProps, isActive = false }, i) => (
3836
<li key={i}>
3937
<Link
4038
{...linkProps}

stories/Header.stories.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ const { meta, getStory } = getStoryFactory({
1010
"wrappedComponent": { Header },
1111
"description": `
1212
- [See DSFR documentation](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/en-tete)
13-
- [See source code](https://github.com/codegouvfr/react-dsfr/blob/main/src/Header/Header.tsx)`,
13+
- [See source code](https://github.com/codegouvfr/react-dsfr/blob/main/src/Header/Header.tsx)
14+
15+
See also [\\<MainNavigation \\/\\>](https://react-dsfr-components.etalab.studio/?path=/docs/components-mainnavigation)`,
1416
"disabledProps": ["lang"]
1517
});
1618

stories/MainNavigation.stories.tsx

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import React from "react";
2+
import { Header } from "../dist/Header";
3+
import { sectionName } from "./sectionName";
4+
import { getStoryFactory } from "./getStory";
5+
import "./utils.css";
6+
7+
const { meta, getStory } = getStoryFactory({
8+
sectionName,
9+
"wrappedComponent": { "MainNavigation": Header },
10+
"description": `
11+
- [See DSFR documentation](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/navigation-principale)
12+
- [See source code](https://github.com/codegouvfr/react-dsfr/blob/main/src/Header/MainNavigation.tsx)
13+
14+
This component isn't meant to be used directly but via the [\\<Header \\/\\>](https://react-dsfr-components.etalab.studio/?path=/docs/components-header).`,
15+
"disabledProps": ["lang"],
16+
"doHideImportInstruction": true
17+
});
18+
19+
export default meta;
20+
21+
export const DirectLinks = getStory({
22+
"brandTop": (
23+
<>
24+
INTITULE
25+
<br />
26+
OFFICIEL
27+
</>
28+
),
29+
"homeLinkProps": {
30+
"href": "/",
31+
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
32+
},
33+
"navItems": [
34+
{
35+
"text": "accès direct",
36+
"linkProps": {
37+
"href": "#",
38+
"target": "_self"
39+
}
40+
},
41+
{
42+
"text": "accès direct",
43+
"linkProps": {
44+
"href": "#",
45+
"target": "_self"
46+
},
47+
"isActive": true
48+
},
49+
{
50+
"text": "accès direct",
51+
"linkProps": {
52+
"href": "#",
53+
"target": "_self"
54+
}
55+
},
56+
{
57+
"text": "accès direct",
58+
"linkProps": {
59+
"href": "#",
60+
"target": "_self"
61+
}
62+
}
63+
]
64+
});
65+
66+
export const DropdownMenu = getStory({
67+
"className": "margin-bottom-300px",
68+
"brandTop": (
69+
<>
70+
INTITULE
71+
<br />
72+
OFFICIEL
73+
</>
74+
),
75+
"homeLinkProps": {
76+
"href": "/",
77+
"title": "Accueil - Nom de l’entité (ministère, secrétariat d‘état, gouvernement)"
78+
},
79+
"navItems": [
80+
{
81+
"text": "Entrée menu active",
82+
"isActive": true,
83+
"menuLinks": [
84+
{
85+
"text": "Lien de navigation",
86+
"linkProps": {
87+
"href": "#"
88+
}
89+
},
90+
{
91+
"text": "Lien de navigation",
92+
"linkProps": {
93+
"href": "#"
94+
}
95+
},
96+
{
97+
"text": "Lien de navigation",
98+
"linkProps": {
99+
"href": "#"
100+
}
101+
},
102+
{
103+
"text": "Lien de navigation",
104+
"linkProps": {
105+
"href": "#"
106+
},
107+
"isActive": true
108+
},
109+
{
110+
"text": "Lien de navigation",
111+
"linkProps": {
112+
"href": "#"
113+
}
114+
},
115+
{
116+
"text": "Lien de navigation",
117+
"linkProps": {
118+
"href": "#"
119+
}
120+
}
121+
]
122+
},
123+
{
124+
"text": "accès direct",
125+
"menuLinks": [
126+
{
127+
"text": "Lien de navigation",
128+
"linkProps": {
129+
"href": "#"
130+
}
131+
},
132+
{
133+
"text": "Lien de navigation",
134+
"linkProps": {
135+
"href": "#"
136+
}
137+
},
138+
{
139+
"text": "Lien de navigation",
140+
"linkProps": {
141+
"href": "#"
142+
}
143+
},
144+
{
145+
"text": "Lien de navigation",
146+
"linkProps": {
147+
"href": "#"
148+
}
149+
},
150+
{
151+
"text": "Lien de navigation",
152+
"linkProps": {
153+
"href": "#"
154+
}
155+
},
156+
{
157+
"text": "Lien de navigation",
158+
"linkProps": {
159+
"href": "#"
160+
}
161+
}
162+
]
163+
},
164+
{
165+
"text": "accès direct",
166+
"linkProps": {
167+
"href": "#",
168+
"target": "_self"
169+
}
170+
},
171+
{
172+
"text": "accès direct",
173+
"linkProps": {
174+
"href": "#",
175+
"target": "_self"
176+
}
177+
}
178+
]
179+
});

stories/getStory.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ export function getStoryFactory<Props extends Record<string, any>>(params: {
1313
argTypes?: Partial<Record<keyof Props, ArgType>>;
1414
defaultContainerWidth?: number;
1515
disabledProps?: ("containerWidth" | "lang" | "darkMode")[];
16+
/** Default false */
17+
doHideImportInstruction?: boolean;
1618
}) {
1719
const {
1820
sectionName,
1921
wrappedComponent,
2022
description,
2123
argTypes = {},
2224
defaultContainerWidth,
23-
disabledProps = []
25+
disabledProps = [],
26+
doHideImportInstruction = false
2427
} = params;
2528

2629
const Component: any = Object.entries(wrappedComponent).map(([, component]) => component)[0];
@@ -123,7 +126,11 @@ export function getStoryFactory<Props extends Record<string, any>>(params: {
123126
"docs": {
124127
"description": {
125128
"component": [
126-
`\`import { ${componentName} } from "@codegouvfr/react-dsfr/${componentName}"\``,
129+
...(doHideImportInstruction
130+
? []
131+
: [
132+
`\`import { ${componentName} } from "@codegouvfr/react-dsfr/${componentName}"\``
133+
]),
127134
...(description === undefined ? [] : [description])
128135
].join(" \n")
129136
}

stories/utils.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
.margin-bottom-300px {
3+
margin-bottom: 300px;
4+
}

0 commit comments

Comments
 (0)