@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,71 @@
1
+ @layer components {
2
+ /* MARK: Summary list
3
+ GDS govuk-summary-list pattern. Uses <dl> with <div> row wrappers so
4
+ the border spans the full width rather than individual cells. Stacks
5
+ vertically on mobile, flex row on sm+. */
6
+ .cn-summary-list {
7
+ @apply m-0 p-0;
8
+ }
9
+
10
+ /* MARK: Row */
11
+ .cn-summary-list-row {
12
+ @apply flex flex-col sm:flex-row border-b border-divider gap-y-gds-1 sm:gap-y-0;
13
+ }
14
+
15
+ /* MARK: Key, value, actions, shared padding */
16
+ .cn-summary-list-key,
17
+ .cn-summary-list-value,
18
+ .cn-summary-list-actions {
19
+ @apply m-0 py-gds-1 sm:py-gds-2;
20
+ }
21
+
22
+ /* Unbreakable text (a single long word, a URL) would otherwise overflow
23
+ the key's fixed sm:w-[40%] and visually overlap the value next to it,
24
+ rather than wrapping the way multi-word text already does. Matches
25
+ GDS's own govuk-summary-list__key/__value, same reasoning. */
26
+ .cn-summary-list-key,
27
+ .cn-summary-list-value {
28
+ @apply wrap-break-word;
29
+ }
30
+
31
+ /* MARK: Key
32
+ Wider than GDS's own default 30%: this project's keys tend to run
33
+ longer than GDS's own examples, and at 30% they wrap mid-word often
34
+ enough to look broken rather than intentional. 40% gives long keys
35
+ more room to wrap on whole words before running out of width. */
36
+ .cn-summary-list-key {
37
+ @apply font-bold sm:w-[40%] sm:flex-none sm:pr-gds-4;
38
+ }
39
+
40
+ /* MARK: Value */
41
+ .cn-summary-list-value {
42
+ @apply sm:flex-1;
43
+ }
44
+
45
+ /* MARK: Actions
46
+ Right-aligned on sm+, stacks below value on mobile. */
47
+ .cn-summary-list-actions {
48
+ @apply sm:ml-auto sm:pl-gds-4 sm:text-right;
49
+ }
50
+
51
+ /* MARK: Skeleton
52
+ Reuses SummaryList/Row/Key/Value directly, only the text content is
53
+ replaced with bars, so dimensions match exactly once real data loads.
54
+
55
+ w-full max-w-* (not a fixed w-*): sm:w-[30%]/sm:flex-1 on the real
56
+ Key/Value only kick in past the sm *viewport* breakpoint, not however
57
+ wide this SummaryList's own container actually is, so a narrow
58
+ container on a wide viewport (a sidebar, a Popup) still lays key/value
59
+ out side by side there. Real content is text, it wraps to whatever
60
+ width it's given so this never bites it, but a fixed-width bar can't
61
+ shrink to fit and overflows into the other column instead. max-w-*
62
+ keeps the same size as before wherever there's room for it, and only
63
+ shrinks below that once the row genuinely doesn't have the space. */
64
+ .cn-summary-list-skeleton-key {
65
+ @apply h-4 w-full max-w-24;
66
+ }
67
+
68
+ .cn-summary-list-skeleton-value {
69
+ @apply h-4 w-full max-w-40;
70
+ }
71
+ }
@@ -0,0 +1,211 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import {
4
+ SummaryList,
5
+ SummaryListActions,
6
+ SummaryListKey,
7
+ SummaryListRow,
8
+ SummaryListValue,
9
+ } from './SummaryList';
10
+ import { Link } from '../Link/Link';
11
+
12
+ const meta: Meta<typeof SummaryList> = {
13
+ title: 'Components/SummaryList',
14
+ component: SummaryList,
15
+ tags: ['autodocs'],
16
+ parameters: {
17
+ docs: {
18
+ description: {
19
+ component: `
20
+ GDS summary list for displaying key–value pairs, most commonly used on "check your answers" pages.
21
+
22
+ Uses semantic \`<dl>\` / \`<dt>\` / \`<dd>\` markup. Row \`<div>\` wrappers allow the bottom border to span the full width.
23
+
24
+ **Components:**
25
+ - \`SummaryList\`: the \`<dl>\` container
26
+ - \`SummaryListRow\`: wraps each key–value pair
27
+ - \`SummaryListKey\`: the \`<dt>\` term (bold)
28
+ - \`SummaryListValue\`: the \`<dd>\` value
29
+ - \`SummaryListActions\`: optional \`<dd>\` for change/delete links, right-aligned on desktop
30
+ `.trim(),
31
+ },
32
+ },
33
+ },
34
+ };
35
+
36
+ export default meta;
37
+ type Story = StoryObj<typeof SummaryList>;
38
+
39
+ export const Default: Story = {
40
+ parameters: {
41
+ docs: {
42
+ description: { story: 'Typical "check your answers" usage with a change link on each row.' },
43
+ },
44
+ },
45
+ render: () => (
46
+ <SummaryList>
47
+ <SummaryListRow>
48
+ <SummaryListKey>Name</SummaryListKey>
49
+
50
+ <SummaryListValue>Sarah Philips</SummaryListValue>
51
+
52
+ <SummaryListActions>
53
+ <Link href="#">
54
+ Change <span className="sr-only">name</span>
55
+ </Link>
56
+ </SummaryListActions>
57
+ </SummaryListRow>
58
+
59
+ <SummaryListRow>
60
+ <SummaryListKey>Date of birth</SummaryListKey>
61
+
62
+ <SummaryListValue>5 January 1978</SummaryListValue>
63
+
64
+ <SummaryListActions>
65
+ <Link href="#">
66
+ Change <span className="sr-only">date of birth</span>
67
+ </Link>
68
+ </SummaryListActions>
69
+ </SummaryListRow>
70
+
71
+ <SummaryListRow>
72
+ <SummaryListKey>Contact information</SummaryListKey>
73
+
74
+ <SummaryListValue>
75
+ 72 Guild Street
76
+ <br />
77
+ London
78
+ <br />
79
+ SE23 6FH
80
+ </SummaryListValue>
81
+
82
+ <SummaryListActions>
83
+ <Link href="#">
84
+ Change <span className="sr-only">contact information</span>
85
+ </Link>
86
+ </SummaryListActions>
87
+ </SummaryListRow>
88
+ </SummaryList>
89
+ ),
90
+ };
91
+
92
+ export const MultipleActions: Story = {
93
+ parameters: {
94
+ docs: {
95
+ description: {
96
+ story:
97
+ 'When a row has more than one action, list them with visually hidden context text on each.',
98
+ },
99
+ },
100
+ },
101
+ render: () => (
102
+ <SummaryList>
103
+ <SummaryListRow>
104
+ <SummaryListKey>Name</SummaryListKey>
105
+
106
+ <SummaryListValue>Sarah Philips</SummaryListValue>
107
+
108
+ <SummaryListActions>
109
+ <ul className="m-0 p-0 list-none flex gap-gds-2 sm:flex-col sm:gap-gds-1">
110
+ <li>
111
+ <Link href="#">
112
+ Change <span className="sr-only">name</span>
113
+ </Link>
114
+ </li>
115
+
116
+ <li>
117
+ <Link href="#">
118
+ Delete <span className="sr-only">name</span>
119
+ </Link>
120
+ </li>
121
+ </ul>
122
+ </SummaryListActions>
123
+ </SummaryListRow>
124
+
125
+ <SummaryListRow>
126
+ <SummaryListKey>Date of birth</SummaryListKey>
127
+
128
+ <SummaryListValue>5 January 1978</SummaryListValue>
129
+
130
+ <SummaryListActions>
131
+ <ul className="m-0 p-0 list-none flex gap-gds-2 sm:flex-col sm:gap-gds-1">
132
+ <li>
133
+ <Link href="#">
134
+ Change <span className="sr-only">date of birth</span>
135
+ </Link>
136
+ </li>
137
+
138
+ <li>
139
+ <Link href="#">
140
+ Delete <span className="sr-only">date of birth</span>
141
+ </Link>
142
+ </li>
143
+ </ul>
144
+ </SummaryListActions>
145
+ </SummaryListRow>
146
+ </SummaryList>
147
+ ),
148
+ };
149
+
150
+ export const NarrowContainer: Story = {
151
+ parameters: {
152
+ docs: {
153
+ description: {
154
+ story:
155
+ 'A single long, unbreakable word (no space to wrap at) in a narrow container. Without break-words on the key/value, this would overflow its own box and visually overlap its neighbour rather than wrapping the way multi-word text does.',
156
+ },
157
+ },
158
+ },
159
+ render: () => (
160
+ <div className="max-w-xs">
161
+ <SummaryList>
162
+ <SummaryListRow>
163
+ <SummaryListKey>Sites</SummaryListKey>
164
+
165
+ <SummaryListValue>240</SummaryListValue>
166
+ </SummaryListRow>
167
+
168
+ <SummaryListRow>
169
+ <SummaryListKey>Total area</SummaryListKey>
170
+
171
+ <SummaryListValue>1,315,000 ha</SummaryListValue>
172
+ </SummaryListRow>
173
+
174
+ <SummaryListRow>
175
+ <SummaryListKey>Percentage</SummaryListKey>
176
+
177
+ <SummaryListValue>34.2%</SummaryListValue>
178
+ </SummaryListRow>
179
+ </SummaryList>
180
+ </div>
181
+ ),
182
+ };
183
+
184
+ export const NoActions: Story = {
185
+ parameters: {
186
+ docs: {
187
+ description: { story: 'Read-only display, no actions column.' },
188
+ },
189
+ },
190
+ render: () => (
191
+ <SummaryList>
192
+ <SummaryListRow>
193
+ <SummaryListKey>Name</SummaryListKey>
194
+
195
+ <SummaryListValue>Sarah Philips</SummaryListValue>
196
+ </SummaryListRow>
197
+
198
+ <SummaryListRow>
199
+ <SummaryListKey>Date of birth</SummaryListKey>
200
+
201
+ <SummaryListValue>5 January 1978</SummaryListValue>
202
+ </SummaryListRow>
203
+
204
+ <SummaryListRow>
205
+ <SummaryListKey>Address</SummaryListKey>
206
+
207
+ <SummaryListValue>72 Guild Street, London, SE23 6FH</SummaryListValue>
208
+ </SummaryListRow>
209
+ </SummaryList>
210
+ ),
211
+ };
@@ -0,0 +1,41 @@
1
+ import { type ComponentProps } from 'react';
2
+
3
+ import { cn } from '../../utils/components';
4
+
5
+ export type SummaryListProps = ComponentProps<'dl'>;
6
+
7
+ export const SummaryList = ({ className, ...props }: SummaryListProps) => (
8
+ <dl data-slot="summary-list" className={cn('cn-summary-list', className)} {...props} />
9
+ );
10
+
11
+ export type SummaryListRowProps = ComponentProps<'div'>;
12
+
13
+ export const SummaryListRow = ({ className, ...props }: SummaryListRowProps) => (
14
+ <div data-slot="summary-list-row" className={cn('cn-summary-list-row', className)} {...props} />
15
+ );
16
+
17
+ export type SummaryListKeyProps = ComponentProps<'dt'>;
18
+
19
+ export const SummaryListKey = ({ className, ...props }: SummaryListKeyProps) => (
20
+ <dt data-slot="summary-list-key" className={cn('cn-summary-list-key', className)} {...props} />
21
+ );
22
+
23
+ export type SummaryListValueProps = ComponentProps<'dd'>;
24
+
25
+ export const SummaryListValue = ({ className, ...props }: SummaryListValueProps) => (
26
+ <dd
27
+ data-slot="summary-list-value"
28
+ className={cn('cn-summary-list-value', className)}
29
+ {...props}
30
+ />
31
+ );
32
+
33
+ export type SummaryListActionsProps = ComponentProps<'dd'>;
34
+
35
+ export const SummaryListActions = ({ className, ...props }: SummaryListActionsProps) => (
36
+ <dd
37
+ data-slot="summary-list-actions"
38
+ className={cn('cn-summary-list-actions', className)}
39
+ {...props}
40
+ />
41
+ );
@@ -0,0 +1,67 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { SummaryList, SummaryListKey, SummaryListRow, SummaryListValue } from './SummaryList';
4
+ import { SummaryListSkeleton } from './SummaryListSkeleton';
5
+
6
+ const meta: Meta<typeof SummaryListSkeleton> = {
7
+ title: 'Components/SummaryList/Skeleton',
8
+ component: SummaryListSkeleton,
9
+ tags: ['autodocs'],
10
+ parameters: {
11
+ docs: {
12
+ description: {
13
+ component:
14
+ 'Placeholder for a SummaryList while its rows are loading. Reuses SummaryList/SummaryListRow/SummaryListKey/SummaryListValue directly, so it lines up exactly with the real list once data arrives.',
15
+ },
16
+ },
17
+ },
18
+ };
19
+
20
+ export default meta;
21
+
22
+ type Story = StoryObj<typeof SummaryListSkeleton>;
23
+
24
+ export const Default: Story = {
25
+ render: () => (
26
+ <div className="max-w-md">
27
+ <SummaryListSkeleton />
28
+ </div>
29
+ ),
30
+ };
31
+
32
+ export const SideBySide: Story = {
33
+ parameters: {
34
+ docs: {
35
+ description: { story: 'The skeleton and the real list line up exactly once loaded.' },
36
+ },
37
+ },
38
+ render: () => (
39
+ <div className="flex gap-gds-6">
40
+ <div className="max-w-md w-full">
41
+ <SummaryListSkeleton rows={3} />
42
+ </div>
43
+
44
+ <div className="max-w-md w-full">
45
+ <SummaryList>
46
+ <SummaryListRow>
47
+ <SummaryListKey>Name</SummaryListKey>
48
+
49
+ <SummaryListValue>Sarah Philips</SummaryListValue>
50
+ </SummaryListRow>
51
+
52
+ <SummaryListRow>
53
+ <SummaryListKey>Date of birth</SummaryListKey>
54
+
55
+ <SummaryListValue>5 January 1978</SummaryListValue>
56
+ </SummaryListRow>
57
+
58
+ <SummaryListRow>
59
+ <SummaryListKey>Address</SummaryListKey>
60
+
61
+ <SummaryListValue>72 Guild Street, London, SE23 6FH</SummaryListValue>
62
+ </SummaryListRow>
63
+ </SummaryList>
64
+ </div>
65
+ </div>
66
+ ),
67
+ };
@@ -0,0 +1,40 @@
1
+ import type { ComponentProps } from 'react';
2
+
3
+ import { SummaryList, SummaryListKey, SummaryListRow, SummaryListValue } from './SummaryList';
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 row's identity is never tied to
8
+ // its position at render time.
9
+ const ROW_KEYS = ['row-1', 'row-2', 'row-3', 'row-4', 'row-5', 'row-6'] as const;
10
+
11
+ export type SummaryListSkeletonProps = Omit<ComponentProps<typeof SummaryList>, 'children'> & {
12
+ /** Explicitly disallow children, a skeleton is a placeholder shape, not a content wrapper. */
13
+ children?: never;
14
+ /** Number of rows to show. Defaults to 3. */
15
+ rows?: number;
16
+ };
17
+
18
+ export const SummaryListSkeleton = ({
19
+ className,
20
+ rows = 3,
21
+ ...props
22
+ }: SummaryListSkeletonProps) => {
23
+ const rowKeys = ROW_KEYS.slice(0, rows);
24
+
25
+ return (
26
+ <SummaryList aria-hidden className={className} {...props}>
27
+ {rowKeys.map((key) => (
28
+ <SummaryListRow key={key}>
29
+ <SummaryListKey>
30
+ <Skeleton className="cn-summary-list-skeleton-key" />
31
+ </SummaryListKey>
32
+
33
+ <SummaryListValue>
34
+ <Skeleton className="cn-summary-list-skeleton-value" />
35
+ </SummaryListValue>
36
+ </SummaryListRow>
37
+ ))}
38
+ </SummaryList>
39
+ );
40
+ };
@@ -0,0 +1,84 @@
1
+ @layer components {
2
+ /* MARK: Tab list
3
+ h-full: stretches to fill whatever height its parent establishes (e.g. a
4
+ taller header) rather than shrinking to its own content's height, so it
5
+ actually reaches that container's top edge instead of floating wherever
6
+ it naturally lands. items-end then sits each trigger (text + its
7
+ underline, as one rigid unit, see cn-tabs-trigger below) flush against
8
+ the bottom of that now-taller box rather than the top, with no extra gap
9
+ introduced either within the trigger or between the list and whatever
10
+ comes right after it (typically TabsContent). relative + cn-z-top keeps
11
+ the active-tab underline visible over anything else rendered nearby,
12
+ needs its own stacking context since this element isn't necessarily a
13
+ flex/grid item of anything itself. */
14
+ .cn-tabs-list {
15
+ @apply relative flex h-full items-end cn-z-top flex-wrap;
16
+ }
17
+
18
+ /* MARK: Tab trigger
19
+ Column flex so the hidden sizer stacks above the visible text.
20
+ The sizer is bold (matching the active state) with height: 0 so it
21
+ contributes its bold width to the trigger without adding any height.
22
+ This means the trigger is always sized to the bold width, preventing
23
+ siblings from shifting when the active tab changes. */
24
+ .cn-tabs-trigger {
25
+ @apply flex flex-col items-center px-gds-3 py-gds-1 bg-transparent border-none cursor-pointer
26
+ select-none transition-transform duration-150;
27
+
28
+ &:hover:not(:disabled) {
29
+ @apply bg-focus;
30
+ }
31
+
32
+ &:hover:not([data-state='active'], :disabled) {
33
+ @apply -translate-y-px;
34
+ }
35
+
36
+ &:focus-visible {
37
+ @apply outline-focus;
38
+ }
39
+
40
+ &[data-disabled] {
41
+ @apply opacity-50 cursor-not-allowed;
42
+ }
43
+ }
44
+
45
+ /* Invisible bold copy, sets the width, takes no height */
46
+ .cn-tabs-trigger-sizer {
47
+ @apply font-bold invisible overflow-hidden whitespace-nowrap select-none pointer-events-none
48
+ h-0;
49
+ }
50
+
51
+ /* Visible text, underline transitions from transparent to body colour on active */
52
+ .cn-tabs-trigger-text {
53
+ @apply text-base text-body underline decoration-transparent decoration-2 underline-offset-4
54
+ transition-[font-weight,text-decoration-color] duration-150;
55
+ line-height: 1.5rem;
56
+ text-underline-offset: var(--spacing-gds-2);
57
+ }
58
+
59
+ .cn-tabs-trigger[data-state='active'] .cn-tabs-trigger-text {
60
+ @apply font-bold decoration-body;
61
+ }
62
+
63
+ /* MARK: Tab content
64
+ Radix's forceMount makes a TabsContent panel present={forceMount ||
65
+ isSelected}, which is unconditionally true whenever forceMount is set,
66
+ so its own hidden={!present} is unconditionally false too, and React
67
+ omits a hidden={false} attribute from the DOM entirely. forceMount's
68
+ actual contract is "stay mounted always, you handle hiding it
69
+ yourself" via data-state, not "hidden natively while inactive": don't
70
+ reintroduce a [hidden] selector here expecting it to ever match.
71
+ !important still matters here for the same reason it would for
72
+ [hidden]: a consumer's own layout class on TabsContent (e.g. flex/h-full,
73
+ to make a map fill the panel) is a same-origin, equal-or-higher-
74
+ specificity display declaration that would otherwise win. */
75
+ .cn-tabs-content {
76
+ &:focus-visible {
77
+ @apply outline-focus;
78
+ }
79
+
80
+ &[data-state='inactive'] {
81
+ display: none !important;
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,133 @@
1
+ import { useState } from 'react';
2
+
3
+ import type { Meta, StoryObj } from '@storybook/react-vite';
4
+
5
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from './Tabs';
6
+
7
+ const meta: Meta<typeof Tabs> = {
8
+ title: 'Components/Tabs',
9
+ component: Tabs,
10
+ };
11
+
12
+ export default meta;
13
+ type Story = StoryObj<typeof Tabs>;
14
+
15
+ export const Default: Story = {
16
+ render: () => (
17
+ <Tabs defaultValue="overview">
18
+ <TabsList>
19
+ <TabsTrigger value="overview">Overview</TabsTrigger>
20
+
21
+ <TabsTrigger value="details">Details</TabsTrigger>
22
+
23
+ <TabsTrigger value="history">History</TabsTrigger>
24
+ </TabsList>
25
+
26
+ <TabsContent value="overview">
27
+ <p className="text-body">Overview tab content.</p>
28
+ </TabsContent>
29
+
30
+ <TabsContent value="details">
31
+ <p className="text-body">Details tab content.</p>
32
+ </TabsContent>
33
+
34
+ <TabsContent value="history">
35
+ <p className="text-body">History tab content.</p>
36
+ </TabsContent>
37
+ </Tabs>
38
+ ),
39
+ };
40
+
41
+ export const WithDisabledTab: Story = {
42
+ render: () => (
43
+ <Tabs defaultValue="active">
44
+ <TabsList>
45
+ <TabsTrigger value="active">Active</TabsTrigger>
46
+
47
+ <TabsTrigger value="disabled" disabled>
48
+ Disabled
49
+ </TabsTrigger>
50
+
51
+ <TabsTrigger value="another">Another</TabsTrigger>
52
+ </TabsList>
53
+
54
+ <TabsContent value="active">
55
+ <p className="text-body">Active tab content.</p>
56
+ </TabsContent>
57
+
58
+ <TabsContent value="disabled">
59
+ <p className="text-body">Disabled tab content (unreachable).</p>
60
+ </TabsContent>
61
+
62
+ <TabsContent value="another">
63
+ <p className="text-body">Another tab content.</p>
64
+ </TabsContent>
65
+ </Tabs>
66
+ ),
67
+ };
68
+
69
+ const ControlledTabs = () => {
70
+ const [value, setValue] = useState('tab1');
71
+
72
+ return (
73
+ <div className="flex flex-col gap-gds-2">
74
+ <p className="text-body text-sm">
75
+ Active tab: <strong>{value}</strong>
76
+ </p>
77
+
78
+ <Tabs value={value} onValueChange={setValue}>
79
+ <TabsList>
80
+ <TabsTrigger value="tab1">Tab 1</TabsTrigger>
81
+
82
+ <TabsTrigger value="tab2">Tab 2</TabsTrigger>
83
+
84
+ <TabsTrigger value="tab3">Tab 3</TabsTrigger>
85
+ </TabsList>
86
+
87
+ <TabsContent value="tab1">
88
+ <p className="text-body">Content for Tab 1.</p>
89
+ </TabsContent>
90
+
91
+ <TabsContent value="tab2">
92
+ <p className="text-body">Content for Tab 2.</p>
93
+ </TabsContent>
94
+
95
+ <TabsContent value="tab3">
96
+ <p className="text-body">Content for Tab 3.</p>
97
+ </TabsContent>
98
+ </Tabs>
99
+ </div>
100
+ );
101
+ };
102
+
103
+ export const Controlled: Story = {
104
+ render: () => <ControlledTabs />,
105
+ };
106
+
107
+ export const BottomAligned: Story = {
108
+ parameters: {
109
+ docs: {
110
+ description: {
111
+ story:
112
+ 'If TabsList itself is given more height than its content needs (here via className="h-20", e.g. sitting inside a taller header bar), the triggers sit flush against its bottom edge rather than floating at the top, with no extra gap introduced between the text and its own underline.',
113
+ },
114
+ },
115
+ },
116
+ render: () => (
117
+ <Tabs defaultValue="overview">
118
+ <TabsList className="h-20 border-b border-divider">
119
+ <TabsTrigger value="overview">Overview</TabsTrigger>
120
+
121
+ <TabsTrigger value="details">Details</TabsTrigger>
122
+ </TabsList>
123
+
124
+ <TabsContent value="overview">
125
+ <p className="text-body">Overview tab content.</p>
126
+ </TabsContent>
127
+
128
+ <TabsContent value="details">
129
+ <p className="text-body">Details tab content.</p>
130
+ </TabsContent>
131
+ </Tabs>
132
+ ),
133
+ };