From 81e6b7ff551b1d934b0df222783345dcb22c90c4 Mon Sep 17 00:00:00 2001 From: Rowell Heria Date: Mon, 3 Jun 2024 19:25:07 +0100 Subject: [PATCH 1/5] feat: add a-to-z and back to top --- .../navigation/a-to-z/AToZ.spec.tsx | 17 ++ .../navigation/a-to-z/AToZ.stories.tsx | 52 ++++ .../src/components/navigation/a-to-z/AToZ.tsx | 85 ++++++ .../a-to-z/__snapshots__/AToZ.spec.tsx.snap | 277 ++++++++++++++++++ .../back-to-top-link/BackToTopLink.spec.tsx | 12 + .../BackToTopLink.stories.tsx | 19 ++ .../back-to-top-link/BackToTopLink.tsx | 37 +++ 7 files changed, 499 insertions(+) create mode 100644 packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.spec.tsx create mode 100644 packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.stories.tsx create mode 100644 packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.tsx create mode 100644 packages/nhsuk-frontend-react/src/components/navigation/a-to-z/__snapshots__/AToZ.spec.tsx.snap create mode 100644 packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.spec.tsx create mode 100644 packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.stories.tsx create mode 100644 packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.tsx diff --git a/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.spec.tsx b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.spec.tsx new file mode 100644 index 00000000..4dc15010 --- /dev/null +++ b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.spec.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { it, expect } from 'vitest'; +import { render } from '@testing-library/react'; +import { composeStory } from '@storybook/react'; +import meta, { Default as DefaultStory } from './AToZ.stories'; + +const AToZ = composeStory(DefaultStory, meta); + +it('should render AToZ', () => { + const { container } = render(); + + expect(container).toMatchSnapshot(); + expect(container.querySelectorAll('a')).toHaveLength(24); + expect( + container.querySelectorAll('.nhsuk-u-secondary-text-color'), + ).toHaveLength(2); +}); diff --git a/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.stories.tsx b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.stories.tsx new file mode 100644 index 00000000..1b220405 --- /dev/null +++ b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.stories.tsx @@ -0,0 +1,52 @@ +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { AToZ } from './AToZ'; + +const meta: Meta = { + title: 'Components/Navigation/A to Z', + component: AToZ, + subcomponents: { + 'AToZ.Item': AToZ.Item, + } as Record>, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: (args) => ( + + A + + B + + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + + Z + + + ), +}; diff --git a/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.tsx b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.tsx new file mode 100644 index 00000000..a422aa0d --- /dev/null +++ b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/AToZ.tsx @@ -0,0 +1,85 @@ +import React from 'react'; +import { ElementProps } from '@/types/shared'; +import clsx from 'clsx'; +import { Factory, factory } from '@/internal/factory/factory'; +import { PolymorphicFactory } from '@/internal/factory/polymorphic-factory'; +import { Base } from '@/components/core/base/Base'; + +export type AToZProps = { 'aria-label': string } & ElementProps< + 'nav', + 'aria-label' +>; + +type AToZFactory = Factory<{ + props: AToZProps; + ref: HTMLDivElement; + staticComponents: { + Item: typeof AToZItem; + }; +}>; + +const AToZ = factory( + ( + { + children, + className, + role = 'navigation', + 'aria-label': ariaLabel = 'A to Z Navigation', + ...props + }: AToZProps, + ref, + ) => { + return ( + + ); + }, +); + +export type AToZItemProps = { noItems?: boolean } & ElementProps<'a'>; + +type AToZItemFactory = PolymorphicFactory<{ + props: AToZItemProps; + defaultComponent: 'a'; + defaultRef: HTMLAnchorElement; +}>; + +const AToZItem = factory( + ({ children, className, noItems, ...props }: AToZItemProps, ref) => { + return ( +
  • + + as={noItems ? 'span' : 'a'} + className={clsx( + 'nhsuk-u-font-size-22 nhsuk-u-padding-2 nhsuk-u-display-block', + { 'nhsuk-u-secondary-text-color': noItems }, + className, + )} + {...props} + ref={ref} + > + {children} + +
  • + ); + }, +); + +AToZ.displayName = 'AToZ'; +AToZItem.displayName = 'AToZ.Item'; + +AToZ.Item = AToZItem; + +export { AToZ, AToZItem }; diff --git a/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/__snapshots__/AToZ.spec.tsx.snap b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/__snapshots__/AToZ.spec.tsx.snap new file mode 100644 index 00000000..84958a5d --- /dev/null +++ b/packages/nhsuk-frontend-react/src/components/navigation/a-to-z/__snapshots__/AToZ.spec.tsx.snap @@ -0,0 +1,277 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`should render AToZ 1`] = ` +
    + +
    +`; diff --git a/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.spec.tsx b/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.spec.tsx new file mode 100644 index 00000000..1745959e --- /dev/null +++ b/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.spec.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { it, expect } from 'vitest'; +import { render } from '@testing-library/react'; +import { composeStory } from '@storybook/react'; +import meta, { Default as DefaultStory } from './BackToTopLink.stories'; + +const BackToTopLink = composeStory(DefaultStory, meta); + +it('should render the BackToTopLink component', () => { + const { getByText } = render(); + expect(getByText('Back to top')).toBeInTheDocument(); +}); diff --git a/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.stories.tsx b/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.stories.tsx new file mode 100644 index 00000000..a31b57d3 --- /dev/null +++ b/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.stories.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { BackToTopLink } from './BackToTopLink'; + +const meta: Meta = { + title: 'Components/Navigation/Back To Top Link', + component: BackToTopLink, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + args: { + href: '#top', + }, + render: (args) => Back to top, +}; diff --git a/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.tsx b/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.tsx new file mode 100644 index 00000000..1a3e156d --- /dev/null +++ b/packages/nhsuk-frontend-react/src/components/navigation/back-to-top-link/BackToTopLink.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import clsx from 'clsx'; +import { ElementProps } from '@/types/shared'; +import { + PolymorphicFactory, + polymorphicFactory, +} from '@/internal/factory/polymorphic-factory'; +import { Base } from '@/components/core/base/Base'; + +export type BackToTopLinkProps = ElementProps<'a'>; + +type BackToTopLinkFactory = PolymorphicFactory<{ + props: BackToTopLinkProps; + defaultComponent: 'a'; + defaultRef: HTMLAnchorElement; +}>; + +const BackToTopLink = polymorphicFactory( + ({ children, className, ...props }: BackToTopLinkProps, ref) => { + return ( +
    + + {children} + +
    + ); + }, +); + +BackToTopLink.displayName = 'BackToTopLink'; + +export { BackToTopLink }; From 61eb5acb40ed269aa13d1d0e9804bd91b44d95b2 Mon Sep 17 00:00:00 2001 From: Rowell Heria Date: Mon, 3 Jun 2024 19:25:21 +0100 Subject: [PATCH 2/5] style: format codebase --- .../HelpUsersDecideWhenAndWhereToGetCare.stories.tsx | 6 +++++- .../ReassureUsersThatAPageIsUpToDate.stories.tsx | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/nhsuk-frontend-react/src/__stories__/patterns/HelpUsersDecideWhenAndWhereToGetCare.stories.tsx b/packages/nhsuk-frontend-react/src/__stories__/patterns/HelpUsersDecideWhenAndWhereToGetCare.stories.tsx index d25f13d5..feae2f84 100644 --- a/packages/nhsuk-frontend-react/src/__stories__/patterns/HelpUsersDecideWhenAndWhereToGetCare.stories.tsx +++ b/packages/nhsuk-frontend-react/src/__stories__/patterns/HelpUsersDecideWhenAndWhereToGetCare.stories.tsx @@ -1,5 +1,9 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { NonUrgentCareCard, UrgentCareCard, EmergencyCareCard } from '@/components/navigation/card/Card.stories'; +import { + NonUrgentCareCard, + UrgentCareCard, + EmergencyCareCard, +} from '@/components/navigation/card/Card.stories'; /** * Care cards help users identify and understand the care they need, who to contact and how quickly. diff --git a/packages/nhsuk-frontend-react/src/__stories__/patterns/ReassureUsersThatAPageIsUpToDate.stories.tsx b/packages/nhsuk-frontend-react/src/__stories__/patterns/ReassureUsersThatAPageIsUpToDate.stories.tsx index 36181957..b83c77b8 100644 --- a/packages/nhsuk-frontend-react/src/__stories__/patterns/ReassureUsersThatAPageIsUpToDate.stories.tsx +++ b/packages/nhsuk-frontend-react/src/__stories__/patterns/ReassureUsersThatAPageIsUpToDate.stories.tsx @@ -17,8 +17,13 @@ type Story = StoryObj; export const ReassureUsersThatAPageIsUpToDate: Story = { render: (args) => ( - - Page last reviewed: 15 March 2021
    + + Page last reviewed: 15 March 2021 +
    Next review due: 15 March 2024
    ), From 3fe29f61904b072396442e434624b75e898a317c Mon Sep 17 00:00:00 2001 From: Rowell Heria Date: Mon, 3 Jun 2024 19:44:43 +0100 Subject: [PATCH 3/5] fix: add missing element props for heading --- .../src/components/styles/typography/heading/Heading.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/nhsuk-frontend-react/src/components/styles/typography/heading/Heading.tsx b/packages/nhsuk-frontend-react/src/components/styles/typography/heading/Heading.tsx index 3580964e..ba85ee28 100644 --- a/packages/nhsuk-frontend-react/src/components/styles/typography/heading/Heading.tsx +++ b/packages/nhsuk-frontend-react/src/components/styles/typography/heading/Heading.tsx @@ -4,13 +4,14 @@ import { PolymorphicFactory, polymorphicFactory, } from '@/internal/factory/polymorphic-factory'; -import { AsElementProps, HeadingLevel } from '@/types/shared'; +import { AsElementProps, ElementProps, HeadingLevel } from '@/types/shared'; import clsx from 'clsx'; export type HeadingSize = 'xl' | 'l' | 'm' | 's' | 'xs'; export type HeadingProps = { size?: HeadingSize } & BaseProps & - AsElementProps; + AsElementProps & + ElementProps<'h1'>; type HeadingFactory = PolymorphicFactory<{ props: HeadingProps; From ad3357ddc3aedd17ff90fa3a232e555dd0f3d046 Mon Sep 17 00:00:00 2001 From: Rowell Heria Date: Mon, 3 Jun 2024 20:35:03 +0100 Subject: [PATCH 4/5] docs: add pages patterns --- .../__stories__/patterns/AToZPage.stories.tsx | 95 ++++++++++++++ .../__stories__/patterns/MiniHub.stories.tsx | 120 ++++++++++++++++++ .../patterns/StartPage.stories.tsx | 84 ++++++++++++ 3 files changed, 299 insertions(+) create mode 100644 packages/nhsuk-frontend-react/src/__stories__/patterns/AToZPage.stories.tsx create mode 100644 packages/nhsuk-frontend-react/src/__stories__/patterns/MiniHub.stories.tsx create mode 100644 packages/nhsuk-frontend-react/src/__stories__/patterns/StartPage.stories.tsx diff --git a/packages/nhsuk-frontend-react/src/__stories__/patterns/AToZPage.stories.tsx b/packages/nhsuk-frontend-react/src/__stories__/patterns/AToZPage.stories.tsx new file mode 100644 index 00000000..5469b150 --- /dev/null +++ b/packages/nhsuk-frontend-react/src/__stories__/patterns/AToZPage.stories.tsx @@ -0,0 +1,95 @@ +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { AToZ } from '@/components/navigation/a-to-z/AToZ'; +import { Header } from '@/components/navigation/header/Header'; +import { Container } from '@/components/styles/layout/container/Container'; +import { Card } from '@/components/navigation/card/Card'; +import { Main } from '@/components/styles/layout/main/Main'; +import { Column, Row } from '@/components/styles/layout/grid/Grid'; +import { Heading } from '@/components/styles/typography/heading/Heading'; +import { List } from '@/components/styles/typography/list/List'; +import { Link } from '@/components/styles/typography/link/Link'; +import { Footer } from '@/components/navigation/footer/Footer'; + +/** + * A to Z is a way of presenting a number of pages alphabetically. + * + * https://service-manual.nhs.uk/design-system/patterns/a-to-z-page + */ +const meta: Meta = { + title: 'Patterns/Page types/A to Z page', + parameters: { + layout: 'fullscreen', + }, +}; + +export default meta; + +type Story = StoryObj; + +export const AToZPage: Story = { + render: (args) => ( + <> +
    + + + + +
    + + +
    + + + Health A to Z + + + A + + B + + C + D + + + + + A + + + AAA + + + Abdominal aortic aneurysm + + + Abscess + + + + + + + + B + + + There are currently no conditions listed + + + + + + +
    +
    + +
    + + + NHS England + +
    + + ), +}; diff --git a/packages/nhsuk-frontend-react/src/__stories__/patterns/MiniHub.stories.tsx b/packages/nhsuk-frontend-react/src/__stories__/patterns/MiniHub.stories.tsx new file mode 100644 index 00000000..eb8a6054 --- /dev/null +++ b/packages/nhsuk-frontend-react/src/__stories__/patterns/MiniHub.stories.tsx @@ -0,0 +1,120 @@ +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { Header } from '@/components/navigation/header/Header'; +import { Container } from '@/components/styles/layout/container/Container'; +import { Main } from '@/components/styles/layout/main/Main'; +import { Column, Row } from '@/components/styles/layout/grid/Grid'; +import { Heading } from '@/components/styles/typography/heading/Heading'; +import { List } from '@/components/styles/typography/list/List'; +import { Footer } from '@/components/navigation/footer/Footer'; +import { Breadcrumb } from '@/components/navigation/breadcrumb/Breadcrumb'; +import { VisuallyHidden } from '@/components/core/visually-hidden/VisuallyHidden'; +import { ContentsList } from '@/components/navigation/contents-list/ContentsList'; +import { Paragraph } from '@/components/styles/typography/paragraph/Paragraph'; +import { Pagination } from '@/components/navigation/pagination/Pagination'; + +const meta: Meta = { + title: 'Patterns/Page types/Mini-hub page', + parameters: { + layout: 'fullscreen', + }, +}; + +export default meta; + +type Story = StoryObj; + +export const MiniHub: Story = { + render: (args) => ( + <> +
    + + + + +
    + + + + Home + Health A to Z + + Health A to Z + + + +
    + + + + + What is AMD? + + - + Age-related macular degeneration (AMD) + + + + + + + What is AMD? + + Symptoms + + Getting diagnosed + + Treatment + Living with AMD + + + + + + Age-related macular degeneration (AMD) is a common condition + that affects the middle part of your vision. + {' '} + It usually first affects people in their 50s and 60s. + + + It doesn't cause total blindness. But it can + make everyday activities like reading and recognising faces + difficult. + + + Without treatment, your vision may get worse.{' '} + This can happen gradually over several years ("dry AMD"), or + quickly over a few weeks or months ("wet AMD"). + + + The exact cause is unknown. It's been linked + to smoking, high blood pressure, being overweight and having a + family history of AMD. + + + + + Page last reviewed: 27 March 2018
    + Next review due: 27 March 2021 +
    + + + + +
    +
    +
    +
    + +
    + + + NHS England + +
    + + ), +}; diff --git a/packages/nhsuk-frontend-react/src/__stories__/patterns/StartPage.stories.tsx b/packages/nhsuk-frontend-react/src/__stories__/patterns/StartPage.stories.tsx new file mode 100644 index 00000000..43241e1c --- /dev/null +++ b/packages/nhsuk-frontend-react/src/__stories__/patterns/StartPage.stories.tsx @@ -0,0 +1,84 @@ +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react'; +import { Header } from '@/components/navigation/header/Header'; +import { Container } from '@/components/styles/layout/container/Container'; +import { Main } from '@/components/styles/layout/main/Main'; +import { Column, Row } from '@/components/styles/layout/grid/Grid'; +import { Heading } from '@/components/styles/typography/heading/Heading'; +import { Footer } from '@/components/navigation/footer/Footer'; +import { Breadcrumb } from '@/components/navigation/breadcrumb/Breadcrumb'; +import { Paragraph } from '@/components/styles/typography/paragraph/Paragraph'; +import { Pagination } from '@/components/navigation/pagination/Pagination'; +import { Button } from '@/components/form-elements/button/Button'; + +const meta: Meta = { + title: 'Patterns/Page types/Start page', + parameters: { + layout: 'fullscreen', + }, +}; + +export default meta; + +type Story = StoryObj; + +export const MiniHub: Story = { + render: (args) => ( + <> +
    + + + + +
    + + + + Home + Section + Subsection + + Subsection + + + +
    + + + Service name goes here + + Use this service to do something. + You can use this service if you: + +
      +
    • live in England
    • +
    • need to get a thing
    • +
    • need to change a thing
    • +
    + + Before you start + + We'll ask you for: ... + + + + + By using this service you are agreeing to our{' '} + terms of use and privacy policy. + +
    +
    +
    +
    + +
    + + + NHS England + +
    + + ), +}; From fd62a29f3528163f36846735082f0fd673489dcd Mon Sep 17 00:00:00 2001 From: Rowell Heria Date: Mon, 3 Jun 2024 20:37:54 +0100 Subject: [PATCH 5/5] chore: generate changeset --- .changeset/gold-suns-argue.md | 5 +++++ .changeset/smooth-falcons-provide.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/gold-suns-argue.md create mode 100644 .changeset/smooth-falcons-provide.md diff --git a/.changeset/gold-suns-argue.md b/.changeset/gold-suns-argue.md new file mode 100644 index 00000000..fb8aaf08 --- /dev/null +++ b/.changeset/gold-suns-argue.md @@ -0,0 +1,5 @@ +--- +"nhsuk-frontend-react": minor +--- + +feat: add a-to-z and back to top diff --git a/.changeset/smooth-falcons-provide.md b/.changeset/smooth-falcons-provide.md new file mode 100644 index 00000000..d01fe124 --- /dev/null +++ b/.changeset/smooth-falcons-provide.md @@ -0,0 +1,5 @@ +--- +"nhsuk-frontend-react": patch +--- + +fix: add missing element props for heading