@scottish-government/designsystem-react 0.10.2 → 0.11.1

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 (419) hide show
  1. package/@types/components/Accordion.d.ts +3 -2
  2. package/@types/components/ButtonGroup.d.ts +5 -0
  3. package/@types/components/PageHeader.d.ts +2 -1
  4. package/@types/components/RadioButton.d.ts +2 -2
  5. package/@types/components/SearchFacets.d.ts +18 -0
  6. package/@types/components/SearchFilters.d.ts +14 -0
  7. package/@types/components/SearchResult.d.ts +30 -0
  8. package/@types/components/SearchSort.d.ts +9 -0
  9. package/@types/components/SideNavigation.d.ts +1 -1
  10. package/CHANGELOG.md +39 -5
  11. package/dist/common/AbstractNotificationBanner/AbstractNotificationBanner.d.ts +9 -0
  12. package/dist/common/AbstractNotificationBanner/AbstractNotificationBanner.jsx +62 -0
  13. package/dist/common/AbstractNotificationBanner/index.d.ts +1 -0
  14. package/dist/common/AbstractNotificationBanner/index.js +8 -0
  15. package/dist/common/ActionLink/ActionLink.d.ts +5 -0
  16. package/dist/common/ActionLink/ActionLink.jsx +19 -0
  17. package/dist/common/ActionLink/index.d.ts +1 -0
  18. package/dist/common/ActionLink/index.js +8 -0
  19. package/dist/common/ConditionalWrapper/ConditionalWrapper.d.ts +8 -0
  20. package/dist/common/ConditionalWrapper/ConditionalWrapper.jsx +8 -0
  21. package/dist/common/ConditionalWrapper/index.d.ts +1 -0
  22. package/dist/common/ConditionalWrapper/index.js +8 -0
  23. package/dist/common/FileIcon/FileIcon.d.ts +6 -0
  24. package/dist/common/FileIcon/FileIcon.jsx +46 -0
  25. package/dist/common/FileIcon/index.d.ts +1 -0
  26. package/dist/common/FileIcon/index.js +8 -0
  27. package/dist/common/HintText/HintText.d.ts +5 -0
  28. package/dist/common/HintText/HintText.jsx +9 -0
  29. package/dist/common/HintText/index.d.ts +1 -0
  30. package/dist/common/HintText/index.js +8 -0
  31. package/dist/common/Icon/Icon.d.ts +6 -0
  32. package/dist/common/Icon/Icon.jsx +51 -0
  33. package/dist/common/Icon/index.d.ts +1 -0
  34. package/dist/common/Icon/index.js +8 -0
  35. package/dist/common/ScreenReaderText/ScreenReaderText.d.ts +5 -0
  36. package/dist/common/ScreenReaderText/ScreenReaderText.jsx +9 -0
  37. package/dist/common/ScreenReaderText/index.d.ts +1 -0
  38. package/dist/common/ScreenReaderText/index.js +8 -0
  39. package/dist/common/WrapperTag/WrapperTag.d.ts +8 -0
  40. package/dist/common/WrapperTag/WrapperTag.jsx +11 -0
  41. package/dist/common/WrapperTag/index.d.ts +1 -0
  42. package/dist/common/WrapperTag/index.js +8 -0
  43. package/dist/common/index.d.ts +8 -0
  44. package/dist/common/index.js +22 -0
  45. package/dist/components/Accordion/Accordion.d.ts +10 -0
  46. package/dist/components/Accordion/Accordion.jsx +8 -3
  47. package/dist/components/Accordion/index.d.ts +1 -0
  48. package/dist/components/Accordion/index.js +8 -0
  49. package/dist/components/AspectBox/AspectBox.d.ts +6 -0
  50. package/dist/components/AspectBox/index.d.ts +1 -0
  51. package/dist/components/AspectBox/index.js +8 -0
  52. package/dist/components/BackToTop/BackToTop.d.ts +5 -0
  53. package/dist/components/BackToTop/index.d.ts +1 -0
  54. package/dist/components/BackToTop/index.js +8 -0
  55. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +9 -0
  56. package/dist/components/Breadcrumbs/index.d.ts +1 -0
  57. package/dist/components/Breadcrumbs/index.js +8 -0
  58. package/dist/components/Button/Button.d.ts +5 -0
  59. package/dist/components/Button/ButtonGroup.d.ts +5 -0
  60. package/dist/components/Button/ButtonGroup.jsx +13 -0
  61. package/dist/components/Button/index.d.ts +2 -0
  62. package/dist/components/Button/index.js +10 -0
  63. package/dist/components/ButtonGroup/ButtonGroup.jsx +13 -0
  64. package/dist/components/CategoryItem/CategoryItem.d.ts +5 -0
  65. package/dist/components/CategoryItem/index.d.ts +1 -0
  66. package/dist/components/CategoryItem/index.js +8 -0
  67. package/dist/components/CategoryList/CategoryList.d.ts +6 -0
  68. package/dist/components/CategoryList/index.d.ts +1 -0
  69. package/dist/components/CategoryList/index.js +8 -0
  70. package/dist/components/Checkbox/Checkbox.d.ts +5 -0
  71. package/dist/components/Checkbox/CheckboxGroup.d.ts +6 -0
  72. package/dist/components/Checkbox/index.d.ts +2 -0
  73. package/dist/components/Checkbox/index.js +10 -0
  74. package/dist/components/ConfirmationMessage/ConfirmationMessage.d.ts +5 -0
  75. package/dist/components/ConfirmationMessage/index.d.ts +1 -0
  76. package/dist/components/ConfirmationMessage/index.js +8 -0
  77. package/dist/components/ContentsNav/ContentsNav.d.ts +10 -0
  78. package/dist/components/ContentsNav/index.d.ts +1 -0
  79. package/dist/components/ContentsNav/index.js +8 -0
  80. package/dist/components/CookieBanner/CookieBanner.d.ts +9 -0
  81. package/dist/components/CookieBanner/index.d.ts +1 -0
  82. package/dist/components/CookieBanner/index.js +8 -0
  83. package/dist/components/DatePicker/DatePicker.d.ts +5 -0
  84. package/dist/components/DatePicker/DatePicker.jsx +2 -2
  85. package/dist/components/DatePicker/index.d.ts +1 -0
  86. package/dist/components/DatePicker/index.js +8 -0
  87. package/dist/components/Details/Details.d.ts +5 -0
  88. package/dist/components/Details/index.d.ts +1 -0
  89. package/dist/components/Details/index.js +8 -0
  90. package/dist/components/ErrorMessage/ErrorMessage.d.ts +5 -0
  91. package/dist/components/ErrorMessage/index.d.ts +1 -0
  92. package/dist/components/ErrorMessage/index.js +8 -0
  93. package/dist/components/ErrorSummary/ErrorSummary.d.ts +9 -0
  94. package/dist/components/ErrorSummary/index.d.ts +1 -0
  95. package/dist/components/ErrorSummary/index.js +8 -0
  96. package/dist/components/FeatureHeader/FeatureHeader.d.ts +13 -0
  97. package/dist/components/FeatureHeader/FeatureHeader.jsx +70 -0
  98. package/dist/components/FeatureHeader/index.d.ts +1 -0
  99. package/dist/components/FeatureHeader/index.js +8 -0
  100. package/dist/components/FileDownload/FileDownload.d.ts +5 -0
  101. package/dist/components/FileDownload/index.d.ts +1 -0
  102. package/dist/components/FileDownload/index.js +8 -0
  103. package/dist/components/HideThisPage/HideThisPage.d.ts +6 -0
  104. package/dist/components/HideThisPage/index.d.ts +1 -0
  105. package/dist/components/HideThisPage/index.js +8 -0
  106. package/dist/components/InsetText/InsetText.d.ts +5 -0
  107. package/dist/components/InsetText/index.d.ts +1 -0
  108. package/dist/components/InsetText/index.js +8 -0
  109. package/dist/components/NotificationBanner/NotificationBanner.d.ts +9 -0
  110. package/dist/components/NotificationBanner/index.d.ts +1 -0
  111. package/dist/components/NotificationBanner/index.js +8 -0
  112. package/dist/components/NotificationPanel/NotificationPanel.d.ts +5 -0
  113. package/dist/components/NotificationPanel/index.d.ts +1 -0
  114. package/dist/components/NotificationPanel/index.js +8 -0
  115. package/dist/components/PageHeader/PageHeader.d.ts +5 -0
  116. package/dist/components/PageHeader/PageHeader.jsx +2 -2
  117. package/dist/components/PageHeader/index.d.ts +1 -0
  118. package/dist/components/PageHeader/index.js +8 -0
  119. package/dist/components/PageMetadata/PageMetadata.d.ts +9 -0
  120. package/dist/components/PageMetadata/index.d.ts +1 -0
  121. package/dist/components/PageMetadata/index.js +8 -0
  122. package/dist/components/Pagination/Pagination.d.ts +7 -0
  123. package/dist/components/Pagination/index.d.ts +1 -0
  124. package/dist/components/Pagination/index.js +8 -0
  125. package/dist/components/PhaseBanner/PhaseBanner.d.ts +5 -0
  126. package/dist/components/PhaseBanner/index.d.ts +1 -0
  127. package/dist/components/PhaseBanner/index.js +8 -0
  128. package/dist/components/Question/Question.d.ts +5 -0
  129. package/dist/components/Question/Question.jsx +1 -1
  130. package/dist/components/Question/index.d.ts +1 -0
  131. package/dist/components/Question/index.js +8 -0
  132. package/dist/components/RadioButton/RadioButton.d.ts +5 -0
  133. package/dist/components/RadioButton/RadioGroup.d.ts +6 -0
  134. package/dist/components/RadioButton/RadioGroup.jsx +1 -1
  135. package/dist/components/RadioButton/index.d.ts +2 -0
  136. package/dist/components/RadioButton/index.js +10 -0
  137. package/dist/components/SearchFacets/SearchFacets.d.ts +14 -0
  138. package/dist/components/SearchFacets/SearchFacets.jsx +101 -0
  139. package/dist/components/SearchFacets/index.d.ts +1 -0
  140. package/dist/components/SearchFacets/index.js +8 -0
  141. package/dist/components/SearchFilters/SearchFilters.d.ts +16 -0
  142. package/dist/components/SearchFilters/SearchFilters.jsx +63 -0
  143. package/dist/components/SearchFilters/index.d.ts +1 -0
  144. package/dist/components/SearchFilters/index.js +8 -0
  145. package/dist/components/SearchResult/SearchResult.d.ts +28 -0
  146. package/dist/components/SearchResult/SearchResult.jsx +93 -0
  147. package/dist/components/SearchResult/index.d.ts +1 -0
  148. package/dist/components/SearchResult/index.js +8 -0
  149. package/dist/components/SearchSort/SearchSort.d.ts +10 -0
  150. package/dist/components/SearchSort/SearchSort.jsx +28 -0
  151. package/dist/components/SearchSort/index.d.ts +1 -0
  152. package/dist/components/SearchSort/index.js +8 -0
  153. package/dist/components/Select/Select.d.ts +5 -0
  154. package/dist/components/Select/Select.jsx +1 -1
  155. package/dist/components/Select/index.d.ts +1 -0
  156. package/dist/components/Select/index.js +8 -0
  157. package/dist/components/SequentialNavigation/SequentialNavigation.d.ts +13 -0
  158. package/dist/components/SequentialNavigation/SequentialNavigation.jsx +0 -1
  159. package/dist/components/SequentialNavigation/index.d.ts +1 -0
  160. package/dist/components/SequentialNavigation/index.js +8 -0
  161. package/dist/components/SideNavigation/SideNavigation.d.ts +13 -0
  162. package/dist/components/SideNavigation/SideNavigation.jsx +2 -2
  163. package/dist/components/SideNavigation/index.d.ts +1 -0
  164. package/dist/components/SideNavigation/index.js +8 -0
  165. package/dist/components/SiteFooter/SiteFooter.d.ts +22 -0
  166. package/dist/components/SiteFooter/index.d.ts +1 -0
  167. package/dist/components/SiteFooter/index.js +8 -0
  168. package/dist/components/SiteHeader/SiteHeader.d.ts +22 -0
  169. package/dist/components/SiteHeader/SiteHeader.jsx +1 -2
  170. package/dist/components/SiteHeader/index.d.ts +1 -0
  171. package/dist/components/SiteHeader/index.js +8 -0
  172. package/dist/components/SiteNavigation/SiteNavigation.d.ts +9 -0
  173. package/dist/components/SiteNavigation/index.d.ts +1 -0
  174. package/dist/components/SiteNavigation/index.js +8 -0
  175. package/dist/components/SiteSearch/SiteSearch.d.ts +5 -0
  176. package/dist/components/SiteSearch/SiteSearch.jsx +1 -1
  177. package/dist/components/SiteSearch/index.d.ts +1 -0
  178. package/dist/components/SiteSearch/index.js +8 -0
  179. package/dist/components/SkipLinks/SkipLinks.d.ts +10 -0
  180. package/dist/components/SkipLinks/SkipLinks.jsx +42 -0
  181. package/dist/components/SkipLinks/index.d.ts +1 -0
  182. package/dist/components/SkipLinks/index.js +8 -0
  183. package/dist/components/SummaryCard/SummaryCard.d.ts +10 -0
  184. package/dist/components/SummaryCard/index.d.ts +1 -0
  185. package/dist/components/SummaryCard/index.js +8 -0
  186. package/dist/components/SummaryList/SummaryList.d.ts +18 -0
  187. package/dist/components/SummaryList/index.d.ts +1 -0
  188. package/dist/components/SummaryList/index.js +8 -0
  189. package/dist/components/Table/Table.d.ts +5 -0
  190. package/dist/components/Table/index.d.ts +1 -0
  191. package/dist/components/Table/index.js +8 -0
  192. package/dist/components/Tabs/Tabs.d.ts +10 -0
  193. package/dist/components/Tabs/index.d.ts +1 -0
  194. package/dist/components/Tabs/index.js +8 -0
  195. package/dist/components/Tag/Tag.d.ts +5 -0
  196. package/dist/components/Tag/index.d.ts +1 -0
  197. package/dist/components/Tag/index.js +8 -0
  198. package/dist/components/TaskList/TaskList.d.ts +13 -0
  199. package/dist/components/TaskList/TaskList.jsx +1 -1
  200. package/dist/components/TaskList/index.d.ts +1 -0
  201. package/dist/components/TaskList/index.js +8 -0
  202. package/dist/components/TextInput/TextInput.d.ts +5 -0
  203. package/dist/components/TextInput/TextInput.jsx +2 -2
  204. package/dist/components/TextInput/index.d.ts +1 -0
  205. package/dist/components/TextInput/index.js +8 -0
  206. package/dist/components/Textarea/Textarea.d.ts +5 -0
  207. package/dist/components/Textarea/Textarea.jsx +1 -1
  208. package/dist/components/Textarea/index.d.ts +1 -0
  209. package/dist/components/Textarea/index.js +8 -0
  210. package/dist/components/WarningText/WarningText.d.ts +5 -0
  211. package/dist/components/WarningText/index.d.ts +1 -0
  212. package/dist/components/WarningText/index.js +8 -0
  213. package/dist/components/index.d.ts +46 -0
  214. package/dist/components/index.js +101 -0
  215. package/dist/hooks/index.d.ts +1 -0
  216. package/dist/hooks/index.js +8 -0
  217. package/dist/hooks/useTracking/index.d.ts +1 -0
  218. package/dist/hooks/useTracking/index.js +8 -0
  219. package/dist/hooks/useTracking/useTracking.d.ts +1 -0
  220. package/dist/hooks/useTracking/useTracking.js +21 -0
  221. package/dist/images/documents/audio.d.ts +4 -0
  222. package/dist/images/documents/csv.d.ts +4 -0
  223. package/dist/images/documents/excel.d.ts +4 -0
  224. package/dist/images/documents/file.d.ts +4 -0
  225. package/dist/images/documents/generic.d.ts +4 -0
  226. package/dist/images/documents/geodata.d.ts +4 -0
  227. package/dist/images/documents/ical.d.ts +4 -0
  228. package/dist/images/documents/ico.d.ts +4 -0
  229. package/dist/images/documents/image.d.ts +4 -0
  230. package/dist/images/documents/index.d.ts +22 -0
  231. package/dist/images/documents/odf.d.ts +4 -0
  232. package/dist/images/documents/odg.d.ts +4 -0
  233. package/dist/images/documents/odp.d.ts +4 -0
  234. package/dist/images/documents/ods.d.ts +4 -0
  235. package/dist/images/documents/odt.d.ts +4 -0
  236. package/dist/images/documents/pdf.d.ts +4 -0
  237. package/dist/images/documents/ppt.d.ts +4 -0
  238. package/dist/images/documents/rtf.d.ts +4 -0
  239. package/dist/images/documents/text.d.ts +4 -0
  240. package/dist/images/documents/video.d.ts +4 -0
  241. package/dist/images/documents/word.d.ts +4 -0
  242. package/dist/images/documents/xml.d.ts +4 -0
  243. package/dist/images/documents/zip.d.ts +4 -0
  244. package/dist/images/icons/arrow_upward.d.ts +4 -0
  245. package/dist/images/icons/calendar_today.d.ts +4 -0
  246. package/dist/images/icons/cancel.d.ts +4 -0
  247. package/dist/images/icons/check_circle.d.ts +4 -0
  248. package/dist/images/icons/chevron_left.d.ts +4 -0
  249. package/dist/images/icons/chevron_right.d.ts +4 -0
  250. package/dist/images/icons/close.d.ts +4 -0
  251. package/dist/images/icons/description.d.ts +4 -0
  252. package/dist/images/icons/double_chevron_left.d.ts +4 -0
  253. package/dist/images/icons/double_chevron_right.d.ts +4 -0
  254. package/dist/images/icons/error.d.ts +4 -0
  255. package/dist/images/icons/expand_less.d.ts +4 -0
  256. package/dist/images/icons/expand_more.d.ts +4 -0
  257. package/dist/images/icons/index.d.ts +17 -0
  258. package/dist/images/icons/list.d.ts +4 -0
  259. package/dist/images/icons/menu.d.ts +4 -0
  260. package/dist/images/icons/priority_high.d.ts +4 -0
  261. package/dist/images/icons/search.d.ts +4 -0
  262. package/dist/images/index.d.ts +2 -0
  263. package/dist/images/index.js +38 -0
  264. package/dist/index.d.ts +4 -0
  265. package/dist/index.js +40 -0
  266. package/dist/tsconfig.tsbuildinfo +1 -1
  267. package/dist/utils/context.d.ts +4 -0
  268. package/package.json +25 -23
  269. package/src/common/{AbstractNotificationBanner.test.tsx → AbstractNotificationBanner/AbstractNotificationBanner.test.tsx} +1 -1
  270. package/src/common/{AbstractNotificationBanner.tsx → AbstractNotificationBanner/AbstractNotificationBanner.tsx} +2 -2
  271. package/src/common/AbstractNotificationBanner/index.ts +1 -0
  272. package/src/common/ActionLink/index.ts +1 -0
  273. package/src/common/ConditionalWrapper/index.ts +1 -0
  274. package/src/common/{FileIcon.tsx → FileIcon/FileIcon.tsx} +1 -1
  275. package/src/common/FileIcon/index.ts +1 -0
  276. package/src/common/HintText/index.ts +1 -0
  277. package/src/common/{Icon.tsx → Icon/Icon.tsx} +1 -1
  278. package/src/common/Icon/index.ts +1 -0
  279. package/src/common/ScreenReaderText/index.ts +1 -0
  280. package/src/common/WrapperTag/index.ts +1 -0
  281. package/src/common/index.ts +8 -0
  282. package/src/components/Accordion/Accordion.Item.stories.tsx +10 -9
  283. package/src/components/Accordion/Accordion.stories.tsx +4 -4
  284. package/src/components/Accordion/Accordion.test.tsx +48 -14
  285. package/src/components/Accordion/Accordion.tsx +12 -1
  286. package/src/components/Accordion/index.ts +1 -0
  287. package/src/components/AspectBox/index.ts +1 -0
  288. package/src/components/BackToTop/index.ts +1 -0
  289. package/src/components/Breadcrumbs/Breadcrumbs.Item.stories.tsx +8 -1
  290. package/src/components/Breadcrumbs/index.ts +1 -0
  291. package/src/components/Button/Button.stories.tsx +1 -1
  292. package/src/components/Button/ButtonGroup.stories.tsx +41 -0
  293. package/src/components/Button/ButtonGroup.test.tsx +45 -0
  294. package/src/components/Button/ButtonGroup.tsx +20 -0
  295. package/src/components/Button/index.ts +2 -0
  296. package/src/components/CategoryItem/index.ts +1 -0
  297. package/src/components/CategoryList/CategoryList.stories.tsx +1 -1
  298. package/src/components/CategoryList/CategoryList.test.tsx +1 -1
  299. package/src/components/CategoryList/index.ts +1 -0
  300. package/src/components/Checkbox/index.ts +2 -0
  301. package/src/components/ConfirmationMessage/index.ts +1 -0
  302. package/src/components/ContentsNav/ContentsNav.Item.stories.tsx +8 -0
  303. package/src/components/ContentsNav/index.ts +1 -0
  304. package/src/components/CookieBanner/CookieBanner.Buttons.stories.tsx +1 -1
  305. package/src/components/CookieBanner/CookieBanner.stories.tsx +1 -1
  306. package/src/components/CookieBanner/index.ts +1 -0
  307. package/src/components/DatePicker/DatePicker.tsx +2 -2
  308. package/src/components/DatePicker/index.ts +1 -0
  309. package/src/components/Details/index.ts +1 -0
  310. package/src/components/ErrorMessage/index.ts +1 -0
  311. package/src/components/ErrorSummary/ErrorSummary.Item.stories.tsx +7 -0
  312. package/src/components/ErrorSummary/index.ts +1 -0
  313. package/src/components/FeatureHeader/FeatureHeader.stories.tsx +60 -0
  314. package/src/components/FeatureHeader/FeatureHeader.tsx +94 -0
  315. package/src/components/FeatureHeader/index.ts +1 -0
  316. package/src/components/FileDownload/index.ts +1 -0
  317. package/src/components/HideThisPage/index.ts +1 -0
  318. package/src/components/InsetText/index.ts +1 -0
  319. package/src/components/NotificationBanner/index.ts +1 -0
  320. package/src/components/NotificationPanel/index.ts +1 -0
  321. package/src/components/PageHeader/PageHeader.stories.tsx +1 -1
  322. package/src/components/PageHeader/PageHeader.tsx +2 -1
  323. package/src/components/PageHeader/index.ts +1 -0
  324. package/src/components/PageMetadata/PageMetadata.Item.stories.tsx +9 -0
  325. package/src/components/PageMetadata/index.ts +1 -0
  326. package/src/components/Pagination/index.ts +1 -0
  327. package/src/components/PhaseBanner/index.ts +1 -0
  328. package/src/components/Question/Question.stories.tsx +2 -3
  329. package/src/components/Question/Question.tsx +2 -2
  330. package/src/components/Question/index.ts +1 -0
  331. package/src/components/RadioButton/RadioGroup.stories.tsx +1 -2
  332. package/src/components/RadioButton/RadioGroup.test.tsx +1 -2
  333. package/src/components/RadioButton/RadioGroup.tsx +2 -2
  334. package/src/components/RadioButton/index.ts +2 -0
  335. package/src/components/SearchFacets/SearchFacets.Group.stories.tsx +56 -0
  336. package/src/components/SearchFacets/SearchFacets.Item.stories.tsx +53 -0
  337. package/src/components/SearchFacets/SearchFacets.stories.tsx +38 -0
  338. package/src/components/SearchFacets/SearchFacets.test.tsx +214 -0
  339. package/src/components/SearchFacets/SearchFacets.tsx +99 -0
  340. package/src/components/SearchFacets/index.ts +1 -0
  341. package/src/components/SearchFilters/SearchFilters.Panel.stories.tsx +201 -0
  342. package/src/components/SearchFilters/SearchFilters.stories.tsx +137 -0
  343. package/src/components/SearchFilters/SearchFilters.test.tsx +161 -0
  344. package/src/components/SearchFilters/SearchFilters.tsx +89 -0
  345. package/src/components/SearchFilters/index.ts +1 -0
  346. package/src/components/SearchResult/SearchResult.stories.tsx +111 -0
  347. package/src/components/SearchResult/SearchResult.test.tsx +215 -0
  348. package/src/components/SearchResult/SearchResult.tsx +137 -0
  349. package/src/components/SearchResult/index.ts +1 -0
  350. package/src/components/SearchSort/SearchSort.stories.tsx +32 -0
  351. package/src/components/SearchSort/SearchSort.test.tsx +129 -0
  352. package/src/components/SearchSort/SearchSort.tsx +45 -0
  353. package/src/components/SearchSort/index.ts +1 -0
  354. package/src/components/Select/Select.tsx +1 -1
  355. package/src/components/Select/index.ts +1 -0
  356. package/src/components/SequentialNavigation/SequentialNavigation.Next.stories.tsx +1 -1
  357. package/src/components/SequentialNavigation/SequentialNavigation.Previous.stories.tsx +1 -1
  358. package/src/components/SequentialNavigation/SequentialNavigation.tsx +0 -1
  359. package/src/components/SequentialNavigation/index.ts +1 -0
  360. package/src/components/SideNavigation/SideNavigation.Item.stories.tsx +9 -0
  361. package/src/components/SideNavigation/SideNavigation.List.stories.tsx +7 -0
  362. package/src/components/SideNavigation/SideNavigation.tsx +2 -1
  363. package/src/components/SideNavigation/index.ts +1 -0
  364. package/src/components/SiteFooter/SiteFooter.License.stories.tsx +7 -0
  365. package/src/components/SiteFooter/SiteFooter.Link.stories.tsx +9 -0
  366. package/src/components/SiteFooter/SiteFooter.Org.stories.tsx +7 -0
  367. package/src/components/SiteFooter/index.ts +1 -0
  368. package/src/components/SiteHeader/SiteHeader.stories.tsx +3 -3
  369. package/src/components/SiteHeader/SiteHeader.test.tsx +3 -3
  370. package/src/components/SiteHeader/SiteHeader.tsx +1 -3
  371. package/src/components/SiteHeader/index.ts +1 -0
  372. package/src/components/SiteNavigation/SiteNavigation.Item.stories.tsx +10 -0
  373. package/src/components/SiteNavigation/index.ts +1 -0
  374. package/src/components/SiteSearch/SiteSearch.tsx +1 -1
  375. package/src/components/SiteSearch/index.ts +1 -0
  376. package/src/components/SkipLinks/SkipLinks.Item.stories.tsx +11 -1
  377. package/src/components/SkipLinks/SkipLinks.tsx +10 -0
  378. package/src/components/SkipLinks/index.ts +1 -0
  379. package/src/components/SummaryCard/SummaryCard.Action.stories.tsx +7 -0
  380. package/src/components/SummaryCard/SummaryCard.stories.tsx +8 -1
  381. package/src/components/SummaryCard/SummaryCard.test.tsx +2 -2
  382. package/src/components/SummaryCard/index.ts +1 -0
  383. package/src/components/SummaryList/SummaryList.Item.stories.tsx +15 -0
  384. package/src/components/SummaryList/SummaryList.Value.stories.tsx +5 -2
  385. package/src/components/SummaryList/index.ts +1 -0
  386. package/src/components/Table/index.ts +1 -0
  387. package/src/components/Tabs/Tabs.Item.stories.tsx +4 -1
  388. package/src/components/Tabs/index.ts +1 -0
  389. package/src/components/Tag/index.ts +1 -0
  390. package/src/components/TaskList/TaskList.Group.stories.tsx +9 -0
  391. package/src/components/TaskList/TaskList.Item.stories.tsx +7 -0
  392. package/src/components/TaskList/TaskList.tsx +1 -1
  393. package/src/components/TaskList/index.ts +1 -0
  394. package/src/components/TextInput/TextInput.tsx +2 -2
  395. package/src/components/TextInput/index.ts +1 -0
  396. package/src/components/Textarea/Textarea.tsx +1 -1
  397. package/src/components/Textarea/index.ts +1 -0
  398. package/src/components/WarningText/index.ts +1 -0
  399. package/src/components/index.ts +46 -0
  400. package/src/hooks/index.ts +1 -0
  401. package/src/hooks/useTracking/index.ts +1 -0
  402. package/src/images/index.ts +2 -0
  403. package/src/index.ts +4 -0
  404. package/tsconfig.json +14 -14
  405. package/vite.config.ts +2 -1
  406. /package/src/common/{ActionLink.test.tsx → ActionLink/ActionLink.test.tsx} +0 -0
  407. /package/src/common/{ActionLink.tsx → ActionLink/ActionLink.tsx} +0 -0
  408. /package/src/common/{ConditionalWrapper.test.tsx → ConditionalWrapper/ConditionalWrapper.test.tsx} +0 -0
  409. /package/src/common/{ConditionalWrapper.tsx → ConditionalWrapper/ConditionalWrapper.tsx} +0 -0
  410. /package/src/common/{FileIcon.test.tsx → FileIcon/FileIcon.test.tsx} +0 -0
  411. /package/src/common/{HintText.test.tsx → HintText/HintText.test.tsx} +0 -0
  412. /package/src/common/{HintText.tsx → HintText/HintText.tsx} +0 -0
  413. /package/src/common/{Icon.test.tsx → Icon/Icon.test.tsx} +0 -0
  414. /package/src/common/{ScreenReaderText.test.tsx → ScreenReaderText/ScreenReaderText.test.tsx} +0 -0
  415. /package/src/common/{ScreenReaderText.tsx → ScreenReaderText/ScreenReaderText.tsx} +0 -0
  416. /package/src/common/{WrapperTag.test.tsx → WrapperTag/WrapperTag.test.tsx} +0 -0
  417. /package/src/common/{WrapperTag.tsx → WrapperTag/WrapperTag.tsx} +0 -0
  418. /package/src/hooks/{useTracking.test.tsx → useTracking/useTracking.test.tsx} +0 -0
  419. /package/src/hooks/{useTracking.ts → useTracking/useTracking.ts} +0 -0
@@ -0,0 +1,111 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import SearchResult from './SearchResult';
5
+
6
+ //@ts-ignore
7
+ import coo from '../../../static/images/highland-cow.jpg';
8
+
9
+ const meta = {
10
+ title: 'Components/Search results/Result',
11
+ component: SearchResult,
12
+ argTypes: {
13
+ children: argTypes.children()
14
+ },
15
+ args: {
16
+ title: 'Application incomplete'
17
+ }
18
+ } satisfies Meta<typeof SearchResult>;
19
+
20
+ export default meta;
21
+ type Story = StoryObj<typeof meta>;
22
+
23
+ export const Default: Story = {
24
+ render: (args) => (
25
+ <SearchResult href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
26
+ <SearchResult.Content>
27
+ Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
28
+ </SearchResult.Content>
29
+ </SearchResult>
30
+ )
31
+ };
32
+
33
+ export const Metadata: Story = {
34
+ render: (args) => (
35
+ <SearchResult href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
36
+ <SearchResult.Content>
37
+ Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
38
+ </SearchResult.Content>
39
+ <SearchResult.Meta>
40
+ <SearchResult.MetaItem name="Publication type">
41
+ Statistics
42
+ </SearchResult.MetaItem>
43
+ <SearchResult.MetaItem name="Date">
44
+ 18 June 2024
45
+ </SearchResult.MetaItem>
46
+ </SearchResult.Meta>
47
+ </SearchResult>
48
+ )
49
+ };
50
+
51
+ export const Context: Story = {
52
+ render: (args) => (
53
+ <SearchResult href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
54
+ <SearchResult.Content>
55
+ Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
56
+ </SearchResult.Content>
57
+ <SearchResult.Context title="Part of">
58
+ <SearchResult.ContextItem><a href="#">Environment statistics</a></SearchResult.ContextItem>
59
+ <SearchResult.ContextItem><a href="#">Energy statistics</a></SearchResult.ContextItem>
60
+ </SearchResult.Context>
61
+ </SearchResult>
62
+ )
63
+ };
64
+
65
+ export const Media: Story = {
66
+ render: (args) => (
67
+ <SearchResult href="#foo" title="Application incomplete" {...args}>
68
+ <SearchResult.Content>
69
+ <SearchResult.Media>
70
+ <img src={coo} alt="" />
71
+ </SearchResult.Media>
72
+ Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
73
+ </SearchResult.Content>
74
+ </SearchResult>
75
+ )
76
+ };
77
+
78
+ export const Promoted: Story = {
79
+ render: (args) => (
80
+ <SearchResult isPromoted href="#foo" title="Greenhouse gas statistics 1990-2022" {...args}>
81
+ <SearchResult.Content>
82
+ Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
83
+ </SearchResult.Content>
84
+ </SearchResult>
85
+ )
86
+ };
87
+
88
+ export const KitchenSink: Story = {
89
+ render: (args) => (
90
+ <SearchResult isPromoted href="#foo" title="Application incomplete" {...args}>
91
+ <SearchResult.Content>
92
+ <SearchResult.Media>
93
+ <img src={coo} alt="" />
94
+ </SearchResult.Media>
95
+ Official statistics showing emissions of greenhouse gases in Scotland over the period 1990 to 2022.
96
+ </SearchResult.Content>
97
+ <SearchResult.Meta>
98
+ <SearchResult.MetaItem name="Publication type">
99
+ Statistics
100
+ </SearchResult.MetaItem>
101
+ <SearchResult.MetaItem name="Date">
102
+ 18 June 2024
103
+ </SearchResult.MetaItem>
104
+ </SearchResult.Meta>
105
+ <SearchResult.Context title="Part of">
106
+ <SearchResult.ContextItem><a href="#">Environment statistics</a></SearchResult.ContextItem>
107
+ <SearchResult.ContextItem><a href="#">Energy statistics</a></SearchResult.ContextItem>
108
+ </SearchResult.Context>
109
+ </SearchResult>
110
+ )
111
+ };
@@ -0,0 +1,215 @@
1
+ import { test, expect } from 'vitest';
2
+ import { render, screen, within } from '@testing-library/react';
3
+ import SearchResult from './SearchResult';
4
+
5
+ const RESULT_TITLE = 'My title';
6
+ const RESULT_HREF = '#foo';
7
+ const RESULT_CONTENT = 'My content';
8
+ const META_KEY = 'My meta key';
9
+ const META_VALUE = 'My meta value';
10
+ const CONTEXT_VALUE = 'My context value';
11
+
12
+ test('search result renders correctly', () => {
13
+ render(
14
+ <SearchResult href={RESULT_HREF} title={RESULT_TITLE} data-testid="searchresult">
15
+ <SearchResult.Content>
16
+ {RESULT_CONTENT}
17
+ </SearchResult.Content>
18
+ <SearchResult.Meta>
19
+ <SearchResult.MetaItem name={META_KEY}>
20
+ {META_VALUE}
21
+ </SearchResult.MetaItem>
22
+ </SearchResult.Meta>
23
+ <SearchResult.Context>
24
+ <SearchResult.ContextItem>{CONTEXT_VALUE}</SearchResult.ContextItem>
25
+ </SearchResult.Context>
26
+ </SearchResult>
27
+ );
28
+
29
+ const searchResult = screen.getByTestId('searchresult');
30
+ expect(searchResult).toHaveClass('ds_search-result');
31
+ expect(searchResult).not.toHaveClass('ds_search-result--promoted');
32
+
33
+ const title = screen.getByRole('heading');
34
+ expect(title).toHaveClass('ds_search-result__title');
35
+ expect(title).toHaveTextContent(RESULT_TITLE);
36
+ expect(title?.parentElement).toEqual(searchResult);
37
+
38
+ const link = within(title).getByRole('link');
39
+ expect(link).toHaveClass('ds_search-result__link');
40
+ expect(link).toHaveAttribute('href', RESULT_HREF);
41
+ expect(link.tagName).toBe('A');
42
+
43
+ const content = screen.getByText(RESULT_CONTENT);
44
+ expect(content).toBeInTheDocument();
45
+ expect(content).toHaveClass('ds_search-result__summary');
46
+ expect(content?.previousElementSibling).toEqual(title);
47
+
48
+ const meta = searchResult.querySelector('.ds_metadata');
49
+ expect(meta).toBeInTheDocument();
50
+ expect(meta).toHaveClass('ds_metadata--inline', 'ds_search-result__metadata');
51
+ expect(meta?.previousElementSibling).toEqual(content);
52
+ expect(meta?.tagName).toBe('DL');
53
+
54
+ const metaItem = meta.querySelector('.ds_metadata__item');
55
+ expect(metaItem).toBeInTheDocument();
56
+ expect(metaItem).toHaveClass('ds_metadata__item');
57
+ expect(metaItem?.parentElement).toEqual(meta);
58
+
59
+ const metaTerm = meta.querySelector('dt');
60
+ expect(metaTerm).toBeInTheDocument();
61
+ expect(metaTerm).toHaveClass('ds_metadata__key');
62
+ expect(metaTerm?.textContent).toBe(META_KEY);
63
+ expect(metaTerm?.parentElement).toEqual(metaItem);
64
+
65
+ const metaDesc = meta.querySelector('dd');
66
+ expect(metaDesc).toBeInTheDocument();
67
+ expect(metaDesc).toHaveClass('ds_metadata__value');
68
+ expect(metaDesc?.textContent.trim()).toBe(META_VALUE);
69
+ expect(metaDesc?.parentElement).toEqual(metaItem);
70
+ expect(metaDesc?.previousElementSibling).toEqual(metaTerm);
71
+
72
+ const context = searchResult.querySelector('.ds_search-result__context');
73
+ expect(context).toBeInTheDocument();
74
+ expect(context).toHaveClass('ds_search-result__context');
75
+ expect(context?.tagName).toBe('DL');
76
+ expect(context?.previousElementSibling).toEqual(meta);
77
+
78
+ const contextTitle = context?.querySelector('dt');
79
+ expect(contextTitle).toBeInTheDocument();
80
+ expect(contextTitle).toHaveClass('ds_search-result__context-key');
81
+ expect(contextTitle?.textContent).toBe('Part of:');
82
+ expect(contextTitle?.parentElement).toEqual(context);
83
+
84
+ const contextValue = context?.querySelector('dd');
85
+ expect(contextValue).toBeInTheDocument();
86
+ expect(contextValue).toHaveClass('ds_search-result__context-value');
87
+ expect(contextValue?.textContent).toBe(CONTEXT_VALUE);
88
+ expect(contextValue?.previousElementSibling).toEqual(contextTitle);
89
+ expect(contextValue?.parentElement).toEqual(context);
90
+ });
91
+
92
+ test('promoted search result renders correctly', () => {
93
+ render(
94
+ <SearchResult isPromoted href="#foo" title={RESULT_TITLE} data-testid="searchresult">
95
+ <SearchResult.Content>
96
+ {RESULT_CONTENT}
97
+ </SearchResult.Content>
98
+ </SearchResult>
99
+ );
100
+
101
+ const searchResult = screen.getByTestId('searchresult');
102
+ expect(searchResult).toHaveClass('ds_search-result', 'ds_search-result--promoted');
103
+
104
+ const promotedContent = searchResult.querySelector('.ds_search-result--promoted-content');
105
+ expect(promotedContent).toBeInTheDocument();
106
+ expect(promotedContent?.parentElement).toEqual(searchResult);
107
+ expect(promotedContent?.tagName).toBe('DIV');
108
+
109
+ const promotedTitle = promotedContent?.querySelector('.ds_search-result--promoted-title');
110
+ expect(promotedTitle).toBeInTheDocument();
111
+ expect(promotedTitle?.textContent).toBe('Recommended');
112
+ expect(promotedTitle?.parentElement).toEqual(promotedContent);
113
+
114
+ const title = screen.getByRole('heading');
115
+ expect(title).toHaveClass('ds_search-result__title');
116
+ expect(title).toHaveTextContent(RESULT_TITLE);
117
+ expect(title?.parentElement).toEqual(promotedContent);
118
+
119
+ const content = screen.getByText(RESULT_CONTENT);
120
+ expect(content).toBeInTheDocument();
121
+ expect(content?.previousElementSibling).toEqual(title);
122
+ expect(content?.parentElement).toEqual(promotedContent);
123
+ });
124
+
125
+ test('search result with media renders correctly', () => {
126
+ const IMAGE = <img alt=""/>;
127
+
128
+ render(
129
+ <SearchResult href={RESULT_HREF} title={RESULT_TITLE} data-testid="searchresult">
130
+ <SearchResult.Content>
131
+ <SearchResult.Media>
132
+ {IMAGE}
133
+ </SearchResult.Media>
134
+ {RESULT_CONTENT}
135
+ </SearchResult.Content>
136
+ </SearchResult>
137
+ );
138
+
139
+ const searchResult = screen.getByTestId('searchresult');
140
+ const title = screen.getByRole('heading');
141
+
142
+ const summary = searchResult.querySelector('.ds_search-result__has-media');
143
+ expect(summary).toBeInTheDocument();
144
+ expect(summary?.tagName).toBe('DIV');
145
+ expect(summary?.parentElement).toEqual(searchResult);
146
+ expect(summary?.previousElementSibling).toEqual(title);
147
+
148
+ const mediaWrapper = summary?.querySelector('.ds_search-result__media-wrapper');
149
+ expect(mediaWrapper).toBeInTheDocument();
150
+ expect(mediaWrapper?.parentElement).toEqual(summary);
151
+
152
+ const mediaLink = mediaWrapper?.querySelector('.ds_search-result__media-link');
153
+ expect(mediaLink).toBeInTheDocument();
154
+ expect(mediaLink).toHaveAttribute('aria-hidden', 'true');
155
+ expect(mediaLink).toHaveAttribute('href', RESULT_HREF);
156
+ expect(mediaLink).toHaveAttribute('tabindex', '-1');
157
+ expect(mediaLink?.parentElement).toEqual(mediaWrapper);
158
+ expect(mediaLink?.tagName).toBe('A');
159
+
160
+ const media = summary?.querySelector('.ds_search-result__media');
161
+ expect(media).toBeInTheDocument();
162
+ expect(media).toHaveClass('ds_aspect-box', 'ds_aspect-box--square');
163
+ expect(media?.parentElement).toEqual(mediaLink);
164
+ expect(media?.tagName).toBe('DIV');
165
+
166
+ const img = media?.querySelector('img');
167
+ expect(img).toBeInTheDocument();
168
+ expect(img?.parentElement).toEqual(media);
169
+
170
+ const content = screen.getByText(RESULT_CONTENT);
171
+ expect(content).toBeInTheDocument();
172
+ expect(content).toHaveClass('ds_search-result__summary');
173
+ expect(content?.parentElement).toEqual(summary);
174
+ expect(content?.previousElementSibling).toEqual(mediaWrapper);
175
+ });
176
+
177
+ test('linkComponent is used for title link', () => {
178
+ render(
179
+ <SearchResult href={RESULT_HREF} title={RESULT_TITLE} data-testid="searchresult" linkComponent={
180
+ ({ className, ...props }) => (
181
+ <span role="link" className={className} {...props}/>
182
+ )}>
183
+ <SearchResult.Content>
184
+ {RESULT_CONTENT}
185
+ </SearchResult.Content>
186
+ </SearchResult>
187
+ );
188
+
189
+ const title = screen.getByRole('heading');
190
+
191
+ const link = within(title).getByRole('link');
192
+ expect(link).toHaveClass('ds_search-result__link');
193
+ expect(link).toHaveAttribute('href', RESULT_HREF);
194
+ expect(link.tagName).toBe('SPAN');
195
+ expect(link?.parentElement).toEqual(title);
196
+ expect(link?.previousElementSibling).toBeNull();
197
+ });
198
+
199
+ test('passing additional props', () => {
200
+ render(
201
+ <SearchResult data-test="foo" data-testid="searchresult"/>
202
+ );
203
+
204
+ const searchResult = screen.getByTestId('searchresult');
205
+ expect(searchResult?.dataset.test).toEqual('foo');
206
+ });
207
+
208
+ test('passing additional CSS classes', () => {
209
+ render(
210
+ <SearchResult className="foo" data-testid="searchresult"/>
211
+ );
212
+
213
+ const searchResult = screen.getByTestId('searchresult');
214
+ expect(searchResult).toHaveClass('foo');
215
+ });
@@ -0,0 +1,137 @@
1
+ import { Children, createContext, useContext } from 'react';
2
+ import ConditionalWrapper from '../../common/ConditionalWrapper';
3
+ import AspectBox from '../AspectBox';
4
+ import Metadata from '../PageMetadata';
5
+
6
+ const SearchResultLinkHrefContext = createContext('');
7
+
8
+ const SearchResultContent = ({
9
+ children
10
+ }: SGDS.Component.SearchResult.Content) => {
11
+ const otherChildren: any[] = [];
12
+ let imageChild: React.ReactNode = null;
13
+
14
+ // assign to slots
15
+ Children.forEach(children, (child: React.ReactNode) => {
16
+ const thisChild = child as React.ReactElement<any>;
17
+ if (thisChild && thisChild.type === SearchResultMedia) {
18
+ imageChild = thisChild;
19
+ } else {
20
+ otherChildren.push(thisChild);
21
+ }
22
+ });
23
+
24
+ return (
25
+ imageChild ?
26
+ (<div className="ds_search-result__has-media">
27
+ {imageChild}
28
+ <div className="ds_search-result__summary">{otherChildren}</div>
29
+ </div>)
30
+ :
31
+ (<div className="ds_search-result__summary">
32
+ {otherChildren}
33
+ </div>)
34
+ )
35
+ };
36
+
37
+ const SearchResultContext = ({
38
+ children,
39
+ title = 'Part of'
40
+ }: SGDS.Component.SearchResult.Context) => {
41
+ return (
42
+ <dl className="ds_search-result__context">
43
+ <dt className="ds_search-result__context-key">{title}:</dt>
44
+ {children}
45
+ </dl>
46
+ )
47
+ };
48
+
49
+ const SearchResultContextItem = ({
50
+ children
51
+ }: SGDS.Component.SearchResult.ContextItem) => {
52
+ return (
53
+ <dd className="ds_search-result__context-value">
54
+ {children}
55
+ </dd>
56
+ )
57
+ };
58
+
59
+ const SearchResultMedia = ({
60
+ children
61
+ }: SGDS.Component.SearchResult.Media) => {
62
+ return (
63
+ <div className="ds_search-result__media-wrapper">
64
+ <a className="ds_search-result__media-link" href={useContext(SearchResultLinkHrefContext)} tabIndex={-1} aria-hidden="true">
65
+ <AspectBox className="ds_search-result__media" ratio="1:1">
66
+ {children}
67
+ </AspectBox>
68
+ </a>
69
+ </div>
70
+ )
71
+ };
72
+
73
+ const SearchResultMeta = ({
74
+ children
75
+ }: SGDS.Component.SearchResult.Meta) => {
76
+ return (
77
+ <Metadata className="ds_search-result__metadata" isInline>
78
+ {children}
79
+ </Metadata>
80
+ )
81
+ };
82
+
83
+ const SearchResult = ({
84
+ children,
85
+ href,
86
+ isPromoted,
87
+ linkComponent,
88
+ promotedTitle = 'Recommended',
89
+ title,
90
+ ...props
91
+ }: SGDS.Component.SearchResult) => {
92
+ const LINK_CLASS = 'ds_search-result__link';
93
+
94
+ return (
95
+ <div className={[
96
+ 'ds_search-result',
97
+ isPromoted ? 'ds_search-result--promoted' : ''
98
+ ].join(' ')}
99
+ {...props}
100
+ >
101
+ <ConditionalWrapper
102
+ condition={!!isPromoted}
103
+ wrapper={(children: React.JSX.Element) => <div className="ds_search-result--promoted-content">
104
+ <header className="ds_search-result--promoted-title">{promotedTitle}</header>
105
+ {children}
106
+ </div>}
107
+ >
108
+ <SearchResultLinkHrefContext value={href}>
109
+ <h3 className="ds_search-result__title">
110
+ {linkComponent ?
111
+ linkComponent({ className: LINK_CLASS, children: title, href }) :
112
+ <a className={LINK_CLASS} href={href}>{title}</a>
113
+ }
114
+ </h3>
115
+
116
+ {children}
117
+ </SearchResultLinkHrefContext>
118
+ </ConditionalWrapper>
119
+ </div>
120
+ );
121
+ };
122
+
123
+ SearchResult.Content = SearchResultContent;
124
+ SearchResult.Context = SearchResultContext;
125
+ SearchResult.ContextItem = SearchResultContextItem;
126
+ SearchResult.Media = SearchResultMedia;
127
+ SearchResult.Meta = SearchResultMeta;
128
+ SearchResult.MetaItem = Metadata.Item;
129
+
130
+ SearchResultContent.displayName = 'SearchResult.Content';
131
+ SearchResultContext.displayName = 'SearchResult.Context';
132
+ SearchResultContextItem.displayName = 'SearchResult.ContextItem';
133
+ SearchResultMedia.displayName = 'SearchResult.Media';
134
+ SearchResultMeta.displayName = 'SearchResult.Meta';
135
+ SearchResult.MetaItem.displayName = 'SearchResult.MetaItem';
136
+
137
+ export default SearchResult;
@@ -0,0 +1 @@
1
+ export { default } from './SearchResult';
@@ -0,0 +1,32 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import SearchSort from './SearchSort';
5
+
6
+ const meta = {
7
+ title: 'Components/Search results/Sort',
8
+ component: SearchSort,
9
+ argTypes: {
10
+ children: argTypes.children(),
11
+ id: argTypes.id(),
12
+ label: argTypes.label({ defaultValue: 'Sort by' }),
13
+ onApply: argTypes.onClick({ description: 'Callback function to be called when the Apply sort button is clicked' }),
14
+ },
15
+ args: {
16
+ id: 'sort-by',
17
+ label: 'Sort by'
18
+ }
19
+ } satisfies Meta<typeof SearchSort>;
20
+
21
+ export default meta;
22
+ type Story = StoryObj<typeof meta>;
23
+
24
+ export const Default: Story = {
25
+ render: (args) => (
26
+ <SearchSort {...args}>
27
+ <SearchSort.Option value="relevance">Most relevant</SearchSort.Option>
28
+ <SearchSort.Option value="date">Updated (newest)</SearchSort.Option>
29
+ <SearchSort.Option value="adate">Updated (oldest)</SearchSort.Option>
30
+ </SearchSort>
31
+ )
32
+ };
@@ -0,0 +1,129 @@
1
+ import { test, expect, vi } from 'vitest';
2
+ import { render, screen, within } from '@testing-library/react';
3
+ import SearchSort from './SearchSort';
4
+
5
+ const SELECT_ID = 'sort-by';
6
+ const LABEL_TEXT = 'Sort by';
7
+
8
+ test('renders correctly', () => {
9
+ render(
10
+ <SearchSort data-testid="search-sort">
11
+ </SearchSort>
12
+ );
13
+
14
+ const searchSort = screen.getByTestId('search-sort');
15
+ const select = screen.getByRole('combobox');
16
+ const selectWrapper = select.parentElement;
17
+ const label = selectWrapper?.previousElementSibling;
18
+ const selectArrow = select.nextElementSibling;
19
+ const button = within(searchSort).getByRole('button');
20
+
21
+ expect(select).toHaveClass('ds_select');
22
+ expect(select.id).toEqual(SELECT_ID);
23
+ expect(select).toHaveAttribute('name', SELECT_ID);
24
+
25
+ expect(selectWrapper).toHaveClass('ds_select-wrapper');
26
+ expect(selectWrapper?.tagName).toEqual('DIV');
27
+
28
+ expect(label).toHaveClass('ds_label');
29
+ expect(label).toHaveAttribute('for', SELECT_ID);
30
+ expect(label).toHaveTextContent(LABEL_TEXT);
31
+
32
+ expect(selectArrow).toHaveClass('ds_select-arrow');
33
+ expect(selectArrow).toHaveAttribute('aria-hidden');
34
+ expect(selectArrow?.textContent).toEqual('');
35
+
36
+ expect(searchSort).toBeInTheDocument();
37
+ expect(searchSort).toHaveClass('ds_sort-options');
38
+ expect(searchSort.tagName).toEqual('DIV');
39
+
40
+ expect(button).toHaveClass('ds_button', 'ds_button--small', 'ds_button--secondary');
41
+ expect(button).toHaveTextContent('Apply sort');
42
+ expect(button).toHaveAttribute('type', 'submit');
43
+ expect(button.previousElementSibling).toEqual(selectWrapper);
44
+ });
45
+
46
+ test('custom id and label', () => {
47
+ const CUSTOM_ID = 'custom-sort-by';
48
+ const CUSTOM_LABEL = 'Custom sort by';
49
+
50
+ render(
51
+ <SearchSort id={CUSTOM_ID} label={CUSTOM_LABEL} data-testid="search-sort">
52
+ </SearchSort>
53
+ );
54
+
55
+ const select = screen.getByRole('combobox');
56
+ const selectWrapper = select.parentElement;
57
+ const label = selectWrapper?.previousElementSibling;
58
+
59
+ expect(select.id).toEqual(CUSTOM_ID);
60
+ expect(select).toHaveAttribute('name', CUSTOM_ID);
61
+ expect(label).toHaveAttribute('for', CUSTOM_ID);
62
+ expect(label).toHaveTextContent(CUSTOM_LABEL);
63
+ });
64
+
65
+ test('event handler onApply', async () => {
66
+ const onApply = vi.fn();
67
+ render(
68
+ <SearchSort onApply={onApply} data-testid="search-sort">
69
+ </SearchSort>
70
+ );
71
+
72
+ const button = within(screen.getByTestId('search-sort')).getByRole('button');
73
+ await button.click();
74
+ expect(onApply).toHaveBeenCalled();
75
+ });
76
+
77
+ test('passing additional props', () => {
78
+ render(
79
+ <SearchSort data-test="foo" data-testid="search-sort">
80
+ </SearchSort>
81
+ );
82
+
83
+ const searchSort = screen.getByTestId('search-sort');
84
+ expect(searchSort.dataset.test).toEqual('foo');
85
+ });
86
+
87
+ test('passing additional CSS classes', () => {
88
+ render(
89
+ <SearchSort className="foo" data-testid="search-sort">
90
+ </SearchSort>
91
+ );
92
+
93
+ const searchSort = screen.getByTestId('search-sort');
94
+ expect(searchSort).toHaveClass('foo', 'ds_sort-options');
95
+ });
96
+
97
+ test('renders options correctly', () => {
98
+ const OPTION_VALUE_1 = 'relevance';
99
+ const OPTION_TEXT_1 = 'Most relevant';
100
+ const OPTION_VALUE_2 = 'date';
101
+ const OPTION_TEXT_2 = 'Updated (newest)';
102
+ const OPTION_VALUE_3 = 'adate';
103
+ const OPTION_TEXT_3 = 'Updated (oldest)';
104
+
105
+ render(
106
+ <SearchSort data-testid="search-sort">
107
+ <SearchSort.Option value={OPTION_VALUE_1}>{OPTION_TEXT_1}</SearchSort.Option>
108
+ <SearchSort.Option value={OPTION_VALUE_2}>{OPTION_TEXT_2}</SearchSort.Option>
109
+ <SearchSort.Option value={OPTION_VALUE_3}>{OPTION_TEXT_3}</SearchSort.Option>
110
+ </SearchSort>
111
+ );
112
+
113
+ const select = screen.getByRole('combobox');
114
+ const options = within(select).getAllByRole('option');
115
+
116
+ expect(options).toHaveLength(4);
117
+
118
+ expect(options[0]).toHaveTextContent('');
119
+ expect(options[0]).toHaveAttribute('value', '');
120
+
121
+ expect(options[1]).toHaveTextContent(OPTION_TEXT_1);
122
+ expect(options[1]).toHaveAttribute('value', OPTION_VALUE_1);
123
+
124
+ expect(options[2]).toHaveTextContent(OPTION_TEXT_2);
125
+ expect(options[2]).toHaveAttribute('value', OPTION_VALUE_2);
126
+
127
+ expect(options[3]).toHaveTextContent(OPTION_TEXT_3);
128
+ expect(options[3]).toHaveAttribute('value', OPTION_VALUE_3);
129
+ });
@@ -0,0 +1,45 @@
1
+ import { AllHTMLAttributes } from "react";
2
+ import Button from "../Button";
3
+ import Select from "../Select";
4
+
5
+ const Option = ({
6
+ children,
7
+ value
8
+ }: AllHTMLAttributes<HTMLOptionElement>) => {
9
+ return (
10
+ <option value={value}>
11
+ {children}
12
+ </option>
13
+ );
14
+ }
15
+
16
+ const SearchSort = ({
17
+ children,
18
+ className,
19
+ id = 'sort-by',
20
+ label = 'Sort by',
21
+ onApply,
22
+ ...props
23
+ }: SGDS.Component.SearchSort) => {
24
+ return (
25
+ <div
26
+ className={[
27
+ 'ds_sort-options',
28
+ className
29
+ ].join(' ')}
30
+ {...props}
31
+ >
32
+ <Select id={id} label={label}>
33
+ {children}
34
+ </Select>
35
+
36
+ <Button onClick={onApply} isSmall buttonStyle="secondary" type="submit">Apply sort</Button>
37
+ </div>
38
+ );
39
+ };
40
+
41
+ SearchSort.displayName = 'SearchSort';
42
+ Option.displayName = 'SearchSort.Option';
43
+ SearchSort.Option = Option;
44
+
45
+ export default SearchSort;
@@ -0,0 +1 @@
1
+ export { default } from './SearchSort';
@@ -1,4 +1,4 @@
1
- import ErrorMessage from '../ErrorMessage/ErrorMessage';
1
+ import ErrorMessage from '../ErrorMessage';
2
2
  import HintText from '../../common/HintText';
3
3
 
4
4
  const Select = function ({
@@ -0,0 +1 @@
1
+ export { default } from './Select';