@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,120 @@
1
+ 'use client';
2
+
3
+ import type { ComponentProps, ReactNode } from 'react';
4
+
5
+ import { LuCircleAlert } from 'react-icons/lu';
6
+
7
+ import { formatErrorForClipboard, getErrorDisplayInfo } from '../../errors/errorDisplay';
8
+ import { Button } from '../Button/Button';
9
+ import { CopyButton } from '../CopyButton/CopyButton';
10
+ import { Details, DetailsContent, DetailsTrigger } from '../Details/Details';
11
+ import { HintText } from '../HintText/HintText';
12
+ import { Stack } from '../Layout/Stack/Stack';
13
+ import {
14
+ Modal,
15
+ ModalContent,
16
+ ModalDescription,
17
+ ModalFooter,
18
+ ModalHeader,
19
+ ModalTitle,
20
+ } from '../Modal/Modal';
21
+ import {
22
+ SummaryList,
23
+ SummaryListKey,
24
+ SummaryListRow,
25
+ SummaryListValue,
26
+ } from '../SummaryList/SummaryList';
27
+
28
+ export type ErrorModalProps = Omit<ComponentProps<typeof Modal>, 'children'> & {
29
+ /** The error that occurred. When set, an expandable "Technical information"
30
+ * section shows its message/details/digest, with a button to copy all of
31
+ * it (including the stack trace, when available) to the clipboard. */
32
+ error?: unknown;
33
+ title?: ReactNode;
34
+ children?: ReactNode;
35
+ closeLabel?: ReactNode;
36
+ };
37
+
38
+ export const ErrorModal = ({
39
+ error,
40
+ title = 'An error occurred',
41
+ children,
42
+ closeLabel = 'Close',
43
+ onOpenChange,
44
+ ...props
45
+ }: ErrorModalProps) => {
46
+ const info = error !== undefined ? getErrorDisplayInfo(error) : null;
47
+
48
+ return (
49
+ <Modal onOpenChange={onOpenChange} {...props}>
50
+ <ModalContent className="cn-error-modal">
51
+ <div className="cn-error-modal-icon">
52
+ <LuCircleAlert aria-hidden className="size-8" />
53
+ </div>
54
+
55
+ <div className="cn-error-modal-body">
56
+ <ModalHeader>
57
+ <ModalTitle>{title}</ModalTitle>
58
+ </ModalHeader>
59
+
60
+ <ModalDescription>
61
+ <Stack gap="sm">
62
+ {children}
63
+
64
+ {info ? (
65
+ <Details>
66
+ <DetailsTrigger>Technical information</DetailsTrigger>
67
+
68
+ <DetailsContent>
69
+ <Stack gap="sm">
70
+ <div className="cn-error-modal-details">
71
+ <SummaryList>
72
+ <SummaryListRow>
73
+ <SummaryListKey>Reason</SummaryListKey>
74
+
75
+ <SummaryListValue>{info.message}</SummaryListValue>
76
+ </SummaryListRow>
77
+
78
+ {info.details ? (
79
+ <SummaryListRow>
80
+ <SummaryListKey>Details</SummaryListKey>
81
+
82
+ <SummaryListValue>{info.details}</SummaryListValue>
83
+ </SummaryListRow>
84
+ ) : null}
85
+
86
+ {info.digest ? (
87
+ <SummaryListRow>
88
+ <SummaryListKey>Digest</SummaryListKey>
89
+
90
+ <SummaryListValue>{info.digest}</SummaryListValue>
91
+ </SummaryListRow>
92
+ ) : null}
93
+ </SummaryList>
94
+ </div>
95
+
96
+ <div className="flex flex-col gap-gds-1">
97
+ <CopyButton
98
+ appearance="secondary"
99
+ content={formatErrorForClipboard(info)}
100
+ />
101
+
102
+ <HintText className="text-sm">
103
+ Copy to share error details with the app administrator.
104
+ </HintText>
105
+ </div>
106
+ </Stack>
107
+ </DetailsContent>
108
+ </Details>
109
+ ) : null}
110
+ </Stack>
111
+ </ModalDescription>
112
+
113
+ <ModalFooter className="sm:justify-start">
114
+ <Button onClick={() => onOpenChange?.(false)}>{closeLabel}</Button>
115
+ </ModalFooter>
116
+ </div>
117
+ </ModalContent>
118
+ </Modal>
119
+ );
120
+ };
@@ -0,0 +1,22 @@
1
+ @layer components {
2
+ /* Meant to stay mounted at all times (even with no error, as empty
3
+ children), rather than being conditionally rendered, so it's a stable
4
+ role="alert" live region screen readers can reliably announce content
5
+ changes on. A live region needs to already exist in the DOM before its
6
+ content changes for that announcement to be reliable, inserting a
7
+ brand new role="alert" node after the fact is a recognised trigger too,
8
+ but is markedly less consistent across AT/browser combinations.
9
+ Consumers that always render a fixed, non-empty message (e.g.
10
+ ErrorFallback) are unaffected by the rule below, it only ever matches
11
+ when there's genuinely no content. */
12
+ .cn-error-text {
13
+ @apply text-error font-bold;
14
+
15
+ /* Cancels out the gap-gds-1 that FormGroup/FieldSet's flex layout would
16
+ otherwise still apply around this element even while it's empty,
17
+ leaving no permanent dead space when there's no error to show. */
18
+ &:empty {
19
+ margin-top: calc(var(--spacing-gds-1) * -1);
20
+ }
21
+ }
22
+ }
@@ -1,27 +1,30 @@
1
+ import { useState } from 'react';
2
+
1
3
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
4
 
3
5
  import { ErrorText } from './ErrorText';
4
- import { ExternalLink } from '../link/ExternalLink';
6
+ import { Button } from '../Button/Button';
7
+ import { FormGroup } from '../Form/FormGroup';
8
+ import { Input } from '../Input/Input';
9
+ import { Label } from '../Label/Label';
5
10
 
6
11
  const meta: Meta<typeof ErrorText> = {
7
12
  title: 'Components/ErrorText',
8
13
  component: ErrorText,
14
+ tags: ['autodocs'],
9
15
  parameters: {
10
- layout: 'padded',
16
+ docs: {
17
+ description: {
18
+ component:
19
+ 'Show an error message next to the field and in the Error summary component when there is a validation error. Renders role="alert" (plus explicit aria-live/aria-atomic). Always render ErrorText, even with no error (empty children), rather than conditionally mounting it: a live region needs to already exist in the DOM before its content changes for screen readers to reliably announce that change, inserting a brand new role="alert" node after the fact is a recognised trigger too, but is markedly less consistent. The empty state collapses to zero height and cancels out FormGroup/FieldSet\'s own gap, so it never leaves a permanent gap when there\'s nothing to show.',
20
+ },
21
+ },
11
22
  },
12
- tags: ['autodocs'],
13
23
  argTypes: {
14
- children: {
15
- description: 'The content to display for the error',
16
- control: false,
17
- },
18
- className: {
19
- description: 'Additional TailwindCSS classes to apply',
20
- control: 'text',
21
- },
24
+ children: { control: 'text' },
22
25
  },
23
26
  args: {
24
- children: 'Error message',
27
+ children: 'The date your passport was issued must be in the past',
25
28
  },
26
29
  };
27
30
 
@@ -31,22 +34,34 @@ type Story = StoryObj<typeof ErrorText>;
31
34
 
32
35
  export const Default: Story = {};
33
36
 
34
- export const CustomStyling: Story = {
35
- args: {
36
- className: 'text-3xl',
37
- children: 'Custom styled error message',
38
- },
37
+ const ToggleableExample = () => {
38
+ const [hasError, setHasError] = useState(false);
39
+
40
+ return (
41
+ <div className="flex flex-col gap-gds-4">
42
+ <FormGroup invalid={hasError}>
43
+ <Label htmlFor="full-name">Full name</Label>
44
+
45
+ <Input id="full-name" aria-invalid={hasError} aria-describedby="full-name-error" />
46
+
47
+ <ErrorText id="full-name-error">{hasError ? 'Enter your full name' : ''}</ErrorText>
48
+ </FormGroup>
49
+
50
+ <Button onClick={() => setHasError((current) => !current)} className="self-start">
51
+ Toggle error
52
+ </Button>
53
+ </div>
54
+ );
39
55
  };
40
56
 
41
- export const ComplexChildren: Story = {
42
- args: {
43
- children: (
44
- <div>
45
- Error message with{' '}
46
- <ExternalLink className="underline text-link" href="/">
47
- Link
48
- </ExternalLink>
49
- </div>
50
- ),
57
+ export const AlwaysMounted: Story = {
58
+ parameters: {
59
+ docs: {
60
+ description: {
61
+ story:
62
+ "ErrorText stays mounted the whole time here, only its children toggle between empty and the message, click the button to see there's no gap left behind when it's empty.",
63
+ },
64
+ },
51
65
  },
66
+ render: () => <ToggleableExample />,
52
67
  };
@@ -1,18 +1,20 @@
1
- import type { ExtendProps } from '../../types/utils';
2
- import { cn } from '../../utils';
1
+ import type { ComponentProps } from 'react';
3
2
 
4
- export type ErrorTextProps = ExtendProps<'p'>;
3
+ import { cn } from '../../utils/components';
4
+ import { Paragraph } from '../Paragraph/Paragraph';
5
5
 
6
- export const ErrorText = ({ className, children, ...props }: ErrorTextProps) => {
7
- const Component = typeof children === 'string' ? 'p' : 'div';
6
+ export type ErrorTextProps = ComponentProps<typeof Paragraph>;
8
7
 
8
+ export const ErrorText = ({ className, children, ...props }: ErrorTextProps) => {
9
9
  return (
10
- <Component
10
+ <Paragraph
11
11
  role="alert"
12
- className={cn('mb-3 text-base text-error font-bold', className)}
12
+ aria-live="assertive"
13
+ aria-atomic="true"
14
+ className={cn('cn-error-text', className)}
13
15
  {...props}
14
16
  >
15
17
  {children}
16
- </Component>
18
+ </Paragraph>
17
19
  );
18
20
  };
@@ -0,0 +1,12 @@
1
+ @layer components {
2
+ .cn-external-link-icon-wrapper {
3
+ @apply whitespace-nowrap;
4
+ }
5
+
6
+ .cn-external-link-icon {
7
+ @apply inline ml-0.5;
8
+ width: 1em;
9
+ height: 1em;
10
+ vertical-align: -0.15em;
11
+ }
12
+ }
@@ -0,0 +1,43 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { ExternalLink } from './ExternalLink';
4
+
5
+ const meta: Meta<typeof ExternalLink> = {
6
+ title: 'Components/ExternalLink',
7
+ component: ExternalLink,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component:
13
+ 'Use ExternalLink for navigation that should open in a new tab. Generally avoid opening links in a new tab or window, however, if needed, aim to include the words `opens in new tab` in the link. This is the default variant of this component.',
14
+ },
15
+ },
16
+ },
17
+ argTypes: {
18
+ variant: {
19
+ control: { type: 'radio' },
20
+ options: ['default', 'icon', 'text'],
21
+ },
22
+ href: { control: 'text' },
23
+ children: { control: 'text' },
24
+ },
25
+ args: {
26
+ href: '#',
27
+ children: 'Story link',
28
+ },
29
+ };
30
+
31
+ export default meta;
32
+
33
+ type Story = StoryObj<typeof ExternalLink>;
34
+
35
+ export const Default: Story = {};
36
+
37
+ export const WithIcon: Story = {
38
+ args: { variant: 'icon' },
39
+ };
40
+
41
+ export const WithNothing: Story = {
42
+ args: { variant: 'plain' },
43
+ };
@@ -0,0 +1,43 @@
1
+ import type { ComponentProps } from 'react';
2
+
3
+ import { LuExternalLink } from 'react-icons/lu';
4
+
5
+ import { cn } from '../../utils/components';
6
+ import { Link } from '../Link/Link';
7
+
8
+ export type ExternalLinkVariants = 'plain' | 'icon' | 'text';
9
+
10
+ export type ExternalLinkProps = Omit<ComponentProps<typeof Link>, 'target' | 'rel' | 'variant'> & {
11
+ variant?: ExternalLinkVariants;
12
+ };
13
+
14
+ export const ExternalLink = ({
15
+ children,
16
+ variant = 'text',
17
+ className,
18
+ ...props
19
+ }: ExternalLinkProps) => {
20
+ const content = {
21
+ plain: null,
22
+ icon: (
23
+ <span className="cn-external-link-icon-wrapper">
24
+ <span className="sr-only">(opens in new tab)</span>
25
+ &nbsp;
26
+ <LuExternalLink aria-hidden className="cn-external-link-icon" />
27
+ </span>
28
+ ),
29
+ text: <span> (opens in new tab)</span>,
30
+ } as const;
31
+
32
+ return (
33
+ <Link
34
+ {...props}
35
+ className={cn('cn-external-link', className)}
36
+ rel="noopener noreferrer"
37
+ target="_blank"
38
+ >
39
+ {children}
40
+ {content[variant]}
41
+ </Link>
42
+ );
43
+ };
@@ -0,0 +1,103 @@
1
+ @layer components {
2
+ /* MARK: Fieldset
3
+ Reset browser fieldset defaults. Browsers apply borders,
4
+ padding, and an unusual min-width that breaks flex layouts. */
5
+ .cn-field-set {
6
+ @apply min-w-0 m-0 p-0 border-0 flex flex-col gap-gds-2;
7
+ }
8
+
9
+ /* MARK: Legend
10
+ Plain body text by default, matching GDS's own unmodified
11
+ govuk-fieldset__legend (and govuk-label): no bold, same size as a
12
+ label (govuk-fieldset__legend and govuk-label both use govuk-font(19)
13
+ in real GDS, this project's text-lg), not automatically a heading. For
14
+ a heading-like look, nest a real Heading component inside FieldLegend
15
+ instead, mirroring GDS's own documented pattern of nesting an <h1>
16
+ inside <legend> on question-per-page forms, rather than baking
17
+ heading-mimicking size variants into the legend itself. */
18
+ /* margin-bottom (not the fieldset's own gap-gds-2): a <legend> is exempt
19
+ from its fieldset's flex gap. Per spec, a flex/grid fieldset lays out
20
+ its OTHER children inside an anonymous wrapper box, legend sits
21
+ outside it as its own block box, so gap, which only bridges children
22
+ within the same flex/grid formatting context, never reaches the
23
+ space between legend and whatever follows it, unlike FormGroup's
24
+ Label, an ordinary element with no such carve-out, which does get its
25
+ gap-gds-1 for free. Matches gap-gds-2 so a legend reads the same as
26
+ any other item-to-item gap in the set. */
27
+ .cn-field-legend {
28
+ @apply block box-border max-w-full p-0 text-lg text-body whitespace-normal;
29
+ margin-bottom: var(--spacing-gds-2);
30
+ }
31
+
32
+ /* GDS tightens the gap specifically when a group-level hint sits directly
33
+ under a plain legend (margin-top: govuk-spacing(-1) on the hint). This
34
+ stacks with cn-field-legend's own margin-bottom above (flex item
35
+ margins never collapse), landing on a net gds-1 (5px) rather than the
36
+ usual gds-2 (10px) between legend and controls. */
37
+ .cn-field-legend + .cn-hint-text {
38
+ margin-top: calc(var(--spacing-gds-1) * -1);
39
+ }
40
+
41
+ /* MARK: Divider
42
+ Appears between groups of controls, typically contains "or".
43
+ Width matches GDS (40px). Sits naturally in the item flex-col gap. */
44
+ .cn-field-divider {
45
+ @apply w-10 text-center text-base font-normal;
46
+ }
47
+
48
+ /* MARK: Item
49
+ Mirrors GDS's govuk-radios__item/govuk-checkboxes__item exactly: flex
50
+ with wrap, not grid. Control and label sit side by side on the first
51
+ line; the hint (if any) is forced onto its own wrapped line by w-full,
52
+ a flex item at 100% width can't share a line with anything else. Unlike
53
+ grid, flex has no shared column to auto-align the hint into under the
54
+ label, so its start padding has to repeat the control's width plus the
55
+ item's own gap-x by hand, same as GDS hardcodes touch-target + label
56
+ padding rather than measuring anything. margin-top is negative for the
57
+ same reason GDS's own hint margin-top is: it sits closer to the label
58
+ above it than a hint normally would on its own.
59
+
60
+ No align-items override here, same as GDS's own item wrapper: the
61
+ control (Radio/Checkbox) has an explicit, non-auto height, so the
62
+ default stretch alignment has no size to stretch it into and falls
63
+ back to flex-start, top-aligning it for free. The label gets its own
64
+ align-self: center instead (see below), matching GDS's own
65
+ govuk-radios__label/govuk-checkboxes__label. Centering only the label,
66
+ not the row, is what keeps both cases correct at once: a short label
67
+ centers against the control's full height same as before, and a
68
+ wrapping label, being the row's own tallest item once it wraps,
69
+ already fills the full row height, so centering it is a no-op and it
70
+ stays flush with the control's top instead of floating down between
71
+ the lines the way row-level centering would. */
72
+ .cn-field-item {
73
+ @apply flex flex-wrap gap-x-gds-2;
74
+ }
75
+
76
+ /* min-w-0 flex-1: without this, a long label wraps as a whole flex item
77
+ instead of wrapping its own text, a flex item's default min-width is
78
+ auto, not 0, so it won't shrink below its label text's full unwrapped
79
+ width, and once that doesn't fit next to the control on the row,
80
+ flex-wrap moves the entire label below the control rather than
81
+ letting the label's own text wrap while staying beside it. flex-1
82
+ (not just min-w-0) is what makes the label actually claim the row's
83
+ remaining width to wrap within, rather than shrinking to its own
84
+ content and only wrapping once genuinely out of room.
85
+
86
+ self-center: see the item comment above. */
87
+ .cn-field-item > .cn-label {
88
+ @apply min-w-0 flex-1 self-center;
89
+ }
90
+
91
+ .cn-field-item > .cn-hint-text {
92
+ @apply w-full;
93
+ margin-top: calc(var(--spacing-gds-1) * -1);
94
+ padding-inline-start: calc(2.5rem + var(--spacing-gds-2));
95
+ padding-inline-end: var(--spacing-gds-3);
96
+ }
97
+
98
+ /* Small Radio/Checkbox (cn-radio-size-sm/cn-checkbox-size-sm) are 1.5rem,
99
+ not the base 2.5rem, so the hint's offset needs to match. */
100
+ .cn-field-item:has(.cn-radio-size-sm, .cn-checkbox-size-sm) > .cn-hint-text {
101
+ padding-inline-start: calc(1.5rem + var(--spacing-gds-2));
102
+ }
103
+ }