@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,40 @@
1
+ import type { ComponentProps } from 'react';
2
+
3
+ import { cn } from '../../utils/components';
4
+ import { Spinner } from '../Spinner/Spinner';
5
+
6
+ export type LoadingBoxProps = ComponentProps<'div'> & {
7
+ loading?: boolean;
8
+ title?: string;
9
+ };
10
+
11
+ export const LoadingBox = ({
12
+ loading = false,
13
+ title = 'Loading',
14
+ className,
15
+ children,
16
+ ...props
17
+ }: LoadingBoxProps) => (
18
+ <div data-slot="loading-box" className={cn('cn-loading-box', className)} {...props}>
19
+ <div
20
+ data-slot="loading-box-overlay"
21
+ data-loading={loading || undefined}
22
+ inert={!loading}
23
+ role="status"
24
+ className="cn-loading-box-overlay"
25
+ >
26
+ <Spinner aria-hidden className="cn-loading-box-spinner" />
27
+
28
+ <span className="sr-only">{title}</span>
29
+ </div>
30
+
31
+ {/* display:contents so this purely exists to carry `inert`, it doesn't
32
+ add a box that could change how children participate in whatever
33
+ layout the consumer's own content establishes. Blocks focus/clicks
34
+ on content that's about to be replaced once loading starts, rather
35
+ than just visually covering it while leaving it reachable. */}
36
+ <div data-slot="loading-box-content" inert={loading} className="contents">
37
+ {children}
38
+ </div>
39
+ </div>
40
+ );
@@ -0,0 +1,114 @@
1
+ @layer components {
2
+ /*
3
+ MARK: Modal overlay
4
+ Semi-transparent backdrop. Radix sets data-state to open or closed
5
+ which drives enter and exit fade transitions.
6
+ */
7
+ .cn-modal-overlay {
8
+ @apply bg-black/50 cn-z-overlay;
9
+
10
+ &[data-state='open'] {
11
+ animation: cn-modal-overlay-in 150ms ease-out;
12
+ }
13
+ &[data-state='closed'] {
14
+ animation: cn-modal-overlay-out 150ms ease-in;
15
+ }
16
+ }
17
+
18
+ @keyframes cn-modal-overlay-in {
19
+ from {
20
+ opacity: 0;
21
+ }
22
+ to {
23
+ opacity: 1;
24
+ }
25
+ }
26
+
27
+ @keyframes cn-modal-overlay-out {
28
+ from {
29
+ opacity: 1;
30
+ }
31
+ to {
32
+ opacity: 0;
33
+ }
34
+ }
35
+
36
+ /*
37
+ MARK: Modal content
38
+ The panel box with white background and GDS form-width border.
39
+ No rounded corners. The fixed position and centring transform are
40
+ applied via Tailwind in the TSX. Only visual appearance is set here.
41
+
42
+ Add a max-w-* class to ModalContent to widen for specific modals.
43
+ */
44
+ .cn-modal-content {
45
+ @apply panel cn-z-overlay p-gds-4 w-full max-w-sm;
46
+
47
+ &[data-state='open'] {
48
+ animation: cn-modal-content-in 150ms ease-out;
49
+ }
50
+ &[data-state='closed'] {
51
+ animation: cn-modal-content-out 150ms ease-in;
52
+ }
53
+ }
54
+
55
+ @keyframes cn-modal-content-in {
56
+ from {
57
+ opacity: 0;
58
+ }
59
+ to {
60
+ opacity: 1;
61
+ }
62
+ }
63
+
64
+ @keyframes cn-modal-content-out {
65
+ from {
66
+ opacity: 1;
67
+ }
68
+ to {
69
+ opacity: 0;
70
+ }
71
+ }
72
+
73
+ /*
74
+ MARK: Modal close button
75
+ Positioned absolutely in the top-right corner of the panel.
76
+ The parent cn-modal-content has position fixed which acts
77
+ as the containing block for absolute children.
78
+ */
79
+ .cn-modal-close {
80
+ @apply absolute top-gds-2 right-gds-2;
81
+ }
82
+
83
+ /* MARK: Modal header and footer */
84
+
85
+ .cn-modal-header {
86
+ @apply flex flex-col gap-gds-1;
87
+ }
88
+
89
+ .cn-modal-footer {
90
+ @apply flex flex-col gap-gds-2 sm:flex-row;
91
+ }
92
+
93
+ /* MARK: Vertical rhythm between sections
94
+ Adjacency-based rather than flex+gap on cn-modal-content itself,
95
+ ModalContent needs to stay a plain block so consumers can turn it into a
96
+ flex row instead (e.g. ErrorModal, an icon beside the content) without
97
+ fighting a hardcoded flex-direction. Applies wherever these three end up
98
+ as direct siblings, regardless of what wraps them, ModalDescription is
99
+ usually a sibling of ModalHeader rather than nested inside it. */
100
+ :where(.cn-modal-header, .cn-modal-description, .cn-modal-footer)
101
+ + :where(.cn-modal-header, .cn-modal-description, .cn-modal-footer) {
102
+ margin-top: var(--spacing-gds-4);
103
+ }
104
+
105
+ /* MARK: Modal title and description */
106
+
107
+ .cn-modal-title {
108
+ @apply text-xl font-bold text-body;
109
+ }
110
+
111
+ .cn-modal-description {
112
+ @apply font-normal text-body;
113
+ }
114
+ }
@@ -1,188 +1,69 @@
1
1
  import { useState } from 'react';
2
2
 
3
- import { useArgs } from 'storybook/preview-api';
4
-
5
3
  import type { Meta, StoryObj } from '@storybook/react-vite';
6
4
 
7
- import { Modal } from './Modal';
5
+ import {
6
+ Modal,
7
+ ModalClose,
8
+ ModalContent,
9
+ ModalDescription,
10
+ ModalFooter,
11
+ ModalHeader,
12
+ ModalTitle,
13
+ ModalTrigger,
14
+ } from './Modal';
15
+ import { Button } from '../Button/Button';
8
16
 
9
17
  const meta: Meta<typeof Modal> = {
10
18
  title: 'Components/Modal',
11
19
  component: Modal,
20
+ tags: ['autodocs'],
12
21
  parameters: {
13
- layout: 'fullscreen',
14
22
  docs: {
15
23
  description: {
16
- component: 'A modal dialog component that renders content in a portal overlay.',
24
+ component: 'Use the Modal primitives to display dialog content in an overlay.',
17
25
  },
18
26
  },
19
27
  },
20
- // removed the auto-docs for now as that will cause all modals to open immediately
21
- // tags: ['autodocs'],
22
28
  argTypes: {
23
- isOpen: {
24
- control: 'boolean',
25
- description: 'Whether the modal is open',
26
- },
27
- onClose: {
28
- action: 'onClose',
29
- description: 'Callback function called when the modal should close',
30
- },
31
- children: {
32
- control: false,
33
- description: 'Content to display inside the modal',
34
- },
29
+ children: { control: false },
35
30
  },
36
- decorators: [
37
- (Story, context) => {
38
- const [{ isOpen }, updateArgs] = useArgs();
39
-
40
- const handleClose = () => {
41
- updateArgs({ isOpen: false });
42
- };
43
-
44
- // Override onClose prop to use local handler
45
- return <Story args={{ ...context.args, isOpen, onClose: handleClose }} />;
46
- },
47
- ],
48
31
  };
49
32
 
50
33
  export default meta;
34
+
51
35
  type Story = StoryObj<typeof Modal>;
52
36
 
53
37
  export const Default: Story = {
54
- args: {
55
- isOpen: true,
56
- children: (
57
- <div>
58
- <h2 className="mb-4 text-xl font-bold">Modal Title</h2>
59
-
60
- <p className="mb-4 text-gray-600">
61
- This is a basic modal with some content. You can close it by clicking the X button,
62
- pressing Escape, or clicking outside the modal.
63
- </p>
64
-
65
- <div className="flex gap-2">
66
- <button className="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-600">
67
- Confirm
68
- </button>
69
-
70
- <button className="px-4 py-2 text-gray-700 bg-gray-300 rounded hover:bg-gray-400">
71
- Cancel
72
- </button>
73
- </div>
74
- </div>
75
- ),
76
- },
77
- };
78
-
79
- export const Closed: Story = {
80
- args: {
81
- isOpen: false,
82
- children: (
83
- <div>
84
- <h2 className="mb-4 text-xl font-bold">You won&apos;t see this</h2>
85
-
86
- <p>This modal is closed, so the content is not visible.</p>
87
- </div>
88
- ),
89
- },
90
- };
91
-
92
- export const SimpleMessage: Story = {
93
- args: {
94
- isOpen: true,
95
- children: (
96
- <div className="text-center">
97
- <h3 className="mb-2 text-lg font-semibold">Success!</h3>
98
-
99
- <p className="text-gray-600">Your action was completed successfully.</p>
100
- </div>
101
- ),
102
- },
103
- };
104
-
105
- export const Interactive: Story = {
106
38
  render: () => {
107
- const [isOpen, setIsOpen] = useState(false);
108
- const [selectedModal, setSelectedModal] = useState<string | null>(null);
109
-
110
- const openModal = (type: string) => {
111
- setSelectedModal(type);
112
- setIsOpen(true);
113
- };
114
-
115
- const closeModal = () => {
116
- setIsOpen(false);
117
- setSelectedModal(null);
118
- };
119
-
120
- const renderModalContent = () => {
121
- switch (selectedModal) {
122
- case 'info':
123
- return (
124
- <div>
125
- <h3 className="mb-2 text-lg font-semibold">Information</h3>
126
-
127
- <p className="text-gray-600">This is an informational modal.</p>
128
- </div>
129
- );
130
- case 'warning':
131
- return (
132
- <div>
133
- <h3 className="mb-2 text-lg font-semibold text-yellow-600">Warning</h3>
134
-
135
- <p className="text-gray-600">This action requires confirmation.</p>
136
- </div>
137
- );
138
- case 'error':
139
- return (
140
- <div>
141
- <h3 className="mb-2 text-lg font-semibold text-red-600">Error</h3>
142
-
143
- <p className="text-gray-600">Something went wrong. Please try again.</p>
144
- </div>
145
- );
146
- default:
147
- return <p>Default modal content</p>;
148
- }
149
- };
39
+ const [open, setOpen] = useState(false);
150
40
 
151
41
  return (
152
- <div className="p-8">
153
- <h2 className="mb-4 text-xl font-bold">Interactive Modal Demo</h2>
154
-
155
- <p className="mb-6 text-gray-600">
156
- Click any button below to open different types of modals.
157
- </p>
158
-
159
- <div className="space-x-4">
160
- <button
161
- onClick={() => openModal('info')}
162
- className="px-4 py-2 text-white bg-blue-500 rounded hover:bg-blue-600"
163
- >
164
- Info Modal
165
- </button>
166
-
167
- <button
168
- onClick={() => openModal('warning')}
169
- className="px-4 py-2 text-white bg-yellow-500 rounded hover:bg-yellow-600"
170
- >
171
- Warning Modal
172
- </button>
173
-
174
- <button
175
- onClick={() => openModal('error')}
176
- className="px-4 py-2 text-white bg-red-500 rounded hover:bg-red-600"
177
- >
178
- Error Modal
179
- </button>
180
- </div>
181
-
182
- <Modal isOpen={isOpen} onClose={closeModal}>
183
- {renderModalContent()}
184
- </Modal>
185
- </div>
42
+ <Modal open={open} onOpenChange={setOpen}>
43
+ <ModalTrigger asChild>
44
+ <Button>Open modal</Button>
45
+ </ModalTrigger>
46
+
47
+ <ModalContent>
48
+ <ModalHeader>
49
+ <ModalTitle>Confirm action</ModalTitle>
50
+ </ModalHeader>
51
+
52
+ <ModalDescription>
53
+ Are you sure you want to continue? This action cannot be undone.
54
+ </ModalDescription>
55
+
56
+ <ModalFooter>
57
+ <Button appearance="secondary" onClick={() => setOpen(false)}>
58
+ Cancel
59
+ </Button>
60
+
61
+ <ModalClose asChild>
62
+ <Button>Confirm</Button>
63
+ </ModalClose>
64
+ </ModalFooter>
65
+ </ModalContent>
66
+ </Modal>
186
67
  );
187
68
  },
188
69
  };
@@ -1,83 +1,140 @@
1
1
  'use client';
2
2
 
3
- import { useCallback, useEffect, useRef } from 'react';
3
+ import type { ComponentProps } from 'react';
4
4
 
5
- import { createPortal } from 'react-dom';
6
- import { IoMdCloseCircle } from 'react-icons/io';
5
+ import { Dialog as DialogPrimitive } from 'radix-ui';
6
+ import { LuX } from 'react-icons/lu';
7
7
 
8
- import type { ExtendProps } from '../../types';
9
- import { cn } from '../../utils';
8
+ import { cn } from '../../utils/components';
9
+ import { Button } from '../Button/Button';
10
10
 
11
- type Props = {
12
- isOpen: boolean;
13
- onClose: () => void;
14
- children: React.ReactNode;
11
+ export type ModalProps = ComponentProps<typeof DialogPrimitive.Root>;
12
+
13
+ export const Modal = ({ ...props }: ModalProps) => (
14
+ <DialogPrimitive.Root data-slot="modal" {...props} />
15
+ );
16
+
17
+ export type ModalTriggerProps = ComponentProps<typeof DialogPrimitive.Trigger>;
18
+
19
+ export const ModalTrigger = ({ ...props }: ModalTriggerProps) => (
20
+ <DialogPrimitive.Trigger data-slot="modal-trigger" {...props} />
21
+ );
22
+
23
+ export type ModalPortalProps = ComponentProps<typeof DialogPrimitive.Portal>;
24
+
25
+ export const ModalPortal = ({ ...props }: ModalPortalProps) => (
26
+ <DialogPrimitive.Portal data-slot="modal-portal" {...props} />
27
+ );
28
+
29
+ export type ModalCloseProps = ComponentProps<typeof DialogPrimitive.Close>;
30
+
31
+ export const ModalClose = ({ ...props }: ModalCloseProps) => (
32
+ <DialogPrimitive.Close data-slot="modal-close" {...props} />
33
+ );
34
+
35
+ export type ModalOverlayProps = ComponentProps<typeof DialogPrimitive.Overlay>;
36
+
37
+ export const ModalOverlay = ({ className, ...props }: ModalOverlayProps) => (
38
+ <DialogPrimitive.Overlay
39
+ data-slot="modal-overlay"
40
+ className={cn('cn-modal-overlay fixed inset-0 isolate', className)}
41
+ {...props}
42
+ />
43
+ );
44
+
45
+ export type ModalContentProps = ComponentProps<typeof DialogPrimitive.Content> & {
46
+ showCloseButton?: boolean;
15
47
  };
16
48
 
17
- export type ModalProps = ExtendProps<'dialog', Props>;
18
-
19
- export const Modal = ({ isOpen, onClose, children, className, ...props }: ModalProps) => {
20
- const modalRef = useRef<HTMLDialogElement>(null);
21
-
22
- const handleClose = useCallback(() => {
23
- modalRef.current?.close();
24
- onClose();
25
- }, [onClose]);
26
-
27
- useEffect(() => {
28
- if (!isOpen) {
29
- return;
30
- }
31
-
32
- modalRef.current?.showModal();
33
- }, [isOpen]);
34
-
35
- // typically dialogs don't need to be rendered conditionally, as the browser sets `display: none` when it's closed, but
36
- // as we override the display style and make it `flex`, we need the condition to hide it
37
- return isOpen
38
- ? // although dialogs are in their own special top-layer, this is only for styling, and DOM-wise they receive events like any other element,
39
- // so we want to portal it to be the highest element in the DOM
40
- createPortal(
41
- // dialog elements do have a key handler as you can close them with `Escape`, so this can be ignored
42
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions
43
- <dialog
44
- className={cn(
45
- `fixed inset-0 flex items-center justify-center w-full h-full m-0 bg-transparent
46
- backdrop:bg-black/50`,
47
- className,
48
- )}
49
- ref={modalRef}
50
- onCancel={(event) => {
51
- event.preventDefault();
52
- event.stopPropagation();
53
-
54
- handleClose();
55
- }}
56
- onClick={() => {
57
- // close the modal if the user clicks outside the main content (i.e. on the backdrop)
58
- handleClose();
59
- }}
60
- {...props}
61
- >
62
- {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
63
- <div
64
- className="relative z-10 w-full max-w-md p-6 bg-white rounded-lg shadow-lg"
65
- onClick={(event) => {
66
- // stop event from bubbling to the `dialog` element, as we don't want the modal to close if you click the content
67
- event.stopPropagation();
68
- }}
69
- >
70
- <button
71
- onClick={handleClose}
72
- className="absolute text-gray-600 text-static-xl top-2 right-2 hover:text-black"
73
- aria-label="Close modal"
74
- >
75
- <IoMdCloseCircle size={20} />
76
- </button>
77
- {children}
78
- </div>
79
- </dialog>,
80
- document.body,
81
- )
82
- : null;
49
+ export const ModalContent = ({
50
+ className,
51
+ children,
52
+ showCloseButton = true,
53
+ ...props
54
+ }: ModalContentProps) => (
55
+ <ModalPortal>
56
+ <ModalOverlay />
57
+
58
+ <DialogPrimitive.Content
59
+ data-slot="modal-content"
60
+ className={cn(
61
+ `cn-modal-content fixed top-1/2 left-1/2 w-full -translate-x-1/2 -translate-y-1/2
62
+ outline-none`,
63
+ className,
64
+ )}
65
+ {...props}
66
+ >
67
+ {children}
68
+
69
+ {showCloseButton && (
70
+ <div className="cn-modal-close">
71
+ <DialogPrimitive.Close data-slot="modal-close" asChild>
72
+ <Button variant="icon" appearance="ghost">
73
+ <LuX />
74
+
75
+ <span className="sr-only">Close</span>
76
+ </Button>
77
+ </DialogPrimitive.Close>
78
+ </div>
79
+ )}
80
+ </DialogPrimitive.Content>
81
+ </ModalPortal>
82
+ );
83
+
84
+ export type ModalHeaderProps = ComponentProps<'div'>;
85
+
86
+ export const ModalHeader = ({ className, ...props }: ModalHeaderProps) => (
87
+ <div
88
+ data-slot="modal-header"
89
+ className={cn('cn-modal-header flex flex-col', className)}
90
+ {...props}
91
+ />
92
+ );
93
+
94
+ export type ModalFooterProps = ComponentProps<'div'> & {
95
+ showCloseButton?: boolean;
83
96
  };
97
+
98
+ export const ModalFooter = ({
99
+ className,
100
+ showCloseButton = false,
101
+ children,
102
+ ...props
103
+ }: ModalFooterProps) => (
104
+ <div
105
+ data-slot="modal-footer"
106
+ className={cn(
107
+ 'cn-modal-footer flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',
108
+ className,
109
+ )}
110
+ {...props}
111
+ >
112
+ {children}
113
+
114
+ {showCloseButton && (
115
+ <DialogPrimitive.Close asChild>
116
+ <Button appearance="secondary">Close</Button>
117
+ </DialogPrimitive.Close>
118
+ )}
119
+ </div>
120
+ );
121
+
122
+ export type ModalTitleProps = ComponentProps<typeof DialogPrimitive.Title>;
123
+
124
+ export const ModalTitle = ({ className, ...props }: ModalTitleProps) => (
125
+ <DialogPrimitive.Title
126
+ data-slot="modal-title"
127
+ className={cn('cn-modal-title cn-font-heading', className)}
128
+ {...props}
129
+ />
130
+ );
131
+
132
+ export type ModalDescriptionProps = ComponentProps<typeof DialogPrimitive.Description>;
133
+
134
+ export const ModalDescription = ({ className, ...props }: ModalDescriptionProps) => (
135
+ <DialogPrimitive.Description
136
+ data-slot="modal-description"
137
+ className={cn('cn-modal-description', className)}
138
+ {...props}
139
+ />
140
+ );
@@ -0,0 +1,17 @@
1
+ @layer components {
2
+ /* MARK: NoScript banner
3
+ Full-width accent-coloured bar. Intended as the very first element in
4
+ the DOM, above the header, same position as the cookie banner, so it's
5
+ unmissable and consistent across every app. role="region" + aria-label
6
+ keeps it discoverable via landmark navigation even though it sits
7
+ outside both the header and main landmarks. */
8
+ .cn-noscript-banner {
9
+ @apply bg-accent text-on-accent py-gds-4;
10
+ }
11
+
12
+ /* MARK: Inner wrapper
13
+ Centres and constrains content, matching cn-cookie-banner-inner. */
14
+ .cn-noscript-banner-inner {
15
+ @apply mx-auto max-w-page px-gds-4;
16
+ }
17
+ }
@@ -0,0 +1,46 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { NoScriptBanner } from './NoScriptBanner';
4
+ import { Heading } from '../Heading/Heading';
5
+ import { HeadingGroup } from '../Layout/HeadingGroup/HeadingGroup';
6
+ import { Paragraph } from '../Paragraph/Paragraph';
7
+
8
+ const meta: Meta<typeof NoScriptBanner> = {
9
+ title: 'Components/NoScriptBanner',
10
+ component: NoScriptBanner,
11
+ tags: ['autodocs'],
12
+ parameters: {
13
+ docs: {
14
+ description: {
15
+ component: `
16
+ Full-width accent-coloured banner shown only when JavaScript is disabled. Renders inside a real \`<noscript>\` element, so the browser (not React) decides whether to show it, place it as the very first element in the DOM, above the header, the same position as the cookie banner.
17
+
18
+ The title ("JavaScript is not available") is fixed for consistency across apps. Pass children to explain what that means for your specific service.
19
+
20
+ Because Storybook itself runs on JavaScript, the browser will never actually display this component's \`<noscript>\` content here. The story below is a plain, unwrapped reproduction of the same markup for visual reference only, disable JavaScript in your browser's dev tools against a real page to see the genuine behaviour.
21
+ `.trim(),
22
+ },
23
+ },
24
+ },
25
+ };
26
+
27
+ export default meta;
28
+
29
+ type Story = StoryObj<typeof NoScriptBanner>;
30
+
31
+ export const Preview: Story = {
32
+ render: () => (
33
+ <div className="cn-noscript-banner">
34
+ <div className="cn-noscript-banner-inner">
35
+ <HeadingGroup>
36
+ <Heading level="h2">JavaScript is not available</Heading>
37
+
38
+ <Paragraph>
39
+ This service needs JavaScript to work. Enable JavaScript in your browser, or contact us
40
+ for support with an alternative way to apply.
41
+ </Paragraph>
42
+ </HeadingGroup>
43
+ </div>
44
+ </div>
45
+ ),
46
+ };