From 3ae0b8ef4d286ef0988e1ef372892e3b1110c15f Mon Sep 17 00:00:00 2001 From: Colin Rotherham Date: Mon, 1 Sep 2025 12:24:04 +0100 Subject: [PATCH 01/65] Upgrade to NHS.UK frontend v10.0.0 --- package.json | 4 ++-- yarn.lock | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 671def70..615e22da 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "jest": "^29.7.0", "jest-axe": "^8.0.0", "jest-environment-jsdom": "^29.7.0", - "nhsuk-frontend": "^9.0.1", + "nhsuk-frontend": "^10.0.0", "prettier": "^3.2.5", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -87,7 +87,7 @@ "classnames": "^2.2.6" }, "peerDependencies": { - "nhsuk-frontend": ">=9.0.0 <10.0.0", + "nhsuk-frontend": ">=10.0.0 <11.0.0", "react": ">=16.8.0", "react-dom": ">=16.8.0" }, diff --git a/yarn.lock b/yarn.lock index 96e463c0..ed763ba3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9269,10 +9269,10 @@ __metadata: languageName: node linkType: hard -"nhsuk-frontend@npm:^9.0.1": - version: 9.0.1 - resolution: "nhsuk-frontend@npm:9.0.1" - checksum: 10c0/50a071be382807bb5c7b474d01f40d6cc59198cf601c9b52f168c7cc8d7e09c092d35dfea53bc654417cb07739b5fceb481e61aeb39a7c2621b54b78b82c8e0c +"nhsuk-frontend@npm:^10.0.0": + version: 10.0.0 + resolution: "nhsuk-frontend@npm:10.0.0" + checksum: 10c0/5a24cc7b56188d18bbd86c040e39b420546451f1b955eed176f4acd5f3b75d6ec5eef86b8ab970cff1b4741f2f599debae03bf4be75c3f6a903cfce205e88501 languageName: node linkType: hard @@ -9321,7 +9321,7 @@ __metadata: jest: "npm:^29.7.0" jest-axe: "npm:^8.0.0" jest-environment-jsdom: "npm:^29.7.0" - nhsuk-frontend: "npm:^9.0.1" + nhsuk-frontend: "npm:^10.0.0" prettier: "npm:^3.2.5" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" @@ -9338,7 +9338,7 @@ __metadata: vite: "npm:^4.5.3" vite-tsconfig-paths: "npm:^4.3.2" peerDependencies: - nhsuk-frontend: ">=9.0.0 <10.0.0" + nhsuk-frontend: ">=10.0.0 <11.0.0" react: ">=16.8.0" react-dom: ">=16.8.0" languageName: unknown From ac97ac186d942b698319abd05d92c19364779c34 Mon Sep 17 00:00:00 2001 From: Colin Rotherham Date: Mon, 8 Sep 2025 07:53:27 +0100 Subject: [PATCH 02/65] Set up environments for NHS.UK frontend v10.0.0 --- .storybook/preview-body.html | 4 ++++ .storybook/preview-head.html | 9 ------- package.json | 1 + src/setupTests.ts | 46 ++++++++++++++++++++++++++++++++++++ yarn.lock | 8 +++++++ 5 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 .storybook/preview-body.html delete mode 100644 .storybook/preview-head.html diff --git a/.storybook/preview-body.html b/.storybook/preview-body.html new file mode 100644 index 00000000..a76f826b --- /dev/null +++ b/.storybook/preview-body.html @@ -0,0 +1,4 @@ + diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index 439f564f..00000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/package.json b/package.json index 615e22da..75da2bde 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "jest-axe": "^8.0.0", "jest-environment-jsdom": "^29.7.0", "nhsuk-frontend": "^10.0.0", + "outdent": "^0.8.0", "prettier": "^3.2.5", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/src/setupTests.ts b/src/setupTests.ts index 7b0828bf..4f88ef00 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -1 +1,47 @@ import '@testing-library/jest-dom'; +import { outdent } from 'outdent'; + +/** + * Polyfill Element methods for NHS.UK frontend error summary + * + * @see {@link https://github.com/jsdom/jsdom/issues/1695} + */ +Object.defineProperties(Element.prototype, { + scrollIntoView: { value: jest.fn() }, +}); + +/** + * Polyfill `window.matchMedia()` for NHS.UK frontend tabs + */ +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: jest.fn().mockImplementation((query) => ({ + matches: true, + media: query, + onchange: null, + addListener: jest.fn(), + addEventListener: jest.fn(), + removeListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + })), +}); + +beforeEach(() => { + const stylesheet = document.createElement('style'); + + stylesheet.innerHTML = outdent` + :root { + --nhsuk-breakpoint-mobile: 20rem; + --nhsuk-breakpoint-tablet: 40.0625rem; + --nhsuk-breakpoint-desktop: 48.0625rem; + --nhsuk-breakpoint-large-desktop: 61.875rem; + } + `; + + // Add styles for NHS.UK frontend checks + document.head.appendChild(stylesheet); + + // Flag NHS.UK frontend as supported + document.body.classList.add('nhsuk-frontend-supported'); +}); diff --git a/yarn.lock b/yarn.lock index ed763ba3..e10eba5e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9322,6 +9322,7 @@ __metadata: jest-axe: "npm:^8.0.0" jest-environment-jsdom: "npm:^29.7.0" nhsuk-frontend: "npm:^10.0.0" + outdent: "npm:^0.8.0" prettier: "npm:^3.2.5" react: "npm:^18.2.0" react-dom: "npm:^18.2.0" @@ -9669,6 +9670,13 @@ __metadata: languageName: node linkType: hard +"outdent@npm:^0.8.0": + version: 0.8.0 + resolution: "outdent@npm:0.8.0" + checksum: 10c0/d8a6c38b838b7ac23ebf1cc50442312f4efe286b211dbe5c71fa84d5daa2512fb94a8f2df1389313465acb0b4e5fa72270dd78f519f3d4db5bc22b2762c86827 + languageName: node + linkType: hard + "p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" From 67278a01fa931896e7db62b2743333694de34282 Mon Sep 17 00:00:00 2001 From: Colin Rotherham Date: Tue, 23 Sep 2025 18:10:09 +0100 Subject: [PATCH 03/65] Prevent clashes with NHS.UK frontend exports --- src/__tests__/index.test.ts | 2 - .../content-presentation/details/Details.tsx | 12 +-- .../content-presentation/details/index.ts | 4 +- .../do-and-dont-list/DoAndDontList.tsx | 8 +- .../do-and-dont-list/index.ts | 4 +- .../content-presentation/hero/Hero.tsx | 10 +- .../content-presentation/hero/index.ts | 4 +- .../content-presentation/images/Images.tsx | 4 +- .../content-presentation/images/index.ts | 4 +- .../inset-text/InsetText.tsx | 4 +- .../content-presentation/inset-text/index.ts | 4 +- .../summary-list/SummaryList.tsx | 14 +-- .../summary-list/index.ts | 4 +- .../content-presentation/table/Table.tsx | 18 ++-- .../content-presentation/table/index.ts | 4 +- .../content-presentation/tabs/Tabs.tsx | 18 ++-- .../content-presentation/tabs/index.ts | 4 +- .../content-presentation/tag/Tag.tsx | 4 +- .../content-presentation/tag/index.ts | 4 +- .../warning-callout/WarningCallout.tsx | 6 +- .../warning-callout/index.ts | 4 +- .../form-elements/button/Button.tsx | 23 ++--- .../button/__tests__/Button.test.tsx | 48 +++++----- .../__snapshots__/Button.test.tsx.snap | 94 +++++++++---------- src/components/form-elements/button/index.ts | 5 +- .../character-count/CharacterCount.tsx | 8 +- .../form-elements/character-count/index.ts | 5 +- .../form-elements/checkboxes/Checkboxes.tsx | 16 ++-- .../checkboxes/__tests__/Checkboxes.test.tsx | 38 ++++---- .../checkboxes/components/Divider.tsx | 4 +- .../components/{Box.tsx => Item.tsx} | 6 +- .../form-elements/checkboxes/index.ts | 4 +- .../form-elements/date-input/DateInput.tsx | 16 ++-- .../form-elements/date-input/index.ts | 4 +- .../error-message/ErrorMessage.tsx | 4 +- .../form-elements/error-message/index.ts | 4 +- .../error-summary/ErrorSummary.tsx | 48 +++++----- .../form-elements/error-summary/index.ts | 4 +- .../form-elements/fieldset/Fieldset.tsx | 11 ++- .../form-elements/fieldset/index.ts | 4 +- src/components/form-elements/form/Form.tsx | 4 +- src/components/form-elements/form/index.ts | 6 +- .../form-elements/hint-text/HintText.tsx | 4 +- .../form-elements/hint-text/index.ts | 4 +- src/components/form-elements/label/Label.tsx | 10 +- src/components/form-elements/label/index.ts | 4 +- .../form-elements/radios/Radios.tsx | 12 +-- .../radios/__tests__/Radios.test.tsx | 24 ++--- .../radios/components/Divider.tsx | 4 +- .../radios/components/{Radio.tsx => Item.tsx} | 6 +- src/components/form-elements/radios/index.ts | 4 +- .../form-elements/select/Select.tsx | 6 +- src/components/form-elements/select/index.ts | 4 +- .../form-elements/text-input/TextInput.tsx | 4 +- .../form-elements/text-input/index.ts | 4 +- .../form-elements/textarea/Textarea.tsx | 4 +- .../form-elements/textarea/index.ts | 4 +- .../navigation/action-link/ActionLink.tsx | 10 +- .../navigation/action-link/index.ts | 4 +- .../navigation/back-link/BackLink.tsx | 10 +- src/components/navigation/back-link/index.ts | 4 +- .../navigation/breadcrumb/Breadcrumb.tsx | 22 ++--- src/components/navigation/breadcrumb/index.ts | 4 +- src/components/navigation/card/Card.tsx | 18 ++-- .../navigation/card/components/CardLink.tsx | 4 +- src/components/navigation/card/index.ts | 4 +- .../navigation/contents-list/ContentsList.tsx | 8 +- .../navigation/contents-list/index.ts | 4 +- src/components/navigation/footer/Footer.tsx | 17 ++-- src/components/navigation/footer/index.ts | 4 +- src/components/navigation/header/Header.tsx | 26 ++--- .../navigation/header/components/NHSLogo.tsx | 6 +- .../navigation/header/components/NavItem.tsx | 6 +- .../header/components/OrganisationalLogo.tsx | 6 +- src/components/navigation/header/index.ts | 4 +- .../navigation/pagination/Pagination.tsx | 8 +- src/components/navigation/pagination/index.ts | 4 +- .../navigation/skip-link/SkipLink.tsx | 4 +- src/components/navigation/skip-link/index.ts | 4 +- src/index.ts | 6 +- src/patterns/nav-a-z/NavAZ.tsx | 4 +- src/patterns/panel/Panel.tsx | 4 +- stories/Form Elements/Button.stories.tsx | 20 +--- stories/Form Elements/Checkboxes.stories.tsx | 92 +++++++++--------- stories/Form Elements/Radios.stories.tsx | 86 ++++++++--------- 85 files changed, 455 insertions(+), 532 deletions(-) rename src/components/form-elements/checkboxes/components/{Box.tsx => Item.tsx} (95%) rename src/components/form-elements/radios/components/{Radio.tsx => Item.tsx} (94%) diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 80446756..19aa2712 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -13,7 +13,6 @@ describe('Index', () => { 'BodyText', 'Breadcrumb', 'Button', - 'ButtonLink', 'Card', 'CharacterCount', 'CharacterCountType', @@ -27,7 +26,6 @@ describe('Index', () => { 'ContentsList', 'CrossIcon', 'DateInput', - 'DefaultButton', 'Details', 'DoAndDontList', 'EmdashIcon', diff --git a/src/components/content-presentation/details/Details.tsx b/src/components/content-presentation/details/Details.tsx index 64a07302..8adb7253 100644 --- a/src/components/content-presentation/details/Details.tsx +++ b/src/components/content-presentation/details/Details.tsx @@ -5,14 +5,14 @@ interface DetailsProps extends HTMLProps { expander?: boolean; } -interface Details extends FC { +interface DetailsComponent extends FC { Summary: FC>; Text: FC>; ExpanderGroup: FC>; } // TODO: Check if standard NHS.UK polyfill "details.polyfill.js" is required -const Details: Details = ({ className, expander, ...rest }) => ( +const DetailsComponent: DetailsComponent = ({ className, expander, ...rest }) => (
> = ({ className, ...rest }) =>
); -Details.Summary = DetailsSummary; -Details.Text = DetailsText; -Details.ExpanderGroup = ExpanderGroup; +DetailsComponent.Summary = DetailsSummary; +DetailsComponent.Text = DetailsText; +DetailsComponent.ExpanderGroup = ExpanderGroup; -export default Details; +export default DetailsComponent; diff --git a/src/components/content-presentation/details/index.ts b/src/components/content-presentation/details/index.ts index 2c1372e2..72e3cee2 100644 --- a/src/components/content-presentation/details/index.ts +++ b/src/components/content-presentation/details/index.ts @@ -1,3 +1 @@ -import Details from './Details'; - -export default Details; +export { default } from './Details'; diff --git a/src/components/content-presentation/do-and-dont-list/DoAndDontList.tsx b/src/components/content-presentation/do-and-dont-list/DoAndDontList.tsx index 28c037a2..a77ffb2b 100644 --- a/src/components/content-presentation/do-and-dont-list/DoAndDontList.tsx +++ b/src/components/content-presentation/do-and-dont-list/DoAndDontList.tsx @@ -12,13 +12,13 @@ interface DoAndDontListProps extends HTMLProps { headingLevel?: HeadingLevelType; } -interface DoAndDontList extends FC { +interface DoAndDontListComponent extends FC { Item: FC; } const DoAndDontListContext = createContext('do'); -const DoAndDontList: DoAndDontList = ({ +const DoAndDontListComponent: DoAndDontListComponent = ({ className, listType, children, @@ -71,6 +71,6 @@ const DoAndDontItem: FC = ({ prefixText, listItemType, child ); }; -DoAndDontList.Item = DoAndDontItem; +DoAndDontListComponent.Item = DoAndDontItem; -export default DoAndDontList; +export default DoAndDontListComponent; diff --git a/src/components/content-presentation/do-and-dont-list/index.ts b/src/components/content-presentation/do-and-dont-list/index.ts index 9f2802b5..f6db6b15 100644 --- a/src/components/content-presentation/do-and-dont-list/index.ts +++ b/src/components/content-presentation/do-and-dont-list/index.ts @@ -1,3 +1 @@ -import DoAndDontList from './DoAndDontList'; - -export default DoAndDontList; +export { default } from './DoAndDontList'; diff --git a/src/components/content-presentation/hero/Hero.tsx b/src/components/content-presentation/hero/Hero.tsx index 09a60434..cf8a45e4 100644 --- a/src/components/content-presentation/hero/Hero.tsx +++ b/src/components/content-presentation/hero/Hero.tsx @@ -49,12 +49,12 @@ interface HeroProps extends HTMLProps { imageSrc?: string; } -interface Hero extends FC { +interface HeroComponent extends FC { Heading: FC; Text: FC>; } -const Hero: Hero = ({ className, children, imageSrc, ...rest }) => ( +const HeroComponent: HeroComponent = ({ className, children, imageSrc, ...rest }) => (
(
); -Hero.Heading = HeroHeading; -Hero.Text = HeroText; +HeroComponent.Heading = HeroHeading; +HeroComponent.Text = HeroText; -export default Hero; +export default HeroComponent; diff --git a/src/components/content-presentation/hero/index.ts b/src/components/content-presentation/hero/index.ts index a9cfb5f3..9c292bc0 100644 --- a/src/components/content-presentation/hero/index.ts +++ b/src/components/content-presentation/hero/index.ts @@ -1,3 +1 @@ -import Hero from './Hero'; - -export default Hero; +export { default } from './Hero'; diff --git a/src/components/content-presentation/images/Images.tsx b/src/components/content-presentation/images/Images.tsx index 83b68ad2..978ee242 100644 --- a/src/components/content-presentation/images/Images.tsx +++ b/src/components/content-presentation/images/Images.tsx @@ -8,7 +8,7 @@ interface ImageProps extends HTMLProps { caption?: string; } -const Images: FC = ({ className, caption, ...rest }) => ( +const ImagesComponent: FC = ({ className, caption, ...rest }) => (
{/* eslint-disable-next-line jsx-a11y/alt-text */} @@ -16,4 +16,4 @@ const Images: FC = ({ className, caption, ...rest }) => (
); -export default Images; +export default ImagesComponent; diff --git a/src/components/content-presentation/images/index.ts b/src/components/content-presentation/images/index.ts index 3edaab75..c75230f3 100644 --- a/src/components/content-presentation/images/index.ts +++ b/src/components/content-presentation/images/index.ts @@ -1,3 +1 @@ -import Images from './Images'; - -export default Images; +export { default } from './Images'; diff --git a/src/components/content-presentation/inset-text/InsetText.tsx b/src/components/content-presentation/inset-text/InsetText.tsx index b61dcb5a..31ddf11a 100644 --- a/src/components/content-presentation/inset-text/InsetText.tsx +++ b/src/components/content-presentation/inset-text/InsetText.tsx @@ -5,7 +5,7 @@ interface InsetTextProps extends HTMLProps { visuallyHiddenText?: string | false; } -const InsetText: FC = ({ +const InsetTextComponent: FC = ({ className, children, visuallyHiddenText = 'Information: ', @@ -19,4 +19,4 @@ const InsetText: FC = ({
); -export default InsetText; +export default InsetTextComponent; diff --git a/src/components/content-presentation/inset-text/index.ts b/src/components/content-presentation/inset-text/index.ts index 1edf1f43..4839c489 100644 --- a/src/components/content-presentation/inset-text/index.ts +++ b/src/components/content-presentation/inset-text/index.ts @@ -1,3 +1 @@ -import InsetText from './InsetText'; - -export default InsetText; +export { default } from './InsetText'; diff --git a/src/components/content-presentation/summary-list/SummaryList.tsx b/src/components/content-presentation/summary-list/SummaryList.tsx index 7eb4426d..d98d0ba4 100644 --- a/src/components/content-presentation/summary-list/SummaryList.tsx +++ b/src/components/content-presentation/summary-list/SummaryList.tsx @@ -21,14 +21,14 @@ interface SummaryListProps extends HTMLProps { noBorder?: boolean; } -interface SummaryList extends FC { +interface SummaryListComponent extends FC { Row: FC>; Key: FC>; Value: FC>; Actions: FC>; } -const SummaryList: SummaryList = ({ className, noBorder, ...rest }) => ( +const SummaryListComponent: SummaryListComponent = ({ className, noBorder, ...rest }) => (
( /> ); -SummaryList.Row = SummaryListRow; -SummaryList.Key = SummaryListKey; -SummaryList.Value = SummaryListValue; -SummaryList.Actions = SummaryListActions; +SummaryListComponent.Row = SummaryListRow; +SummaryListComponent.Key = SummaryListKey; +SummaryListComponent.Value = SummaryListValue; +SummaryListComponent.Actions = SummaryListActions; -export default SummaryList; +export default SummaryListComponent; diff --git a/src/components/content-presentation/summary-list/index.ts b/src/components/content-presentation/summary-list/index.ts index 0b806295..b5626639 100644 --- a/src/components/content-presentation/summary-list/index.ts +++ b/src/components/content-presentation/summary-list/index.ts @@ -1,3 +1 @@ -import SummaryList from './SummaryList'; - -export default SummaryList; +export { default } from './SummaryList'; diff --git a/src/components/content-presentation/table/Table.tsx b/src/components/content-presentation/table/Table.tsx index 73942891..2eef0107 100644 --- a/src/components/content-presentation/table/Table.tsx +++ b/src/components/content-presentation/table/Table.tsx @@ -15,7 +15,7 @@ interface TableProps extends HTMLProps { captionProps?: ComponentProps; } -interface Table extends FC { +interface TableComponent extends FC { Body: FC>; Cell: FC; Container: FC>; @@ -24,7 +24,7 @@ interface Table extends FC { Row: FC>; } -const Table = ({ +const TableComponent = ({ caption, captionProps, children, @@ -59,11 +59,11 @@ const Table = ({ ); }; -Table.Body = TableBody; -Table.Cell = TableCell; -Table.Container = TableContainer; -Table.Head = TableHead; -Table.Panel = TablePanel; -Table.Row = TableRow; +TableComponent.Body = TableBody; +TableComponent.Cell = TableCell; +TableComponent.Container = TableContainer; +TableComponent.Head = TableHead; +TableComponent.Panel = TablePanel; +TableComponent.Row = TableRow; -export default Table; +export default TableComponent; diff --git a/src/components/content-presentation/table/index.ts b/src/components/content-presentation/table/index.ts index de4c7d5e..ae769447 100644 --- a/src/components/content-presentation/table/index.ts +++ b/src/components/content-presentation/table/index.ts @@ -1,3 +1 @@ -import Table from './Table'; - -export default Table; +export { default } from './Table'; diff --git a/src/components/content-presentation/tabs/Tabs.tsx b/src/components/content-presentation/tabs/Tabs.tsx index edfcf250..06239e2a 100644 --- a/src/components/content-presentation/tabs/Tabs.tsx +++ b/src/components/content-presentation/tabs/Tabs.tsx @@ -2,7 +2,7 @@ import classNames from 'classnames'; import React, { FC, HTMLAttributes, useEffect } from 'react'; import HeadingLevel, { HeadingLevelType } from '@components/utils/HeadingLevel'; -import TabsJs from '@resources/tabs'; +import Tabs from '@resources/tabs'; type TabsProps = HTMLAttributes; @@ -46,16 +46,16 @@ const TabContents: FC = ({ id, children }) => ( ); -interface Tabs extends FC { +interface TabsComponent extends FC { Title: FC; List: FC; ListItem: FC; Contents: FC; } -const Tabs: Tabs = ({ className, children, ...rest }) => { +const TabsComponent: TabsComponent = ({ className, children, ...rest }) => { useEffect(() => { - TabsJs(); + Tabs(); }, []); return ( @@ -65,9 +65,9 @@ const Tabs: Tabs = ({ className, children, ...rest }) => { ); }; -Tabs.Title = TabTitle; -Tabs.List = TabList; -Tabs.ListItem = TabListItem; -Tabs.Contents = TabContents; +TabsComponent.Title = TabTitle; +TabsComponent.List = TabList; +TabsComponent.ListItem = TabListItem; +TabsComponent.Contents = TabContents; -export default Tabs; +export default TabsComponent; diff --git a/src/components/content-presentation/tabs/index.ts b/src/components/content-presentation/tabs/index.ts index 4b674c98..bc6749b1 100644 --- a/src/components/content-presentation/tabs/index.ts +++ b/src/components/content-presentation/tabs/index.ts @@ -1,3 +1 @@ -import Tabs from './Tabs'; - -export default Tabs; +export { default } from './Tabs'; diff --git a/src/components/content-presentation/tag/Tag.tsx b/src/components/content-presentation/tag/Tag.tsx index 3774ec99..eb7fa30f 100644 --- a/src/components/content-presentation/tag/Tag.tsx +++ b/src/components/content-presentation/tag/Tag.tsx @@ -15,11 +15,11 @@ interface TagProps extends HTMLProps { | 'yellow'; } -const Tag: FC = ({ className, color, ...rest }) => ( +const TagComponent: FC = ({ className, color, ...rest }) => ( ); -export default Tag; +export default TagComponent; diff --git a/src/components/content-presentation/tag/index.ts b/src/components/content-presentation/tag/index.ts index efd8e04b..15774bff 100644 --- a/src/components/content-presentation/tag/index.ts +++ b/src/components/content-presentation/tag/index.ts @@ -1,3 +1 @@ -import Tag from './Tag'; - -export default Tag; +export { default } from './Tag'; diff --git a/src/components/content-presentation/warning-callout/WarningCallout.tsx b/src/components/content-presentation/warning-callout/WarningCallout.tsx index e908c6ee..3d58c6eb 100644 --- a/src/components/content-presentation/warning-callout/WarningCallout.tsx +++ b/src/components/content-presentation/warning-callout/WarningCallout.tsx @@ -26,10 +26,10 @@ interface IWarningCallout extends FC> { Label: typeof WarningCalloutLabel; } -const WarningCallout: IWarningCallout = ({ className, ...rest }) => ( +const WarningCalloutComponent: IWarningCallout = ({ className, ...rest }) => (
); -WarningCallout.Label = WarningCalloutLabel; +WarningCalloutComponent.Label = WarningCalloutLabel; -export default WarningCallout; +export default WarningCalloutComponent; diff --git a/src/components/content-presentation/warning-callout/index.ts b/src/components/content-presentation/warning-callout/index.ts index ab0690ea..8886011c 100644 --- a/src/components/content-presentation/warning-callout/index.ts +++ b/src/components/content-presentation/warning-callout/index.ts @@ -1,3 +1 @@ -import WarningCallout from './WarningCallout'; - -export default WarningCallout; +export { default } from './WarningCallout'; diff --git a/src/components/form-elements/button/Button.tsx b/src/components/form-elements/button/Button.tsx index 11cd64c0..8015f63e 100644 --- a/src/components/form-elements/button/Button.tsx +++ b/src/components/form-elements/button/Button.tsx @@ -60,7 +60,7 @@ const useDebounceTimeout = ( return handler; }; -export const Button: FC = ({ +export const ButtonComponent: FC = ({ className, disabled, secondary, @@ -93,7 +93,8 @@ export const Button: FC = ({ /> ); }; -export const ButtonLink: FC = ({ + +export const ButtonLinkComponent: FC = ({ className, role = 'button', draggable = false, @@ -148,17 +149,11 @@ export const ButtonLink: FC = ({ ); }; -const ButtonWrapper: FC = ({ href, as, ...rest }) => { - if (as === 'a') { - return ; - } - if (as === 'button') { - return , ); - + const button = container.querySelector('button'); - + button?.click(); expect(clickHandler).toHaveBeenCalledTimes(1); @@ -102,7 +102,7 @@ describe('Button', () => { Submit , ); - + const button = container.querySelector('button'); button?.click(); expect(clickHandler).toHaveBeenCalledTimes(1); @@ -142,15 +142,15 @@ describe('Button', () => { }); }); -describe('ButtonLink', () => { +describe('Button as a link', () => { it('matches snapshot', () => { - const { container } = render(Submit); + const { container } = render(); expect(container).toMatchSnapshot('PlainButton'); }); it('renders child text as expected', () => { - const { container } = render(Submit); + const { container } = render(); expect(container.querySelector('a')?.textContent).toEqual('Submit'); }); @@ -159,9 +159,9 @@ describe('ButtonLink', () => { describe('disabled', () => { it('matches snapshot', () => { const { container } = render( - + , ); expect(container).toMatchSnapshot('DisabledButton'); @@ -169,9 +169,9 @@ describe('ButtonLink', () => { it('adds correct classes for type - disabled', () => { const { container } = render( - + , ); expect(container.querySelector('.nhsuk-button--disabled')).toBeTruthy(); @@ -181,9 +181,9 @@ describe('ButtonLink', () => { describe('secondary', () => { it('matches snapshot', () => { const { container } = render( - + , ); expect(container).toMatchSnapshot('SecondaryButton'); @@ -191,9 +191,9 @@ describe('ButtonLink', () => { it('adds correct classes for type - secondary', () => { const { container } = render( - + , ); expect(container.querySelector('.nhsuk-button--secondary')).toBeTruthy(); @@ -203,9 +203,9 @@ describe('ButtonLink', () => { describe('reverse', () => { it('matches snapshot', () => { const { container } = render( - + , ); expect(container).toMatchSnapshot('ReverseButton'); @@ -213,9 +213,9 @@ describe('ButtonLink', () => { it('adds correct classes for type - reverse', () => { const { container } = render( - + , ); expect(container.querySelector('.nhsuk-button--reverse')).toBeTruthy(); @@ -225,9 +225,9 @@ describe('ButtonLink', () => { it('adds aria disabled props to disabled button', () => { const { container } = render( - + , ); expect( @@ -241,15 +241,15 @@ describe('ButtonLink', () => { }); }); -describe('ButtonWrapper', () => { +describe('Button as a button', () => { it('renders a button when not given a href', () => { - const { container } = render(Submit); + const { container } = render(); expect(container.querySelector('button.nhsuk-button')?.textContent).toBe('Submit'); }); it('renders an anchor when given a href', () => { - const { container } = render(Submit); + const { container } = render(); expect(container.querySelector('a.nhsuk-button')?.textContent).toBe('Submit'); }); diff --git a/src/components/form-elements/button/__tests__/__snapshots__/Button.test.tsx.snap b/src/components/form-elements/button/__tests__/__snapshots__/Button.test.tsx.snap index 4afeb8e1..53867111 100644 --- a/src/components/form-elements/button/__tests__/__snapshots__/Button.test.tsx.snap +++ b/src/components/form-elements/button/__tests__/__snapshots__/Button.test.tsx.snap @@ -1,106 +1,106 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Button disabled matches snapshot: DisabledButton 1`] = ` +exports[`Button as a link button types disabled matches snapshot: DisabledButton 1`] = `
- +
`; -exports[`Button matches snapshot: PlainButton 1`] = ` +exports[`Button as a link button types reverse matches snapshot: ReverseButton 1`] = `
- +
`; -exports[`Button reverse matches snapshot: ReverseButton 1`] = ` +exports[`Button as a link button types secondary matches snapshot: SecondaryButton 1`] = `
- +
`; -exports[`Button secondary matches snapshot: SecondaryButton 1`] = ` +exports[`Button as a link matches snapshot: PlainButton 1`] = `
- +
`; -exports[`ButtonLink button types disabled matches snapshot: DisabledButton 1`] = ` +exports[`Button disabled matches snapshot: DisabledButton 1`] = ` `; -exports[`ButtonLink button types reverse matches snapshot: ReverseButton 1`] = ` +exports[`Button matches snapshot: PlainButton 1`] = ` `; -exports[`ButtonLink button types secondary matches snapshot: SecondaryButton 1`] = ` +exports[`Button reverse matches snapshot: ReverseButton 1`] = ` `; -exports[`ButtonLink matches snapshot: PlainButton 1`] = ` +exports[`Button secondary matches snapshot: SecondaryButton 1`] = ` `; diff --git a/src/components/form-elements/button/index.ts b/src/components/form-elements/button/index.ts index 6af3b1cf..efe8c800 100644 --- a/src/components/form-elements/button/index.ts +++ b/src/components/form-elements/button/index.ts @@ -1,4 +1 @@ -import ButtonElement from './Button'; - -export default ButtonElement; -export { Button, ButtonLink } from './Button'; +export { default } from './Button'; diff --git a/src/components/form-elements/character-count/CharacterCount.tsx b/src/components/form-elements/character-count/CharacterCount.tsx index e19ca0e9..e3178d6f 100644 --- a/src/components/form-elements/character-count/CharacterCount.tsx +++ b/src/components/form-elements/character-count/CharacterCount.tsx @@ -1,6 +1,6 @@ 'use client'; import React, { FC, useEffect } from 'react'; -import CharacterCountJs from '@resources/character-count'; +import CharacterCount from '@resources/character-count'; import { HTMLAttributesWithData } from '@util/types/NHSUKTypes'; export enum CharacterCountType { @@ -16,7 +16,7 @@ type CharacterCountProps = React.HTMLAttributes & { thresholdPercent?: number; }; -const CharacterCount: FC = ({ +const CharacterCountComponent: FC = ({ children, maxLength, countType, @@ -25,7 +25,7 @@ const CharacterCount: FC = ({ ...rest }) => { useEffect(() => { - CharacterCountJs(); + CharacterCount(); }, []); const characterCountProps: HTMLAttributesWithData = @@ -52,4 +52,4 @@ const CharacterCount: FC = ({ ); }; -export default CharacterCount; +export default CharacterCountComponent; diff --git a/src/components/form-elements/character-count/index.ts b/src/components/form-elements/character-count/index.ts index a4cba558..a053b404 100644 --- a/src/components/form-elements/character-count/index.ts +++ b/src/components/form-elements/character-count/index.ts @@ -1,4 +1 @@ -import CharacterCount, { CharacterCountType } from './CharacterCount'; - -export { CharacterCountType }; -export default CharacterCount; +export { default, CharacterCountType } from './CharacterCount'; diff --git a/src/components/form-elements/checkboxes/Checkboxes.tsx b/src/components/form-elements/checkboxes/Checkboxes.tsx index 4b10e37b..1113aadd 100644 --- a/src/components/form-elements/checkboxes/Checkboxes.tsx +++ b/src/components/form-elements/checkboxes/Checkboxes.tsx @@ -5,22 +5,22 @@ import classNames from 'classnames'; import { FormElementProps } from '@util/types/FormTypes'; import SingleInputFormGroup from '@components/utils/SingleInputFormGroup'; import CheckboxContext, { ICheckboxContext } from './CheckboxContext'; -import Box from './components/Box'; -import Divider from './components/Divider'; +import CheckboxesItem from './components/Item'; +import CheckboxesDivider from './components/Divider'; import { generateRandomName } from '@util/RandomID'; -import CheckboxJs from '@resources/checkboxes'; +import Checkboxes from '@resources/checkboxes'; interface CheckboxesProps extends HTMLProps, FormElementProps { idPrefix?: string; } -const Checkboxes = ({ children, idPrefix, ...rest }: CheckboxesProps) => { +const CheckboxesComponent = ({ children, idPrefix, ...rest }: CheckboxesProps) => { const _boxReferences: string[] = []; let _boxCount: number = 0; let _boxIds: Record = {}; useEffect(() => { - CheckboxJs(); + Checkboxes(); }, []); const getBoxId = (id: string, reference: string): string => { @@ -73,7 +73,7 @@ const Checkboxes = ({ children, idPrefix, ...rest }: CheckboxesProps) => { ); }; -Checkboxes.Box = Box; -Checkboxes.Divider = Divider; +CheckboxesComponent.Item = CheckboxesItem; +CheckboxesComponent.Divider = CheckboxesDivider; -export default Checkboxes; +export default CheckboxesComponent; diff --git a/src/components/form-elements/checkboxes/__tests__/Checkboxes.test.tsx b/src/components/form-elements/checkboxes/__tests__/Checkboxes.test.tsx index ced26677..8a40bdad 100644 --- a/src/components/form-elements/checkboxes/__tests__/Checkboxes.test.tsx +++ b/src/components/form-elements/checkboxes/__tests__/Checkboxes.test.tsx @@ -7,9 +7,9 @@ describe('Checkboxes', () => { const { container } = render(
- Waste from animal carcasses - Waste from mines or quarries - Farm or agricultural waste + Waste from animal carcasses + Waste from mines or quarries + Farm or agricultural waste
, ); @@ -21,9 +21,9 @@ describe('Checkboxes', () => { const { container } = render(
- Waste from animal carcasses - Waste from mines or quarries - Farm or agricultural waste + Waste from animal carcasses + Waste from mines or quarries + Farm or agricultural waste
, ); @@ -35,9 +35,9 @@ describe('Checkboxes', () => { const { container } = render(
- Waste from animal carcasses - Waste from mines or quarries - Farm or agricultural waste + Waste from animal carcasses + Waste from mines or quarries + Farm or agricultural waste
, ); @@ -49,13 +49,13 @@ describe('Checkboxes', () => { const { container } = render(
- Waste from animal carcasses - Waste from mines or quarries - Farm or agricultural waste + Waste from animal carcasses + Waste from mines or quarries + Farm or agricultural waste - + None - +
, ); @@ -67,12 +67,12 @@ describe('Checkboxes', () => { const { container } = render(
- Waste from animal carcasses - Waste from mines or quarries - Farm or agricultural waste - + Waste from animal carcasses + Waste from mines or quarries + Farm or agricultural waste + None - +
, ); diff --git a/src/components/form-elements/checkboxes/components/Divider.tsx b/src/components/form-elements/checkboxes/components/Divider.tsx index 547aa302..f4565d9c 100644 --- a/src/components/form-elements/checkboxes/components/Divider.tsx +++ b/src/components/form-elements/checkboxes/components/Divider.tsx @@ -4,8 +4,8 @@ type DividerProps = { dividerText?: string; }; -const Divider: FC = ({ dividerText = 'or' }) => ( +const CheckboxesDivider: FC = ({ dividerText = 'or' }) => (
{dividerText}
); -export default Divider; +export default CheckboxesDivider; diff --git a/src/components/form-elements/checkboxes/components/Box.tsx b/src/components/form-elements/checkboxes/components/Item.tsx similarity index 95% rename from src/components/form-elements/checkboxes/components/Box.tsx rename to src/components/form-elements/checkboxes/components/Item.tsx index 3c576c57..24d92df3 100644 --- a/src/components/form-elements/checkboxes/components/Box.tsx +++ b/src/components/form-elements/checkboxes/components/Item.tsx @@ -15,7 +15,7 @@ import Label, { LabelProps } from '../../label/Label'; import HintText, { HintTextProps } from '../../hint-text/HintText'; import { HTMLAttributesWithData } from '@util/types/NHSUKTypes'; -type BoxProps = Omit, 'label'> & { +type CheckboxesItemProps = Omit, 'label'> & { labelProps?: LabelProps; hint?: string; hintProps?: HintTextProps; @@ -26,7 +26,7 @@ type BoxProps = Omit, 'label'> & { exclusive?: boolean; }; -const Box: FC = ({ +const CheckboxesItem: FC = ({ id, labelProps, children, @@ -119,4 +119,4 @@ const Box: FC = ({ ); }; -export default Box; +export default CheckboxesItem; diff --git a/src/components/form-elements/checkboxes/index.ts b/src/components/form-elements/checkboxes/index.ts index 22c6e492..d537b67e 100644 --- a/src/components/form-elements/checkboxes/index.ts +++ b/src/components/form-elements/checkboxes/index.ts @@ -1,3 +1 @@ -import Checkboxes from './Checkboxes'; - -export default Checkboxes; +export { default } from './Checkboxes'; diff --git a/src/components/form-elements/date-input/DateInput.tsx b/src/components/form-elements/date-input/DateInput.tsx index 50f2040b..084d1e31 100644 --- a/src/components/form-elements/date-input/DateInput.tsx +++ b/src/components/form-elements/date-input/DateInput.tsx @@ -29,7 +29,7 @@ interface DateInputProps type InputType = 'day' | 'month' | 'year'; -const DateInput = ({ +const DateInputComponent = ({ autoSelectNext, children, onChange, @@ -110,9 +110,9 @@ const DateInput = ({ {children || ( <> - - - + + + )} @@ -123,8 +123,8 @@ const DateInput = ({ ); }; -DateInput.Day = DayInput; -DateInput.Month = MonthInput; -DateInput.Year = YearInput; +DateInputComponent.Day = DayInput; +DateInputComponent.Month = MonthInput; +DateInputComponent.Year = YearInput; -export default DateInput; +export default DateInputComponent; diff --git a/src/components/form-elements/date-input/index.ts b/src/components/form-elements/date-input/index.ts index 278d4da8..a8bd7bc4 100644 --- a/src/components/form-elements/date-input/index.ts +++ b/src/components/form-elements/date-input/index.ts @@ -1,3 +1 @@ -import DateInput from './DateInput'; - -export default DateInput; +export { default } from './DateInput'; diff --git a/src/components/form-elements/error-message/ErrorMessage.tsx b/src/components/form-elements/error-message/ErrorMessage.tsx index 4bc89ead..4fc402af 100644 --- a/src/components/form-elements/error-message/ErrorMessage.tsx +++ b/src/components/form-elements/error-message/ErrorMessage.tsx @@ -5,7 +5,7 @@ export interface ErrorMessageProps extends HTMLProps { visuallyHiddenText?: false | string; } -const ErrorMessage: FC = ({ +const ErrorMessageComponent: FC = ({ className, visuallyHiddenText = 'Error: ', children, @@ -19,4 +19,4 @@ const ErrorMessage: FC = ({ ); -export default ErrorMessage; +export default ErrorMessageComponent; diff --git a/src/components/form-elements/error-message/index.ts b/src/components/form-elements/error-message/index.ts index 282b401d..43c8c9cc 100644 --- a/src/components/form-elements/error-message/index.ts +++ b/src/components/form-elements/error-message/index.ts @@ -1,3 +1 @@ -import ErrorMessage from './ErrorMessage'; - -export default ErrorMessage; +export { default } from './ErrorMessage'; diff --git a/src/components/form-elements/error-summary/ErrorSummary.tsx b/src/components/form-elements/error-summary/ErrorSummary.tsx index 83fceb49..5f29a8fa 100644 --- a/src/components/form-elements/error-summary/ErrorSummary.tsx +++ b/src/components/form-elements/error-summary/ErrorSummary.tsx @@ -15,10 +15,7 @@ const ErrorSummaryTitle: FC> = ({ className, id = DefaultErrorSummaryTitleID, ...rest -}) => ( -

-); - +}) =>

; const ErrorSummaryBody: FC> = ({ className, ...rest }) => (
@@ -34,7 +31,7 @@ const ErrorSummaryListItem: FC> = (props) => ( ); -interface ErrorSummary +interface ErrorSummaryComponent extends ForwardRefExoticComponent< PropsWithoutRef> & RefAttributes > { @@ -45,18 +42,25 @@ interface ErrorSummary } const ErrorSummaryDiv = forwardRef>( - ({ - className, - tabIndex = -1, - role = 'alert', - 'aria-labelledby': ariaLabelledBy = DefaultErrorSummaryTitleID, - ...rest - }, - ref -) => { - useDevWarning('The ErrorSummary component should always have a tabIndex of -1', () => tabIndex !== -1) - useDevWarning('The ErrorSummary component should always have a role of alert', () => role !== 'alert') - + ( + { + className, + tabIndex = -1, + role = 'alert', + 'aria-labelledby': ariaLabelledBy = DefaultErrorSummaryTitleID, + ...rest + }, + ref, + ) => { + useDevWarning( + 'The ErrorSummary component should always have a tabIndex of -1', + () => tabIndex !== -1, + ); + useDevWarning( + 'The ErrorSummary component should always have a role of alert', + () => role !== 'alert', + ); + return (
>( aria-labelledby={ariaLabelledBy} {...rest} /> - ) -}); - + ); + }, +); ErrorSummaryDiv.displayName = 'ErrorSummary'; -const ErrorSummary: ErrorSummary = Object.assign(ErrorSummaryDiv, { +const ErrorSummaryComponent: ErrorSummaryComponent = Object.assign(ErrorSummaryDiv, { Title: ErrorSummaryTitle, Body: ErrorSummaryBody, List: ErrorSummaryList, Item: ErrorSummaryListItem, }); -export default ErrorSummary; +export default ErrorSummaryComponent; diff --git a/src/components/form-elements/error-summary/index.ts b/src/components/form-elements/error-summary/index.ts index 95d155c2..20fb46a1 100644 --- a/src/components/form-elements/error-summary/index.ts +++ b/src/components/form-elements/error-summary/index.ts @@ -1,3 +1 @@ -import ErrorSummary from './ErrorSummary'; - -export default ErrorSummary; +export { default } from './ErrorSummary'; diff --git a/src/components/form-elements/fieldset/Fieldset.tsx b/src/components/form-elements/fieldset/Fieldset.tsx index 4e7445e5..ca53b7d0 100644 --- a/src/components/form-elements/fieldset/Fieldset.tsx +++ b/src/components/form-elements/fieldset/Fieldset.tsx @@ -44,7 +44,12 @@ interface FieldsetProps extends HTMLProps { disableErrorLine?: boolean; } -const FieldSet = ({ className, fieldsetRef, disableErrorLine, ...rest }: FieldsetProps) => { +const FieldsetComponent = ({ + className, + fieldsetRef, + disableErrorLine, + ...rest +}: FieldsetProps) => { return (
@@ -52,6 +57,6 @@ const FieldSet = ({ className, fieldsetRef, disableErrorLine, ...rest }: Fieldse ); }; -FieldSet.Legend = Legend; +FieldsetComponent.Legend = Legend; -export default FieldSet; +export default FieldsetComponent; diff --git a/src/components/form-elements/fieldset/index.ts b/src/components/form-elements/fieldset/index.ts index e888581d..e5d92007 100644 --- a/src/components/form-elements/fieldset/index.ts +++ b/src/components/form-elements/fieldset/index.ts @@ -1,3 +1 @@ -import Fieldset from './Fieldset'; - -export default Fieldset; +export { default } from './Fieldset'; diff --git a/src/components/form-elements/form/Form.tsx b/src/components/form-elements/form/Form.tsx index 2e97664d..d9c6e8bf 100644 --- a/src/components/form-elements/form/Form.tsx +++ b/src/components/form-elements/form/Form.tsx @@ -5,10 +5,10 @@ type FormProps = HTMLProps & { disableErrorFromComponents?: boolean; }; -const Form: FC = ({ disableErrorFromComponents, ...rest }) => ( +const FormComponent: FC = ({ disableErrorFromComponents, ...rest }) => (
); -export default Form; +export default FormComponent; diff --git a/src/components/form-elements/form/index.ts b/src/components/form-elements/form/index.ts index 8f5e7e88..84bc0aca 100644 --- a/src/components/form-elements/form/index.ts +++ b/src/components/form-elements/form/index.ts @@ -1,5 +1 @@ -import Form from './Form'; - -export { useFormContext } from './FormContext'; - -export default Form; +export { default, useFormContext } from './FormContext'; diff --git a/src/components/form-elements/hint-text/HintText.tsx b/src/components/form-elements/hint-text/HintText.tsx index 17f7e5f4..df941c9c 100644 --- a/src/components/form-elements/hint-text/HintText.tsx +++ b/src/components/form-elements/hint-text/HintText.tsx @@ -3,8 +3,8 @@ import classNames from 'classnames'; export type HintTextProps = HTMLProps; -const HintText: FC = ({ className, ...rest }) => ( +const HintTextComponent: FC = ({ className, ...rest }) => (
); -export default HintText; +export default HintTextComponent; diff --git a/src/components/form-elements/hint-text/index.ts b/src/components/form-elements/hint-text/index.ts index 1af2f426..708441db 100644 --- a/src/components/form-elements/hint-text/index.ts +++ b/src/components/form-elements/hint-text/index.ts @@ -1,3 +1 @@ -import HintText from './HintText'; - -export default HintText; +export { default } from './HintText'; diff --git a/src/components/form-elements/label/Label.tsx b/src/components/form-elements/label/Label.tsx index af0eff1b..42638958 100644 --- a/src/components/form-elements/label/Label.tsx +++ b/src/components/form-elements/label/Label.tsx @@ -8,7 +8,7 @@ export interface LabelProps extends Omit, 'size'> { size?: NHSUKSize; } -const BaseLabel: FC = ({ className, bold, size, isPageHeading, ...rest }) => ( +const Label: FC = ({ className, bold, size, isPageHeading, ...rest }) => ( // eslint-disable-next-line jsx-a11y/label-has-associated-control