@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,26 @@
1
+ import type { ComponentProps } from 'react';
2
+
3
+ import { cn } from '../../utils/components';
4
+ import { Heading } from '../Heading/Heading';
5
+ import { HeadingGroup } from '../Layout/HeadingGroup/HeadingGroup';
6
+
7
+ export type NoScriptBannerProps = ComponentProps<'div'>;
8
+
9
+ export const NoScriptBanner = ({ className, children, ...props }: NoScriptBannerProps) => (
10
+ <noscript>
11
+ <div
12
+ role="region"
13
+ aria-label="JavaScript is not available"
14
+ className={cn('cn-noscript-banner', className)}
15
+ {...props}
16
+ >
17
+ <div className="cn-noscript-banner-inner">
18
+ <HeadingGroup>
19
+ <Heading level="h2">JavaScript is not available</Heading>
20
+
21
+ {children}
22
+ </HeadingGroup>
23
+ </div>
24
+ </div>
25
+ </noscript>
26
+ );
@@ -0,0 +1,22 @@
1
+ @layer components {
2
+ /* MARK: Paragraph */
3
+ .cn-paragraph {
4
+ @apply text-base;
5
+ }
6
+
7
+ /* MARK: Skeleton
8
+ Stacks one bar per wrapped line. Overrides cn-skeleton's inline-block,
9
+ these are meant to be full lines, not inline text. */
10
+ .cn-paragraph-skeleton {
11
+ @apply flex flex-col gap-2;
12
+ }
13
+
14
+ .cn-paragraph-skeleton-line {
15
+ @apply block h-4 w-full;
16
+ }
17
+
18
+ /* Shorter, matching where real wrapped text would naturally end mid-line. */
19
+ .cn-paragraph-skeleton-line-last {
20
+ @apply w-3/4;
21
+ }
22
+ }
@@ -1,24 +1,16 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite';
2
2
 
3
3
  import { Paragraph } from './Paragraph';
4
- import { ExternalLink } from '../link/ExternalLink';
5
4
 
6
5
  const meta: Meta<typeof Paragraph> = {
7
- title: 'Components/Paragraph',
6
+ title: 'Components/Paragraph/Paragraph',
8
7
  component: Paragraph,
9
- parameters: {
10
- layout: 'padded',
11
- },
12
8
  tags: ['autodocs'],
13
9
  argTypes: {
14
10
  children: {
15
11
  description: 'Content of the paragraph',
16
12
  control: false,
17
13
  },
18
- className: {
19
- description: 'Additional TailwindCSS classes to apply to the paragraph',
20
- control: 'text',
21
- },
22
14
  },
23
15
  args: {
24
16
  children: 'Hello, this is some simple text',
@@ -31,13 +23,6 @@ type Story = StoryObj<typeof Paragraph>;
31
23
 
32
24
  export const Default: Story = {};
33
25
 
34
- export const CustomStyling: Story = {
35
- args: {
36
- className: 'text-yellow-800 p-2',
37
- children: 'Hello, this is some simple text with custom styling',
38
- },
39
- };
40
-
41
26
  export const LongText: Story = {
42
27
  args: {
43
28
  children:
@@ -45,29 +30,3 @@ export const LongText: Story = {
45
30
  'It is used to test how the Paragraph component handles large amounts of text.',
46
31
  },
47
32
  };
48
-
49
- export const WithLink: Story = {
50
- args: {
51
- children: (
52
- <span>
53
- This paragraph contains a <ExternalLink href="https://storybook.js.org/">link</ExternalLink>
54
- .
55
- </span>
56
- ),
57
- },
58
- };
59
-
60
- export const ImageAndText: Story = {
61
- args: {
62
- children: (
63
- <div>
64
- <img
65
- src="https://images.unsplash.com/photo-1563991655280-cb95c90ca2fb?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8M3x8bm8lMjBjb3B5cmlnaHR8ZW58MHx8MHx8fDA%3D"
66
- alt="Card"
67
- />
68
-
69
- <p>This is text about the image</p>
70
- </div>
71
- ),
72
- },
73
- };
@@ -1,11 +1,12 @@
1
- import type { ExtendProps } from '../../types/utils';
1
+ import type { ComponentProps } from 'react';
2
+
2
3
  import { cn } from '../../utils';
3
4
 
4
- export type ParagraphProps = ExtendProps<'p'>;
5
+ export type ParagraphProps = ComponentProps<'p'>;
5
6
 
6
7
  export const Paragraph = ({ className, children, ...props }: ParagraphProps) => {
7
8
  return (
8
- <p className={cn('pb-4 text-sm text-text-primary', className)} {...props}>
9
+ <p className={cn('cn-paragraph', className)} {...props}>
9
10
  {children}
10
11
  </p>
11
12
  );
@@ -0,0 +1,44 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { ParagraphSkeleton } from './ParagraphSkeleton';
4
+
5
+ const meta: Meta<typeof ParagraphSkeleton> = {
6
+ title: 'Components/Paragraph/Skeleton',
7
+ component: ParagraphSkeleton,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component:
13
+ 'Placeholder for a Paragraph while its real text is loading. Renders one bar per wrapped line (`lines`, defaults to 3), with the last line narrower to mimic where real text naturally wraps.',
14
+ },
15
+ },
16
+ },
17
+ argTypes: {
18
+ lines: { control: { type: 'number', min: 1, max: 6 } },
19
+ },
20
+ args: {
21
+ lines: 3,
22
+ },
23
+ };
24
+
25
+ export default meta;
26
+
27
+ type Story = StoryObj<typeof ParagraphSkeleton>;
28
+
29
+ export const Default: Story = {
30
+ render: (args) => (
31
+ <div className="max-w-md">
32
+ <ParagraphSkeleton {...args} />
33
+ </div>
34
+ ),
35
+ };
36
+
37
+ export const SingleLine: Story = {
38
+ args: { lines: 1 },
39
+ render: (args) => (
40
+ <div className="max-w-md">
41
+ <ParagraphSkeleton {...args} />
42
+ </div>
43
+ ),
44
+ };
@@ -0,0 +1,33 @@
1
+ import type { ComponentProps } from 'react';
2
+
3
+ import { cn } from '../../utils/components';
4
+ import { Skeleton } from '../Skeleton/Skeleton';
5
+
6
+ // Stable, fixed identifiers rather than the array index, even though these
7
+ // are decorative and never reorder, so a line's identity is never tied to
8
+ // its position at render time.
9
+ const LINE_KEYS = ['line-1', 'line-2', 'line-3', 'line-4', 'line-5', 'line-6'] as const;
10
+
11
+ export type ParagraphSkeletonProps = Omit<ComponentProps<'div'>, 'children'> & {
12
+ children?: never;
13
+ /** Number of wrapped lines to show. Defaults to 3. */
14
+ lines?: number;
15
+ };
16
+
17
+ export const ParagraphSkeleton = ({ className, lines = 3, ...props }: ParagraphSkeletonProps) => {
18
+ const lineKeys = LINE_KEYS.slice(0, lines);
19
+
20
+ return (
21
+ <div aria-hidden className={cn('cn-paragraph-skeleton', className)} {...props}>
22
+ {lineKeys.map((key, index) => (
23
+ <Skeleton
24
+ key={key}
25
+ className={cn(
26
+ 'cn-paragraph-skeleton-line',
27
+ index === lineKeys.length - 1 && 'cn-paragraph-skeleton-line-last',
28
+ )}
29
+ />
30
+ ))}
31
+ </div>
32
+ );
33
+ };
@@ -0,0 +1,3 @@
1
+ @layer components {
2
+ /* PasswordInput uses InputGroup/InputSuffix from Input.css so no custom layout needed. */
3
+ }
@@ -0,0 +1,47 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { PasswordInput } from './PasswordInput';
4
+ import { ErrorText } from '../ErrorText/ErrorText';
5
+ import { FormGroup } from '../Form/FormGroup';
6
+ import { Label } from '../Label/Label';
7
+
8
+ const meta: Meta<typeof PasswordInput> = {
9
+ title: 'Components/PasswordInput',
10
+ component: PasswordInput,
11
+ tags: ['autodocs'],
12
+ parameters: {
13
+ docs: {
14
+ description: {
15
+ component: 'Help users to create and enter passwords.',
16
+ },
17
+ },
18
+ },
19
+ argTypes: {},
20
+ args: {},
21
+ };
22
+
23
+ export default meta;
24
+
25
+ type Story = StoryObj<typeof PasswordInput>;
26
+
27
+ export const Default: Story = {};
28
+
29
+ export const Disabled: Story = {
30
+ render: () => (
31
+ <fieldset disabled>
32
+ <PasswordInput />
33
+ </fieldset>
34
+ ),
35
+ };
36
+
37
+ export const Invalid: Story = {
38
+ render: () => (
39
+ <FormGroup invalid>
40
+ <Label htmlFor="password-invalid">Password</Label>
41
+
42
+ <ErrorText id="password-error">Enter your password</ErrorText>
43
+
44
+ <PasswordInput id="password-invalid" aria-invalid aria-describedby="password-error" />
45
+ </FormGroup>
46
+ ),
47
+ };
@@ -0,0 +1,45 @@
1
+ 'use client';
2
+
3
+ import { useId, useState, type ComponentProps } from 'react';
4
+
5
+ import { LuEye, LuEyeClosed } from 'react-icons/lu';
6
+
7
+ import { Button } from '../Button/Button';
8
+ import { Input } from '../Input/Input';
9
+ import { InputGroup, InputSuffix } from '../InputGroup/InputGroup';
10
+
11
+ export type PasswordInputProps = Omit<
12
+ ComponentProps<typeof Input>,
13
+ 'type' | 'size' | 'appearance' | 'children'
14
+ >;
15
+
16
+ export const PasswordInput = ({ autoComplete, id, ...props }: PasswordInputProps) => {
17
+ const generatedId = useId();
18
+ const inputId = id ?? generatedId;
19
+
20
+ const [shown, setShown] = useState(false);
21
+
22
+ return (
23
+ <InputGroup>
24
+ <Input
25
+ id={inputId}
26
+ type={shown ? 'text' : 'password'}
27
+ autoComplete={autoComplete ?? 'current-password'}
28
+ spellCheck={false}
29
+ {...props}
30
+ />
31
+
32
+ <InputSuffix>
33
+ <Button
34
+ appearance="secondary"
35
+ variant="icon"
36
+ aria-label={shown ? 'Hide password' : 'Show password'}
37
+ aria-controls={inputId}
38
+ onClick={() => setShown((previous) => !previous)}
39
+ >
40
+ {shown ? <LuEye aria-hidden /> : <LuEyeClosed aria-hidden />}
41
+ </Button>
42
+ </InputSuffix>
43
+ </InputGroup>
44
+ );
45
+ };
@@ -0,0 +1,12 @@
1
+ @layer components {
2
+ /* MARK: Phase banner
3
+ Displayed at the top of the page to communicate service phase (Alpha, Beta).
4
+ Bottom border matches GDS. Layout is flex rather than the legacy display:table. */
5
+ .cn-phase-banner {
6
+ @apply py-gds-2 border-b border-divider;
7
+ }
8
+
9
+ .cn-phase-banner-content {
10
+ @apply flex items-center gap-gds-2 text-base m-0;
11
+ }
12
+ }
@@ -0,0 +1,61 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { PhaseBanner } from './PhaseBanner';
4
+ import { Link } from '../Link/Link';
5
+ import { Tag } from '../Tag/Tag';
6
+
7
+ const meta: Meta<typeof PhaseBanner> = {
8
+ title: 'Components/PhaseBanner',
9
+ component: PhaseBanner,
10
+ tags: ['autodocs'],
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component:
15
+ 'Displayed at the top of a page to communicate that a service is in an early development phase. Accepts a `Tag` via the `tag` prop and descriptive text as `children`.',
16
+ },
17
+ },
18
+ },
19
+ args: {
20
+ children: 'This is a new service – your feedback will help us to improve it.',
21
+ },
22
+ };
23
+
24
+ export default meta;
25
+
26
+ type Story = StoryObj<typeof PhaseBanner>;
27
+
28
+ export const Alpha: Story = {
29
+ args: {
30
+ tag: (
31
+ <Tag size="sm" appearance="info">
32
+ Alpha
33
+ </Tag>
34
+ ),
35
+ },
36
+ };
37
+
38
+ export const Beta: Story = {
39
+ args: {
40
+ tag: (
41
+ <Tag size="sm" appearance="info">
42
+ Beta
43
+ </Tag>
44
+ ),
45
+ },
46
+ };
47
+
48
+ export const WithFeedbackLink: Story = {
49
+ args: {
50
+ tag: (
51
+ <Tag size="sm" appearance="info">
52
+ Beta
53
+ </Tag>
54
+ ),
55
+ children: (
56
+ <>
57
+ This is a new service – <Link href="#">give your feedback</Link> to help us improve it.
58
+ </>
59
+ ),
60
+ },
61
+ };
@@ -0,0 +1,17 @@
1
+ import type { ComponentProps, ReactElement } from 'react';
2
+
3
+ import { cn } from '../../utils/components';
4
+ import { Tag } from '../Tag/Tag';
5
+
6
+ export type PhaseBannerProps = ComponentProps<'div'> & {
7
+ tag: ReactElement<ComponentProps<typeof Tag>, typeof Tag>;
8
+ };
9
+
10
+ export const PhaseBanner = ({ tag, children, className, ...props }: PhaseBannerProps) => (
11
+ <div data-slot="phase-banner" className={cn('cn-phase-banner', className)} {...props}>
12
+ <p className="cn-phase-banner-content">
13
+ {tag}
14
+ <span className="cn-phase-banner-text">{children}</span>
15
+ </p>
16
+ </div>
17
+ );
@@ -0,0 +1,43 @@
1
+ @layer components {
2
+ /* MARK: Popover content
3
+ Same panel treatment as Tooltip (panel bg + border) but with more
4
+ padding and no max-width cap, consumers control width via className.
5
+ Portal-rendered so DOM order is always safe above page content, but
6
+ cn-z-overlay still matters against other elements that set their own
7
+ high z-index (e.g. a resizable handle's cn-z-top). */
8
+ .cn-popover-content {
9
+ @apply panel cn-z-overlay p-gds-3 text-base text-body;
10
+
11
+ &[data-state='open'] {
12
+ animation: cn-popover-in 0.1s ease-out;
13
+ }
14
+
15
+ &[data-state='closed'] {
16
+ animation: cn-popover-out 0.075s ease-in;
17
+ }
18
+ }
19
+
20
+ .cn-popover-arrow {
21
+ fill: var(--color-panel-border);
22
+ }
23
+
24
+ @keyframes cn-popover-in {
25
+ from {
26
+ opacity: 0;
27
+ transform: scale(0.97);
28
+ }
29
+ to {
30
+ opacity: 1;
31
+ transform: scale(1);
32
+ }
33
+ }
34
+
35
+ @keyframes cn-popover-out {
36
+ from {
37
+ opacity: 1;
38
+ }
39
+ to {
40
+ opacity: 0;
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,102 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { Popover, PopoverContent, PopoverTrigger } from './Popover';
4
+ import { Button } from '../Button/Button';
5
+ import { Label } from '../Label/Label';
6
+ import { Paragraph } from '../Paragraph/Paragraph';
7
+ import { Textarea } from '../Textarea/Textarea';
8
+
9
+ const meta: Meta<typeof Popover> = {
10
+ title: 'Components/Popover',
11
+ component: Popover,
12
+ tags: ['autodocs'],
13
+ parameters: {
14
+ docs: {
15
+ description: {
16
+ component:
17
+ 'A floating panel anchored to a trigger element, activated by click or tap. Use it to surface supplementary content, filters, or short forms without navigating away from the current page. Because it activates on click rather than hover, it works correctly on both desktop and touch devices. Prefer Popover over Tooltip whenever touch support is needed or the content is longer than a short label.',
18
+ },
19
+ },
20
+ },
21
+ };
22
+
23
+ export default meta;
24
+
25
+ type Story = StoryObj<typeof Popover>;
26
+
27
+ export const Default: Story = {
28
+ render: () => (
29
+ <div className="flex items-center justify-center min-h-40">
30
+ <Popover>
31
+ <PopoverTrigger asChild>
32
+ <Button appearance="secondary">More information</Button>
33
+ </PopoverTrigger>
34
+
35
+ <PopoverContent>
36
+ <Paragraph>
37
+ Payments are issued quarterly once your evidence has been reviewed and approved by your
38
+ area coordinator.
39
+ </Paragraph>
40
+ </PopoverContent>
41
+ </Popover>
42
+ </div>
43
+ ),
44
+ };
45
+
46
+ export const WithForm: Story = {
47
+ parameters: {
48
+ docs: {
49
+ description: {
50
+ story:
51
+ 'Interactive content inside the popover. Popover does not trap focus, so tab order continues naturally through any form controls inside it.',
52
+ },
53
+ },
54
+ },
55
+ render: () => (
56
+ <div className="flex items-center justify-center min-h-40">
57
+ <Popover>
58
+ <PopoverTrigger asChild>
59
+ <Button appearance="secondary">Add note</Button>
60
+ </PopoverTrigger>
61
+
62
+ <PopoverContent className="w-72">
63
+ <div className="flex flex-col gap-gds-2">
64
+ <Label className="text-sm font-bold" htmlFor="popover-note">
65
+ Note
66
+ </Label>
67
+
68
+ <Textarea id="popover-note" rows={3} placeholder="Enter a note..." />
69
+
70
+ <Button className="self-end">Save</Button>
71
+ </div>
72
+ </PopoverContent>
73
+ </Popover>
74
+ </div>
75
+ ),
76
+ };
77
+
78
+ export const Positions: Story = {
79
+ parameters: {
80
+ docs: {
81
+ description: {
82
+ story:
83
+ 'The popover repositions automatically when it would overflow the viewport, but you can set a preferred side.',
84
+ },
85
+ },
86
+ },
87
+ render: () => (
88
+ <div className="flex gap-gds-4 flex-wrap items-center justify-center min-h-40">
89
+ {(['top', 'right', 'bottom', 'left'] as const).map((side) => (
90
+ <Popover key={side}>
91
+ <PopoverTrigger asChild>
92
+ <Button appearance="secondary">{side}</Button>
93
+ </PopoverTrigger>
94
+
95
+ <PopoverContent side={side}>
96
+ <Paragraph>Appears on the {side}</Paragraph>
97
+ </PopoverContent>
98
+ </Popover>
99
+ ))}
100
+ </div>
101
+ ),
102
+ };
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+
3
+ import type { ComponentProps } from 'react';
4
+
5
+ import { Popover as PopoverPrimitive } from 'radix-ui';
6
+
7
+ import { cn } from '../../utils/components';
8
+
9
+ export const Popover = ({ ...props }: ComponentProps<typeof PopoverPrimitive.Root>) => (
10
+ <PopoverPrimitive.Root data-slot="popover" {...props} />
11
+ );
12
+
13
+ export const PopoverTrigger = ({ ...props }: ComponentProps<typeof PopoverPrimitive.Trigger>) => (
14
+ <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
15
+ );
16
+
17
+ export const PopoverAnchor = ({ ...props }: ComponentProps<typeof PopoverPrimitive.Anchor>) => (
18
+ <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />
19
+ );
20
+
21
+ export const PopoverContent = ({
22
+ className,
23
+ align = 'center',
24
+ sideOffset = 6,
25
+ children,
26
+ ...props
27
+ }: ComponentProps<typeof PopoverPrimitive.Content>) => (
28
+ <PopoverPrimitive.Portal>
29
+ <PopoverPrimitive.Content
30
+ data-slot="popover-content"
31
+ align={align}
32
+ sideOffset={sideOffset}
33
+ className={cn('cn-popover-content', className)}
34
+ {...props}
35
+ >
36
+ {children}
37
+ <PopoverPrimitive.Arrow className="cn-popover-arrow" />
38
+ </PopoverPrimitive.Content>
39
+ </PopoverPrimitive.Portal>
40
+ );
@@ -0,0 +1,69 @@
1
+ @layer components {
2
+ /* MARK: Radio
3
+ Radix RadioGroup.Item renders a <button role="radio">.
4
+ Border is explicit (not @apply cn-form-border) because appearance:none on
5
+ <button> can override utility-layer border styles. */
6
+ .cn-radio {
7
+ @apply relative rounded-full appearance-none cursor-pointer flex-none box-border bg-white p-0
8
+ outline-none;
9
+ border: var(--border-width-form) solid var(--color-divider-input);
10
+
11
+ &:focus:not(:disabled) {
12
+ @apply outline-focus border-4 outline-offset-1;
13
+ box-shadow: 0 0 0 var(--outline-width-focus) var(--color-focus);
14
+ }
15
+
16
+ &:disabled {
17
+ @apply opacity-50 cursor-not-allowed;
18
+ }
19
+ }
20
+
21
+ /* MARK: Indicator
22
+ RadioGroup.Indicator only mounts when checked, styled as a black dot.
23
+ Absolutely positioned + translate(-50%, -50%) rather than the parent's
24
+ flex items-center/justify-center: flex centering resolves (container -
25
+ item) / 2 during layout, which has to snap to a whole device pixel, so
26
+ a fractional remainder rounds asymmetrically (one side up, one down) at
27
+ 1x DPR, visible as the dot sitting a pixel off-centre, while the exact
28
+ same fraction is imperceptible at 2x/3x DPR where it still lands on a
29
+ clean device pixel either way. translate is resolved in the compositor
30
+ rather than layout, so it isn't pixel-snapped the same way. This also
31
+ matches real GDS: govuk-radios positions its own dot with absolute
32
+ top/left, not flexbox. */
33
+ .cn-radio-indicator {
34
+ @apply absolute top-1/2 left-1/2 -translate-1/2 block rounded-full bg-body;
35
+ }
36
+
37
+ /* MARK: Sizes */
38
+ .cn-radio-size-sm {
39
+ @apply w-6 h-6;
40
+
41
+ & .cn-radio-indicator {
42
+ @apply w-3 h-3;
43
+ }
44
+ }
45
+
46
+ .cn-radio-size-base {
47
+ @apply w-10 h-10;
48
+
49
+ & .cn-radio-indicator {
50
+ @apply w-5 h-5;
51
+ }
52
+ }
53
+
54
+ /* MARK: Group
55
+ gap-gds-2 matches GDS's own govuk-radios__item margin-bottom (10px).
56
+ Radix reflects the orientation prop as aria-orientation on the group's
57
+ own root, but doesn't do anything visual with it itself (it's only used
58
+ internally for arrow-key roving focus direction), so the row layout for
59
+ orientation="horizontal" has to be applied here. flex-wrap + the wider
60
+ gap-x match GDS's own govuk-radios--inline (wraps rather than
61
+ overflowing, govuk-spacing(4) between items horizontally). */
62
+ .cn-radio-group {
63
+ @apply flex flex-col gap-gds-2;
64
+
65
+ &[aria-orientation='horizontal'] {
66
+ @apply flex-row flex-wrap items-center gap-x-gds-4 gap-y-gds-2;
67
+ }
68
+ }
69
+ }