11'use client' ;
2- import React , { FC , HTMLProps , useContext , useState , useEffect , useMemo , useRef } from 'react' ;
2+ import React , { HTMLProps , useState , useEffect , useMemo , useRef , Children } from 'react' ;
33import classNames from 'classnames' ;
4- import NHSLogo , { NHSLogoNavProps } from './ components/NHSLogo ' ;
5- import OrganisationalLogo , { OrganisationalLogoProps } from './components/OrganisationalLogo ' ;
4+ import { Container } from '@ components/layout ' ;
5+ import { childIsOfComponentType } from '@util/types/TypeGuards ' ;
66import HeaderContext , { IHeaderContext } from './HeaderContext' ;
7+ import Account from './components/Account' ;
8+ import AccountItem from './components/AccountItem' ;
79import Search from './components/Search' ;
8- import Nav from './components/Nav' ;
9- import NavItem from './components/NavItem' ;
10- import NavDropdownMenu from './components/NavDropdownMenu' ;
11- import { Container } from '@components/layout' ;
12- import Content from './components/Content' ;
13- import TransactionalServiceName from './components/TransactionalServiceName' ;
10+ import Navigation from './components/Navigation' ;
11+ import NavigationItem from './components/NavigationItem' ;
12+ import Service from './components/Service' ;
1413import { Header } from 'nhsuk-frontend' ;
1514
16- const HeaderLogo : FC < OrganisationalLogoProps & NHSLogoNavProps > = ( props ) => {
17- const { orgName } = useContext < IHeaderContext > ( HeaderContext ) ;
18- if ( orgName ) {
19- return < OrganisationalLogo { ...props } /> ;
20- }
21- return < NHSLogo { ...props } /> ;
22- } ;
23-
24- const HeaderContainer : FC < HTMLProps < HTMLDivElement > > = ( { className, ...rest } ) => (
25- < Container className = { classNames ( 'nhsuk-header__container' , className ) } { ...rest } />
26- ) ;
27-
2815interface HeaderProps extends HTMLProps < HTMLDivElement > {
29- transactional ?: boolean ;
30- orgName ?: string ;
31- orgSplit ?: string ;
32- orgDescriptor ?: string ;
33- serviceName ?: string ;
34- white ?: boolean ;
16+ containerClasses ?: string ;
17+ organisation ?: IHeaderContext [ 'organisation' ] ;
3518}
3619
37- const HeaderComponent = ( {
38- className,
39- children,
40- transactional,
41- orgName,
42- orgSplit,
43- orgDescriptor,
44- role = 'banner' ,
45- serviceName,
46- white,
47- ...rest
48- } : HeaderProps ) => {
20+ const HeaderComponent = ( { className, containerClasses, children, ...rest } : HeaderProps ) => {
4921 const moduleRef = useRef < HTMLDivElement > ( null ) ;
5022
51- const [ hasMenuToggle , setHasMenuToggle ] = useState ( false ) ;
52- const [ hasSearch , setHasSearch ] = useState ( false ) ;
53- const [ hasServiceName , setHasServiceName ] = useState ( false ) ;
23+ const [ service , setService ] = useState < IHeaderContext [ 'service' ] > ( ) ;
24+ const [ organisation , setOrganisation ] = useState < IHeaderContext [ 'organisation' ] > ( ) ;
5425 const [ instance , setInstance ] = useState < Header > ( ) ;
55- const [ menuOpen , setMenuOpen ] = useState ( false ) ;
26+
27+ useEffect ( ( ) => {
28+ setOrganisation ( rest . organisation ) ;
29+ return ( ) => setOrganisation ( undefined ) ;
30+ } , [ rest . organisation ] ) ;
5631
5732 useEffect ( ( ) => {
5833 if ( ! moduleRef . current || instance ) {
@@ -62,79 +37,50 @@ const HeaderComponent = ({
6237 setInstance ( new Header ( moduleRef . current ) ) ;
6338 } , [ moduleRef , instance ] ) ;
6439
65- const setMenuToggle = ( toggle : boolean ) : void => {
66- setHasMenuToggle ( toggle ) ;
67- } ;
68-
69- const setSearch = ( toggle : boolean ) : void => {
70- setHasSearch ( toggle ) ;
71- } ;
72-
73- const toggleMenu = ( ) : void => {
74- setMenuOpen ( ! menuOpen ) ;
75- } ;
76-
77- const setServiceName = ( toggle : boolean ) : void => {
78- setHasServiceName ( toggle ) ;
79- } ;
80-
8140 const contextValue : IHeaderContext = useMemo ( ( ) => {
8241 return {
83- orgName,
84- orgSplit,
85- orgDescriptor,
86- serviceName,
87- hasSearch,
88- hasMenuToggle,
89- hasServiceName,
90- setMenuToggle,
91- setSearch,
92- setServiceName,
93- toggleMenu,
94- menuOpen,
95- transactional : transactional ?? false ,
42+ service,
43+ organisation,
44+ setService,
45+ setOrganisation,
9646 } ;
97- } , [
98- orgName ,
99- orgSplit ,
100- orgDescriptor ,
101- serviceName ,
102- hasSearch ,
103- hasMenuToggle ,
104- hasServiceName ,
105- setMenuToggle ,
106- setSearch ,
107- setServiceName ,
108- toggleMenu ,
109- menuOpen ,
110- transactional ,
111- ] ) ;
47+ } , [ service , organisation ] ) ;
48+
49+ const items = Children . toArray ( children ) ;
50+
51+ const [ childService ] = items . filter ( ( child ) => childIsOfComponentType ( child , Service ) ) ;
52+ const [ childSearch ] = items . filter ( ( child ) => childIsOfComponentType ( child , Search ) ) ;
53+ const [ childNavigation ] = items . filter ( ( child ) => childIsOfComponentType ( child , Navigation ) ) ;
54+ const [ childAccount ] = items . filter ( ( child ) => childIsOfComponentType ( child , Account ) ) ;
11255
11356 return (
11457 < header
11558 className = { classNames (
11659 'nhsuk-header' ,
117- { 'nhsuk-header__transactional' : transactional } ,
118- { 'nhsuk-header--organisation' : orgName } ,
119- { 'nhsuk-header--white' : white } ,
60+ { 'nhsuk-header--organisation' : organisation } ,
12061 className ,
12162 ) }
122- role = { role }
63+ data-module = "nhsuk-header"
64+ role = "banner"
12365 ref = { moduleRef }
124- { ...rest }
12566 >
126- < HeaderContext . Provider value = { contextValue } > { children } </ HeaderContext . Provider >
67+ < HeaderContext . Provider value = { contextValue } >
68+ < Container className = { classNames ( 'nhsuk-header__container' , containerClasses ) } >
69+ { childService }
70+ { childSearch }
71+ { childAccount }
72+ </ Container >
73+ { childNavigation }
74+ </ HeaderContext . Provider >
12775 </ header >
12876 ) ;
12977} ;
13078
131- HeaderComponent . Logo = HeaderLogo ;
79+ HeaderComponent . Account = Account ;
80+ HeaderComponent . AccountItem = AccountItem ;
13281HeaderComponent . Search = Search ;
133- HeaderComponent . Nav = Nav ;
134- HeaderComponent . NavItem = NavItem ;
135- HeaderComponent . NavDropdownMenu = NavDropdownMenu ;
136- HeaderComponent . Container = HeaderContainer ;
137- HeaderComponent . Content = Content ;
138- HeaderComponent . ServiceName = TransactionalServiceName ;
82+ HeaderComponent . Navigation = Navigation ;
83+ HeaderComponent . NavigationItem = NavigationItem ;
84+ HeaderComponent . Service = Service ;
13985
14086export default HeaderComponent ;
0 commit comments