@tpzdsp/next-toolkit 2.5.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +21 -12
- package/src/assets/styles/globals.css +75 -95
- package/src/assets/styles/ol.css +57 -16
- package/src/assets/styles/utils.css +80 -0
- package/src/components/Accordion/Accordion.css +85 -0
- package/src/components/Accordion/Accordion.stories.tsx +264 -0
- package/src/components/Accordion/Accordion.tsx +98 -0
- package/src/components/Alert/Alert.css +129 -0
- package/src/components/Alert/Alert.stories.tsx +291 -0
- package/src/components/Alert/Alert.tsx +76 -0
- package/src/components/BackLink/BackLink.css +12 -0
- package/src/components/BackLink/BackLink.stories.tsx +52 -0
- package/src/components/BackLink/BackLink.tsx +44 -0
- package/src/components/BackToTop/BackToTop.css +23 -0
- package/src/components/BackToTop/BackToTop.stories.tsx +41 -0
- package/src/components/BackToTop/BackToTop.tsx +48 -0
- package/src/components/Breadcrumb/Breadcrumb.css +42 -0
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +94 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +135 -0
- package/src/components/Button/Button.css +229 -0
- package/src/components/Button/Button.stories.tsx +140 -20
- package/src/components/Button/Button.tsx +53 -28
- package/src/components/Button/ButtonSkeleton.stories.tsx +50 -0
- package/src/components/Button/ButtonSkeleton.tsx +14 -0
- package/src/components/ButtonGroup/ButtonGroup.css +52 -0
- package/src/components/ButtonGroup/ButtonGroup.stories.tsx +156 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +50 -0
- package/src/components/ButtonLink/ButtonLink.css +114 -0
- package/src/components/ButtonLink/ButtonLink.stories.tsx +38 -51
- package/src/components/ButtonLink/ButtonLink.tsx +54 -23
- package/src/components/Card/Card.css +13 -0
- package/src/components/Card/Card.stories.tsx +98 -57
- package/src/components/Card/Card.tsx +4 -13
- package/src/components/CardGroup/CardGroup.css +10 -0
- package/src/components/CardGroup/CardGroup.stories.tsx +81 -0
- package/src/components/CardGroup/CardGroup.tsx +9 -0
- package/src/components/Checkbox/Checkbox.css +49 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +86 -0
- package/src/components/Checkbox/Checkbox.tsx +32 -0
- package/src/components/Chip/Chip.css +54 -0
- package/src/components/Chip/Chip.stories.tsx +94 -0
- package/src/components/Chip/Chip.tsx +34 -0
- package/src/components/CookieBanner/CookieBanner.css +19 -0
- package/src/components/CookieBanner/CookieBanner.stories.tsx +52 -0
- package/src/components/CookieBanner/CookieBanner.tsx +55 -0
- package/src/components/CopyButton/CopyButton.stories.tsx +28 -0
- package/src/components/CopyButton/CopyButton.tsx +65 -0
- package/src/components/DateInput/DateInput.css +13 -0
- package/src/components/DateInput/DateInput.stories.tsx +131 -0
- package/src/components/DateInput/DateInput.test.tsx +21 -0
- package/src/components/DateInput/DateInput.tsx +98 -0
- package/src/components/Details/Details.css +28 -0
- package/src/components/Details/Details.stories.tsx +48 -0
- package/src/components/Details/Details.tsx +41 -0
- package/src/components/Dropdown/Dropdown.css +81 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +131 -0
- package/src/components/Dropdown/Dropdown.tsx +69 -0
- package/src/components/ErrorBoundary/ErrorBoundary.stories.tsx +4 -39
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +7 -4
- package/src/components/ErrorBoundary/ErrorFallback.tsx +32 -66
- package/src/components/ErrorModal/ErrorModal.css +32 -0
- package/src/components/ErrorModal/ErrorModal.stories.tsx +101 -0
- package/src/components/ErrorModal/ErrorModal.tsx +120 -0
- package/src/components/ErrorText/ErrorText.css +22 -0
- package/src/components/ErrorText/ErrorText.stories.tsx +42 -27
- package/src/components/ErrorText/ErrorText.tsx +10 -8
- package/src/components/ExternalLink/ExternalLink.css +12 -0
- package/src/components/ExternalLink/ExternalLink.stories.tsx +43 -0
- package/src/components/ExternalLink/ExternalLink.tsx +43 -0
- package/src/components/Fieldset/Fieldset.css +103 -0
- package/src/components/Fieldset/Fieldset.stories.tsx +304 -0
- package/src/components/Fieldset/Fieldset.tsx +38 -0
- package/src/components/FileUpload/FileUpload.css +85 -0
- package/src/components/FileUpload/FileUpload.stories.tsx +106 -0
- package/src/components/FileUpload/FileUpload.tsx +99 -0
- package/src/components/{layout/footer → Footer}/Copyright.tsx +4 -2
- package/src/components/Footer/Footer.stories.tsx +24 -0
- package/src/components/Footer/Footer.tsx +41 -0
- package/src/components/Footer/Licence.tsx +18 -0
- package/src/components/{layout/footer → Footer}/MetaLinks.tsx +8 -3
- package/src/components/Footer/Small/SmallFooter.tsx +43 -42
- package/src/components/Form/FormGroup.css +18 -0
- package/src/components/Form/FormGroup.stories.tsx +87 -0
- package/src/components/Form/FormGroup.tsx +16 -0
- package/src/components/{layout/header → Header}/Header.stories.tsx +26 -12
- package/src/components/Header/Header.test.tsx +87 -0
- package/src/components/Header/Header.tsx +303 -0
- package/src/components/Header/HeaderAppContent.tsx +120 -0
- package/src/components/Heading/Heading.css +40 -0
- package/src/components/Heading/Heading.stories.tsx +15 -5
- package/src/components/Heading/Heading.tsx +21 -44
- package/src/components/Heading/HeadingSkeleton.stories.tsx +30 -0
- package/src/components/Heading/HeadingSkeleton.tsx +14 -0
- package/src/components/Hero/Hero.css +19 -0
- package/src/components/Hero/Hero.stories.tsx +41 -0
- package/src/components/Hero/Hero.tsx +14 -0
- package/src/components/HintText/HintText.css +5 -0
- package/src/components/HintText/HintText.stories.tsx +29 -0
- package/src/components/HintText/HintText.tsx +13 -0
- package/src/components/InfoBox/InfoBox.css +38 -0
- package/src/components/InfoBox/InfoBox.stories.tsx +51 -403
- package/src/components/InfoBox/InfoBox.tsx +31 -158
- package/src/components/Input/Input.css +77 -0
- package/src/components/Input/Input.stories.tsx +123 -0
- package/src/components/Input/Input.tsx +74 -0
- package/src/components/InputGroup/InputGroup.css +140 -0
- package/src/components/InputGroup/InputGroup.stories.tsx +125 -0
- package/src/components/InputGroup/InputGroup.tsx +47 -0
- package/src/components/InsetText/InsetText.css +5 -0
- package/src/components/InsetText/InsetText.stories.tsx +30 -0
- package/src/components/InsetText/InsetText.tsx +9 -0
- package/src/components/Keyboard/Keyboard.css +9 -0
- package/src/components/Keyboard/Keyboard.stories.tsx +63 -0
- package/src/components/Keyboard/Keyboard.tsx +30 -0
- package/src/components/Label/Label.css +27 -0
- package/src/components/Label/Label.stories.tsx +40 -0
- package/src/components/Label/Label.tsx +17 -0
- package/src/components/LayerSwitcher/LayerSwitcher.css +59 -0
- package/src/components/LayerSwitcher/LayerSwitcher.stories.tsx +112 -0
- package/src/components/LayerSwitcher/LayerSwitcher.tsx +61 -0
- package/src/components/Layout/401/401.stories.tsx +23 -0
- package/src/components/Layout/401/401.tsx +1 -0
- package/src/components/Layout/403/403.stories.tsx +23 -0
- package/src/components/Layout/403/403.tsx +21 -0
- package/src/components/Layout/404/404.stories.tsx +23 -0
- package/src/components/Layout/404/404.tsx +28 -0
- package/src/components/Layout/500/500.stories.tsx +56 -0
- package/src/components/Layout/500/500.tsx +63 -0
- package/src/components/Layout/ButtonGroup/ButtonGroup.css +52 -0
- package/src/components/Layout/ButtonGroup/ButtonGroup.stories.tsx +156 -0
- package/src/components/Layout/ButtonGroup/ButtonGroup.tsx +50 -0
- package/src/components/Layout/HeadingGroup/HeadingGroup.css +21 -0
- package/src/components/Layout/HeadingGroup/HeadingGroup.stories.tsx +84 -0
- package/src/components/Layout/HeadingGroup/HeadingGroup.tsx +9 -0
- package/src/components/Layout/MainWrapper/MainWrapper.css +12 -0
- package/src/components/Layout/MainWrapper/MainWrapper.stories.tsx +36 -0
- package/src/components/Layout/MainWrapper/MainWrapper.tsx +14 -0
- package/src/components/Layout/PageShell/PageShell.css +42 -0
- package/src/components/Layout/PageShell/PageShell.stories.tsx +108 -0
- package/src/components/Layout/PageShell/PageShell.tsx +31 -0
- package/src/components/Layout/ParagraphGroup/ParagraphGroup.css +5 -0
- package/src/components/Layout/ParagraphGroup/ParagraphGroup.stories.tsx +34 -0
- package/src/components/Layout/ParagraphGroup/ParagraphGroup.tsx +9 -0
- package/src/components/Layout/Stack/Stack.css +29 -0
- package/src/components/Layout/Stack/Stack.stories.tsx +83 -0
- package/src/components/Layout/Stack/Stack.tsx +19 -0
- package/src/components/Layout/WidthContainer/WidthContainer.css +17 -0
- package/src/components/Layout/WidthContainer/WidthContainer.stories.tsx +59 -0
- package/src/components/Layout/WidthContainer/WidthContainer.tsx +13 -0
- package/src/components/Legend/Legend.css +95 -0
- package/src/components/Legend/Legend.stories.tsx +81 -0
- package/src/components/Legend/Legend.tsx +32 -0
- package/src/components/Legend/LegendDot.tsx +15 -0
- package/src/components/Legend/LegendPanel.stories.tsx +101 -0
- package/src/components/Legend/LegendPanel.tsx +68 -0
- package/src/components/Legend/LegendSkeleton.stories.tsx +87 -0
- package/src/components/Legend/LegendSkeleton.tsx +73 -0
- package/src/components/LegendSelect/LegendSelect.css +8 -0
- package/src/components/LegendSelect/LegendSelect.stories.tsx +80 -0
- package/src/components/LegendSelect/LegendSelect.tsx +26 -0
- package/src/components/Link/Link.css +98 -0
- package/src/components/Link/Link.stories.tsx +70 -0
- package/src/components/Link/Link.tsx +52 -0
- package/src/components/LinkButton/LinkButton.css +67 -0
- package/src/components/LinkButton/LinkButton.stories.tsx +90 -42
- package/src/components/LinkButton/LinkButton.tsx +50 -63
- package/src/components/LinkList/LinkList.css +28 -0
- package/src/components/LinkList/LinkList.stories.tsx +46 -0
- package/src/components/LinkList/LinkList.tsx +23 -0
- package/src/components/List/Li.tsx +9 -0
- package/src/components/List/List.css +9 -0
- package/src/components/List/OrderedList.stories.tsx +36 -0
- package/src/components/List/OrderedList.tsx +9 -0
- package/src/components/List/UnorderedList.stories.tsx +36 -0
- package/src/components/List/UnorderedList.tsx +9 -0
- package/src/components/LoadingBox/LoadingBox.css +27 -0
- package/src/components/LoadingBox/LoadingBox.stories.tsx +66 -0
- package/src/components/LoadingBox/LoadingBox.tsx +40 -0
- package/src/components/Modal/Modal.css +114 -0
- package/src/components/Modal/Modal.stories.tsx +41 -160
- package/src/components/Modal/Modal.tsx +132 -75
- package/src/components/NoScriptBanner/NoScriptBanner.css +17 -0
- package/src/components/NoScriptBanner/NoScriptBanner.stories.tsx +46 -0
- package/src/components/NoScriptBanner/NoScriptBanner.tsx +26 -0
- package/src/components/Paragraph/Paragraph.css +22 -0
- package/src/components/Paragraph/Paragraph.stories.tsx +1 -42
- package/src/components/Paragraph/Paragraph.tsx +4 -3
- package/src/components/Paragraph/ParagraphSkeleton.stories.tsx +44 -0
- package/src/components/Paragraph/ParagraphSkeleton.tsx +33 -0
- package/src/components/PasswordInput/PasswordInput.css +3 -0
- package/src/components/PasswordInput/PasswordInput.stories.tsx +47 -0
- package/src/components/PasswordInput/PasswordInput.tsx +45 -0
- package/src/components/PhaseBanner/PhaseBanner.css +12 -0
- package/src/components/PhaseBanner/PhaseBanner.stories.tsx +61 -0
- package/src/components/PhaseBanner/PhaseBanner.tsx +17 -0
- package/src/components/Popover/Popover.css +43 -0
- package/src/components/Popover/Popover.stories.tsx +102 -0
- package/src/components/Popover/Popover.tsx +40 -0
- package/src/components/Radio/Radio.css +69 -0
- package/src/components/Radio/Radio.stories.tsx +169 -0
- package/src/components/Radio/Radio.tsx +56 -0
- package/src/components/Resizable/Resizable.css +86 -0
- package/src/components/Resizable/Resizable.stories.tsx +123 -0
- package/src/components/Resizable/Resizable.tsx +86 -0
- package/src/components/ScrollArea/ScrollArea.css +9 -0
- package/src/components/ScrollArea/ScrollArea.stories.tsx +42 -0
- package/src/components/ScrollArea/ScrollArea.tsx +11 -0
- package/src/components/SearchBox/SearchBox.stories.tsx +88 -0
- package/src/components/SearchBox/SearchBox.tsx +36 -0
- package/src/components/Select/AsyncSelect.stories.tsx +84 -0
- package/src/components/Select/AsyncSelect.tsx +41 -0
- package/src/components/Select/Select.css +194 -0
- package/src/components/Select/Select.stories.tsx +162 -0
- package/src/components/Select/Select.test.tsx +36 -0
- package/src/components/Select/Select.tsx +291 -0
- package/src/components/Select/SelectSkeleton.stories.tsx +51 -0
- package/src/components/Select/SelectSkeleton.tsx +23 -0
- package/src/components/Separator/Separator.css +41 -0
- package/src/components/Separator/Separator.stories.tsx +63 -0
- package/src/components/Separator/Separator.tsx +42 -0
- package/src/components/Sidebar/ResizableSidebar.tsx +118 -0
- package/src/components/Sidebar/Sidebar.css +203 -0
- package/src/components/Sidebar/Sidebar.stories.tsx +438 -0
- package/src/components/Sidebar/Sidebar.tsx +225 -0
- package/src/components/Skeleton/Skeleton.css +16 -0
- package/src/components/Skeleton/Skeleton.stories.tsx +39 -0
- package/src/components/Skeleton/Skeleton.tsx +12 -0
- package/src/components/SkipLink/SkipLink.css +16 -0
- package/src/components/SkipLink/SkipLink.stories.tsx +40 -0
- package/src/components/SkipLink/SkipLink.tsx +15 -0
- package/src/components/Spinner/Spinner.css +30 -0
- package/src/components/Spinner/Spinner.stories.tsx +36 -0
- package/src/components/Spinner/Spinner.tsx +45 -0
- package/src/components/StartButton/StartButton.css +13 -0
- package/src/components/StartButton/StartButton.stories.tsx +68 -0
- package/src/components/StartButton/StartButton.tsx +50 -0
- package/src/components/SubmitButton/SubmitButton.stories.tsx +31 -0
- package/src/components/SubmitButton/SubmitButton.tsx +14 -0
- package/src/components/SummaryList/SummaryList.css +71 -0
- package/src/components/SummaryList/SummaryList.stories.tsx +211 -0
- package/src/components/SummaryList/SummaryList.tsx +41 -0
- package/src/components/SummaryList/SummaryListSkeleton.stories.tsx +67 -0
- package/src/components/SummaryList/SummaryListSkeleton.tsx +40 -0
- package/src/components/Tabs/Tabs.css +84 -0
- package/src/components/Tabs/Tabs.stories.tsx +133 -0
- package/src/components/Tabs/Tabs.tsx +66 -0
- package/src/components/Tag/Tag.css +8 -0
- package/src/components/Tag/Tag.stories.tsx +96 -0
- package/src/components/Tag/Tag.tsx +34 -0
- package/src/components/Textarea/Textarea.css +38 -0
- package/src/components/Textarea/Textarea.stories.tsx +131 -0
- package/src/components/Textarea/Textarea.tsx +50 -0
- package/src/components/TextareaCount/TextareaCount.css +17 -0
- package/src/components/TextareaCount/TextareaCount.stories.tsx +131 -0
- package/src/components/TextareaCount/TextareaCount.tsx +108 -0
- package/src/components/Tooltip/Tooltip.css +43 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +110 -0
- package/src/components/Tooltip/Tooltip.tsx +53 -0
- package/src/components/WarningText/WarningText.css +20 -0
- package/src/components/WarningText/WarningText.stories.tsx +29 -0
- package/src/components/WarningText/WarningText.tsx +17 -0
- package/src/components/index.ts +342 -61
- package/src/errors/errorDisplay.ts +70 -0
- package/src/errors/index.ts +1 -0
- package/src/http/constants.ts +1 -0
- package/src/http/fetch.ts +7 -3
- package/src/map/LayerSwitcherPanel.tsx +2 -173
- package/src/map/LegendShim.tsx +2 -0
- package/src/map/MapComponent.tsx +7 -17
- package/src/map/MapControlsOverlay.tsx +68 -175
- package/src/map/Popup.tsx +71 -24
- package/src/map/geocoder/Geocoder.test.tsx +46 -3
- package/src/map/geocoder/Geocoder.tsx +155 -278
- package/src/map/index.ts +1 -1
- package/src/types/utils.ts +0 -10
- package/src/utils/components.ts +96 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/utils.ts +0 -12
- package/src/assets/images/defra-logo.svg +0 -51
- package/src/assets/images/ea-logo.svg +0 -58
- package/src/assets/images/ogl.svg +0 -1
- package/src/components/Button/Button.test.tsx +0 -53
- package/src/components/ButtonLink/ButtonLink.test.tsx +0 -154
- package/src/components/Card/Card.test.tsx +0 -51
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +0 -75
- package/src/components/ErrorBoundary/ErrorFallback.test.tsx +0 -107
- package/src/components/ErrorText/ErrorText.test.tsx +0 -33
- package/src/components/Heading/Heading.test.tsx +0 -22
- package/src/components/Hint/Hint.stories.tsx +0 -58
- package/src/components/Hint/Hint.test.tsx +0 -33
- package/src/components/Hint/Hint.tsx +0 -12
- package/src/components/InfoBox/InfoBox.test.tsx +0 -330
- package/src/components/InfoBox/types.ts +0 -6
- package/src/components/LinkButton/LinkButton.test.tsx +0 -177
- package/src/components/Modal/Modal.test.tsx +0 -246
- package/src/components/NotificationBanner/NotificationBanner.stories.tsx +0 -45
- package/src/components/NotificationBanner/NotificationBanner.test.tsx +0 -58
- package/src/components/NotificationBanner/NotificationBanner.tsx +0 -45
- package/src/components/Paragraph/Paragraph.test.tsx +0 -10
- package/src/components/SlidingPanel/SlidingPanel.stories.tsx +0 -129
- package/src/components/SlidingPanel/SlidingPanel.test.tsx +0 -83
- package/src/components/SlidingPanel/SlidingPanel.tsx +0 -258
- package/src/components/accordion/Accordion.stories.tsx +0 -234
- package/src/components/accordion/Accordion.test.tsx +0 -192
- package/src/components/accordion/Accordion.tsx +0 -73
- package/src/components/backToTop/BackToTop.stories.tsx +0 -407
- package/src/components/backToTop/BackToTop.test.tsx +0 -57
- package/src/components/backToTop/BackToTop.tsx +0 -134
- package/src/components/chip/Chip.stories.tsx +0 -61
- package/src/components/chip/Chip.test.tsx +0 -31
- package/src/components/chip/Chip.tsx +0 -23
- package/src/components/container/Container.tsx +0 -42
- package/src/components/cookieBanner/CookieBanner.stories.tsx +0 -257
- package/src/components/cookieBanner/CookieBanner.test.tsx +0 -68
- package/src/components/cookieBanner/CookieBanner.tsx +0 -73
- package/src/components/divider/RuleDivider.stories.tsx +0 -254
- package/src/components/divider/RuleDivider.test.tsx +0 -164
- package/src/components/divider/RuleDivider.tsx +0 -23
- package/src/components/dropdown/DropdownMenu.test.tsx +0 -211
- package/src/components/dropdown/DropdownMenu.tsx +0 -108
- package/src/components/dropdown/useDropdownMenu.ts +0 -249
- package/src/components/form/Input.stories.tsx +0 -435
- package/src/components/form/Input.test.tsx +0 -206
- package/src/components/form/Input.tsx +0 -23
- package/src/components/form/TextArea.stories.tsx +0 -464
- package/src/components/form/TextArea.test.tsx +0 -232
- package/src/components/form/TextArea.tsx +0 -23
- package/src/components/layout/footer/Footer.tsx +0 -26
- package/src/components/layout/footer/Licence.tsx +0 -19
- package/src/components/layout/header/Header.test.tsx +0 -36
- package/src/components/layout/header/Header.tsx +0 -90
- package/src/components/layout/header/HeaderAuthClient.test.tsx +0 -45
- package/src/components/layout/header/HeaderAuthClient.tsx +0 -40
- package/src/components/layout/header/HeaderNavClient.test.tsx +0 -44
- package/src/components/layout/header/HeaderNavClient.tsx +0 -67
- package/src/components/link/ExternalLink.test.tsx +0 -102
- package/src/components/link/ExternalLink.tsx +0 -29
- package/src/components/link/Link.tsx +0 -26
- package/src/components/select/Select.stories.tsx +0 -336
- package/src/components/select/Select.test.tsx +0 -474
- package/src/components/select/Select.tsx +0 -125
- package/src/components/select/SelectSkeleton.stories.tsx +0 -194
- package/src/components/select/SelectSkeleton.test.tsx +0 -104
- package/src/components/select/SelectSkeleton.tsx +0 -23
- package/src/components/select/common.ts +0 -3
- package/src/components/select/index.ts +0 -18
- package/src/components/skipLink/SkipLink.stories.tsx +0 -346
- package/src/components/skipLink/SkipLink.test.tsx +0 -22
- package/src/components/skipLink/SkipLink.tsx +0 -49
- package/src/map/LegendPanel.tsx +0 -85
- /package/src/{components → assets}/images/DefraLogo.tsx +0 -0
- /package/src/{components → assets}/images/EaLogo.tsx +0 -0
- /package/src/{components → assets}/images/OglLogo.tsx +0 -0
- /package/src/components/{googleAnalytics → GoogleAnalytics}/GlobalVars.tsx +0 -0
- /package/src/components/{googleAnalytics → GoogleAnalytics}/GoogleAnalytics.tsx +0 -0
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import { LinkButton } from './LinkButton';
|
|
2
|
-
import { render, screen } from '../../test/renderers';
|
|
3
|
-
|
|
4
|
-
// Mock next/link
|
|
5
|
-
vi.mock('next/link', () => ({
|
|
6
|
-
default: ({
|
|
7
|
-
href,
|
|
8
|
-
children,
|
|
9
|
-
className,
|
|
10
|
-
...props
|
|
11
|
-
}: {
|
|
12
|
-
href: string;
|
|
13
|
-
children: React.ReactNode;
|
|
14
|
-
className?: string;
|
|
15
|
-
}) => (
|
|
16
|
-
<a href={href} className={className} data-testid="next-link" {...props}>
|
|
17
|
-
{children}
|
|
18
|
-
</a>
|
|
19
|
-
),
|
|
20
|
-
}));
|
|
21
|
-
|
|
22
|
-
describe('LinkButton', () => {
|
|
23
|
-
describe('rendering', () => {
|
|
24
|
-
it('should render with children', () => {
|
|
25
|
-
render(<LinkButton href="/test">Click me</LinkButton>);
|
|
26
|
-
|
|
27
|
-
expect(screen.getByRole('link', { name: 'Click me' })).toBeInTheDocument();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should render as a link with correct href', () => {
|
|
31
|
-
render(<LinkButton href="/explore">Explore</LinkButton>);
|
|
32
|
-
|
|
33
|
-
const link = screen.getByRole('link', { name: 'Explore' });
|
|
34
|
-
|
|
35
|
-
expect(link).toHaveAttribute('href', '/explore');
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it('should apply primary variant by default', () => {
|
|
39
|
-
render(<LinkButton href="/test">Button</LinkButton>);
|
|
40
|
-
|
|
41
|
-
const link = screen.getByRole('link');
|
|
42
|
-
|
|
43
|
-
expect(link).toHaveClass('bg-brand');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should apply secondary variant when specified', () => {
|
|
47
|
-
render(
|
|
48
|
-
<LinkButton href="/test" variant="secondary">
|
|
49
|
-
Button
|
|
50
|
-
</LinkButton>,
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
const link = screen.getByRole('link');
|
|
54
|
-
|
|
55
|
-
expect(link).toHaveClass('bg-slate-100');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should apply inverse variant when specified', () => {
|
|
59
|
-
render(
|
|
60
|
-
<LinkButton href="/test" variant="inverse">
|
|
61
|
-
Button
|
|
62
|
-
</LinkButton>,
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
const link = screen.getByRole('link');
|
|
66
|
-
|
|
67
|
-
expect(link).toHaveClass('bg-white');
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should merge custom className', () => {
|
|
71
|
-
render(
|
|
72
|
-
<LinkButton href="/test" className="custom-class">
|
|
73
|
-
Button
|
|
74
|
-
</LinkButton>,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
const link = screen.getByRole('link');
|
|
78
|
-
|
|
79
|
-
expect(link).toHaveClass('custom-class');
|
|
80
|
-
expect(link).toHaveClass('bg-brand'); // Still has base classes
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
describe('external links', () => {
|
|
85
|
-
it('should automatically detect external URLs', () => {
|
|
86
|
-
render(<LinkButton href="https://example.com">External</LinkButton>);
|
|
87
|
-
|
|
88
|
-
const link = screen.getByRole('link');
|
|
89
|
-
|
|
90
|
-
expect(link).toHaveAttribute('target', '_blank');
|
|
91
|
-
expect(link).toHaveAttribute('rel', 'noopener noreferrer');
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('should detect protocol-relative URLs as external', () => {
|
|
95
|
-
render(<LinkButton href="//example.com">External</LinkButton>);
|
|
96
|
-
|
|
97
|
-
const link = screen.getByRole('link');
|
|
98
|
-
|
|
99
|
-
expect(link).toHaveAttribute('target', '_blank');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should detect mailto links as external', () => {
|
|
103
|
-
render(<LinkButton href="mailto:test@example.com">Email</LinkButton>);
|
|
104
|
-
|
|
105
|
-
const link = screen.getByRole('link');
|
|
106
|
-
|
|
107
|
-
expect(link).toHaveAttribute('target', '_blank');
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should use Next.js Link for internal URLs', () => {
|
|
111
|
-
render(<LinkButton href="/internal">Internal</LinkButton>);
|
|
112
|
-
|
|
113
|
-
expect(screen.getByTestId('next-link')).toBeInTheDocument();
|
|
114
|
-
|
|
115
|
-
const link = screen.getByRole('link');
|
|
116
|
-
|
|
117
|
-
expect(link).not.toHaveAttribute('target');
|
|
118
|
-
expect(link).not.toHaveAttribute('rel');
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe('openInNewTab', () => {
|
|
123
|
-
it('should open in new tab when openInNewTab is true', () => {
|
|
124
|
-
render(
|
|
125
|
-
<LinkButton href="/internal" openInNewTab>
|
|
126
|
-
Open in new tab
|
|
127
|
-
</LinkButton>,
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
const link = screen.getByRole('link');
|
|
131
|
-
|
|
132
|
-
expect(link).toHaveAttribute('target', '_blank');
|
|
133
|
-
expect(link).toHaveAttribute('rel', 'noopener noreferrer');
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('should use regular anchor tag when openInNewTab is true', () => {
|
|
137
|
-
render(
|
|
138
|
-
<LinkButton href="/internal" openInNewTab>
|
|
139
|
-
Open in new tab
|
|
140
|
-
</LinkButton>,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
// Should not use Next.js Link when opening in new tab
|
|
144
|
-
expect(screen.queryByTestId('next-link')).not.toBeInTheDocument();
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it('should not open in new tab by default for internal links', () => {
|
|
148
|
-
render(<LinkButton href="/internal">Internal</LinkButton>);
|
|
149
|
-
|
|
150
|
-
const link = screen.getByRole('link');
|
|
151
|
-
|
|
152
|
-
expect(link).not.toHaveAttribute('target');
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
describe('accessibility', () => {
|
|
157
|
-
it('should have link role', () => {
|
|
158
|
-
render(<LinkButton href="/test">Button</LinkButton>);
|
|
159
|
-
|
|
160
|
-
const link = screen.getByRole('link');
|
|
161
|
-
|
|
162
|
-
expect(link).toBeInTheDocument();
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it('should accept aria attributes', () => {
|
|
166
|
-
render(
|
|
167
|
-
<LinkButton href="/test" aria-label="Custom label">
|
|
168
|
-
Button
|
|
169
|
-
</LinkButton>,
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
const link = screen.getByRole('link', { name: 'Custom label' });
|
|
173
|
-
|
|
174
|
-
expect(link).toBeInTheDocument();
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
});
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import { Modal } from './Modal';
|
|
2
|
-
import { render, screen, userEvent } from '../../test/renderers';
|
|
3
|
-
|
|
4
|
-
const MODAL_CONTENT = 'Modal content';
|
|
5
|
-
const MODAL_ROOT_ID = 'modal-root';
|
|
6
|
-
const BACKDROP_SELECTOR = '[aria-modal="true"]';
|
|
7
|
-
|
|
8
|
-
// Mock the useClickOutside hook
|
|
9
|
-
vi.mock('../../hooks/useClickOutside', () => ({
|
|
10
|
-
useClickOutside: vi.fn(),
|
|
11
|
-
}));
|
|
12
|
-
|
|
13
|
-
describe.todo('Modal', () => {
|
|
14
|
-
// Setup modal root element for each test
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
const modalRoot = document.createElement('div');
|
|
17
|
-
|
|
18
|
-
modalRoot.id = MODAL_ROOT_ID;
|
|
19
|
-
document.body.appendChild(modalRoot);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
afterEach(() => {
|
|
23
|
-
const modalRoot = document.getElementById(MODAL_ROOT_ID);
|
|
24
|
-
|
|
25
|
-
if (modalRoot) {
|
|
26
|
-
modalRoot.remove();
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should render modal when isOpen is true', () => {
|
|
31
|
-
render(
|
|
32
|
-
<Modal isOpen={true} onClose={vi.fn()}>
|
|
33
|
-
<div>{MODAL_CONTENT}</div>
|
|
34
|
-
</Modal>,
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
expect(screen.getByText(MODAL_CONTENT)).toBeInTheDocument();
|
|
38
|
-
|
|
39
|
-
// Check for the backdrop with aria-modal attribute instead of role
|
|
40
|
-
const backdrop = screen.getByText(MODAL_CONTENT).closest(BACKDROP_SELECTOR);
|
|
41
|
-
|
|
42
|
-
expect(backdrop).toBeInTheDocument();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should not render modal when isOpen is false', () => {
|
|
46
|
-
render(
|
|
47
|
-
<Modal isOpen={false} onClose={vi.fn()}>
|
|
48
|
-
<div>{MODAL_CONTENT}</div>
|
|
49
|
-
</Modal>,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
expect(screen.queryByText(MODAL_CONTENT)).not.toBeInTheDocument();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should not render modal when modal root is missing', () => {
|
|
56
|
-
// Remove modal root
|
|
57
|
-
const modalRoot = document.getElementById(MODAL_ROOT_ID);
|
|
58
|
-
|
|
59
|
-
if (modalRoot) {
|
|
60
|
-
document.body.removeChild(modalRoot);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
render(
|
|
64
|
-
<Modal isOpen={true} onClose={vi.fn()}>
|
|
65
|
-
<div>{MODAL_CONTENT}</div>
|
|
66
|
-
</Modal>,
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
expect(screen.queryByText(MODAL_CONTENT)).not.toBeInTheDocument();
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should have proper accessibility attributes', () => {
|
|
73
|
-
render(
|
|
74
|
-
<Modal isOpen={true} onClose={vi.fn()}>
|
|
75
|
-
<div>{MODAL_CONTENT}</div>
|
|
76
|
-
</Modal>,
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
const backdrop = screen.getByText(MODAL_CONTENT).closest(BACKDROP_SELECTOR);
|
|
80
|
-
|
|
81
|
-
expect(backdrop).toHaveAttribute('aria-modal', 'true');
|
|
82
|
-
|
|
83
|
-
const closeButton = screen.getByRole('button', { name: /close modal/i });
|
|
84
|
-
|
|
85
|
-
expect(closeButton).toHaveAttribute('aria-label', 'Close modal');
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('should call onClose when close button is clicked', async () => {
|
|
89
|
-
const user = userEvent.setup();
|
|
90
|
-
const onCloseMock = vi.fn();
|
|
91
|
-
|
|
92
|
-
render(
|
|
93
|
-
<Modal isOpen={true} onClose={onCloseMock}>
|
|
94
|
-
<div>{MODAL_CONTENT}</div>
|
|
95
|
-
</Modal>,
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
const closeButton = screen.getByRole('button', { name: /close modal/i });
|
|
99
|
-
|
|
100
|
-
await user.click(closeButton);
|
|
101
|
-
|
|
102
|
-
expect(onCloseMock).toHaveBeenCalledTimes(1);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should call onClose when Escape key is pressed', async () => {
|
|
106
|
-
const user = userEvent.setup();
|
|
107
|
-
const onCloseMock = vi.fn();
|
|
108
|
-
|
|
109
|
-
render(
|
|
110
|
-
<Modal isOpen={true} onClose={onCloseMock}>
|
|
111
|
-
<div>{MODAL_CONTENT}</div>
|
|
112
|
-
</Modal>,
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
await user.keyboard('{Escape}');
|
|
116
|
-
|
|
117
|
-
expect(onCloseMock).toHaveBeenCalledTimes(1);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should not call onClose when other keys are pressed', async () => {
|
|
121
|
-
const user = userEvent.setup();
|
|
122
|
-
const onCloseMock = vi.fn();
|
|
123
|
-
|
|
124
|
-
render(
|
|
125
|
-
<Modal isOpen={true} onClose={onCloseMock}>
|
|
126
|
-
<div>{MODAL_CONTENT}</div>
|
|
127
|
-
</Modal>,
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
await user.keyboard('{Enter}');
|
|
131
|
-
await user.keyboard('{Space}');
|
|
132
|
-
await user.keyboard('a');
|
|
133
|
-
|
|
134
|
-
expect(onCloseMock).not.toHaveBeenCalled();
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it('should render complex content correctly', () => {
|
|
138
|
-
render(
|
|
139
|
-
<Modal isOpen={true} onClose={vi.fn()}>
|
|
140
|
-
<div>
|
|
141
|
-
<h2>Modal Title</h2>
|
|
142
|
-
|
|
143
|
-
<p>Modal description</p>
|
|
144
|
-
|
|
145
|
-
<button>Action Button</button>
|
|
146
|
-
|
|
147
|
-
<ul>
|
|
148
|
-
<li>Item 1</li>
|
|
149
|
-
|
|
150
|
-
<li>Item 2</li>
|
|
151
|
-
</ul>
|
|
152
|
-
</div>
|
|
153
|
-
</Modal>,
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
expect(screen.getByText('Modal Title')).toBeInTheDocument();
|
|
157
|
-
expect(screen.getByText('Modal description')).toBeInTheDocument();
|
|
158
|
-
expect(screen.getByRole('button', { name: 'Action Button' })).toBeInTheDocument();
|
|
159
|
-
expect(screen.getByText('Item 1')).toBeInTheDocument();
|
|
160
|
-
expect(screen.getByText('Item 2')).toBeInTheDocument();
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('should have correct styling classes', () => {
|
|
164
|
-
render(
|
|
165
|
-
<Modal isOpen={true} onClose={vi.fn()}>
|
|
166
|
-
<div>{MODAL_CONTENT}</div>
|
|
167
|
-
</Modal>,
|
|
168
|
-
);
|
|
169
|
-
|
|
170
|
-
const backdrop = screen.getByText(MODAL_CONTENT).closest(BACKDROP_SELECTOR);
|
|
171
|
-
|
|
172
|
-
expect(backdrop).toHaveClass(
|
|
173
|
-
'fixed',
|
|
174
|
-
'inset-0',
|
|
175
|
-
'z-50',
|
|
176
|
-
'flex',
|
|
177
|
-
'items-center',
|
|
178
|
-
'justify-center',
|
|
179
|
-
'bg-black',
|
|
180
|
-
'bg-opacity-50',
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
const modalContent = backdrop?.firstChild as HTMLElement;
|
|
184
|
-
|
|
185
|
-
expect(modalContent).toHaveClass(
|
|
186
|
-
'bg-white',
|
|
187
|
-
'rounded-lg',
|
|
188
|
-
'p-6',
|
|
189
|
-
'relative',
|
|
190
|
-
'max-w-md',
|
|
191
|
-
'w-full',
|
|
192
|
-
'shadow-lg',
|
|
193
|
-
'z-10',
|
|
194
|
-
);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it('should render close icon correctly', () => {
|
|
198
|
-
render(
|
|
199
|
-
<Modal isOpen={true} onClose={vi.fn()}>
|
|
200
|
-
<div>{MODAL_CONTENT}</div>
|
|
201
|
-
</Modal>,
|
|
202
|
-
);
|
|
203
|
-
|
|
204
|
-
const closeButton = screen.getByRole('button', { name: /close modal/i });
|
|
205
|
-
const closeIcon = closeButton.querySelector('svg');
|
|
206
|
-
|
|
207
|
-
expect(closeIcon).toBeInTheDocument();
|
|
208
|
-
expect(closeButton).toHaveClass(
|
|
209
|
-
'text-static-xl',
|
|
210
|
-
'absolute',
|
|
211
|
-
'top-2',
|
|
212
|
-
'right-2',
|
|
213
|
-
'text-gray-600',
|
|
214
|
-
'hover:text-black',
|
|
215
|
-
);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('should clean up event listeners when unmounted', () => {
|
|
219
|
-
const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
|
|
220
|
-
const onCloseMock = vi.fn();
|
|
221
|
-
|
|
222
|
-
const { unmount } = render(
|
|
223
|
-
<Modal isOpen={true} onClose={onCloseMock}>
|
|
224
|
-
<div>{MODAL_CONTENT}</div>
|
|
225
|
-
</Modal>,
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
unmount();
|
|
229
|
-
|
|
230
|
-
expect(removeEventListenerSpy).toHaveBeenCalledWith('keydown', expect.any(Function));
|
|
231
|
-
|
|
232
|
-
removeEventListenerSpy.mockRestore();
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it('should have modal content with correct tabIndex', () => {
|
|
236
|
-
render(
|
|
237
|
-
<Modal isOpen={true} onClose={vi.fn()}>
|
|
238
|
-
<div>{MODAL_CONTENT}</div>
|
|
239
|
-
</Modal>,
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
const modalContent = screen.getByText(MODAL_CONTENT).closest('div[tabIndex="-1"]');
|
|
243
|
-
|
|
244
|
-
expect(modalContent).toHaveAttribute('tabIndex', '-1');
|
|
245
|
-
});
|
|
246
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
|
|
3
|
-
import { NotificationBanner } from './NotificationBanner';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
title: 'Components/NotificationBanner',
|
|
7
|
-
component: NotificationBanner,
|
|
8
|
-
parameters: {
|
|
9
|
-
docs: {
|
|
10
|
-
description: {
|
|
11
|
-
component:
|
|
12
|
-
'A notification banner for displaying important messages. Follows the GOV.UK Design System notification banner pattern. Commonly used wrapped in a <noscript> tag to inform users when JavaScript is required.',
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
} as Meta<typeof NotificationBanner>;
|
|
17
|
-
|
|
18
|
-
export const Default: StoryObj<typeof NotificationBanner> = {
|
|
19
|
-
args: {
|
|
20
|
-
message: 'This is an important notification message for users.',
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export const CustomTitle: StoryObj<typeof NotificationBanner> = {
|
|
25
|
-
args: {
|
|
26
|
-
title: 'Service Update',
|
|
27
|
-
message:
|
|
28
|
-
'This service will be undergoing maintenance on Saturday 15th January from 9am to 5pm.',
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export const JavaScriptRequired: StoryObj<typeof NotificationBanner> = {
|
|
33
|
-
args: {
|
|
34
|
-
title: 'Important: JavaScript is required',
|
|
35
|
-
message:
|
|
36
|
-
'This application requires JavaScript to display the interactive map and data. Please enable JavaScript in your browser settings to use this service.',
|
|
37
|
-
},
|
|
38
|
-
parameters: {
|
|
39
|
-
docs: {
|
|
40
|
-
description: {
|
|
41
|
-
story: 'Example usage for a noscript fallback message.',
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { NotificationBanner } from './NotificationBanner';
|
|
2
|
-
import { render, screen } from '../../test/renderers';
|
|
3
|
-
|
|
4
|
-
describe('NotificationBanner Component', () => {
|
|
5
|
-
it('renders with default title and provided message', () => {
|
|
6
|
-
render(<NotificationBanner message="Test message content" />);
|
|
7
|
-
|
|
8
|
-
const heading = screen.getByRole('heading', { name: 'Important' });
|
|
9
|
-
const message = screen.getByText('Test message content');
|
|
10
|
-
|
|
11
|
-
expect(heading).toHaveAttribute('id', 'notification-banner-title');
|
|
12
|
-
expect(heading).toBeInTheDocument();
|
|
13
|
-
expect(message).toBeInTheDocument();
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('renders with custom title and message', () => {
|
|
17
|
-
render(<NotificationBanner title="Custom Title" message="Custom message content" />);
|
|
18
|
-
|
|
19
|
-
const heading = screen.getByRole('heading', { name: 'Custom Title' });
|
|
20
|
-
const message = screen.getByText('Custom message content');
|
|
21
|
-
|
|
22
|
-
expect(heading).toBeInTheDocument();
|
|
23
|
-
expect(message).toBeInTheDocument();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('renders as a section with aria-labelledby', () => {
|
|
27
|
-
render(<NotificationBanner message="Test message" />);
|
|
28
|
-
|
|
29
|
-
const section = screen.getByRole('region', { name: 'Important' });
|
|
30
|
-
|
|
31
|
-
expect(section).toBeInTheDocument();
|
|
32
|
-
expect(section).toHaveAttribute('aria-labelledby', 'notification-banner-title');
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('applies default styling classes', () => {
|
|
36
|
-
render(<NotificationBanner message="Test message" />);
|
|
37
|
-
|
|
38
|
-
const section = screen.getByRole('region');
|
|
39
|
-
|
|
40
|
-
expect(section).toHaveClass('bg-brand', 'text-white', 'font-gds');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('allows custom className to be merged', () => {
|
|
44
|
-
render(<NotificationBanner message="Test message" className="custom-class" />);
|
|
45
|
-
|
|
46
|
-
const section = screen.getByRole('region');
|
|
47
|
-
|
|
48
|
-
expect(section).toHaveClass('bg-brand', 'text-white', 'font-gds', 'custom-class');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('spreads additional props to section element', () => {
|
|
52
|
-
render(<NotificationBanner message="Test message" data-testid="notification-banner" />);
|
|
53
|
-
|
|
54
|
-
const section = screen.getByTestId('notification-banner');
|
|
55
|
-
|
|
56
|
-
expect(section).toBeInTheDocument();
|
|
57
|
-
});
|
|
58
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { ExtendProps } from '../../types';
|
|
2
|
-
import { cn } from '../../utils';
|
|
3
|
-
import { Heading } from '../Heading/Heading';
|
|
4
|
-
import { Paragraph } from '../Paragraph/Paragraph';
|
|
5
|
-
|
|
6
|
-
type Props = {
|
|
7
|
-
title?: string;
|
|
8
|
-
message: string;
|
|
9
|
-
/** Explicitly disallow children as we use title and message props instead */
|
|
10
|
-
children?: never;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type NotificationBannerProps = ExtendProps<'section', Props>;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* A notification banner component for displaying important messages.
|
|
17
|
-
* Follows the GOV.UK Design System notification banner pattern.
|
|
18
|
-
*
|
|
19
|
-
* Common use cases:
|
|
20
|
-
* - Wrapped in <noscript> to inform users that JavaScript is required
|
|
21
|
-
* - Service announcements or maintenance notices
|
|
22
|
-
* - Important information that needs prominent display
|
|
23
|
-
*/
|
|
24
|
-
export const NotificationBanner = ({
|
|
25
|
-
title = 'Important',
|
|
26
|
-
message,
|
|
27
|
-
className,
|
|
28
|
-
...props
|
|
29
|
-
}: NotificationBannerProps) => (
|
|
30
|
-
<section
|
|
31
|
-
aria-labelledby="notification-banner-title"
|
|
32
|
-
className={cn('bg-brand text-white font-gds', className)}
|
|
33
|
-
{...props}
|
|
34
|
-
>
|
|
35
|
-
<div className="px-4 py-2 border-b border-white/30">
|
|
36
|
-
<Heading type="h2" id="notification-banner-title" className="text-lg text-white py-2">
|
|
37
|
-
{title}
|
|
38
|
-
</Heading>
|
|
39
|
-
</div>
|
|
40
|
-
|
|
41
|
-
<div className="p-4">
|
|
42
|
-
<Paragraph className="text-lg text-white pb-0">{message}</Paragraph>
|
|
43
|
-
</div>
|
|
44
|
-
</section>
|
|
45
|
-
);
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Paragraph } from './Paragraph';
|
|
2
|
-
import { render, screen } from '../../test/renderers';
|
|
3
|
-
|
|
4
|
-
describe('Paragraph', () => {
|
|
5
|
-
it('renders with text', () => {
|
|
6
|
-
render(<Paragraph>Some test text</Paragraph>);
|
|
7
|
-
|
|
8
|
-
expect(screen.getByRole('paragraph')).toBeInTheDocument();
|
|
9
|
-
});
|
|
10
|
-
});
|