@tpzdsp/next-toolkit 2.5.0 → 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 +22 -13
- 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
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Copyright } from './Copyright';
|
|
2
|
+
import { Licence } from './Licence';
|
|
3
|
+
import { MetaLinks } from './MetaLinks';
|
|
4
|
+
import { DefraLogo } from '../../assets/images/DefraLogo';
|
|
5
|
+
import { WidthContainer } from '../Layout/WidthContainer/WidthContainer';
|
|
6
|
+
|
|
7
|
+
export const Footer = () => (
|
|
8
|
+
<footer className="bg-wash">
|
|
9
|
+
<WidthContainer className="py-gds-3">
|
|
10
|
+
<div
|
|
11
|
+
className="grid gap-gds-2 grid-cols-1 sm:grid-cols-[1fr_min-content]
|
|
12
|
+
grid-rows-[min-content_min-content_min-content_min-content]
|
|
13
|
+
sm:grid-rows-[min-content_min-content_min-content] md:grid-rows-[min-content_min-content]"
|
|
14
|
+
>
|
|
15
|
+
<nav className="row-start-1 col-start-1 w-full pb-gds-2 self-end">
|
|
16
|
+
<h2 className="sr-only">Support Links</h2>
|
|
17
|
+
|
|
18
|
+
<MetaLinks />
|
|
19
|
+
</nav>
|
|
20
|
+
|
|
21
|
+
<div className="row-start-2 col-start-1 self-end pt-gds-1">
|
|
22
|
+
<Licence />
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<DefraLogo
|
|
26
|
+
aria-hidden
|
|
27
|
+
className="row-start-3 sm:row-span-3 md:row-span-1 sm:row-start-1 col-start-1
|
|
28
|
+
sm:col-start-2 h-20 w-auto shrink-0 fill-body md:h-20 justify-self-start
|
|
29
|
+
sm:justify-self-end"
|
|
30
|
+
/>
|
|
31
|
+
|
|
32
|
+
<div
|
|
33
|
+
className="row-start-4 sm:row-start-3 col-start-1 md:row-start-2 md:col-start-2 self-end
|
|
34
|
+
justify-self-start md:justify-self-end"
|
|
35
|
+
>
|
|
36
|
+
<Copyright />
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</WidthContainer>
|
|
40
|
+
</footer>
|
|
41
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { OglLogo } from '../../assets/images/OglLogo';
|
|
2
|
+
import { ExternalLink } from '../ExternalLink/ExternalLink';
|
|
3
|
+
|
|
4
|
+
export const Licence = () => (
|
|
5
|
+
<span className="block w-full wrap-break-word text-body">
|
|
6
|
+
<OglLogo className="inline w-9 mr-gds-2 align-middle" aria-hidden />
|
|
7
|
+
All content is available under the{' '}
|
|
8
|
+
<ExternalLink
|
|
9
|
+
className="wrap-break-word"
|
|
10
|
+
appearance="contrast"
|
|
11
|
+
variant="plain"
|
|
12
|
+
href="https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/"
|
|
13
|
+
>
|
|
14
|
+
Open Government Licence v3.0
|
|
15
|
+
</ExternalLink>
|
|
16
|
+
, except where otherwise stated.
|
|
17
|
+
</span>
|
|
18
|
+
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExternalLink } from '
|
|
1
|
+
import { ExternalLink } from '../ExternalLink/ExternalLink';
|
|
2
2
|
|
|
3
3
|
const LINKS = [
|
|
4
4
|
{
|
|
@@ -24,10 +24,15 @@ const LINKS = [
|
|
|
24
24
|
];
|
|
25
25
|
|
|
26
26
|
export const MetaLinks = () => (
|
|
27
|
-
<ul className="flex w-full flex-wrap gap-x-4 gap-y-2 md:gap-
|
|
27
|
+
<ul className="flex w-full flex-wrap gap-x-gds-4 gap-y-gds-2 md:gap-gds-5 md:justify-start">
|
|
28
28
|
{LINKS.map((link) => (
|
|
29
29
|
<li className="flex" key={link.label}>
|
|
30
|
-
<ExternalLink
|
|
30
|
+
<ExternalLink
|
|
31
|
+
className="md:text-left"
|
|
32
|
+
appearance="contrast"
|
|
33
|
+
href={link.url}
|
|
34
|
+
variant="plain"
|
|
35
|
+
>
|
|
31
36
|
{link.label}
|
|
32
37
|
</ExternalLink>
|
|
33
38
|
</li>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { DefraLogo } from '
|
|
2
|
-
import { EaLogo } from '
|
|
3
|
-
import { OglLogo } from '
|
|
1
|
+
import { DefraLogo } from '../../../assets/images/DefraLogo';
|
|
2
|
+
import { EaLogo } from '../../../assets/images/EaLogo';
|
|
3
|
+
import { OglLogo } from '../../../assets/images/OglLogo';
|
|
4
|
+
import { ExternalLink } from '../../ExternalLink/ExternalLink';
|
|
5
|
+
import { WidthContainer } from '../../Layout/WidthContainer/WidthContainer';
|
|
4
6
|
|
|
5
7
|
const CROWN_COPYRIGHT_URL =
|
|
6
8
|
'https://www.nationalarchives.gov.uk/information-management/re-using-public-sector-information/uk-government-licensing-framework/crown-copyright/';
|
|
@@ -17,45 +19,44 @@ export const SmallFooter = ({
|
|
|
17
19
|
eaLogoPrimaryFill = '#F3F2F1',
|
|
18
20
|
eaLogoHighlightFill = '#79A12F',
|
|
19
21
|
}: SmallFooterProps) => (
|
|
20
|
-
<footer
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
<footer aria-label="Site footer" className="flex justify-center">
|
|
23
|
+
<WidthContainer className="bg-wash py-gds-2">
|
|
24
|
+
<div className="flex items-center justify-between">
|
|
25
|
+
<div className="flex items-center gap-2">
|
|
26
|
+
<EaLogo
|
|
27
|
+
className="h-8 w-auto"
|
|
28
|
+
aria-hidden="true"
|
|
29
|
+
primaryFill={eaLogoPrimaryFill}
|
|
30
|
+
highlightFill={eaLogoHighlightFill}
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div className="flex items-center gap-gds-6 xs:gap-gds-2">
|
|
35
|
+
<ExternalLink
|
|
36
|
+
appearance="contrast"
|
|
37
|
+
variant="plain"
|
|
38
|
+
href={LICENSING_DETAILS_URL}
|
|
39
|
+
className="flex gap-gds-1 items-center"
|
|
40
|
+
>
|
|
41
|
+
<OglLogo className="size-10 shrink-0" aria-hidden="true" />
|
|
42
|
+
|
|
43
|
+
<span className="hidden xs:inline">Licencing details</span>
|
|
44
|
+
</ExternalLink>
|
|
45
|
+
|
|
46
|
+
<ExternalLink
|
|
47
|
+
appearance="contrast"
|
|
48
|
+
variant="plain"
|
|
49
|
+
href={CROWN_COPYRIGHT_URL}
|
|
50
|
+
className="flex gap-gds-1 items-center"
|
|
51
|
+
>
|
|
52
|
+
<DefraLogo className="size-10 shrink-0" aria-hidden="true" />
|
|
53
|
+
|
|
54
|
+
<span className="inline xs:hidden">©</span>
|
|
55
|
+
|
|
56
|
+
<span className="hidden xs:inline">© Crown copyright</span>
|
|
57
|
+
</ExternalLink>
|
|
58
|
+
</div>
|
|
32
59
|
</div>
|
|
33
|
-
|
|
34
|
-
<div className="flex items-center gap-2 text-sm">
|
|
35
|
-
<OglLogo className="h-4 w-auto" aria-hidden="true" />
|
|
36
|
-
|
|
37
|
-
<a
|
|
38
|
-
href={LICENSING_DETAILS_URL}
|
|
39
|
-
target="_blank"
|
|
40
|
-
rel="noopener noreferrer"
|
|
41
|
-
className="underline"
|
|
42
|
-
>
|
|
43
|
-
Licencing details
|
|
44
|
-
</a>
|
|
45
|
-
|
|
46
|
-
<span aria-hidden="true">|</span>
|
|
47
|
-
|
|
48
|
-
<a
|
|
49
|
-
href={CROWN_COPYRIGHT_URL}
|
|
50
|
-
target="_blank"
|
|
51
|
-
rel="noopener noreferrer"
|
|
52
|
-
className="underline"
|
|
53
|
-
>
|
|
54
|
-
© Crown copyright
|
|
55
|
-
</a>
|
|
56
|
-
|
|
57
|
-
<DefraLogo className="h-8 w-auto" aria-hidden="true" />
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
+
</WidthContainer>
|
|
60
61
|
</footer>
|
|
61
62
|
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
/* MARK: Form group */
|
|
3
|
+
.cn-form-group {
|
|
4
|
+
@apply flex flex-col gap-gds-1;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.cn-form-group[data-invalid] {
|
|
8
|
+
@apply pl-gds-2;
|
|
9
|
+
|
|
10
|
+
border-left: 5px solid var(--color-error);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Label.css handles disabled via sibling combinator (~ :disabled), which
|
|
14
|
+
doesn't pierce wrapper elements like InputGroup. This catches that case. */
|
|
15
|
+
.cn-form-group:has(:is(:disabled, [aria-disabled='true'])) .cn-label {
|
|
16
|
+
@apply cursor-not-allowed select-none text-body-secondary;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
|
|
3
|
+
import { FormGroup } from './FormGroup';
|
|
4
|
+
import { Alert, AlertBody, AlertList, AlertListItem, AlertTitle } from '../Alert/Alert';
|
|
5
|
+
import { ErrorText } from '../ErrorText/ErrorText';
|
|
6
|
+
import { HintText } from '../HintText/HintText';
|
|
7
|
+
import { Input } from '../Input/Input';
|
|
8
|
+
import { Label } from '../Label/Label';
|
|
9
|
+
import { Link } from '../Link/Link';
|
|
10
|
+
|
|
11
|
+
const meta: Meta<typeof FormGroup> = {
|
|
12
|
+
title: 'Components/Form/FormGroup',
|
|
13
|
+
component: FormGroup,
|
|
14
|
+
tags: ['autodocs'],
|
|
15
|
+
parameters: {
|
|
16
|
+
docs: {
|
|
17
|
+
description: {
|
|
18
|
+
component:
|
|
19
|
+
'A layout wrapper that groups a form field with its label, hint, and error text. When `invalid` is set, a red left border is applied to the whole group, matching the GDS error pattern. Accessibility attributes (`aria-describedby`, `aria-invalid`, `id`) must be wired manually on the input.',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default meta;
|
|
26
|
+
|
|
27
|
+
type Story = StoryObj<typeof FormGroup>;
|
|
28
|
+
|
|
29
|
+
export const Default: Story = {
|
|
30
|
+
render: () => (
|
|
31
|
+
<FormGroup>
|
|
32
|
+
<Label htmlFor="name">Full name</Label>
|
|
33
|
+
|
|
34
|
+
<HintText>As it appears on your passport</HintText>
|
|
35
|
+
|
|
36
|
+
<Input id="name" aria-describedby="name-hint" />
|
|
37
|
+
</FormGroup>
|
|
38
|
+
),
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const Invalid: Story = {
|
|
42
|
+
render: () => (
|
|
43
|
+
<FormGroup invalid>
|
|
44
|
+
<Label htmlFor="name-invalid">Full name</Label>
|
|
45
|
+
|
|
46
|
+
<HintText id="name-invalid-hint">As it appears on your passport</HintText>
|
|
47
|
+
|
|
48
|
+
<ErrorText id="name-invalid-error">Enter your full name</ErrorText>
|
|
49
|
+
|
|
50
|
+
<Input
|
|
51
|
+
id="name-invalid"
|
|
52
|
+
aria-invalid
|
|
53
|
+
aria-describedby="name-invalid-hint name-invalid-error"
|
|
54
|
+
/>
|
|
55
|
+
</FormGroup>
|
|
56
|
+
),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const WithErrorSummary: Story = {
|
|
60
|
+
render: () => (
|
|
61
|
+
<div className="flex flex-col gap-gds-4">
|
|
62
|
+
<Alert appearance="error">
|
|
63
|
+
<AlertTitle>There is a problem</AlertTitle>
|
|
64
|
+
|
|
65
|
+
<AlertBody>
|
|
66
|
+
<AlertList>
|
|
67
|
+
<AlertListItem>
|
|
68
|
+
<Link appearance="error" href="#full-name">
|
|
69
|
+
Enter your full name
|
|
70
|
+
</Link>
|
|
71
|
+
</AlertListItem>
|
|
72
|
+
</AlertList>
|
|
73
|
+
</AlertBody>
|
|
74
|
+
</Alert>
|
|
75
|
+
|
|
76
|
+
<FormGroup invalid>
|
|
77
|
+
<Label htmlFor="full-name">Full name</Label>
|
|
78
|
+
|
|
79
|
+
<HintText id="full-name-hint">As it appears on your passport</HintText>
|
|
80
|
+
|
|
81
|
+
<ErrorText id="full-name-error">Enter your full name</ErrorText>
|
|
82
|
+
|
|
83
|
+
<Input id="full-name" aria-invalid aria-describedby="full-name-hint full-name-error" />
|
|
84
|
+
</FormGroup>
|
|
85
|
+
</div>
|
|
86
|
+
),
|
|
87
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
|
|
3
|
+
import { cn } from '../../utils/components';
|
|
4
|
+
|
|
5
|
+
export type FormGroupProps = ComponentProps<'div'> & {
|
|
6
|
+
invalid?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const FormGroup = ({ invalid, className, ...props }: FormGroupProps) => (
|
|
10
|
+
<div
|
|
11
|
+
data-slot="form-group"
|
|
12
|
+
data-invalid={invalid ? true : undefined}
|
|
13
|
+
className={cn('cn-form-group', className)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
|
|
3
3
|
import { Header } from './Header';
|
|
4
|
-
import
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
const navLinks: NavLink[] = [
|
|
8
|
-
{ label: 'Home', url: '/', openInNewTab: false },
|
|
9
|
-
{ label: 'API', url: '/api-docs', openInNewTab: false },
|
|
10
|
-
{ label: 'Support', url: 'https://example.com/support', openInNewTab: true },
|
|
11
|
-
];
|
|
4
|
+
import { HeaderAppContent } from './HeaderAppContent';
|
|
5
|
+
import type { Credentials } from '../../types/auth';
|
|
12
6
|
|
|
13
7
|
const authenticatedCredentials: Credentials = {
|
|
14
8
|
token: 'mock-token',
|
|
@@ -20,7 +14,7 @@ const authenticatedCredentials: Credentials = {
|
|
|
20
14
|
};
|
|
21
15
|
|
|
22
16
|
export default {
|
|
23
|
-
title: 'Components/
|
|
17
|
+
title: 'Components/Header',
|
|
24
18
|
component: Header,
|
|
25
19
|
parameters: {
|
|
26
20
|
layout: 'fullscreen',
|
|
@@ -32,15 +26,35 @@ export default {
|
|
|
32
26
|
},
|
|
33
27
|
},
|
|
34
28
|
args: {
|
|
35
|
-
dspUrl: 'https://environment.data.gov.uk',
|
|
36
|
-
appName: 'Wetlands Inventory',
|
|
37
|
-
navLinks,
|
|
38
29
|
credentials: null,
|
|
39
30
|
},
|
|
40
31
|
} as Meta<typeof Header>;
|
|
41
32
|
|
|
42
33
|
export const Default: StoryObj<typeof Header> = {};
|
|
43
34
|
|
|
35
|
+
export const AppSpecificContent: StoryObj<typeof Header> = {
|
|
36
|
+
parameters: {
|
|
37
|
+
docs: {
|
|
38
|
+
description: {
|
|
39
|
+
story:
|
|
40
|
+
"Resize the viewport (or Storybook's own frame) narrower to see the app nav links collapse from an inline list into a dropdown menu once the row no longer comfortably fits both the title and the links.",
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
args: {
|
|
45
|
+
appContent: (
|
|
46
|
+
<HeaderAppContent
|
|
47
|
+
title="UK Wetland Inventory"
|
|
48
|
+
links={[
|
|
49
|
+
{ url: '/apis', label: 'Wetlands APIs' },
|
|
50
|
+
{ url: '/downloads', label: 'Downloads' },
|
|
51
|
+
{ url: '/faqs', label: 'FAQs' },
|
|
52
|
+
]}
|
|
53
|
+
/>
|
|
54
|
+
),
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
44
58
|
export const Authenticated: StoryObj<typeof Header> = {
|
|
45
59
|
args: {
|
|
46
60
|
credentials: authenticatedCredentials,
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Header } from './Header';
|
|
2
|
+
import { render, screen, userEvent } from '../../test/renderers';
|
|
3
|
+
import type { Credentials } from '../../types/auth';
|
|
4
|
+
|
|
5
|
+
const ARIA_EXPANDED = 'aria-expanded';
|
|
6
|
+
|
|
7
|
+
const CREDENTIALS: Credentials = {
|
|
8
|
+
token: 'mock-token',
|
|
9
|
+
user: {
|
|
10
|
+
name: 'Jamie Taylor',
|
|
11
|
+
email: 'jamie.taylor@example.com',
|
|
12
|
+
groupInfoIds: ['group-1', 'group-2'],
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe('Header', () => {
|
|
17
|
+
it('renders the DEFRA and Data Services Platform brand links', () => {
|
|
18
|
+
render(<Header />);
|
|
19
|
+
|
|
20
|
+
expect(screen.getByRole('link', { name: 'DEFRA' })).toBeInTheDocument();
|
|
21
|
+
expect(screen.getByRole('link', { name: /data services platform/i })).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('shows a Sign-in link pointing at /login when signed out', async () => {
|
|
25
|
+
render(<Header />);
|
|
26
|
+
|
|
27
|
+
const signInLink = await screen.findByRole('link', { name: 'Sign-in' });
|
|
28
|
+
|
|
29
|
+
expect(signInLink).toHaveAttribute('href', expect.stringContaining('/login?redirect_uri='));
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('shows a Profile menu with a sign-out link when signed in', async () => {
|
|
33
|
+
const user = userEvent.setup();
|
|
34
|
+
|
|
35
|
+
render(<Header credentials={CREDENTIALS} />);
|
|
36
|
+
|
|
37
|
+
expect(screen.queryByRole('link', { name: 'Sign-in' })).not.toBeInTheDocument();
|
|
38
|
+
|
|
39
|
+
await user.click(await screen.findByRole('button', { name: 'Profile' }));
|
|
40
|
+
|
|
41
|
+
expect(await screen.findByText(CREDENTIALS.user.email)).toBeInTheDocument();
|
|
42
|
+
|
|
43
|
+
const signOutLink = screen.getByRole('link', { name: 'Sign-out' });
|
|
44
|
+
|
|
45
|
+
expect(signOutLink).toHaveAttribute('href', expect.stringContaining('/logout?redirect_uri='));
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('toggles the nav drawer open and closed', async () => {
|
|
49
|
+
const user = userEvent.setup();
|
|
50
|
+
|
|
51
|
+
render(<Header />);
|
|
52
|
+
|
|
53
|
+
const trigger = screen.getByRole('button', { name: 'Navigation drawer' });
|
|
54
|
+
|
|
55
|
+
expect(trigger).toHaveAttribute(ARIA_EXPANDED, 'false');
|
|
56
|
+
|
|
57
|
+
await user.click(trigger);
|
|
58
|
+
|
|
59
|
+
expect(trigger).toHaveAttribute(ARIA_EXPANDED, 'true');
|
|
60
|
+
expect(screen.getByRole('navigation', { name: 'More navigation' })).toBeInTheDocument();
|
|
61
|
+
|
|
62
|
+
await user.click(screen.getByRole('button', { name: 'Close' }));
|
|
63
|
+
|
|
64
|
+
expect(trigger).toHaveAttribute(ARIA_EXPANDED, 'false');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('toggles the search drawer open and closed', async () => {
|
|
68
|
+
const user = userEvent.setup();
|
|
69
|
+
|
|
70
|
+
render(<Header />);
|
|
71
|
+
|
|
72
|
+
const trigger = screen.getByRole('button', { name: 'Search the Data Services Platform' });
|
|
73
|
+
|
|
74
|
+
expect(trigger).toHaveAttribute(ARIA_EXPANDED, 'false');
|
|
75
|
+
|
|
76
|
+
await user.click(trigger);
|
|
77
|
+
|
|
78
|
+
expect(trigger).toHaveAttribute(ARIA_EXPANDED, 'true');
|
|
79
|
+
expect(screen.getByRole('searchbox')).toBeInTheDocument();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('renders appContent when provided', () => {
|
|
83
|
+
render(<Header appContent={<div>App-specific content</div>} />);
|
|
84
|
+
|
|
85
|
+
expect(screen.getByText('App-specific content')).toBeInTheDocument();
|
|
86
|
+
});
|
|
87
|
+
});
|