Skip to content

Commit 8f998c9

Browse files
Remove unnnecessary header context
1 parent f1871ab commit 8f998c9

File tree

8 files changed

+97
-184
lines changed

8 files changed

+97
-184
lines changed

docs/upgrade-to-6.0.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,22 +239,26 @@ The custom `autoSelectNext` prop is no longer supported.
239239

240240
The updated header component from NHS.UK frontend v10.x has been added. You will need to make the following changes:
241241

242+
- move `Header.Logo` props to `<Header logo={{ href: '/' }}>`
243+
- move `Header.ServiceName` props to `<Header service={{ text: "Manage patients" }}>`
242244
- remove the wrapping `Header.Container` component
243245
- remove the wrapping `Header.Content` component
246+
- remove the automatically created `Header.Logo` component
244247
- remove the automatically created `Header.ServiceName` component
245248
- remove the automatically created `Header.NavDropdownMenu` component
246249
- rename the `Header.Nav` component to `Header.Navigation`
247250
- rename the `Header.NavItem` component to `Header.NavigationItem`
248251

249252
```patch
250-
<Header>
253+
- <Header>
254+
+ <Header service={{ text: "Manage patients", href: '/' }}>
251255
- <Header.Container>
252256
- <Header.Logo href="/" />
257+
- <Header.ServiceName href="/">Manage patients</Header.ServiceName>
253258
- <Header.Content>
254259
- <Header.Search />
255260
- </Header.Content>
256261
- </Header.Container>
257-
+ <Header.Logo href="/" />
258262
+ <Header.Search />
259263
- <Header.Nav>
260264
- <Header.NavItem href="#">Example 1</Header.NavItem>

src/components/navigation/header/Header.tsx

Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,14 @@ import {
1919
HeaderNavigationItem,
2020
HeaderSearch,
2121
HeaderServiceName,
22+
type HeaderServiceNameProps,
2223
} from './components/index.js';
2324
import { HeaderContext, type IHeaderContext } from './HeaderContext.js';
2425
import { Container } from '#components/layout/index.js';
2526
import { childIsOfComponentType } from '#util/types/index.js';
2627

27-
export interface HeaderProps extends ComponentPropsWithoutRef<'div'> {
28+
export interface HeaderProps extends ComponentPropsWithoutRef<'div'>, HeaderServiceNameProps {
2829
containerClasses?: string;
29-
logo?: IHeaderContext['logoProps'];
30-
service?: IHeaderContext['serviceProps'];
31-
organisation?: IHeaderContext['organisationProps'];
3230
white?: boolean;
3331
}
3432

@@ -37,41 +35,10 @@ const HeaderComponent = forwardRef<HTMLElement, HeaderProps>((props, forwardedRe
3735
props;
3836

3937
const [moduleRef] = useState(() => forwardedRef || createRef<HTMLElement>());
40-
41-
const [logoProps, setLogoProps] = useState(logo);
42-
const [serviceProps, setServiceProps] = useState(service);
43-
const [organisationProps, setOrganisationProps] = useState(organisation);
4438
const [instanceError, setInstanceError] = useState<Error>();
4539
const [instance, setInstance] = useState<HeaderModule>();
4640
const [menuOpen, setMenuOpen] = useState(false);
4741

48-
useEffect(() => {
49-
if (!logo) {
50-
return;
51-
}
52-
53-
setLogoProps(logo);
54-
return () => setLogoProps(undefined);
55-
}, [logo]);
56-
57-
useEffect(() => {
58-
if (!service) {
59-
return;
60-
}
61-
62-
setServiceProps(service);
63-
return () => setServiceProps(undefined);
64-
}, [service]);
65-
66-
useEffect(() => {
67-
if (!organisation) {
68-
return;
69-
}
70-
71-
setOrganisationProps(organisation);
72-
return () => setOrganisationProps(undefined);
73-
}, [organisation]);
74-
7542
useEffect(() => {
7643
if (!('current' in moduleRef) || !moduleRef.current || instance) {
7744
if (!instance) {
@@ -97,20 +64,10 @@ const HeaderComponent = forwardRef<HTMLElement, HeaderProps>((props, forwardedRe
9764
}, [moduleRef, instance, menuOpen]);
9865

9966
const contextValue: IHeaderContext = useMemo(() => {
100-
return {
101-
logoProps,
102-
serviceProps,
103-
organisationProps,
104-
menuOpen,
105-
setMenuOpen,
106-
setLogoProps,
107-
setServiceProps,
108-
setOrganisationProps,
109-
};
110-
}, [logoProps, serviceProps, organisationProps, menuOpen]);
67+
return { menuOpen, setMenuOpen };
68+
}, [menuOpen]);
11169

11270
const items = Children.toArray(children);
113-
const childLogo = items.find((child) => childIsOfComponentType(child, HeaderLogo));
11471
const childSearch = items.find((child) => childIsOfComponentType(child, HeaderSearch));
11572
const childNavigation = items.find((child) => childIsOfComponentType(child, HeaderNavigation));
11673
const childAccount = items.find((child) => childIsOfComponentType(child, HeaderAccount));
@@ -123,7 +80,7 @@ const HeaderComponent = forwardRef<HTMLElement, HeaderProps>((props, forwardedRe
12380
<header
12481
className={classNames(
12582
'nhsuk-header',
126-
{ 'nhsuk-header--organisation': !!organisationProps },
83+
{ 'nhsuk-header--organisation': !!organisation },
12784
{ 'nhsuk-header--white': !!white },
12885
className,
12986
)}
@@ -134,7 +91,9 @@ const HeaderComponent = forwardRef<HTMLElement, HeaderProps>((props, forwardedRe
13491
>
13592
<HeaderContext.Provider value={contextValue}>
13693
<Container className={classNames('nhsuk-header__container', containerClasses)}>
137-
<HeaderServiceName {...serviceProps}>{childLogo}</HeaderServiceName>
94+
<HeaderServiceName logo={logo} organisation={organisation} service={service}>
95+
<HeaderLogo logo={logo} organisation={organisation} />
96+
</HeaderServiceName>
13897
{childSearch}
13998
{childAccount}
14099
</Container>
@@ -149,7 +108,6 @@ HeaderComponent.displayName = 'Header';
149108
export const Header = Object.assign(HeaderComponent, {
150109
Account: HeaderAccount,
151110
AccountItem: HeaderAccountItem,
152-
Logo: HeaderLogo,
153111
Search: HeaderSearch,
154112
Navigation: HeaderNavigation,
155113
NavigationItem: HeaderNavigationItem,

src/components/navigation/header/HeaderContext.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,11 @@
33
import { createContext, type Dispatch, type SetStateAction } from 'react';
44

55
export interface IHeaderContext {
6-
logoProps?: {
7-
'href'?: string;
8-
'src'?: string;
9-
'alt'?: string;
10-
'aria-label'?: string;
11-
};
12-
serviceProps?: {
13-
href?: string;
14-
text?: string;
15-
};
16-
organisationProps?: {
17-
name?: string;
18-
split?: string;
19-
descriptor?: string;
20-
};
216
menuOpen: boolean;
227
setMenuOpen: Dispatch<SetStateAction<IHeaderContext['menuOpen']>>;
23-
setLogoProps: Dispatch<SetStateAction<IHeaderContext['logoProps']>>;
24-
setServiceProps: Dispatch<SetStateAction<IHeaderContext['serviceProps']>>;
25-
setOrganisationProps: Dispatch<SetStateAction<IHeaderContext['organisationProps']>>;
268
}
279

2810
export const HeaderContext = createContext<IHeaderContext>({
29-
logoProps: undefined,
30-
serviceProps: undefined,
31-
organisationProps: undefined,
3211
menuOpen: false,
3312
setMenuOpen: () => {},
34-
setLogoProps: () => {},
35-
setServiceProps: () => {},
36-
setOrganisationProps: () => {},
3713
});

src/components/navigation/header/__tests__/Header.test.tsx

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import { renderClient, renderServer } from '#util/components';
55
describe('Header', () => {
66
it('matches snapshot', async () => {
77
const { container } = await renderClient(
8-
<Header>
9-
<Header.Logo href="/" />
8+
<Header logo={{ href: '/' }}>
109
<Header.Search />
1110
<Header.Navigation>
1211
<Header.NavigationItem href="/conditions">Health A-Z</Header.NavigationItem>
@@ -27,8 +26,7 @@ describe('Header', () => {
2726

2827
it('matches snapshot (via server)', async () => {
2928
const { container, element } = await renderServer(
30-
<Header>
31-
<Header.Logo href="/" />
29+
<Header logo={{ href: '/' }}>
3230
<Header.Search />
3331
<Header.Navigation>
3432
<Header.NavigationItem href="/conditions">Health A-Z</Header.NavigationItem>
@@ -58,12 +56,9 @@ describe('Header', () => {
5856
it('forwards refs', async () => {
5957
const ref = createRef<HTMLElement>();
6058

61-
const { modules } = await renderClient(
62-
<Header ref={ref}>
63-
<Header.Logo href="/" />
64-
</Header>,
65-
{ moduleName: 'nhsuk-header' },
66-
);
59+
const { modules } = await renderClient(<Header logo={{ href: '/' }} ref={ref} />, {
60+
moduleName: 'nhsuk-header',
61+
});
6762

6863
const [headerEl] = modules;
6964

@@ -106,12 +101,9 @@ describe('Header', () => {
106101

107102
describe('Header.Logo', () => {
108103
it('renders logo only', async () => {
109-
const { container } = await renderClient(
110-
<Header>
111-
<Header.Logo />
112-
</Header>,
113-
{ moduleName: 'nhsuk-header' },
114-
);
104+
const { container } = await renderClient(<Header />, {
105+
moduleName: 'nhsuk-header',
106+
});
115107

116108
const linkEl = container.querySelector('.nhsuk-header__service a');
117109
const logoEl = container.querySelector('.nhsuk-header__logo');
@@ -121,12 +113,9 @@ describe('Header', () => {
121113
});
122114

123115
it('renders logo only (with link)', async () => {
124-
const { container } = await renderClient(
125-
<Header>
126-
<Header.Logo href="/" />
127-
</Header>,
128-
{ moduleName: 'nhsuk-header' },
129-
);
116+
const { container } = await renderClient(<Header logo={{ href: '/' }} />, {
117+
moduleName: 'nhsuk-header',
118+
});
130119

131120
const linkEl = container.querySelector('.nhsuk-header__service a');
132121
const logoEl = container.querySelector('.nhsuk-header__logo');
@@ -138,9 +127,7 @@ describe('Header', () => {
138127

139128
it('renders logo and organisation name', async () => {
140129
const { container } = await renderClient(
141-
<Header organisation={{ name: 'Test organisation' }}>
142-
<Header.Logo />
143-
</Header>,
130+
<Header organisation={{ name: 'Test organisation' }} />,
144131
{ moduleName: 'nhsuk-header' },
145132
);
146133

@@ -157,9 +144,7 @@ describe('Header', () => {
157144

158145
it('renders logo (with link) and organisation name', async () => {
159146
const { container } = await renderClient(
160-
<Header organisation={{ name: 'Test organisation' }}>
161-
<Header.Logo href="/" />
162-
</Header>,
147+
<Header logo={{ href: '/' }} organisation={{ name: 'Test organisation' }} />,
163148
{ moduleName: 'nhsuk-header' },
164149
);
165150

@@ -177,9 +162,7 @@ describe('Header', () => {
177162

178163
it('renders logo (custom src) and organisation name', async () => {
179164
const { container } = await renderClient(
180-
<Header organisation={{ name: 'Test organisation' }}>
181-
<Header.Logo src="custom.svg" />
182-
</Header>,
165+
<Header logo={{ src: 'custom.svg' }} organisation={{ name: 'Test organisation' }} />,
183166
{ moduleName: 'nhsuk-header' },
184167
);
185168

@@ -196,9 +179,10 @@ describe('Header', () => {
196179

197180
it('renders logo (with link, custom src) and organisation name', async () => {
198181
const { container } = await renderClient(
199-
<Header organisation={{ name: 'Test organisation' }}>
200-
<Header.Logo href="/" src="custom.svg" />
201-
</Header>,
182+
<Header
183+
logo={{ href: '/', src: 'custom.svg' }}
184+
organisation={{ name: 'Test organisation' }}
185+
/>,
202186
{ moduleName: 'nhsuk-header' },
203187
);
204188

@@ -217,14 +201,13 @@ describe('Header', () => {
217201
it('renders logo (with link) and organisation name (split, with descriptor)', async () => {
218202
const { container } = await renderClient(
219203
<Header
204+
logo={{ href: '/' }}
220205
organisation={{
221206
name: 'Anytown Anyplace',
222207
split: 'Anywhere',
223208
descriptor: 'NHS Foundation Trust',
224209
}}
225-
>
226-
<Header.Logo href="/" />
227-
</Header>,
210+
/>,
228211
{ moduleName: 'nhsuk-header' },
229212
);
230213

@@ -245,7 +228,6 @@ describe('Header', () => {
245228
it('matches snapshot', async () => {
246229
const { container } = await renderClient(
247230
<Header>
248-
<Header.Logo />
249231
<Header.Account>
250232
<Header.AccountItem href="#" icon={true}>
251233
@@ -267,7 +249,6 @@ describe('Header', () => {
267249

268250
const { container } = await renderClient(
269251
<Header>
270-
<Header.Logo />
271252
<Header.Account>
272253
<Header.AccountItem href="#" icon={true} ref={ref1}>
273254
@@ -305,7 +286,6 @@ describe('Header', () => {
305286

306287
const { container } = await renderClient(
307288
<Header>
308-
<Header.Logo />
309289
<Header.Account>
310290
<Header.AccountItem asElement={CustomLink} href="#" icon={true}>
311291

src/components/navigation/header/__tests__/__snapshots__/Header.test.tsx.snap

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -276,24 +276,30 @@ exports[`Header matches snapshot (via server): server 1`] = `
276276
<div
277277
class="nhsuk-header__service"
278278
>
279-
<svg
280-
aria-label="NHS"
281-
class="nhsuk-header__logo"
282-
focusable="false"
283-
height="40"
284-
role="img"
285-
viewBox="0 0 200 80"
286-
width="100"
287-
xmlns="http://www.w3.org/2000/svg"
279+
<a
280+
aria-label="NHS homepage"
281+
class="nhsuk-header__service-logo"
282+
href="/"
288283
>
289-
<title>
290-
NHS
291-
</title>
292-
<path
293-
d="M200 0v80H0V0h200Zm-27.5 5.5c-14.5 0-29 5-29 22 0 10.2 7.7 13.5 14.7 16.3l.7.3c5.4 2 10.1 3.9 10.1 8.4 0 6.5-8.5 7.5-14 7.5s-12.5-1.5-16-3.5L135 70c5.5 2 13.5 3.5 20 3.5 15.5 0 32-4.5 32-22.5 0-19.5-25.5-16.5-25.5-25.5 0-5.5 5.5-6.5 12.5-6.5a35 35 0 0 1 14.5 3l4-13.5c-4.5-2-12-3-20-3Zm-131 2h-22l-14 65H22l9-45h.5l13.5 45h21.5l14-65H64l-9 45h-.5l-13-45Zm63 0h-18l-13 65h17l6-28H117l-5.5 28H129l13.5-65H125L119.5 32h-20l5-24.5Z"
294-
fill="currentcolor"
295-
/>
296-
</svg>
284+
<svg
285+
aria-label="NHS"
286+
class="nhsuk-header__logo"
287+
focusable="false"
288+
height="40"
289+
role="img"
290+
viewBox="0 0 200 80"
291+
width="100"
292+
xmlns="http://www.w3.org/2000/svg"
293+
>
294+
<title>
295+
NHS
296+
</title>
297+
<path
298+
d="M200 0v80H0V0h200Zm-27.5 5.5c-14.5 0-29 5-29 22 0 10.2 7.7 13.5 14.7 16.3l.7.3c5.4 2 10.1 3.9 10.1 8.4 0 6.5-8.5 7.5-14 7.5s-12.5-1.5-16-3.5L135 70c5.5 2 13.5 3.5 20 3.5 15.5 0 32-4.5 32-22.5 0-19.5-25.5-16.5-25.5-25.5 0-5.5 5.5-6.5 12.5-6.5a35 35 0 0 1 14.5 3l4-13.5c-4.5-2-12-3-20-3Zm-131 2h-22l-14 65H22l9-45h.5l13.5 45h21.5l14-65H64l-9 45h-.5l-13-45Zm63 0h-18l-13 65h17l6-28H117l-5.5 28H129l13.5-65H125L119.5 32h-20l5-24.5Z"
299+
fill="currentcolor"
300+
/>
301+
</svg>
302+
</a>
297303
</div>
298304
<search
299305
class="nhsuk-header__search"

0 commit comments

Comments
 (0)