Skip to content

Commit dc5fe7e

Browse files
authored
Merge pull request #334 from maximallain/enhance-summary
feat(summary): add subitems
2 parents a93fccd + 63bc1d1 commit dc5fe7e

File tree

2 files changed

+98
-47
lines changed

2 files changed

+98
-47
lines changed

src/Summary.tsx

+52-29
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ import type { RegisteredLinkProps } from "./link";
1010
import { useAnalyticsId } from "./tools/useAnalyticsId";
1111
import { generateValidHtmlId } from "./tools/generateValidHtmlId";
1212

13+
type Link = {
14+
text: string;
15+
linkProps: RegisteredLinkProps;
16+
subLinks?: Link[];
17+
};
18+
1319
export type SummaryProps = {
1420
id?: string;
1521
className?: string;
16-
links: {
17-
text: string;
18-
linkProps: RegisteredLinkProps;
19-
}[];
22+
links: Link[];
2023
title?: string;
2124
/** Default: "p" */
2225
as?: "p" | "h2" | "h3" | "h4" | "h5" | "h6";
@@ -52,6 +55,50 @@ export const Summary = memo(
5255
"explicitlyProvidedId": id_props
5356
});
5457

58+
const getSubLinks = (link: Link, linkIndex: string): JSX.Element | undefined => {
59+
let subLinkElements: JSX.Element[] = [];
60+
if (link.subLinks && link.subLinks.length !== 0) {
61+
subLinkElements = link.subLinks.map((subitem, subLinkIndex) =>
62+
getLinkLi(subitem, `${linkIndex}-${subLinkIndex}`)
63+
);
64+
}
65+
66+
return subLinkElements.length === 0 ? undefined : <ol>{...subLinkElements}</ol>;
67+
};
68+
69+
const getLinkLi = (link: Link, linkIndex: string): JSX.Element => {
70+
if (link.linkProps.href === undefined) return <></>;
71+
72+
const subLinksList = getSubLinks(link, linkIndex);
73+
74+
const mainLink =
75+
link.linkProps.href !== undefined ? (
76+
<li key={linkIndex}>
77+
<Link
78+
{...link.linkProps}
79+
id={
80+
link.linkProps.id ??
81+
`${id}-link${generateValidHtmlId({
82+
"text": link.text
83+
})}-${linkIndex}`
84+
}
85+
className={cx(
86+
fr.cx("fr-summary__link"),
87+
classes.link,
88+
link.linkProps.className
89+
)}
90+
>
91+
{link.text}
92+
</Link>
93+
{subLinksList}
94+
</li>
95+
) : (
96+
<></>
97+
);
98+
99+
return mainLink;
100+
};
101+
55102
return (
56103
<nav
57104
id={id}
@@ -69,31 +116,7 @@ export const Summary = memo(
69116
},
70117
<>{summaryTitle}</>
71118
)}
72-
<ol>
73-
{links.map(
74-
(link, i) =>
75-
link.linkProps.href !== undefined && (
76-
<li key={i}>
77-
<Link
78-
{...link.linkProps}
79-
id={
80-
link.linkProps.id ??
81-
`${id}-link${generateValidHtmlId({
82-
"text": link.text
83-
})}-${i}`
84-
}
85-
className={cx(
86-
fr.cx("fr-summary__link"),
87-
classes.link,
88-
link.linkProps.className
89-
)}
90-
>
91-
{link.text}
92-
</Link>
93-
</li>
94-
)
95-
)}
96-
</ol>
119+
<ol>{links.map((link, i) => getLinkLi(link, String(i)))}</ol>
97120
</nav>
98121
);
99122
})

stories/Summary.stories.tsx

+46-18
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,41 @@ export const Default = getStory({
1717
links: [
1818
{
1919
linkProps: { href: "#" },
20-
text: "Titre de l’ancre"
20+
text: "Titre de l’ancre 1",
21+
subLinks: [
22+
{
23+
linkProps: { href: "#" },
24+
text: "Titre de l’ancre 1.1"
25+
}
26+
]
2127
},
2228
{
2329
linkProps: { href: "#" },
24-
25-
text: "Titre de l’ancre"
30+
text: "Titre de l’ancre 2"
2631
},
2732
{
2833
linkProps: { href: "#" },
29-
30-
text: "Titre de l’ancre"
34+
text: "Titre de l’ancre 3"
3135
},
3236
{
3337
linkProps: { href: "#" },
34-
35-
text: "Titre de l’ancre"
38+
text: "Titre de l’ancre 4",
39+
subLinks: [
40+
{
41+
linkProps: { href: "#" },
42+
text: "Titre de l’ancre 4.1",
43+
subLinks: [
44+
{
45+
linkProps: { href: "#" },
46+
text: "Titre de l’ancre 4.1.1"
47+
}
48+
]
49+
}
50+
]
3651
},
3752
{
3853
linkProps: { href: "#" },
39-
40-
text: "Titre de l’ancre"
54+
text: "Titre de l’ancre 5"
4155
}
4256
]
4357
});
@@ -47,27 +61,41 @@ export const SummaryWithCustomTitle = getStory({
4761
links: [
4862
{
4963
linkProps: { href: "#" },
50-
text: "Titre de l’ancre"
64+
text: "Titre de l’ancre 1",
65+
subLinks: [
66+
{
67+
linkProps: { href: "#" },
68+
text: "Titre de l’ancre 1.1"
69+
}
70+
]
5171
},
5272
{
5373
linkProps: { href: "#" },
54-
55-
text: "Titre de l’ancre"
74+
text: "Titre de l’ancre 2"
5675
},
5776
{
5877
linkProps: { href: "#" },
59-
60-
text: "Titre de l’ancre"
78+
text: "Titre de l’ancre 3"
6179
},
6280
{
6381
linkProps: { href: "#" },
64-
65-
text: "Titre de l’ancre"
82+
text: "Titre de l’ancre 4",
83+
subLinks: [
84+
{
85+
linkProps: { href: "#" },
86+
text: "Titre de l’ancre 4.1",
87+
subLinks: [
88+
{
89+
linkProps: { href: "#" },
90+
text: "Titre de l’ancre 4.1.1"
91+
}
92+
]
93+
}
94+
]
6695
},
6796
{
6897
linkProps: { href: "#" },
69-
70-
text: "Titre de l’ancre"
98+
text: "Titre de l’ancre 5"
7199
}
72100
]
73101
});

0 commit comments

Comments
 (0)