@tpzdsp/next-toolkit 2.5.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/package.json +22 -13
  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
@@ -1,211 +0,0 @@
1
- import { DropdownMenu, type DropdownMenuItem, type DrowndownMenuButton } from './DropdownMenu';
2
- import { render, screen, userEvent, waitFor } from '../../test/renderers';
3
-
4
- type Item = { label: string };
5
-
6
- const ITEMS: Item[] = [{ label: 'A' }, { label: 'B' }, { label: 'C' }, { label: 'D' }];
7
-
8
- const CustomButton = ({ ...props }: DrowndownMenuButton) => {
9
- return <button {...props}>Some Custom Text</button>;
10
- };
11
-
12
- const CustomItem = ({ label, ...props }: DropdownMenuItem<Item>) => {
13
- return (
14
- <a {...props} role="link">
15
- {label}
16
- </a>
17
- );
18
- };
19
-
20
- describe('DropdownMenu Component', () => {
21
- it('should render with no menu when unopened', () => {
22
- render(<DropdownMenu items={ITEMS}></DropdownMenu>);
23
-
24
- expect(screen.getByRole('button', { name: /menu/i })).toBeInTheDocument();
25
- expect(() => screen.getByRole('menu')).toThrow();
26
- });
27
-
28
- it('should render with menu when opened', async () => {
29
- render(<DropdownMenu items={ITEMS}></DropdownMenu>);
30
-
31
- const user = userEvent.setup();
32
-
33
- await user.click(screen.getByRole('button', { name: /menu/i }));
34
-
35
- for (const item of ITEMS) {
36
- expect(await screen.findByRole('menuitem', { name: item.label })).toBeInTheDocument();
37
- }
38
- });
39
-
40
- it('should render with a custom item component', async () => {
41
- render(<DropdownMenu items={ITEMS} itemRenderer={CustomItem}></DropdownMenu>);
42
-
43
- const user = userEvent.setup();
44
-
45
- await user.click(screen.getByRole('button', { name: /menu/i }));
46
-
47
- for (const item of ITEMS) {
48
- expect(await screen.findByRole('link', { name: item.label })).toBeInTheDocument();
49
- }
50
- });
51
-
52
- it('should render with a custom button component', () => {
53
- render(<DropdownMenu items={ITEMS} buttonRenderer={CustomButton}></DropdownMenu>);
54
-
55
- expect(screen.getByRole('button', { name: /some custom text/i })).toBeInTheDocument();
56
- });
57
-
58
- it('should open the menu when button is clicked', async () => {
59
- render(<DropdownMenu items={ITEMS} />);
60
-
61
- const user = userEvent.setup();
62
-
63
- const button = screen.getByRole('button', { name: /menu/i });
64
-
65
- await user.click(button);
66
-
67
- expect(await screen.findByRole('menu')).toBeInTheDocument();
68
- });
69
-
70
- it('should open the menu when Space or Enter is pressed', async () => {
71
- render(<DropdownMenu items={ITEMS} />);
72
-
73
- const user = userEvent.setup();
74
-
75
- const button = screen.getByRole('button', { name: /menu/i });
76
-
77
- button.focus();
78
-
79
- await user.keyboard(' ');
80
-
81
- expect(await screen.findByRole('menu')).toBeInTheDocument();
82
-
83
- // pressing another key will close the menu but assuming the menu wasnt open already this would open it anyway
84
- await user.keyboard('{Enter}');
85
-
86
- await waitFor(() => expect(screen.queryByRole('menu')).not.toBeInTheDocument());
87
- });
88
-
89
- it('should close when Escape is pressed', async () => {
90
- render(<DropdownMenu items={ITEMS} />);
91
-
92
- const user = userEvent.setup();
93
-
94
- const button = screen.getByRole('button', { name: /menu/i });
95
-
96
- await user.click(button);
97
-
98
- expect(await screen.findByRole('menu')).toBeInTheDocument();
99
-
100
- await user.keyboard('{Escape}');
101
-
102
- await waitFor(() => expect(screen.queryByRole('menu')).not.toBeInTheDocument());
103
- });
104
-
105
- it('should close when clicking outside', async () => {
106
- render(
107
- <>
108
- <DropdownMenu items={ITEMS} />
109
-
110
- <button>Outside</button>
111
- </>,
112
- );
113
-
114
- const user = userEvent.setup();
115
-
116
- const button = screen.getByRole('button', { name: /menu/i });
117
-
118
- await user.click(button);
119
-
120
- expect(await screen.findByRole('menu')).toBeInTheDocument();
121
-
122
- // click away to another element, which should close the menu
123
- await user.click(screen.getByRole('button', { name: /outside/i }));
124
-
125
- await waitFor(() => expect(screen.queryByRole('menu')).not.toBeInTheDocument());
126
- });
127
-
128
- it('should close when focus moves outside (blur)', async () => {
129
- render(
130
- <>
131
- <DropdownMenu items={ITEMS} />
132
-
133
- <button>Outside</button>
134
- </>,
135
- );
136
-
137
- const user = userEvent.setup();
138
-
139
- const button = screen.getByRole('button', { name: /menu/i });
140
-
141
- await user.click(button);
142
-
143
- expect(await screen.findByRole('menu')).toBeInTheDocument();
144
-
145
- // move focus away from the menu, which should close it
146
- await user.tab();
147
-
148
- await waitFor(() => expect(screen.queryByRole('menu')).not.toBeInTheDocument());
149
- });
150
-
151
- it('should navigate items with ArrowUp/ArrowDown', async () => {
152
- render(<DropdownMenu items={ITEMS} />);
153
-
154
- const user = userEvent.setup();
155
-
156
- const button = screen.getByRole('button', { name: /menu/i });
157
-
158
- await user.click(button);
159
-
160
- const items = screen.getAllByRole('menuitem');
161
-
162
- // first element is focussed when the menu is open
163
- expect(items[0]).toHaveFocus();
164
-
165
- await user.keyboard('{ArrowDown}');
166
- expect(items[1]).toHaveFocus();
167
-
168
- await user.keyboard('{ArrowUp}');
169
- expect(items[0]).toHaveFocus();
170
- });
171
-
172
- it('should select an item with Enter or Space', async () => {
173
- render(<DropdownMenu items={ITEMS} />);
174
-
175
- const user = userEvent.setup();
176
-
177
- const button = screen.getByRole('button', { name: /menu/i });
178
-
179
- await user.click(button);
180
- const items = screen.getAllByRole('menuitem');
181
-
182
- await user.keyboard('{ArrowDown}');
183
- await user.keyboard('{Enter}');
184
-
185
- await waitFor(() => expect(screen.queryByRole('menu')).not.toBeInTheDocument());
186
-
187
- await user.click(button);
188
-
189
- expect(items[0]).toHaveFocus();
190
- });
191
-
192
- it('should move focus away when pressing Tab', async () => {
193
- render(
194
- <>
195
- <DropdownMenu items={ITEMS} />
196
-
197
- <button>Other Button</button>
198
- </>,
199
- );
200
-
201
- const user = userEvent.setup();
202
-
203
- const button = screen.getByRole('button', { name: /menu/i });
204
-
205
- await user.click(button);
206
-
207
- await user.tab();
208
-
209
- await waitFor(() => expect(screen.queryByRole('menu')).not.toBeInTheDocument());
210
- });
211
- });
@@ -1,108 +0,0 @@
1
- 'use client';
2
-
3
- import type { ComponentType, HTMLAttributes } from 'react';
4
-
5
- import { LuChevronDown } from 'react-icons/lu';
6
-
7
- import {
8
- type ButtonRendererProps,
9
- type ItemRendererProps,
10
- useDropdownMenu,
11
- } from './useDropdownMenu';
12
- import { cn } from '../../utils';
13
-
14
- export type DropdownMenuItem<ItemProps extends object> = ItemRendererProps & {
15
- label: string;
16
- } & ItemProps;
17
-
18
- export type DrowndownMenuButton = ButtonRendererProps;
19
-
20
- type DropdownMenuProps<ItemProps extends object> = HTMLAttributes<HTMLDivElement> & {
21
- items: DropdownMenuItem<ItemProps>[];
22
- containerClassName?: string;
23
- menuContainerClassName?: string;
24
- buttonRenderer?: ComponentType<ButtonRendererProps>;
25
- buttonClassName?: string;
26
- itemRenderer?: ComponentType<DropdownMenuItem<ItemProps>>;
27
- itemClassName?: string;
28
- };
29
-
30
- const DefaultButton = ({ state: { isOpen }, ...props }: ButtonRendererProps) => {
31
- return (
32
- <button
33
- {...props}
34
- aria-label="Open Menu"
35
- className={cn(
36
- `text-black flex gap-2 items-center justify-center border rounded-md border-gray-300
37
- bg-white px-2 py-1 text-sm shadow-sm focus:border-brand focus:outline-none focus:ring-1
38
- focus:ring-brand`,
39
- props.className,
40
- )}
41
- >
42
- <span className="text-base pointer-events-none">Menu</span>
43
-
44
- <LuChevronDown className={`pointer-events-none ${isOpen ? 'rotate-180' : ''}`} />
45
- </button>
46
- );
47
- };
48
-
49
- const DefaultItem = <Item extends object>({ label, ...props }: DropdownMenuItem<Item>) => {
50
- return (
51
- <div
52
- {...props}
53
- aria-label={label}
54
- className={cn(
55
- `text-black cursor-pointer hover:bg-slate-200 focus:bg-slate-200 active:bg-slate-300 px-2
56
- py-1`,
57
- props.className,
58
- )}
59
- >
60
- {label}
61
- </div>
62
- );
63
- };
64
-
65
- export const DropdownMenu = <Item extends object>({
66
- items,
67
- containerClassName,
68
- menuContainerClassName,
69
- buttonRenderer = DefaultButton,
70
- buttonClassName,
71
- itemRenderer = DefaultItem,
72
- itemClassName,
73
- className,
74
- ...props
75
- }: DropdownMenuProps<Item>) => {
76
- // rebind to avoid linting errors
77
- const ButtonRenderer = buttonRenderer;
78
- const ItemRenderer = itemRenderer;
79
-
80
- const { isOpen, buttonProps, itemProps } = useDropdownMenu(items.length);
81
-
82
- return (
83
- <div className={cn('relative', containerClassName, className)} {...props}>
84
- <ButtonRenderer {...buttonProps} className={buttonClassName} />
85
-
86
- <div
87
- style={{ display: isOpen ? 'flex' : 'none' }}
88
- aria-hidden={!isOpen}
89
- className={cn(
90
- `absolute right-0 mt-1 bg-white border shadow-md rounded-md min-w-full flex-col gap-0
91
- z-[999] divide-y divide-slate-400`,
92
- menuContainerClassName,
93
- )}
94
- role="menu"
95
- >
96
- {items.map((item, i) => (
97
- <ItemRenderer
98
- {...item}
99
- {...itemProps[i]}
100
- key={i}
101
- label={item.label}
102
- className={itemClassName}
103
- />
104
- ))}
105
- </div>
106
- </div>
107
- );
108
- };
@@ -1,249 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- useState,
5
- useRef,
6
- useId,
7
- useEffect,
8
- useMemo,
9
- type HTMLAttributes,
10
- useCallback,
11
- } from 'react';
12
-
13
- import type { ExtendProps } from '../../types/utils';
14
- import { KeyboardKeys } from '../../utils';
15
-
16
- /**
17
- * The current state of the menu
18
- */
19
- export type DropdownMenuState = { state: { isOpen: boolean } };
20
-
21
- // use a data attribute with a unique value to tell us which elements belong to the current menu
22
- type DropdownMenuAttribute = { 'data-menu': string };
23
-
24
- /**
25
- * The props that are passed into the button that is used to open/close the menu.
26
- */
27
- export type ButtonRendererProps = ExtendProps<'button', DropdownMenuState>;
28
-
29
- // can't use `ExtendProps` here since we just want the most base level of HTML attributes.
30
- // a number of elements use only these props, like `abbr`, but that implies the menu
31
- // item is an `<abbr>` which isn't strictly true, and so qualifying it ourselves is better
32
- /**
33
- * The props passed into each child item of the menu.
34
- */
35
- export type ItemRendererProps = HTMLAttributes<HTMLElement>;
36
-
37
- export type DropdownMenuHook = {
38
- isOpen: boolean;
39
- buttonProps: ButtonRendererProps & DropdownMenuAttribute;
40
- itemProps: (ItemRendererProps & DropdownMenuAttribute)[];
41
- selectedItemIndex: number;
42
- };
43
-
44
- /**
45
- * This hook handles the behaviour and accessibility concerns when creating a dropdown menu (*not* a select menu).
46
- * while leaving all the styling and design up to the user.
47
- *
48
- * The hook returns an object with 4 keys:
49
- * - `isOpen`: Whether the dropdown is open or not.
50
- * - `buttonProps`: These props are generated by the hook and need to be passed down (via spreading) into the `button` element
51
- * that the user can click to open/close the menu. Other attributes can be applied to the button along side these, but at minimum
52
- * these MUST be added.
53
- * - `itemProps`: These props are also generated by the hook, but they should be passed down to each item displayed in the menu.
54
- * Since the style and design is up to the user, when you create the menu children from some data, you can use the index to get
55
- * the props for each item and spread them in. For example:
56
- * ```tsx
57
- * data.map((_, i) => <div {...itemProps[i]}></div>)
58
- * ```
59
- * - `selectedItemIndex`: This represents which item was last selected by the user.
60
- *
61
- * ### NOTES:
62
- * This hook makes use of `refs`. For that reason, the menu items **must not** be unmounted from the DOM via a conditional statement with `isOpen`.
63
- * Instead, you can show/hide the menu item container using its `display` or `visibility` style and set it to a different value depending on
64
- * if the menu is open or not. This does not affect accessibility.
65
- *
66
- * Keyboard interactivity sources:
67
- * https://www.w3.org/WAI/ARIA/apg/patterns/menubar/examples/menubar-navigation/
68
- *
69
- * @param itemCount The number of items to show in the menu.
70
- * @returns
71
- */
72
- export const useDropdownMenu = (itemCount: number): DropdownMenuHook => {
73
- const [isOpen, setIsOpen] = useState(false);
74
- const [selectedItem, setSelectedItem] = useState(0);
75
-
76
- const currentFocusIndex = useRef<number | null>(null);
77
-
78
- const menuId = useId();
79
-
80
- // track the refs of each child so they can be focussed for accessibility
81
- // this is memoified so it only updates when the number of items changes
82
- const itemRefs: { current: Record<number, HTMLElement | null> } = useMemo(
83
- () => ({ current: {} }),
84
- [],
85
- );
86
-
87
- // use the unique id to determive if a given element is part of the menu
88
- const isMenuItem = useCallback(
89
- (element: Element | null): boolean => {
90
- return (
91
- element?.getAttribute('data-menu') === menuId ||
92
- // get the closest element with that id, essentially checking if we are a child somewhere down the line
93
- element?.closest(`[data-menu="${menuId}"]`) !== null
94
- );
95
- },
96
- [menuId],
97
- );
98
-
99
- const focusItem = useCallback(
100
- (index: number) => {
101
- currentFocusIndex.current = index;
102
- itemRefs.current[index]?.focus();
103
- },
104
- [itemRefs],
105
- );
106
-
107
- const selectItem = (index: number) => {
108
- setSelectedItem(index);
109
- setIsOpen(false);
110
- };
111
-
112
- useEffect(() => {
113
- if (isOpen) {
114
- focusItem(0);
115
- }
116
- }, [focusItem, isOpen]);
117
-
118
- useEffect(() => {
119
- // handles exiting the menu when the `Escape` key is pressed
120
- const escapeExitMenuHandler = (event: KeyboardEvent) => {
121
- if (
122
- event.key === KeyboardKeys.Escape &&
123
- document.activeElement &&
124
- isMenuItem(document.activeElement)
125
- ) {
126
- event.preventDefault();
127
-
128
- setIsOpen(false);
129
- }
130
- };
131
-
132
- // handles exiting the menu when focus moved to another element
133
- const blurExitMenuHandler = () => {
134
- if (!isMenuItem(document.activeElement)) {
135
- setIsOpen(false);
136
- }
137
- };
138
-
139
- // handles exiting the menu when the user clicks/touches outside the menu
140
- const clickExitMenuHandler = (event: PointerEvent) => {
141
- if (event.button === 0 && !isMenuItem(event.target as Element)) {
142
- setIsOpen(false);
143
- }
144
- };
145
-
146
- window.addEventListener('keydown', escapeExitMenuHandler);
147
- // `passive` events just mean we dont call `preventDefault` and it allows the browser to be a bit smarter about the events
148
- // `capture` is a bit more complicated but from what I understand it essentially makes it so this event handler fires BEFORE
149
- // the element gets the event, whereas without it it would trigger AFTER the element recieved the event
150
- document.addEventListener('focus', blurExitMenuHandler, { capture: true, passive: true });
151
- // make use of pointer events instead of click events to support touch devices.
152
- document.addEventListener('pointerup', clickExitMenuHandler, { passive: true });
153
-
154
- return () => {
155
- window.removeEventListener('keydown', escapeExitMenuHandler);
156
- document.removeEventListener('focus', blurExitMenuHandler);
157
- document.removeEventListener('pointerup', clickExitMenuHandler);
158
- };
159
- }, [isMenuItem]);
160
-
161
- return {
162
- isOpen,
163
- selectedItemIndex: selectedItem,
164
-
165
- buttonProps: {
166
- state: { isOpen },
167
- 'data-menu': menuId,
168
- 'aria-haspopup': 'menu',
169
- 'aria-expanded': isOpen,
170
-
171
- onPointerUp: () => setIsOpen(!isOpen),
172
- onKeyDown: (event) => {
173
- // space and enter act more like clicking and can toggle the menu open/closed
174
- if (event.key === KeyboardKeys.Space || event.key === KeyboardKeys.Enter) {
175
- event.preventDefault();
176
-
177
- setIsOpen(!isOpen);
178
- }
179
-
180
- // the down arrow should open the menu
181
- if (event.key === KeyboardKeys.ArrowDown) {
182
- event.preventDefault();
183
-
184
- if (!isOpen) {
185
- setIsOpen(true);
186
- } else {
187
- focusItem(0);
188
- }
189
- }
190
- },
191
- },
192
-
193
- itemProps: Array.from({ length: itemCount }, (_, itemIndex) => ({
194
- key: itemIndex,
195
-
196
- role: 'menuitem',
197
- // the items in the menu should not be focussable. using `Tab` should move the focus away from the menu entirely.
198
- // only arrow keys should navigate each item
199
- tabIndex: -1,
200
- 'data-menu': menuId,
201
-
202
- ref: (el: HTMLElement) => {
203
- itemRefs.current[itemIndex] = el;
204
- },
205
-
206
- // by using a 0 second `setTimeout` the event handler is moved to the bottom of the stack
207
- // this is important because it means our handler is fired AFTER the default behaviour
208
- // without the setTimeout things like links might not work properly because the menu
209
- // would hide BEFORE the browsers own default click handler could redirect you
210
- onPointerUp: () => setTimeout(() => selectItem(itemIndex), 0),
211
- onKeyDown: (event) => {
212
- let focusIndex = currentFocusIndex.current;
213
-
214
- // close the menu if you "select" an item
215
- if (event.key === KeyboardKeys.Space || event.key === KeyboardKeys.Enter) {
216
- event.preventDefault();
217
-
218
- // we just called `preventDefault` so we need to manually click it otherwise nothing will happen
219
- // the reason we must call `preventDefault` is to avoid other behaviour like spacebar scrolling the page
220
- itemRefs.current[itemIndex]?.click();
221
-
222
- selectItem(itemIndex);
223
- }
224
-
225
- if (focusIndex !== null) {
226
- // arrow keys should cycle through each item in the menu
227
- if (event.key === KeyboardKeys.ArrowDown) {
228
- event.preventDefault();
229
-
230
- focusIndex += 1;
231
- } else if (event.key === KeyboardKeys.ArrowUp) {
232
- event.preventDefault();
233
-
234
- focusIndex -= 1;
235
- }
236
-
237
- // allow wrapping of focus
238
- if (focusIndex > itemCount - 1) {
239
- focusIndex = 0;
240
- } else if (focusIndex < 0) {
241
- focusIndex = itemCount - 1;
242
- }
243
-
244
- focusItem(focusIndex);
245
- }
246
- },
247
- })),
248
- };
249
- };