@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.
Files changed (355) hide show
  1. package/package.json +21 -12
  2. package/src/assets/styles/globals.css +75 -95
  3. package/src/assets/styles/ol.css +57 -16
  4. package/src/assets/styles/utils.css +80 -0
  5. package/src/components/Accordion/Accordion.css +85 -0
  6. package/src/components/Accordion/Accordion.stories.tsx +264 -0
  7. package/src/components/Accordion/Accordion.tsx +98 -0
  8. package/src/components/Alert/Alert.css +129 -0
  9. package/src/components/Alert/Alert.stories.tsx +291 -0
  10. package/src/components/Alert/Alert.tsx +76 -0
  11. package/src/components/BackLink/BackLink.css +12 -0
  12. package/src/components/BackLink/BackLink.stories.tsx +52 -0
  13. package/src/components/BackLink/BackLink.tsx +44 -0
  14. package/src/components/BackToTop/BackToTop.css +23 -0
  15. package/src/components/BackToTop/BackToTop.stories.tsx +41 -0
  16. package/src/components/BackToTop/BackToTop.tsx +48 -0
  17. package/src/components/Breadcrumb/Breadcrumb.css +42 -0
  18. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +94 -0
  19. package/src/components/Breadcrumb/Breadcrumb.tsx +135 -0
  20. package/src/components/Button/Button.css +229 -0
  21. package/src/components/Button/Button.stories.tsx +140 -20
  22. package/src/components/Button/Button.tsx +53 -28
  23. package/src/components/Button/ButtonSkeleton.stories.tsx +50 -0
  24. package/src/components/Button/ButtonSkeleton.tsx +14 -0
  25. package/src/components/ButtonGroup/ButtonGroup.css +52 -0
  26. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +156 -0
  27. package/src/components/ButtonGroup/ButtonGroup.tsx +50 -0
  28. package/src/components/ButtonLink/ButtonLink.css +114 -0
  29. package/src/components/ButtonLink/ButtonLink.stories.tsx +38 -51
  30. package/src/components/ButtonLink/ButtonLink.tsx +54 -23
  31. package/src/components/Card/Card.css +13 -0
  32. package/src/components/Card/Card.stories.tsx +98 -57
  33. package/src/components/Card/Card.tsx +4 -13
  34. package/src/components/CardGroup/CardGroup.css +10 -0
  35. package/src/components/CardGroup/CardGroup.stories.tsx +81 -0
  36. package/src/components/CardGroup/CardGroup.tsx +9 -0
  37. package/src/components/Checkbox/Checkbox.css +49 -0
  38. package/src/components/Checkbox/Checkbox.stories.tsx +86 -0
  39. package/src/components/Checkbox/Checkbox.tsx +32 -0
  40. package/src/components/Chip/Chip.css +54 -0
  41. package/src/components/Chip/Chip.stories.tsx +94 -0
  42. package/src/components/Chip/Chip.tsx +34 -0
  43. package/src/components/CookieBanner/CookieBanner.css +19 -0
  44. package/src/components/CookieBanner/CookieBanner.stories.tsx +52 -0
  45. package/src/components/CookieBanner/CookieBanner.tsx +55 -0
  46. package/src/components/CopyButton/CopyButton.stories.tsx +28 -0
  47. package/src/components/CopyButton/CopyButton.tsx +65 -0
  48. package/src/components/DateInput/DateInput.css +13 -0
  49. package/src/components/DateInput/DateInput.stories.tsx +131 -0
  50. package/src/components/DateInput/DateInput.test.tsx +21 -0
  51. package/src/components/DateInput/DateInput.tsx +98 -0
  52. package/src/components/Details/Details.css +28 -0
  53. package/src/components/Details/Details.stories.tsx +48 -0
  54. package/src/components/Details/Details.tsx +41 -0
  55. package/src/components/Dropdown/Dropdown.css +81 -0
  56. package/src/components/Dropdown/Dropdown.stories.tsx +131 -0
  57. package/src/components/Dropdown/Dropdown.tsx +69 -0
  58. package/src/components/ErrorBoundary/ErrorBoundary.stories.tsx +4 -39
  59. package/src/components/ErrorBoundary/ErrorBoundary.tsx +7 -4
  60. package/src/components/ErrorBoundary/ErrorFallback.tsx +32 -66
  61. package/src/components/ErrorModal/ErrorModal.css +32 -0
  62. package/src/components/ErrorModal/ErrorModal.stories.tsx +101 -0
  63. package/src/components/ErrorModal/ErrorModal.tsx +120 -0
  64. package/src/components/ErrorText/ErrorText.css +22 -0
  65. package/src/components/ErrorText/ErrorText.stories.tsx +42 -27
  66. package/src/components/ErrorText/ErrorText.tsx +10 -8
  67. package/src/components/ExternalLink/ExternalLink.css +12 -0
  68. package/src/components/ExternalLink/ExternalLink.stories.tsx +43 -0
  69. package/src/components/ExternalLink/ExternalLink.tsx +43 -0
  70. package/src/components/Fieldset/Fieldset.css +103 -0
  71. package/src/components/Fieldset/Fieldset.stories.tsx +304 -0
  72. package/src/components/Fieldset/Fieldset.tsx +38 -0
  73. package/src/components/FileUpload/FileUpload.css +85 -0
  74. package/src/components/FileUpload/FileUpload.stories.tsx +106 -0
  75. package/src/components/FileUpload/FileUpload.tsx +99 -0
  76. package/src/components/{layout/footer → Footer}/Copyright.tsx +4 -2
  77. package/src/components/Footer/Footer.stories.tsx +24 -0
  78. package/src/components/Footer/Footer.tsx +41 -0
  79. package/src/components/Footer/Licence.tsx +18 -0
  80. package/src/components/{layout/footer → Footer}/MetaLinks.tsx +8 -3
  81. package/src/components/Footer/Small/SmallFooter.tsx +43 -42
  82. package/src/components/Form/FormGroup.css +18 -0
  83. package/src/components/Form/FormGroup.stories.tsx +87 -0
  84. package/src/components/Form/FormGroup.tsx +16 -0
  85. package/src/components/{layout/header → Header}/Header.stories.tsx +26 -12
  86. package/src/components/Header/Header.test.tsx +87 -0
  87. package/src/components/Header/Header.tsx +303 -0
  88. package/src/components/Header/HeaderAppContent.tsx +120 -0
  89. package/src/components/Heading/Heading.css +40 -0
  90. package/src/components/Heading/Heading.stories.tsx +15 -5
  91. package/src/components/Heading/Heading.tsx +21 -44
  92. package/src/components/Heading/HeadingSkeleton.stories.tsx +30 -0
  93. package/src/components/Heading/HeadingSkeleton.tsx +14 -0
  94. package/src/components/Hero/Hero.css +19 -0
  95. package/src/components/Hero/Hero.stories.tsx +41 -0
  96. package/src/components/Hero/Hero.tsx +14 -0
  97. package/src/components/HintText/HintText.css +5 -0
  98. package/src/components/HintText/HintText.stories.tsx +29 -0
  99. package/src/components/HintText/HintText.tsx +13 -0
  100. package/src/components/InfoBox/InfoBox.css +38 -0
  101. package/src/components/InfoBox/InfoBox.stories.tsx +51 -403
  102. package/src/components/InfoBox/InfoBox.tsx +31 -158
  103. package/src/components/Input/Input.css +77 -0
  104. package/src/components/Input/Input.stories.tsx +123 -0
  105. package/src/components/Input/Input.tsx +74 -0
  106. package/src/components/InputGroup/InputGroup.css +140 -0
  107. package/src/components/InputGroup/InputGroup.stories.tsx +125 -0
  108. package/src/components/InputGroup/InputGroup.tsx +47 -0
  109. package/src/components/InsetText/InsetText.css +5 -0
  110. package/src/components/InsetText/InsetText.stories.tsx +30 -0
  111. package/src/components/InsetText/InsetText.tsx +9 -0
  112. package/src/components/Keyboard/Keyboard.css +9 -0
  113. package/src/components/Keyboard/Keyboard.stories.tsx +63 -0
  114. package/src/components/Keyboard/Keyboard.tsx +30 -0
  115. package/src/components/Label/Label.css +27 -0
  116. package/src/components/Label/Label.stories.tsx +40 -0
  117. package/src/components/Label/Label.tsx +17 -0
  118. package/src/components/LayerSwitcher/LayerSwitcher.css +59 -0
  119. package/src/components/LayerSwitcher/LayerSwitcher.stories.tsx +112 -0
  120. package/src/components/LayerSwitcher/LayerSwitcher.tsx +61 -0
  121. package/src/components/Layout/401/401.stories.tsx +23 -0
  122. package/src/components/Layout/401/401.tsx +1 -0
  123. package/src/components/Layout/403/403.stories.tsx +23 -0
  124. package/src/components/Layout/403/403.tsx +21 -0
  125. package/src/components/Layout/404/404.stories.tsx +23 -0
  126. package/src/components/Layout/404/404.tsx +28 -0
  127. package/src/components/Layout/500/500.stories.tsx +56 -0
  128. package/src/components/Layout/500/500.tsx +63 -0
  129. package/src/components/Layout/ButtonGroup/ButtonGroup.css +52 -0
  130. package/src/components/Layout/ButtonGroup/ButtonGroup.stories.tsx +156 -0
  131. package/src/components/Layout/ButtonGroup/ButtonGroup.tsx +50 -0
  132. package/src/components/Layout/HeadingGroup/HeadingGroup.css +21 -0
  133. package/src/components/Layout/HeadingGroup/HeadingGroup.stories.tsx +84 -0
  134. package/src/components/Layout/HeadingGroup/HeadingGroup.tsx +9 -0
  135. package/src/components/Layout/MainWrapper/MainWrapper.css +12 -0
  136. package/src/components/Layout/MainWrapper/MainWrapper.stories.tsx +36 -0
  137. package/src/components/Layout/MainWrapper/MainWrapper.tsx +14 -0
  138. package/src/components/Layout/PageShell/PageShell.css +42 -0
  139. package/src/components/Layout/PageShell/PageShell.stories.tsx +108 -0
  140. package/src/components/Layout/PageShell/PageShell.tsx +31 -0
  141. package/src/components/Layout/ParagraphGroup/ParagraphGroup.css +5 -0
  142. package/src/components/Layout/ParagraphGroup/ParagraphGroup.stories.tsx +34 -0
  143. package/src/components/Layout/ParagraphGroup/ParagraphGroup.tsx +9 -0
  144. package/src/components/Layout/Stack/Stack.css +29 -0
  145. package/src/components/Layout/Stack/Stack.stories.tsx +83 -0
  146. package/src/components/Layout/Stack/Stack.tsx +19 -0
  147. package/src/components/Layout/WidthContainer/WidthContainer.css +17 -0
  148. package/src/components/Layout/WidthContainer/WidthContainer.stories.tsx +59 -0
  149. package/src/components/Layout/WidthContainer/WidthContainer.tsx +13 -0
  150. package/src/components/Legend/Legend.css +95 -0
  151. package/src/components/Legend/Legend.stories.tsx +81 -0
  152. package/src/components/Legend/Legend.tsx +32 -0
  153. package/src/components/Legend/LegendDot.tsx +15 -0
  154. package/src/components/Legend/LegendPanel.stories.tsx +101 -0
  155. package/src/components/Legend/LegendPanel.tsx +68 -0
  156. package/src/components/Legend/LegendSkeleton.stories.tsx +87 -0
  157. package/src/components/Legend/LegendSkeleton.tsx +73 -0
  158. package/src/components/LegendSelect/LegendSelect.css +8 -0
  159. package/src/components/LegendSelect/LegendSelect.stories.tsx +80 -0
  160. package/src/components/LegendSelect/LegendSelect.tsx +26 -0
  161. package/src/components/Link/Link.css +98 -0
  162. package/src/components/Link/Link.stories.tsx +70 -0
  163. package/src/components/Link/Link.tsx +52 -0
  164. package/src/components/LinkButton/LinkButton.css +67 -0
  165. package/src/components/LinkButton/LinkButton.stories.tsx +90 -42
  166. package/src/components/LinkButton/LinkButton.tsx +50 -63
  167. package/src/components/LinkList/LinkList.css +28 -0
  168. package/src/components/LinkList/LinkList.stories.tsx +46 -0
  169. package/src/components/LinkList/LinkList.tsx +23 -0
  170. package/src/components/List/Li.tsx +9 -0
  171. package/src/components/List/List.css +9 -0
  172. package/src/components/List/OrderedList.stories.tsx +36 -0
  173. package/src/components/List/OrderedList.tsx +9 -0
  174. package/src/components/List/UnorderedList.stories.tsx +36 -0
  175. package/src/components/List/UnorderedList.tsx +9 -0
  176. package/src/components/LoadingBox/LoadingBox.css +27 -0
  177. package/src/components/LoadingBox/LoadingBox.stories.tsx +66 -0
  178. package/src/components/LoadingBox/LoadingBox.tsx +40 -0
  179. package/src/components/Modal/Modal.css +114 -0
  180. package/src/components/Modal/Modal.stories.tsx +41 -160
  181. package/src/components/Modal/Modal.tsx +132 -75
  182. package/src/components/NoScriptBanner/NoScriptBanner.css +17 -0
  183. package/src/components/NoScriptBanner/NoScriptBanner.stories.tsx +46 -0
  184. package/src/components/NoScriptBanner/NoScriptBanner.tsx +26 -0
  185. package/src/components/Paragraph/Paragraph.css +22 -0
  186. package/src/components/Paragraph/Paragraph.stories.tsx +1 -42
  187. package/src/components/Paragraph/Paragraph.tsx +4 -3
  188. package/src/components/Paragraph/ParagraphSkeleton.stories.tsx +44 -0
  189. package/src/components/Paragraph/ParagraphSkeleton.tsx +33 -0
  190. package/src/components/PasswordInput/PasswordInput.css +3 -0
  191. package/src/components/PasswordInput/PasswordInput.stories.tsx +47 -0
  192. package/src/components/PasswordInput/PasswordInput.tsx +45 -0
  193. package/src/components/PhaseBanner/PhaseBanner.css +12 -0
  194. package/src/components/PhaseBanner/PhaseBanner.stories.tsx +61 -0
  195. package/src/components/PhaseBanner/PhaseBanner.tsx +17 -0
  196. package/src/components/Popover/Popover.css +43 -0
  197. package/src/components/Popover/Popover.stories.tsx +102 -0
  198. package/src/components/Popover/Popover.tsx +40 -0
  199. package/src/components/Radio/Radio.css +69 -0
  200. package/src/components/Radio/Radio.stories.tsx +169 -0
  201. package/src/components/Radio/Radio.tsx +56 -0
  202. package/src/components/Resizable/Resizable.css +86 -0
  203. package/src/components/Resizable/Resizable.stories.tsx +123 -0
  204. package/src/components/Resizable/Resizable.tsx +86 -0
  205. package/src/components/ScrollArea/ScrollArea.css +9 -0
  206. package/src/components/ScrollArea/ScrollArea.stories.tsx +42 -0
  207. package/src/components/ScrollArea/ScrollArea.tsx +11 -0
  208. package/src/components/SearchBox/SearchBox.stories.tsx +88 -0
  209. package/src/components/SearchBox/SearchBox.tsx +36 -0
  210. package/src/components/Select/AsyncSelect.stories.tsx +84 -0
  211. package/src/components/Select/AsyncSelect.tsx +41 -0
  212. package/src/components/Select/Select.css +194 -0
  213. package/src/components/Select/Select.stories.tsx +162 -0
  214. package/src/components/Select/Select.test.tsx +36 -0
  215. package/src/components/Select/Select.tsx +291 -0
  216. package/src/components/Select/SelectSkeleton.stories.tsx +51 -0
  217. package/src/components/Select/SelectSkeleton.tsx +23 -0
  218. package/src/components/Separator/Separator.css +41 -0
  219. package/src/components/Separator/Separator.stories.tsx +63 -0
  220. package/src/components/Separator/Separator.tsx +42 -0
  221. package/src/components/Sidebar/ResizableSidebar.tsx +118 -0
  222. package/src/components/Sidebar/Sidebar.css +203 -0
  223. package/src/components/Sidebar/Sidebar.stories.tsx +438 -0
  224. package/src/components/Sidebar/Sidebar.tsx +225 -0
  225. package/src/components/Skeleton/Skeleton.css +16 -0
  226. package/src/components/Skeleton/Skeleton.stories.tsx +39 -0
  227. package/src/components/Skeleton/Skeleton.tsx +12 -0
  228. package/src/components/SkipLink/SkipLink.css +16 -0
  229. package/src/components/SkipLink/SkipLink.stories.tsx +40 -0
  230. package/src/components/SkipLink/SkipLink.tsx +15 -0
  231. package/src/components/Spinner/Spinner.css +30 -0
  232. package/src/components/Spinner/Spinner.stories.tsx +36 -0
  233. package/src/components/Spinner/Spinner.tsx +45 -0
  234. package/src/components/StartButton/StartButton.css +13 -0
  235. package/src/components/StartButton/StartButton.stories.tsx +68 -0
  236. package/src/components/StartButton/StartButton.tsx +50 -0
  237. package/src/components/SubmitButton/SubmitButton.stories.tsx +31 -0
  238. package/src/components/SubmitButton/SubmitButton.tsx +14 -0
  239. package/src/components/SummaryList/SummaryList.css +71 -0
  240. package/src/components/SummaryList/SummaryList.stories.tsx +211 -0
  241. package/src/components/SummaryList/SummaryList.tsx +41 -0
  242. package/src/components/SummaryList/SummaryListSkeleton.stories.tsx +67 -0
  243. package/src/components/SummaryList/SummaryListSkeleton.tsx +40 -0
  244. package/src/components/Tabs/Tabs.css +84 -0
  245. package/src/components/Tabs/Tabs.stories.tsx +133 -0
  246. package/src/components/Tabs/Tabs.tsx +66 -0
  247. package/src/components/Tag/Tag.css +8 -0
  248. package/src/components/Tag/Tag.stories.tsx +96 -0
  249. package/src/components/Tag/Tag.tsx +34 -0
  250. package/src/components/Textarea/Textarea.css +38 -0
  251. package/src/components/Textarea/Textarea.stories.tsx +131 -0
  252. package/src/components/Textarea/Textarea.tsx +50 -0
  253. package/src/components/TextareaCount/TextareaCount.css +17 -0
  254. package/src/components/TextareaCount/TextareaCount.stories.tsx +131 -0
  255. package/src/components/TextareaCount/TextareaCount.tsx +108 -0
  256. package/src/components/Tooltip/Tooltip.css +43 -0
  257. package/src/components/Tooltip/Tooltip.stories.tsx +110 -0
  258. package/src/components/Tooltip/Tooltip.tsx +53 -0
  259. package/src/components/WarningText/WarningText.css +20 -0
  260. package/src/components/WarningText/WarningText.stories.tsx +29 -0
  261. package/src/components/WarningText/WarningText.tsx +17 -0
  262. package/src/components/index.ts +342 -61
  263. package/src/errors/errorDisplay.ts +70 -0
  264. package/src/errors/index.ts +1 -0
  265. package/src/http/constants.ts +1 -0
  266. package/src/http/fetch.ts +7 -3
  267. package/src/map/LayerSwitcherPanel.tsx +2 -173
  268. package/src/map/LegendShim.tsx +2 -0
  269. package/src/map/MapComponent.tsx +7 -17
  270. package/src/map/MapControlsOverlay.tsx +68 -175
  271. package/src/map/Popup.tsx +71 -24
  272. package/src/map/geocoder/Geocoder.test.tsx +46 -3
  273. package/src/map/geocoder/Geocoder.tsx +155 -278
  274. package/src/map/index.ts +1 -1
  275. package/src/types/utils.ts +0 -10
  276. package/src/utils/components.ts +96 -0
  277. package/src/utils/index.ts +1 -0
  278. package/src/utils/utils.ts +0 -12
  279. package/src/assets/images/defra-logo.svg +0 -51
  280. package/src/assets/images/ea-logo.svg +0 -58
  281. package/src/assets/images/ogl.svg +0 -1
  282. package/src/components/Button/Button.test.tsx +0 -53
  283. package/src/components/ButtonLink/ButtonLink.test.tsx +0 -154
  284. package/src/components/Card/Card.test.tsx +0 -51
  285. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +0 -75
  286. package/src/components/ErrorBoundary/ErrorFallback.test.tsx +0 -107
  287. package/src/components/ErrorText/ErrorText.test.tsx +0 -33
  288. package/src/components/Heading/Heading.test.tsx +0 -22
  289. package/src/components/Hint/Hint.stories.tsx +0 -58
  290. package/src/components/Hint/Hint.test.tsx +0 -33
  291. package/src/components/Hint/Hint.tsx +0 -12
  292. package/src/components/InfoBox/InfoBox.test.tsx +0 -330
  293. package/src/components/InfoBox/types.ts +0 -6
  294. package/src/components/LinkButton/LinkButton.test.tsx +0 -177
  295. package/src/components/Modal/Modal.test.tsx +0 -246
  296. package/src/components/NotificationBanner/NotificationBanner.stories.tsx +0 -45
  297. package/src/components/NotificationBanner/NotificationBanner.test.tsx +0 -58
  298. package/src/components/NotificationBanner/NotificationBanner.tsx +0 -45
  299. package/src/components/Paragraph/Paragraph.test.tsx +0 -10
  300. package/src/components/SlidingPanel/SlidingPanel.stories.tsx +0 -129
  301. package/src/components/SlidingPanel/SlidingPanel.test.tsx +0 -83
  302. package/src/components/SlidingPanel/SlidingPanel.tsx +0 -258
  303. package/src/components/accordion/Accordion.stories.tsx +0 -234
  304. package/src/components/accordion/Accordion.test.tsx +0 -192
  305. package/src/components/accordion/Accordion.tsx +0 -73
  306. package/src/components/backToTop/BackToTop.stories.tsx +0 -407
  307. package/src/components/backToTop/BackToTop.test.tsx +0 -57
  308. package/src/components/backToTop/BackToTop.tsx +0 -134
  309. package/src/components/chip/Chip.stories.tsx +0 -61
  310. package/src/components/chip/Chip.test.tsx +0 -31
  311. package/src/components/chip/Chip.tsx +0 -23
  312. package/src/components/container/Container.tsx +0 -42
  313. package/src/components/cookieBanner/CookieBanner.stories.tsx +0 -257
  314. package/src/components/cookieBanner/CookieBanner.test.tsx +0 -68
  315. package/src/components/cookieBanner/CookieBanner.tsx +0 -73
  316. package/src/components/divider/RuleDivider.stories.tsx +0 -254
  317. package/src/components/divider/RuleDivider.test.tsx +0 -164
  318. package/src/components/divider/RuleDivider.tsx +0 -23
  319. package/src/components/dropdown/DropdownMenu.test.tsx +0 -211
  320. package/src/components/dropdown/DropdownMenu.tsx +0 -108
  321. package/src/components/dropdown/useDropdownMenu.ts +0 -249
  322. package/src/components/form/Input.stories.tsx +0 -435
  323. package/src/components/form/Input.test.tsx +0 -206
  324. package/src/components/form/Input.tsx +0 -23
  325. package/src/components/form/TextArea.stories.tsx +0 -464
  326. package/src/components/form/TextArea.test.tsx +0 -232
  327. package/src/components/form/TextArea.tsx +0 -23
  328. package/src/components/layout/footer/Footer.tsx +0 -26
  329. package/src/components/layout/footer/Licence.tsx +0 -19
  330. package/src/components/layout/header/Header.test.tsx +0 -36
  331. package/src/components/layout/header/Header.tsx +0 -90
  332. package/src/components/layout/header/HeaderAuthClient.test.tsx +0 -45
  333. package/src/components/layout/header/HeaderAuthClient.tsx +0 -40
  334. package/src/components/layout/header/HeaderNavClient.test.tsx +0 -44
  335. package/src/components/layout/header/HeaderNavClient.tsx +0 -67
  336. package/src/components/link/ExternalLink.test.tsx +0 -102
  337. package/src/components/link/ExternalLink.tsx +0 -29
  338. package/src/components/link/Link.tsx +0 -26
  339. package/src/components/select/Select.stories.tsx +0 -336
  340. package/src/components/select/Select.test.tsx +0 -474
  341. package/src/components/select/Select.tsx +0 -125
  342. package/src/components/select/SelectSkeleton.stories.tsx +0 -194
  343. package/src/components/select/SelectSkeleton.test.tsx +0 -104
  344. package/src/components/select/SelectSkeleton.tsx +0 -23
  345. package/src/components/select/common.ts +0 -3
  346. package/src/components/select/index.ts +0 -18
  347. package/src/components/skipLink/SkipLink.stories.tsx +0 -346
  348. package/src/components/skipLink/SkipLink.test.tsx +0 -22
  349. package/src/components/skipLink/SkipLink.tsx +0 -49
  350. package/src/map/LegendPanel.tsx +0 -85
  351. /package/src/{components → assets}/images/DefraLogo.tsx +0 -0
  352. /package/src/{components → assets}/images/EaLogo.tsx +0 -0
  353. /package/src/{components → assets}/images/OglLogo.tsx +0 -0
  354. /package/src/components/{googleAnalytics → GoogleAnalytics}/GlobalVars.tsx +0 -0
  355. /package/src/components/{googleAnalytics → GoogleAnalytics}/GoogleAnalytics.tsx +0 -0
@@ -0,0 +1,303 @@
1
+ 'use client';
2
+
3
+ import { type ReactNode, useEffect, useId, useRef, useState } from 'react';
4
+
5
+ import { LuEllipsis, LuSearch, LuX } from 'react-icons/lu';
6
+
7
+ import {
8
+ ButtonLink,
9
+ DefraLogo,
10
+ ExternalLink,
11
+ FormGroup,
12
+ Label,
13
+ Link,
14
+ PopoverContent,
15
+ PopoverTrigger,
16
+ SearchBox,
17
+ Separator,
18
+ WidthContainer,
19
+ Popover,
20
+ Paragraph,
21
+ ParagraphGroup,
22
+ } from '@tpzdsp/next-toolkit/components';
23
+ import { cn } from '@tpzdsp/next-toolkit/utils';
24
+
25
+ import type { Credentials } from '../../types/auth';
26
+
27
+ export type HeaderProps = {
28
+ appContent?: ReactNode;
29
+ credentials?: Credentials | null;
30
+ };
31
+
32
+ const DSP_NAV_LINKS = [
33
+ {
34
+ href: '/appgallery',
35
+ label: 'Apps',
36
+ mainNav: '@max-[520px]/main:hidden',
37
+ drawerNav: 'hidden @max-[520px]/drawer:block',
38
+ },
39
+ {
40
+ href: '/apiportal',
41
+ label: 'APIs',
42
+ mainNav: '@max-[620px]/main:hidden',
43
+ drawerNav: 'hidden @max-[620px]/drawer:block',
44
+ },
45
+ {
46
+ href: '/survey',
47
+ label: 'Survey',
48
+ mainNav: '@max-[720px]/main:hidden',
49
+ drawerNav: 'hidden @max-[720px]/drawer:block',
50
+ },
51
+ {
52
+ href: '/support',
53
+ label: 'Support',
54
+ mainNav: '@max-[820px]/main:hidden',
55
+ drawerNav: 'hidden @max-[820px]/drawer:block',
56
+ },
57
+ {
58
+ href: '/register',
59
+ label: 'Create an account',
60
+ mainNav: '@max-[970px]/main:hidden',
61
+ drawerNav: 'hidden @max-[970px]/drawer:block',
62
+ },
63
+ ] as const;
64
+
65
+ const HOME_URL = '/';
66
+ const LOGIN_URL = '/login';
67
+ const LOGOUT_URL = '/logout';
68
+ const DEFRA_URL =
69
+ 'https://www.gov.uk/government/organisations/department-for-environment-food-rural-affairs';
70
+ const GLOBAL_SEARCH_URL = '/globalSearch';
71
+ const GLOBAL_SEARCH_QUERY_PARAM = 'query';
72
+
73
+ export const Header = ({ appContent, credentials }: HeaderProps) => {
74
+ const navDrawerId = useId();
75
+ const searchDrawerId = useId();
76
+ const searchInputId = useId();
77
+
78
+ const [isDrawerOpen, setIsDrawerOpen] = useState(false);
79
+ const [isSearchOpen, setIsSearchOpen] = useState(false);
80
+ const [redirectUri, setRedirectUri] = useState('');
81
+
82
+ const triggerRef = useRef<HTMLLIElement>(null);
83
+ const drawerRef = useRef<HTMLDivElement>(null);
84
+ const hasOpenedRef = useRef(false);
85
+
86
+ // window isn't available during SSR, and the raw value needs encoding
87
+ // anyway (an unescaped ?/&/# in the current URL would otherwise corrupt
88
+ // this query string), so this is deferred to a client-only effect rather
89
+ // than read directly during render. Full absolute URL (not just path +
90
+ // search), sign-in/sign-out live on a separate origin, so it needs the
91
+ // hostname to know where to send the user back to.
92
+ useEffect(() => {
93
+ setRedirectUri(encodeURIComponent(window.location.href));
94
+ }, []);
95
+
96
+ // Move focus into the drawer when it opens; return it to the trigger when it closes.
97
+ // hasOpenedRef prevents a focus jump on initial render.
98
+ useEffect(() => {
99
+ if (isDrawerOpen) {
100
+ hasOpenedRef.current = true;
101
+
102
+ const firstFocusable = drawerRef.current?.querySelector<HTMLElement>(
103
+ 'a[href], button:not([disabled])',
104
+ );
105
+
106
+ firstFocusable?.focus();
107
+ } else if (hasOpenedRef.current) {
108
+ triggerRef.current?.querySelector<HTMLElement>('button')?.focus();
109
+ }
110
+ }, [isDrawerOpen]);
111
+
112
+ useEffect(() => {
113
+ if (!isDrawerOpen) {
114
+ return;
115
+ }
116
+
117
+ const handleKeyDown = (e: KeyboardEvent) => {
118
+ if (e.key === 'Escape') {
119
+ setIsDrawerOpen(false);
120
+ }
121
+ };
122
+
123
+ document.addEventListener('keydown', handleKeyDown);
124
+
125
+ return () => document.removeEventListener('keydown', handleKeyDown);
126
+ }, [isDrawerOpen]);
127
+
128
+ return (
129
+ <header className="w-full text-white border-b border-neutral-mid">
130
+ <WidthContainer className="flex items-center justify-center bg-accent z-10 relative">
131
+ <div
132
+ className="w-full h-14 flex p-gds-2 justify-between items-center gap-gds-4
133
+ @container/main"
134
+ >
135
+ <div className="flex h-full min-w-0 items-center gap-gds-4">
136
+ <div className="flex shrink-0 gap-gds-2 h-full items-center">
137
+ <ExternalLink
138
+ href={DEFRA_URL}
139
+ appearance="inverse"
140
+ variant="plain"
141
+ className="flex gap-gds-1 h-full items-center"
142
+ >
143
+ <DefraLogo aria-hidden className="h-full w-auto shrink-0 block" />
144
+
145
+ <abbr
146
+ title="Department for Environment, Food, and Rural Affairs"
147
+ className="sr-only xs:not-sr-only"
148
+ >
149
+ DEFRA
150
+ </abbr>
151
+ </ExternalLink>
152
+
153
+ <Separator orientation="vertical" className="bg-white" />
154
+
155
+ <Link href={HOME_URL} appearance="inverse" className="text-nowrap">
156
+ <span className="hidden xs:inline">Data Services Platform</span>
157
+
158
+ <span className="inline xs:hidden">
159
+ <abbr title="Data Services Platform">DSP</abbr>
160
+ </span>
161
+ </Link>
162
+ </div>
163
+
164
+ <nav aria-label="Primary navigation" className="min-w-0">
165
+ <ul className="flex items-center gap-gds-4">
166
+ {DSP_NAV_LINKS.map((item) => (
167
+ <li className={cn('flex items-center nav-item', item.mainNav)} key={item.href}>
168
+ <ExternalLink href={item.href} appearance="inverse" variant="plain">
169
+ {item.label}
170
+ </ExternalLink>
171
+ </li>
172
+ ))}
173
+ <li ref={triggerRef} className="flex items-center more-btn shrink-0">
174
+ <ButtonLink
175
+ aria-label="Navigation drawer"
176
+ aria-expanded={isDrawerOpen}
177
+ aria-controls={navDrawerId}
178
+ appearance="inverse"
179
+ variant="icon"
180
+ onClick={() => setIsDrawerOpen(!isDrawerOpen)}
181
+ >
182
+ <LuEllipsis aria-hidden />
183
+ </ButtonLink>
184
+ </li>
185
+ </ul>
186
+ </nav>
187
+ </div>
188
+
189
+ <div className="flex shrink-0 gap-gds-2 h-full items-center">
190
+ {credentials ? (
191
+ <Popover>
192
+ <PopoverTrigger asChild>
193
+ <ButtonLink appearance="inverse">Profile</ButtonLink>
194
+ </PopoverTrigger>
195
+
196
+ <PopoverContent sideOffset={0}>
197
+ <ParagraphGroup>
198
+ <Paragraph>
199
+ <div className="font-bold">Signed in as:</div>
200
+
201
+ <div>{credentials.user.email}</div>
202
+ </Paragraph>
203
+
204
+ <Link href={`${LOGOUT_URL}?redirect_uri=${redirectUri}`}>Sign-out</Link>
205
+ </ParagraphGroup>
206
+ </PopoverContent>
207
+ </Popover>
208
+ ) : (
209
+ <Link
210
+ href={`${LOGIN_URL}?redirect_uri=${redirectUri}`}
211
+ appearance="inverse"
212
+ className="text-nowrap"
213
+ >
214
+ Sign-in
215
+ </Link>
216
+ )}
217
+
218
+ <Separator orientation="vertical" className="bg-white" />
219
+
220
+ <ButtonLink
221
+ appearance="inverse"
222
+ variant="icon"
223
+ aria-label="Search the Data Services Platform"
224
+ aria-controls={searchDrawerId}
225
+ aria-expanded={isSearchOpen}
226
+ onClick={() => setIsSearchOpen(!isSearchOpen)}
227
+ >
228
+ <LuSearch aria-hidden />
229
+ </ButtonLink>
230
+ </div>
231
+ </div>
232
+ </WidthContainer>
233
+
234
+ <div
235
+ id={searchDrawerId}
236
+ inert={!isSearchOpen}
237
+ className={cn(
238
+ 'w-full bg-wash grid transition-[grid-template-rows] duration-200',
239
+ isSearchOpen ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',
240
+ )}
241
+ >
242
+ <WidthContainer className="min-h-0 overflow-hidden">
243
+ <div className="w-full h-40 p-gds-6 flex items-center">
244
+ <form action={GLOBAL_SEARCH_URL} className="w-full">
245
+ <FormGroup>
246
+ <Label htmlFor={searchInputId} className="font-bold text-2xl">
247
+ Search DSP
248
+ </Label>
249
+
250
+ <SearchBox id={searchInputId} name={GLOBAL_SEARCH_QUERY_PARAM} />
251
+ </FormGroup>
252
+ </form>
253
+ </div>
254
+ </WidthContainer>
255
+ </div>
256
+
257
+ <div
258
+ id={navDrawerId}
259
+ ref={drawerRef}
260
+ inert={!isDrawerOpen}
261
+ className={cn(
262
+ `w-full bg-accent grid transition-[grid-template-rows] duration-200 border-b
263
+ border-neutral-mid`,
264
+ isDrawerOpen ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',
265
+ )}
266
+ >
267
+ <WidthContainer className="bg-accent min-h-0 overflow-hidden">
268
+ <div
269
+ className="w-full min-h-14 flex p-gds-2 justify-between items-center gap-gds-4
270
+ @container/drawer"
271
+ >
272
+ <nav aria-label="More navigation">
273
+ <ul className="flex flex-wrap w-full gap-x-gds-2 gap-y-gds-2">
274
+ {DSP_NAV_LINKS.map((item) => (
275
+ <li className={cn('flex items-center nav-item', item.drawerNav)} key={item.href}>
276
+ <ExternalLink href={item.href} appearance="inverse" variant="plain">
277
+ {item.label}
278
+ </ExternalLink>
279
+ </li>
280
+ ))}
281
+ </ul>
282
+ </nav>
283
+
284
+ <ButtonLink
285
+ aria-label="Close"
286
+ appearance="inverse"
287
+ variant="icon"
288
+ onClick={() => setIsDrawerOpen(false)}
289
+ >
290
+ <LuX aria-hidden />
291
+ </ButtonLink>
292
+ </div>
293
+ </WidthContainer>
294
+ </div>
295
+
296
+ {appContent ? (
297
+ <WidthContainer className="bg-body-secondary">
298
+ <div className="w-full h-14 flex p-gds-2 items-center">{appContent}</div>
299
+ </WidthContainer>
300
+ ) : null}
301
+ </header>
302
+ );
303
+ };
@@ -0,0 +1,120 @@
1
+ import type { ComponentType } from 'react';
2
+
3
+ import { LuEllipsis } from 'react-icons/lu';
4
+
5
+ import {
6
+ ButtonLink,
7
+ DropdownMenu,
8
+ DropdownMenuContent,
9
+ DropdownMenuItem,
10
+ DropdownMenuTrigger,
11
+ Link,
12
+ } from '@tpzdsp/next-toolkit/components';
13
+ import type { LinkProps } from '@tpzdsp/next-toolkit/components';
14
+
15
+ import type { NavLink } from '../../types';
16
+
17
+ export type HeaderAppContentProps = {
18
+ /** App name, shown on the left. Plain text, or a NavLink if it should link
19
+ * somewhere (e.g. back to the app's home page). */
20
+ title: string | NavLink;
21
+ links?: NavLink[];
22
+ /** Defaults to this library's own Link (a plain <a>). Pass your app's own Link
23
+ * wrapper instead if it needs Next.js client-side routing, e.g. one that uses
24
+ * asChild internally with next/link, it just needs to accept the same props. */
25
+ linkComponent?: ComponentType<LinkProps>;
26
+ };
27
+
28
+ // Omit<LinkProps, ...> (not a fixed prop list): when this sits inside
29
+ // DropdownMenuItem asChild, Radix clones this component and merges its own
30
+ // props onto it (role="menuitem", tabIndex, the keyboard/selection
31
+ // handlers roving-tabindex needs, className). Without a rest spread here to
32
+ // forward all of that through to LinkComponent, Radix's merge dead-ends at
33
+ // this component and every one of those props is silently dropped, not
34
+ // just a styling gap, menuitem role and keyboard handling would be missing
35
+ // too.
36
+ type HeaderAppContentNavLinkProps = Omit<LinkProps, 'href' | 'children'> & {
37
+ link: NavLink;
38
+ linkComponent: ComponentType<LinkProps>;
39
+ };
40
+
41
+ const HeaderAppContentNavLink = ({
42
+ link,
43
+ linkComponent: LinkComponent,
44
+ appearance = 'inverse',
45
+ ...props
46
+ }: HeaderAppContentNavLinkProps) => (
47
+ <LinkComponent
48
+ href={link.url}
49
+ appearance={appearance}
50
+ target={link.openInNewTab ? '_blank' : undefined}
51
+ rel={link.openInNewTab ? 'noopener noreferrer' : undefined}
52
+ {...props}
53
+ >
54
+ {link.label}
55
+ </LinkComponent>
56
+ );
57
+
58
+ export const HeaderAppContent = ({
59
+ title,
60
+ links = [],
61
+ linkComponent: LinkComponent = Link,
62
+ }: HeaderAppContentProps) => (
63
+ <div className="@container/app-nav flex w-full items-center justify-between gap-gds-4">
64
+ <div className="flex shrink-0 items-center gap-gds-2 text-lg font-bold">
65
+ {typeof title === 'string' ? (
66
+ title
67
+ ) : (
68
+ <HeaderAppContentNavLink link={title} linkComponent={LinkComponent} />
69
+ )}
70
+ </div>
71
+
72
+ {links.length > 0 ? (
73
+ <>
74
+ {/* 650px: below this the inline list and the title no longer
75
+ comfortably fit side by side. A single width rather than
76
+ per-link breakpoints (contrast Header.tsx's own DSP_NAV_LINKS,
77
+ which hides one specific, known link at a time): links here are
78
+ an arbitrary, app-supplied list, there's no fixed set to
79
+ hand-tune individual cutoffs for, so this collapses the whole
80
+ list to a menu at once instead. A reasonable default, not a
81
+ computed value, nudge it if a specific app's title/link lengths
82
+ need something else. */}
83
+ <nav aria-label="App" className="hidden min-w-0 @min-[650px]/app-nav:block">
84
+ <ul className="flex items-center gap-gds-4">
85
+ {links.map((link) => (
86
+ <li key={link.url}>
87
+ <HeaderAppContentNavLink link={link} linkComponent={LinkComponent} />
88
+ </li>
89
+ ))}
90
+ </ul>
91
+ </nav>
92
+
93
+ <DropdownMenu>
94
+ <DropdownMenuTrigger asChild>
95
+ <ButtonLink
96
+ appearance="inverse"
97
+ variant="icon"
98
+ aria-label="App navigation"
99
+ className="@min-[650px]/app-nav:hidden"
100
+ >
101
+ <LuEllipsis aria-hidden />
102
+ </ButtonLink>
103
+ </DropdownMenuTrigger>
104
+
105
+ <DropdownMenuContent align="end">
106
+ {links.map((link) => (
107
+ <DropdownMenuItem key={link.url} asChild>
108
+ <HeaderAppContentNavLink
109
+ link={link}
110
+ linkComponent={LinkComponent}
111
+ appearance="contrast"
112
+ />
113
+ </DropdownMenuItem>
114
+ ))}
115
+ </DropdownMenuContent>
116
+ </DropdownMenu>
117
+ </>
118
+ ) : null}
119
+ </div>
120
+ );
@@ -0,0 +1,40 @@
1
+ @layer components {
2
+ /* MARK: Heading */
3
+ .cn-heading {
4
+ @apply font-bold;
5
+ }
6
+
7
+ .cn-heading-1 {
8
+ @apply text-[2rem] sm:text-5xl;
9
+ }
10
+
11
+ .cn-heading-2 {
12
+ @apply text-2xl sm:text-4xl;
13
+ }
14
+
15
+ .cn-heading-3 {
16
+ @apply text-xl sm:text-3xl;
17
+ }
18
+
19
+ .cn-heading-4 {
20
+ @apply text-lg sm:text-2xl;
21
+ }
22
+
23
+ .cn-heading-5 {
24
+ @apply text-base sm:text-xl;
25
+ }
26
+
27
+ .cn-heading-6 {
28
+ @apply text-sm sm:text-lg;
29
+ }
30
+
31
+ /* MARK: Skeleton
32
+ Sized in em so it scales with whichever cn-heading-N font-size applies,
33
+ one rule covers every level. Shorter than the line-height (~1.2-1.5x
34
+ font-size for every text-* utility here) so it sits inside the line box
35
+ rather than stretching it, the heading ends up exactly as tall as it
36
+ would be with real text. */
37
+ .cn-heading-skeleton-bar {
38
+ @apply h-[0.7em] w-3/4;
39
+ }
40
+ }
@@ -2,16 +2,26 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
 
3
3
  import { Heading, type HeadingProps } from './Heading';
4
4
 
5
- export default {
6
- children: 'Heading',
5
+ const meta: Meta<typeof Heading> = {
6
+ title: 'Components/Heading/Heading',
7
7
  component: Heading,
8
- } as Meta;
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component: 'Responsive heading text.',
13
+ },
14
+ },
15
+ },
16
+ };
17
+
18
+ export default meta;
9
19
 
10
20
  export const AllHeadings: StoryObj<typeof Heading> = {
11
21
  render: () => (
12
22
  <div>
13
- {(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as HeadingProps['type'][]).map((type) => (
14
- <Heading key={type} type={type}>
23
+ {(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as HeadingProps['level'][]).map((type) => (
24
+ <Heading key={type} level={type}>
15
25
  {type.toUpperCase()} Example
16
26
  </Heading>
17
27
  ))}
@@ -1,50 +1,27 @@
1
- import type { ExtendProps } from '../../types';
1
+ import type { ComponentProps } from 'react';
2
+
2
3
  import { cn } from '../../utils';
3
4
 
4
- type Props = {
5
- type: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
5
+ // h1 through h6 have identical props
6
+ export type HeadingProps = ComponentProps<'h1'> & {
7
+ level: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
6
8
  };
7
9
 
8
- // h1 through h6 have identical props
9
- export type HeadingProps = ExtendProps<'h1', Props>;
10
+ const HEADING_LEVELS = {
11
+ h1: 'cn-heading-1',
12
+ h2: 'cn-heading-2',
13
+ h3: 'cn-heading-3',
14
+ h4: 'cn-heading-4',
15
+ h5: 'cn-heading-5',
16
+ h6: 'cn-heading-6',
17
+ } as const;
18
+
19
+ export const Heading = ({ level, className, children, ...props }: HeadingProps) => {
20
+ const Comp = level;
10
21
 
11
- export const Heading = ({ type, className, children, ...props }: HeadingProps) => {
12
- switch (type) {
13
- case 'h1':
14
- return (
15
- <h1 className={cn('py-4 text-4xl font-bold text-text-primary', className)} {...props}>
16
- {children}
17
- </h1>
18
- );
19
- case 'h2':
20
- return (
21
- <h2 className={cn('py-3 text-3xl font-bold text-text-primary', className)} {...props}>
22
- {children}
23
- </h2>
24
- );
25
- case 'h3':
26
- return (
27
- <h3 className={cn('py-3 text-xl font-bold text-text-primary', className)} {...props}>
28
- {children}
29
- </h3>
30
- );
31
- case 'h4':
32
- return (
33
- <h4 className={cn('py-3 text-lg font-bold text-text-primary', className)} {...props}>
34
- {children}
35
- </h4>
36
- );
37
- case 'h5':
38
- return (
39
- <h5 className={cn('py-2 text-base font-bold text-text-primary', className)} {...props}>
40
- {children}
41
- </h5>
42
- );
43
- case 'h6':
44
- return (
45
- <h6 className={cn('py-2 text-sm font-bold text-text-primary', className)} {...props}>
46
- {children}
47
- </h6>
48
- );
49
- }
22
+ return (
23
+ <Comp className={cn('cn-heading', HEADING_LEVELS[level], className)} {...props}>
24
+ {children}
25
+ </Comp>
26
+ );
50
27
  };
@@ -0,0 +1,30 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import type { HeadingProps } from './Heading';
4
+ import { HeadingSkeleton } from './HeadingSkeleton';
5
+
6
+ const meta: Meta<typeof HeadingSkeleton> = {
7
+ title: 'Components/Heading/Skeleton',
8
+ component: HeadingSkeleton,
9
+ tags: ['autodocs'],
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component:
14
+ 'Placeholder for a Heading while its real text is loading. Renders a real Heading at the given level, so the font-size and line-height (and therefore the rendered height) always match what real text at that level would produce, no layout shift when it swaps in.',
15
+ },
16
+ },
17
+ },
18
+ };
19
+
20
+ export default meta;
21
+
22
+ export const AllLevels: StoryObj<typeof HeadingSkeleton> = {
23
+ render: () => (
24
+ <div className="flex flex-col gap-gds-2">
25
+ {(['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as HeadingProps['level'][]).map((level) => (
26
+ <HeadingSkeleton key={level} level={level} />
27
+ ))}
28
+ </div>
29
+ ),
30
+ };
@@ -0,0 +1,14 @@
1
+ import type { ComponentProps } from 'react';
2
+
3
+ import { Heading } from './Heading';
4
+ import { Skeleton } from '../Skeleton/Skeleton';
5
+
6
+ export type HeadingSkeletonProps = Omit<ComponentProps<typeof Heading>, 'children'> & {
7
+ children?: never;
8
+ };
9
+
10
+ export const HeadingSkeleton = ({ className, ...props }: HeadingSkeletonProps) => (
11
+ <Heading aria-hidden className={className} {...props}>
12
+ <Skeleton className="cn-heading-skeleton-bar" />
13
+ </Heading>
14
+ );
@@ -0,0 +1,19 @@
1
+ @layer components {
2
+ /* Full-bleed breakout: Hero is meant to span the viewport regardless of
3
+ where it's mounted, but it's built on WidthContainer, so if it's ever
4
+ nested inside another WidthContainer/MainWrapper (e.g. rendered as page
5
+ content under a shared layout's <main>), it would otherwise inherit that
6
+ ancestor's max-w-page cap. left: 50% shifts it to the viewport's
7
+ horizontal center regardless of the containing block's width, as long as
8
+ that containing block is itself symmetrically centered, true here since
9
+ every ancestor up to the viewport is either full-width or mx-auto; width:
10
+ 100vw + the negative margins then pull its edges out to the true viewport
11
+ edges. Pair with overflow-x-clip on PageShell (or another page-level
12
+ ancestor), 100vw includes the scrollbar gutter in browsers that reserve
13
+ space for it, which can otherwise introduce a few pixels of unwanted
14
+ horizontal scroll. */
15
+ .cn-hero {
16
+ @apply bg-accent text-on-accent py-gds-4 sm:py-gds-6;
17
+ position: relative;
18
+ }
19
+ }
@@ -0,0 +1,41 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Hero } from './Hero';
4
+ import { Heading } from '../Heading/Heading';
5
+ import { ButtonGroup } from '../Layout/ButtonGroup/ButtonGroup';
6
+ import { HeadingGroup } from '../Layout/HeadingGroup/HeadingGroup';
7
+ import { Paragraph } from '../Paragraph/Paragraph';
8
+ import { StartButton } from '../StartButton/StartButton';
9
+
10
+ const meta: Meta<typeof Hero> = {
11
+ title: 'Components/Hero',
12
+ component: Hero,
13
+ tags: ['autodocs'],
14
+ parameters: {
15
+ docs: {
16
+ description: {
17
+ component: 'Use a Hero to associate text with form controls and improve accessibility.',
18
+ },
19
+ },
20
+ },
21
+ };
22
+
23
+ export default meta;
24
+
25
+ type Story = StoryObj<typeof Hero>;
26
+
27
+ export const Default: Story = {
28
+ render: () => (
29
+ <Hero>
30
+ <ButtonGroup orientation="vertical">
31
+ <HeadingGroup>
32
+ <Heading level="h1">UK Wetland Inventory</Heading>
33
+
34
+ <Paragraph>Explore the UK&apos;s vital wetland habits</Paragraph>
35
+ </HeadingGroup>
36
+
37
+ <StartButton appearance="secondary" href="#" />
38
+ </ButtonGroup>
39
+ </Hero>
40
+ ),
41
+ };