Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Header component #104

Merged
merged 3 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bright-owls-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nhsuk-frontend-react": patch
---

style(nhsuk-frontend-react): format Tag source code
7 changes: 7 additions & 0 deletions .changeset/late-masks-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"nhsuk-frontend-react": patch
---

fix(nhsuk-frontend-react): update useEffect to trigger when NavList children update

This moves the invocation of the header script into NavList so it can react to the changes to the children. Useful for when the links are dynamically rendred.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export type TagProps = {
} & ElementProps<'strong'>;

const Tag = ({ variant = 'grey', className, ...props }: TagProps) => {
return <strong className={clsx('nhsuk-tag', `nhsuk-tag--${variant}`, className)} {...props} />;
return (
<strong
className={clsx('nhsuk-tag', `nhsuk-tag--${variant}`, className)}
{...props}
/>
);
};

Tag.displayName = 'Tag';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { Header } from './Header';
import { Header, HeaderProps } from './Header';

/**
* Use the appropriate header at the top of every page to show users they are on an NHS service and help them get started in finding what they need.
Expand Down Expand Up @@ -157,3 +157,56 @@ export const WithOrgansation: Story = {
</Header>
),
};

const SampleNav = (props: HeaderProps) => {
const [isVisible, setIsVisible] = useState(false);

useEffect(() => {
setTimeout(() => {
setIsVisible(true);
}, 2000);
}, []);

return (
<Header {...props}>
<Header.Container>
<Header.Logo href="#" aria-label="NHS homepage" />
<Header.Content>
<Header.Search
inputProps={{ visuallyHiddenText: 'Search the NHS website' }}
buttonProps={{ visuallyHiddenText: 'Search' }}
/>
</Header.Content>
</Header.Container>
<Header.Nav>
<Header.NavList>
{isVisible ? (
<>
<Header.NavItem href="#">Health A-Z</Header.NavItem>
<Header.NavItem href="#">Live Well</Header.NavItem>
<Header.NavItem href="#">Mental health</Header.NavItem>
<Header.NavItem href="#">Care and support</Header.NavItem>
<Header.NavItem href="#">Pregnancy</Header.NavItem>
<Header.NavItem href="#">NHS services</Header.NavItem>
<Header.NavItem href="#" variant="home-link">
Home
</Header.NavItem>
<Header.MobileMenu />
</>
) : (
<Header.NavItem href="#">Health A-Z</Header.NavItem>
)}
</Header.NavList>
</Header.Nav>
</Header>
);
};

export const WithDelayedNav: Story = {
args: {
organisationName: 'Anytown Anyplace',
organisationSplit: 'Anywhere',
organisationDescriptor: 'NHS Foundation Trust',
},
render: (args) => <SampleNav {...args} />,
};
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,6 @@ const Header = factory<HeaderFactory>(
[],
);

const internalRef = useRef<HTMLDivElement>(null);

useImperativeHandle(ref, () => internalRef.current as HTMLDivElement);

useEffect(() => {
if (!internalRef.current) {
return;
}

initHeader();
}, [internalRef]);

return (
<HeaderContextProvider value={value}>
<header
Expand All @@ -133,7 +121,7 @@ const Header = factory<HeaderFactory>(
)}
role="banner"
{...props}
ref={internalRef}
ref={ref}
>
{children}
</header>
Expand Down Expand Up @@ -306,17 +294,36 @@ const HeaderNav = ({ children, className, ...props }: HeaderNavProps) => {

export type HeaderNavListProps = ElementProps<'ul'>;

const HeaderNavList = ({
children,
className,
...props
}: HeaderNavListProps) => {
return (
<ul className={clsx('nhsuk-header__navigation-list', className)} {...props}>
{children}
</ul>
);
};
type HeaderNavListFactory = Factory<{
props: HeaderNavListProps;
ref: HTMLUListElement;
}>;

const HeaderNavList = factory<HeaderNavListFactory>(
({ children, className, ...props }: HeaderNavListProps, ref) => {
const internalRef = useRef<HTMLUListElement>(null);

useImperativeHandle(ref, () => internalRef.current as HTMLUListElement);

useEffect(() => {
if (!internalRef.current) {
return;
}

initHeader();
}, [internalRef, children]);

return (
<ul
className={clsx('nhsuk-header__navigation-list', className)}
{...props}
ref={internalRef}
>
{children}
</ul>
);
},
);

export type HeaderNavItemProps = { variant?: 'home-link' } & BaseProps;

Expand Down