Skip to content

Commit faa8803

Browse files
committed
Enable having more than one header as long as we don't use useIsHeaderMenuModalOpen
1 parent 64d92fd commit faa8803

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

src/Header/Header.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export namespace HeaderProps {
9696
}
9797
}
9898

99-
export const headerMenuModalId = "header-menu-modal";
99+
export const headerMenuModalIdPrefix = "header-menu-modal";
100100

101101
/** @see <https://components.react-dsfr.fr/?path=/docs/components-header> */
102102
export const Header = memo(
@@ -124,14 +124,16 @@ export const Header = memo(
124124

125125
setBrandTopAndHomeLinkProps({ brandTop, homeLinkProps });
126126

127-
const { menuButtonId, searchModalId, searchInputId } = (function useClosure() {
127+
const { menuModalId, menuButtonId, searchModalId, searchInputId } = (function useClosure() {
128128
const id = useId();
129129

130+
const menuModalId = `${headerMenuModalIdPrefix}-${id}`;
130131
const menuButtonId = `button-${id}`;
131132
const searchModalId = `modal-${id}`;
132133
const searchInputId = `search-${id}-input`;
133134

134135
return {
136+
menuModalId,
135137
menuButtonId,
136138
searchModalId,
137139
searchInputId
@@ -253,7 +255,7 @@ export const Header = memo(
253255
<button
254256
className={fr.cx("fr-btn--menu", "fr-btn")}
255257
data-fr-opened="false"
256-
aria-controls={headerMenuModalId}
258+
aria-controls={menuModalId}
257259
aria-haspopup="menu"
258260
id={menuButtonId}
259261
title={t("menu")}
@@ -372,13 +374,13 @@ export const Header = memo(
372374
{(navigation !== undefined || quickAccessItems.length !== 0) && (
373375
<div
374376
className={cx(fr.cx("fr-header__menu", "fr-modal"), classes.menu)}
375-
id={headerMenuModalId}
377+
id={menuModalId}
376378
aria-labelledby={menuButtonId}
377379
>
378380
<div className={fr.cx("fr-container")}>
379381
<button
380382
className={fr.cx("fr-btn--close", "fr-btn")}
381-
aria-controls={headerMenuModalId}
383+
aria-controls={menuModalId}
382384
title={t("close")}
383385
>
384386
{t("close")}

src/Header/useIsHeaderMenuModalOpen.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,33 @@
1-
import { headerMenuModalId } from "./Header";
1+
import { useEffect, useState } from "react";
2+
import { headerMenuModalIdPrefix } from "./Header";
23
import { useIsModalOpen } from "../Modal/useIsModalOpen";
4+
import { symToStr } from "tsafe/symToStr";
35

46
export function useIsHeaderMenuModalOpen() {
7+
const [headerMenuModalId, setHeaderMenuModalId] = useState("");
8+
9+
useEffect(() => {
10+
const matchingElements = document.querySelectorAll(`[id^='${headerMenuModalIdPrefix}']`);
11+
12+
if (matchingElements.length > 1) {
13+
throw new Error(
14+
`There is more than one Header mounted on the page, you can't use ${symToStr({
15+
useIsHeaderMenuModalOpen
16+
})}`
17+
);
18+
}
19+
20+
if (matchingElements.length === 0) {
21+
throw new Error(
22+
`The header is not mounted on the page, you can't use ${symToStr({
23+
useIsHeaderMenuModalOpen
24+
})}`
25+
);
26+
}
27+
28+
setHeaderMenuModalId(matchingElements[0].id);
29+
}, []);
30+
531
return useIsModalOpen({
632
"id": headerMenuModalId,
733
"isOpenedByDefault": false

0 commit comments

Comments
 (0)