@digigov/ui 0.30.2 → 0.31.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 (313) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/admin/AccessibilityMenu/index.d.ts +13 -0
  3. package/admin/AccessibilityMenu/index.js +170 -0
  4. package/admin/AutoComplete/index.d.ts +2 -2
  5. package/admin/Chip/index.d.ts +1 -0
  6. package/admin/Chip/index.js +14 -0
  7. package/admin/Drawer/__stories__/Default.js +18 -7
  8. package/admin/Dropdown/__stories__/AlignRight.js +0 -2
  9. package/admin/Dropdown/__stories__/Default.js +0 -2
  10. package/admin/Dropdown/__stories__/PlacementTop.js +0 -2
  11. package/admin/FilterSection/index.d.ts +1 -2
  12. package/admin/FilterSection/index.js +4 -18
  13. package/admin/Modal/index.d.ts +2 -2
  14. package/admin/Modal/index.js +17 -12
  15. package/admin/Pagination/__stories__/Default.js +4 -7
  16. package/admin/Pagination/__stories__/PaginationSmall.js +2 -3
  17. package/app/Footer/__stories__/FooterAllInclusive.js +1 -0
  18. package/app/Footer/__stories__/FooterWithSecondaryNavigation.js +1 -0
  19. package/app/Header/__stories__/WithNavigation.js +10 -8
  20. package/app/QrCodeScanner/__stories__/Default.js +3 -3
  21. package/app/QrCodeViewer/QRCode.stories.d.ts +0 -1
  22. package/app/QrCodeViewer/index.d.ts +1 -2
  23. package/app/QrCodeViewer/index.js +10 -10
  24. package/app/ThemeOptionsForm/index.d.ts +2 -0
  25. package/app/ThemeOptionsForm/index.js +243 -0
  26. package/app/ThemePaletteForm/index.d.ts +2 -0
  27. package/app/{ThemeSelectorOptions → ThemePaletteForm}/index.js +9 -8
  28. package/app/index.d.ts +2 -1
  29. package/app/index.js +17 -4
  30. package/core/Accordion/index.d.ts +2 -2
  31. package/core/Accordion/index.js +7 -7
  32. package/core/Divider/__stories__/Default.js +5 -10
  33. package/core/ErrorSummary/__stories__/Default.js +3 -3
  34. package/core/ErrorSummary/__stories__/LinkedToCheckbox.js +3 -3
  35. package/core/ErrorSummary/__stories__/LinkedToField.js +3 -3
  36. package/core/ErrorSummary/__stories__/LinkedToInput.js +3 -3
  37. package/core/Link/__stories__/DarkBackground.js +6 -2
  38. package/core/Link/__stories__/DarkBackgroundNoUnderline.js +6 -2
  39. package/core/NavList/NavList.stories.d.ts +3 -1
  40. package/core/NavList/NavList.stories.js +32 -4
  41. package/core/NavList/NavList.stories.playwright.json +6 -6
  42. package/core/NavList/{NavListAuto.js → NavListAuto/NavListAuto.js} +11 -5
  43. package/core/NavList/{NavListBase.d.ts → NavListAuto/NavListBaseAuto.d.ts} +1 -1
  44. package/core/NavList/{NavListBase.js → NavListAuto/NavListBaseAuto.js} +6 -4
  45. package/core/NavList/{NavListContext.d.ts → NavListAuto/NavListContextAuto.d.ts} +7 -4
  46. package/core/NavList/{NavListContext.js → NavListAuto/NavListContextAuto.js} +23 -11
  47. package/core/NavList/NavListAuto/NavListItemAnchorAuto.d.ts +11 -0
  48. package/core/NavList/{NavListSubMenu.js → NavListAuto/NavListItemAnchorAuto.js} +25 -21
  49. package/core/NavList/{NavListItemAuto.js → NavListAuto/NavListItemAuto.js} +23 -20
  50. package/core/NavList/NavListAuto/NavListItemButtonAuto.d.ts +12 -0
  51. package/core/NavList/NavListAuto/NavListItemButtonAuto.js +50 -0
  52. package/core/NavList/NavListAuto/NavListMenuAuto.d.ts +11 -0
  53. package/core/NavList/NavListAuto/NavListMenuAuto.js +59 -0
  54. package/core/NavList/NavListAuto/NavListSubMenuAuto.d.ts +9 -0
  55. package/core/NavList/NavListAuto/NavListSubMenuAuto.js +46 -0
  56. package/core/NavList/NavListItem.js +6 -5
  57. package/core/NavList/NavListItemBase.d.ts +1 -1
  58. package/core/NavList/NavListItemBase.js +3 -3
  59. package/core/NavList/NavMenuContainerContentList.d.ts +3 -1
  60. package/core/NavList/NavMenuContainerContentList.js +76 -3
  61. package/core/NavList/__stories__/Default.js +19 -6
  62. package/core/NavList/__stories__/NavHorizontalLayout.js +17 -5
  63. package/core/NavList/__stories__/NavListEpathlaExample.js +24 -12
  64. package/core/NavList/__stories__/NavListHorizontalAutoExample.d.ts +2 -0
  65. package/core/NavList/__stories__/NavListHorizontalAutoExample.js +67 -0
  66. package/core/NavList/__stories__/NavListSecondaryAutoExample.d.ts +2 -0
  67. package/core/NavList/__stories__/NavListSecondaryAutoExample.js +281 -0
  68. package/core/NavList/__stories__/NavListVerticalAutoExample.d.ts +2 -0
  69. package/core/NavList/__stories__/NavListVerticalAutoExample.js +67 -0
  70. package/core/NavList/index.d.ts +2 -5
  71. package/core/NavList/index.js +5 -33
  72. package/core/NavList/types.d.ts +20 -10
  73. package/core/Tabs/__stories__/Default.js +5 -5
  74. package/core/Tabs/index.d.ts +2 -2
  75. package/core/Tabs/index.js +5 -7
  76. package/es/admin/AccessibilityMenu/index.js +13 -0
  77. package/es/admin/Chip/index.js +1 -0
  78. package/es/admin/Drawer/__stories__/Default.js +19 -8
  79. package/es/admin/Dropdown/__stories__/AlignRight.js +0 -2
  80. package/es/admin/Dropdown/__stories__/Default.js +0 -2
  81. package/es/admin/Dropdown/__stories__/PlacementTop.js +0 -2
  82. package/es/admin/FilterSection/index.js +1 -2
  83. package/es/admin/Modal/index.js +16 -11
  84. package/es/admin/Pagination/__stories__/Default.js +4 -7
  85. package/es/admin/Pagination/__stories__/PaginationSmall.js +2 -3
  86. package/es/app/Footer/__stories__/FooterAllInclusive.js +1 -0
  87. package/es/app/Footer/__stories__/FooterWithSecondaryNavigation.js +1 -0
  88. package/es/app/Header/__stories__/WithNavigation.js +10 -8
  89. package/es/app/QrCodeScanner/__stories__/Default.js +3 -3
  90. package/es/app/QrCodeViewer/index.js +8 -9
  91. package/es/app/ThemeOptionsForm/index.js +215 -0
  92. package/es/app/{ThemeSelectorOptions → ThemePaletteForm}/index.js +5 -4
  93. package/es/app/index.js +2 -1
  94. package/es/core/Accordion/index.js +7 -7
  95. package/es/core/Divider/__stories__/Default.js +5 -10
  96. package/es/core/ErrorSummary/__stories__/Default.js +3 -3
  97. package/es/core/ErrorSummary/__stories__/LinkedToCheckbox.js +3 -3
  98. package/es/core/ErrorSummary/__stories__/LinkedToField.js +3 -3
  99. package/es/core/ErrorSummary/__stories__/LinkedToInput.js +3 -3
  100. package/es/core/Link/__stories__/DarkBackground.js +6 -2
  101. package/es/core/Link/__stories__/DarkBackgroundNoUnderline.js +6 -2
  102. package/es/core/NavList/NavList.stories.js +3 -1
  103. package/es/core/NavList/NavList.stories.playwright.json +6 -6
  104. package/{esm/core/NavList → es/core/NavList/NavListAuto}/NavListAuto.js +11 -5
  105. package/{esm/core/NavList/NavListBase.js → es/core/NavList/NavListAuto/NavListBaseAuto.js} +4 -2
  106. package/es/core/NavList/{NavListContext.js → NavListAuto/NavListContextAuto.js} +20 -8
  107. package/es/core/NavList/NavListAuto/NavListItemAnchorAuto.js +29 -0
  108. package/es/core/NavList/NavListAuto/NavListItemAuto.js +42 -0
  109. package/es/core/NavList/NavListAuto/NavListItemButtonAuto.js +32 -0
  110. package/es/core/NavList/NavListAuto/NavListMenuAuto.js +39 -0
  111. package/es/core/NavList/NavListAuto/NavListSubMenuAuto.js +28 -0
  112. package/es/core/NavList/NavListItem.js +8 -7
  113. package/es/core/NavList/NavListItemBase.js +3 -3
  114. package/es/core/NavList/NavMenuContainerContentList.js +67 -1
  115. package/es/core/NavList/__stories__/Default.js +19 -6
  116. package/es/core/NavList/__stories__/NavHorizontalLayout.js +17 -5
  117. package/es/core/NavList/__stories__/NavListEpathlaExample.js +24 -12
  118. package/es/core/NavList/__stories__/NavListHorizontalAutoExample.js +51 -0
  119. package/es/core/NavList/__stories__/NavListSecondaryAutoExample.js +255 -0
  120. package/es/core/NavList/__stories__/NavListVerticalAutoExample.js +51 -0
  121. package/es/core/NavList/index.js +2 -5
  122. package/es/core/Tabs/__stories__/Default.js +5 -5
  123. package/es/core/Tabs/index.js +5 -7
  124. package/es/hooks/useFontSize.js +10 -0
  125. package/es/hooks/useHighlightLinks.js +38 -0
  126. package/es/hooks/useLetterSpacing.js +10 -0
  127. package/es/hooks/useLineHeight.js +10 -0
  128. package/es/hooks/useNavList.js +10 -7
  129. package/es/hooks/useTheme.js +19 -11
  130. package/es/hooks/useTogglableNav.js +292 -0
  131. package/es/hooks/{useTogglableSections.js → useTogglableTab.js} +2 -8
  132. package/es/hooks/useVariantVars.js +30 -0
  133. package/es/layouts/Basic/__stories__/Default.js +2 -2
  134. package/es/layouts/Basic/__stories__/MultipleRowsLayout.js +3 -3
  135. package/es/layouts/Basic/__stories__/TwoThirdsOneThirdColumns.js +3 -3
  136. package/es/registry.js +36 -14
  137. package/es/typography/NormalText/__stories__/FontSizes.js +18 -6
  138. package/es/typography/NormalText/__stories__/FontWeight.js +3 -1
  139. package/es/typography/NormalText/__stories__/Variants.js +3 -1
  140. package/esm/admin/AccessibilityMenu/index.js +13 -0
  141. package/esm/admin/Chip/index.js +1 -0
  142. package/esm/admin/Drawer/__stories__/Default.js +19 -8
  143. package/esm/admin/Dropdown/__stories__/AlignRight.js +0 -2
  144. package/esm/admin/Dropdown/__stories__/Default.js +0 -2
  145. package/esm/admin/Dropdown/__stories__/PlacementTop.js +0 -2
  146. package/esm/admin/FilterSection/index.js +1 -2
  147. package/esm/admin/Modal/index.js +16 -11
  148. package/esm/admin/Pagination/__stories__/Default.js +4 -7
  149. package/esm/admin/Pagination/__stories__/PaginationSmall.js +2 -3
  150. package/esm/app/Footer/__stories__/FooterAllInclusive.js +1 -0
  151. package/esm/app/Footer/__stories__/FooterWithSecondaryNavigation.js +1 -0
  152. package/esm/app/Header/__stories__/WithNavigation.js +10 -8
  153. package/esm/app/QrCodeScanner/__stories__/Default.js +3 -3
  154. package/esm/app/QrCodeViewer/index.js +8 -9
  155. package/esm/app/ThemeOptionsForm/index.js +215 -0
  156. package/esm/app/{ThemeSelectorOptions → ThemePaletteForm}/index.js +5 -4
  157. package/esm/app/index.js +2 -1
  158. package/esm/core/Accordion/index.js +7 -7
  159. package/esm/core/Divider/__stories__/Default.js +5 -10
  160. package/esm/core/ErrorSummary/__stories__/Default.js +3 -3
  161. package/esm/core/ErrorSummary/__stories__/LinkedToCheckbox.js +3 -3
  162. package/esm/core/ErrorSummary/__stories__/LinkedToField.js +3 -3
  163. package/esm/core/ErrorSummary/__stories__/LinkedToInput.js +3 -3
  164. package/esm/core/Link/__stories__/DarkBackground.js +6 -2
  165. package/esm/core/Link/__stories__/DarkBackgroundNoUnderline.js +6 -2
  166. package/esm/core/NavList/NavList.stories.js +3 -1
  167. package/esm/core/NavList/NavList.stories.playwright.json +6 -6
  168. package/{es/core/NavList → esm/core/NavList/NavListAuto}/NavListAuto.js +11 -5
  169. package/{es/core/NavList/NavListBase.js → esm/core/NavList/NavListAuto/NavListBaseAuto.js} +4 -2
  170. package/esm/core/NavList/{NavListContext.js → NavListAuto/NavListContextAuto.js} +20 -8
  171. package/esm/core/NavList/NavListAuto/NavListItemAnchorAuto.js +29 -0
  172. package/esm/core/NavList/NavListAuto/NavListItemAuto.js +42 -0
  173. package/esm/core/NavList/NavListAuto/NavListItemButtonAuto.js +32 -0
  174. package/esm/core/NavList/NavListAuto/NavListMenuAuto.js +39 -0
  175. package/esm/core/NavList/NavListAuto/NavListSubMenuAuto.js +28 -0
  176. package/esm/core/NavList/NavListItem.js +8 -7
  177. package/esm/core/NavList/NavListItemBase.js +3 -3
  178. package/esm/core/NavList/NavMenuContainerContentList.js +67 -1
  179. package/esm/core/NavList/__stories__/Default.js +19 -6
  180. package/esm/core/NavList/__stories__/NavHorizontalLayout.js +17 -5
  181. package/esm/core/NavList/__stories__/NavListEpathlaExample.js +24 -12
  182. package/esm/core/NavList/__stories__/NavListHorizontalAutoExample.js +51 -0
  183. package/esm/core/NavList/__stories__/NavListSecondaryAutoExample.js +255 -0
  184. package/esm/core/NavList/__stories__/NavListVerticalAutoExample.js +51 -0
  185. package/esm/core/NavList/index.js +2 -5
  186. package/esm/core/Tabs/__stories__/Default.js +5 -5
  187. package/esm/core/Tabs/index.js +5 -7
  188. package/esm/hooks/useFontSize.js +10 -0
  189. package/esm/hooks/useHighlightLinks.js +38 -0
  190. package/esm/hooks/useLetterSpacing.js +10 -0
  191. package/esm/hooks/useLineHeight.js +10 -0
  192. package/esm/hooks/useNavList.js +10 -7
  193. package/esm/hooks/useTheme.js +19 -11
  194. package/esm/hooks/useTogglableNav.js +292 -0
  195. package/esm/hooks/{useTogglableSections.js → useTogglableTab.js} +2 -8
  196. package/esm/hooks/useVariantVars.js +30 -0
  197. package/esm/index.js +1 -1
  198. package/esm/layouts/Basic/__stories__/Default.js +2 -2
  199. package/esm/layouts/Basic/__stories__/MultipleRowsLayout.js +3 -3
  200. package/esm/layouts/Basic/__stories__/TwoThirdsOneThirdColumns.js +3 -3
  201. package/esm/registry.js +36 -14
  202. package/esm/typography/NormalText/__stories__/FontSizes.js +18 -6
  203. package/esm/typography/NormalText/__stories__/FontWeight.js +3 -1
  204. package/esm/typography/NormalText/__stories__/Variants.js +3 -1
  205. package/hooks/useFontSize.d.ts +6 -0
  206. package/hooks/useFontSize.js +23 -0
  207. package/hooks/useHighlightLinks.d.ts +8 -0
  208. package/hooks/useHighlightLinks.js +52 -0
  209. package/hooks/useLetterSpacing.d.ts +6 -0
  210. package/hooks/useLetterSpacing.js +23 -0
  211. package/hooks/useLineHeight.d.ts +6 -0
  212. package/hooks/useLineHeight.js +23 -0
  213. package/hooks/useNavList.d.ts +2 -2
  214. package/hooks/useNavList.js +11 -8
  215. package/hooks/useTheme.d.ts +4 -4
  216. package/hooks/useTheme.js +19 -12
  217. package/hooks/useTogglableNav.d.ts +25 -0
  218. package/hooks/useTogglableNav.js +305 -0
  219. package/hooks/{useTogglableSections.d.ts → useTogglableTab.d.ts} +4 -3
  220. package/hooks/{useTogglableSections.js → useTogglableTab.js} +3 -9
  221. package/hooks/useVariantVars.d.ts +11 -0
  222. package/hooks/useVariantVars.js +41 -0
  223. package/layouts/Basic/__stories__/Default.js +2 -2
  224. package/layouts/Basic/__stories__/MultipleRowsLayout.js +3 -3
  225. package/layouts/Basic/__stories__/TwoThirdsOneThirdColumns.js +3 -3
  226. package/package.json +3 -3
  227. package/registry.d.ts +18 -7
  228. package/registry.js +49 -16
  229. package/src/admin/AccessibilityMenu/index.tsx +14 -0
  230. package/src/admin/AutoComplete/index.tsx +2 -2
  231. package/src/admin/Chip/index.tsx +1 -0
  232. package/src/admin/Drawer/__stories__/Default.tsx +23 -9
  233. package/src/admin/Dropdown/__stories__/AlignRight.tsx +2 -2
  234. package/src/admin/Dropdown/__stories__/Default.tsx +2 -2
  235. package/src/admin/Dropdown/__stories__/PlacementTop.tsx +2 -2
  236. package/src/admin/FilterSection/index.tsx +1 -2
  237. package/src/admin/Modal/index.tsx +43 -39
  238. package/src/admin/Pagination/__stories__/Default.tsx +4 -4
  239. package/src/admin/Pagination/__stories__/PaginationSmall.tsx +2 -2
  240. package/src/app/Footer/__stories__/FooterAllInclusive.tsx +1 -1
  241. package/src/app/Footer/__stories__/FooterWithSecondaryNavigation.tsx +1 -1
  242. package/src/app/Header/__stories__/WithNavigation.tsx +8 -8
  243. package/src/app/QrCodeScanner/__stories__/Default.tsx +2 -2
  244. package/src/app/QrCodeViewer/index.tsx +16 -14
  245. package/src/app/ThemeOptionsForm/index.tsx +220 -0
  246. package/src/app/{ThemeSelectorOptions → ThemePaletteForm}/index.tsx +3 -3
  247. package/src/app/index.ts +2 -1
  248. package/src/core/Accordion/index.tsx +5 -11
  249. package/src/core/Divider/__stories__/Default.tsx +5 -5
  250. package/src/core/ErrorSummary/__stories__/Default.tsx +2 -2
  251. package/src/core/ErrorSummary/__stories__/LinkedToCheckbox.tsx +2 -2
  252. package/src/core/ErrorSummary/__stories__/LinkedToField.tsx +2 -2
  253. package/src/core/ErrorSummary/__stories__/LinkedToInput.tsx +2 -2
  254. package/src/core/Link/__stories__/DarkBackground.tsx +2 -3
  255. package/src/core/Link/__stories__/DarkBackgroundNoUnderline.tsx +2 -3
  256. package/src/core/NavList/NavList.stories.js +3 -1
  257. package/src/core/NavList/NavList.stories.playwright.json +6 -6
  258. package/src/core/NavList/NavListAuto/NavListAuto.tsx +34 -0
  259. package/src/core/NavList/{NavListBase.tsx → NavListAuto/NavListBaseAuto.tsx} +2 -2
  260. package/src/core/NavList/{NavListContext.tsx → NavListAuto/NavListContextAuto.tsx} +26 -11
  261. package/src/core/NavList/NavListAuto/NavListItemAnchorAuto.tsx +41 -0
  262. package/src/core/NavList/NavListAuto/NavListItemAuto.tsx +51 -0
  263. package/src/core/NavList/NavListAuto/NavListItemButtonAuto.tsx +53 -0
  264. package/src/core/NavList/NavListAuto/NavListMenuAuto.tsx +51 -0
  265. package/src/core/NavList/NavListAuto/NavListSubMenuAuto.tsx +32 -0
  266. package/src/core/NavList/NavListItem.tsx +15 -9
  267. package/src/core/NavList/NavListItemBase.tsx +3 -3
  268. package/src/core/NavList/NavMenuContainerContentList.tsx +63 -1
  269. package/src/core/NavList/__stories__/Default.tsx +23 -8
  270. package/src/core/NavList/__stories__/NavHorizontalLayout.tsx +24 -8
  271. package/src/core/NavList/__stories__/NavListEpathlaExample.tsx +46 -25
  272. package/src/core/NavList/__stories__/NavListHorizontalAutoExample.tsx +65 -0
  273. package/src/core/NavList/__stories__/NavListSecondaryAutoExample.tsx +284 -0
  274. package/src/core/NavList/__stories__/NavListVerticalAutoExample.tsx +65 -0
  275. package/src/core/NavList/index.tsx +2 -5
  276. package/src/core/NavList/types.tsx +23 -9
  277. package/src/core/Tabs/__stories__/Default.tsx +5 -5
  278. package/src/core/Tabs/index.tsx +5 -9
  279. package/src/hooks/useFontSize.ts +32 -0
  280. package/src/hooks/useHighlightLinks.ts +45 -0
  281. package/src/hooks/useLetterSpacing.ts +27 -0
  282. package/src/hooks/useLineHeight.ts +31 -0
  283. package/src/hooks/useNavList.ts +5 -7
  284. package/src/hooks/useTheme.ts +28 -20
  285. package/src/hooks/useTogglableNav.tsx +294 -0
  286. package/src/hooks/{useTogglableSections.tsx → useTogglableTab.tsx} +12 -13
  287. package/src/hooks/useVariantVars.ts +35 -0
  288. package/src/layouts/Basic/__stories__/Default.tsx +3 -3
  289. package/src/layouts/Basic/__stories__/MultipleRowsLayout.tsx +8 -8
  290. package/src/layouts/Basic/__stories__/TwoThirdsOneThirdColumns.tsx +6 -6
  291. package/src/registry.js +36 -14
  292. package/src/typography/NormalText/__stories__/FontSizes.tsx +6 -6
  293. package/src/typography/NormalText/__stories__/FontWeight.tsx +1 -1
  294. package/src/typography/NormalText/__stories__/Variants.tsx +1 -1
  295. package/typography/NormalText/__stories__/FontSizes.js +18 -6
  296. package/typography/NormalText/__stories__/FontWeight.js +3 -1
  297. package/typography/NormalText/__stories__/Variants.js +3 -1
  298. package/app/ThemeSelectorOptions/index.d.ts +0 -2
  299. package/core/NavList/NavListSubMenu.d.ts +0 -8
  300. package/core/NavList/__stories__/NavListAutoExample.d.ts +0 -2
  301. package/core/NavList/__stories__/NavListAutoExample.js +0 -63
  302. package/es/core/NavList/NavListItemAuto.js +0 -40
  303. package/es/core/NavList/NavListSubMenu.js +0 -25
  304. package/es/core/NavList/__stories__/NavListAutoExample.js +0 -48
  305. package/esm/core/NavList/NavListItemAuto.js +0 -40
  306. package/esm/core/NavList/NavListSubMenu.js +0 -25
  307. package/esm/core/NavList/__stories__/NavListAutoExample.js +0 -48
  308. package/src/core/NavList/NavListAuto.tsx +0 -20
  309. package/src/core/NavList/NavListItemAuto.tsx +0 -41
  310. package/src/core/NavList/NavListSubMenu.tsx +0 -28
  311. package/src/core/NavList/__stories__/NavListAutoExample.tsx +0 -53
  312. /package/core/NavList/{NavListAuto.d.ts → NavListAuto/NavListAuto.d.ts} +0 -0
  313. /package/core/NavList/{NavListItemAuto.d.ts → NavListAuto/NavListItemAuto.d.ts} +0 -0
@@ -0,0 +1,32 @@
1
+ import useVariantVars, { UseVariantVarsResult } from "@digigov/ui/hooks/useVariantVars";
2
+
3
+ export type FontSizeOptions = 'default' | 'large';
4
+ export type StoredFontSizeOptions = FontSizeOptions | null;
5
+
6
+ export type UseFontSizeResult = UseVariantVarsResult<FontSizeOptions>
7
+
8
+ export const useFontSize = (): UseFontSizeResult => {
9
+
10
+ const config = {
11
+ 'name': 'font-size',
12
+ 'variables': [
13
+ 'text-sm',
14
+ 'text-base',
15
+ 'text-lg',
16
+ 'text-xl',
17
+ 'text-2xl',
18
+ 'text-3xl',
19
+ 'text-4xl',
20
+ 'text-5xl',
21
+ ],
22
+ 'variants': [
23
+ 'default',
24
+ 'large'
25
+ ]
26
+ }
27
+ return useVariantVars(config);
28
+ };
29
+
30
+
31
+
32
+ export default useFontSize;
@@ -0,0 +1,45 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ export type HighlightLinksOptions = 'default' | 'highlight';
4
+ export type StoredHighlightLinksOptions = HighlightLinksOptions | null;
5
+
6
+ export type UseHighlightLinksResult = [
7
+ highlightLinks: HighlightLinksOptions,
8
+ changeHighlightLinks: (selectedHighlightLinks: HighlightLinksOptions) => void,
9
+ ]
10
+
11
+ export const useHighlightLinks = (): UseHighlightLinksResult => {
12
+ const storedHighlightLinks = localStorage.getItem('--theme-highlight-links') as StoredHighlightLinksOptions;
13
+
14
+ const [highlightLinks, changeHighlightLinks] = useState<HighlightLinksOptions>(
15
+ storedHighlightLinks || 'default'
16
+ );
17
+
18
+ useEffect(() => {
19
+ if (highlightLinks === 'highlight') {
20
+ document.documentElement.classList.add(`govgr-highlight-links`);
21
+ } else {
22
+ document.documentElement.classList.remove(`govgr-highlight-links`);
23
+ }
24
+ localStorage.setItem('--theme-highlight-links', highlightLinks);
25
+ }, [highlightLinks]);
26
+
27
+ useEffect(() => {
28
+ const beforePrintListener = () => {
29
+ document.documentElement.classList.remove(`govgr-highlight-links`);
30
+ };
31
+ const afterPrintListener = () => {
32
+ document.documentElement.classList.add(localStorage.getItem('--theme-highlight-links')=== 'highlight' ? `govgr-highlight-links`: '');
33
+ };
34
+ window.addEventListener('beforeprint', beforePrintListener);
35
+ window.addEventListener('afterprint', afterPrintListener);
36
+ return () => {
37
+ window.removeEventListener('beforeprint', beforePrintListener);
38
+ window.removeEventListener('afterprint', afterPrintListener);
39
+ };
40
+ }, []);
41
+
42
+ return [highlightLinks, changeHighlightLinks ];
43
+ };
44
+
45
+ export default useHighlightLinks;
@@ -0,0 +1,27 @@
1
+ import useVariantVars, { UseVariantVarsResult } from '@digigov/ui/hooks/useVariantVars';
2
+
3
+ export type LetterSpacingOptions = 'default' | 'extra';
4
+ export type StoredLetterSpacingOptions = LetterSpacingOptions | null;
5
+
6
+ export type UseLetterSpacingResult = UseVariantVarsResult<LetterSpacingOptions>
7
+
8
+ export const useLetterSpacing = (): UseLetterSpacingResult => {
9
+
10
+ const config = {
11
+ name: 'letter-spacing',
12
+ variables: [
13
+ "letter-spacing-normal",
14
+ "letter-spacing-wide",
15
+ "letter-spacing-wider",
16
+ "letter-spacing-widest"
17
+ ],
18
+ variants: [
19
+ 'default',
20
+ 'extra'
21
+ ]
22
+ }
23
+
24
+ return useVariantVars(config);
25
+ };
26
+
27
+ export default useLetterSpacing;
@@ -0,0 +1,31 @@
1
+ import useVariantVars, { UseVariantVarsResult } from '@digigov/ui/hooks/useVariantVars';
2
+
3
+ export type LineHeightOptions = 'default' | 'large';
4
+ export type StoredLineHeightOptions = LineHeightOptions | null;
5
+
6
+ export type UseLineHeightResult = UseVariantVarsResult<LineHeightOptions>
7
+
8
+ export const useLineHeight = (): UseLineHeightResult => {
9
+
10
+ const config = {
11
+ name: 'line-height',
12
+ variables: [
13
+ "line-h-sm",
14
+ "line-h-base",
15
+ "line-h-lg",
16
+ "line-h-xl",
17
+ "line-h-2xl",
18
+ "line-h-3xl",
19
+ "line-h-4xl",
20
+ "line-h-5xl"
21
+ ],
22
+ variants: [
23
+ 'default',
24
+ 'large'
25
+ ]
26
+ }
27
+ return useVariantVars(config);
28
+
29
+ };
30
+
31
+ export default useLineHeight;
@@ -1,18 +1,16 @@
1
+ import { useTogglableNav, UseTogglableNavReturn } from '@digigov/ui/hooks/useTogglableNav';
1
2
  import { useCallback, useRef } from 'react';
2
- import {
3
- useTogglableSections,
4
- UseTogglableSectionsReturn,
5
- } from '@digigov/ui/hooks/useTogglableSections';
6
3
 
7
- export interface UseNavListReturn extends UseTogglableSectionsReturn {
4
+ export interface UseNavListReturn extends UseTogglableNavReturn {
8
5
  container: (key: string) => { active: boolean; id: string };
9
6
  }
10
7
  export const useNavList = (): UseNavListReturn => {
11
8
  const registeredContainers = useRef({});
12
9
 
13
- const { register, opened, ...rest } = useTogglableSections({
10
+ const { registerButton, registerLink, opened, ...rest } = useTogglableNav({
14
11
  singleOpen: true,
15
12
  toggleOpenClose: true,
13
+ toggleParentOpen: true,
16
14
  toggleProperty: 'active',
17
15
  onToggleProperty: 'onClick',
18
16
  ariaNavigation: true,
@@ -31,6 +29,6 @@ export const useNavList = (): UseNavListReturn => {
31
29
  },
32
30
  [opened]
33
31
  );
34
- return { register, opened, container, ...rest };
32
+ return { registerButton, registerLink, opened, container, ...rest };
35
33
  };
36
34
 
@@ -3,37 +3,45 @@ import { useState, useEffect } from 'react';
3
3
  export type ThemeSelectOptions = 'light' | 'dark' | 'auto';
4
4
  export type StoredThemeOptions = ThemeSelectOptions | null;
5
5
 
6
- export interface UseThemeResult {
7
- theme: ThemeSelectOptions;
8
- changeTheme: (
9
- selectedTheme:ThemeSelectOptions,
10
- ) => void;
11
- };
6
+ export type UseThemeResult = [
7
+ theme: ThemeSelectOptions,
8
+ changeTheme: (selectedTheme: ThemeSelectOptions) => void,
9
+ ]
12
10
 
13
- export const useTheme = () : UseThemeResult => {
11
+ export const useTheme = (): UseThemeResult => {
14
12
  const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)')
15
13
  .matches;
16
- const storedTheme = localStorage.getItem('theme') as StoredThemeOptions;
17
-
18
- const [theme, changeTheme] = useState<ThemeSelectOptions>(storedTheme || 'auto');
14
+ const storedTheme = localStorage.getItem('--theme-palette') as StoredThemeOptions;
19
15
 
16
+ const [theme, changeTheme] = useState<ThemeSelectOptions>(
17
+ storedTheme || 'auto'
18
+ );
20
19
 
21
- useEffect(() => {
20
+ useEffect(() => {
21
+ document.documentElement.classList.remove('dark', 'light', 'auto');
22
22
  if (theme === 'auto') {
23
- document.documentElement.className = prefersDarkScheme ? 'dark' : 'light';
23
+ document.documentElement.classList.add(prefersDarkScheme ? 'dark' : 'light');
24
24
  } else {
25
- document.documentElement.className = theme;
25
+ document.documentElement.classList.add(theme);
26
26
  }
27
- localStorage.setItem('theme', theme);
27
+ localStorage.setItem('--theme-palette', theme);
28
28
  }, [theme]);
29
29
 
30
30
  useEffect(() => {
31
31
  const beforePrintListener = () => {
32
- document.documentElement.className = 'light';
32
+ document.documentElement.classList.remove('dark');
33
+ document.documentElement.classList.add('light');
34
+
33
35
  };
34
36
  const afterPrintListener = () => {
35
- document.documentElement.className =
36
- localStorage.getItem('theme') || theme;
37
+ document.documentElement.classList.remove('light');
38
+ let localtheme;
39
+ if (localStorage.getItem('--theme-palette') === 'auto') {
40
+ localtheme = prefersDarkScheme ? 'dark' : 'light';
41
+ } else {
42
+ localtheme = localStorage.getItem('--theme-palette');
43
+ }
44
+ document.documentElement.classList.add(localtheme || theme);
37
45
  };
38
46
  window.addEventListener('beforeprint', beforePrintListener);
39
47
  window.addEventListener('afterprint', afterPrintListener);
@@ -43,7 +51,7 @@ useEffect(() => {
43
51
  };
44
52
  }, []);
45
53
 
46
- return {theme, changeTheme};
47
- }
54
+ return [ theme, changeTheme ];
55
+ };
48
56
 
49
- export default useTheme;
57
+ export default useTheme;
@@ -0,0 +1,294 @@
1
+ import { useRef, useState, useCallback, useMemo } from 'react';
2
+
3
+ export interface UseTogglableNavInterface {
4
+ toggleProperty: string;
5
+ singleOpen?: boolean;
6
+ toggleOpenClose?: boolean;
7
+ toggleParentOpen?: boolean;
8
+ onToggleProperty: string;
9
+ initial?: Record<string, boolean>;
10
+ firstOpen?: boolean;
11
+ ariaNavigation?: boolean;
12
+ toggleHook?: (id: string) => void;
13
+ }
14
+
15
+ export interface UseTogglableNavReturn {
16
+ registerButton: (el: string) => any;
17
+ registerLink: (el: string) => any;
18
+ registered: { current: Record<string, { el: HTMLElement; type: string }> };
19
+ opened: Record<string, boolean>;
20
+ toggle: (id: string) => void;
21
+ setOpened: (
22
+ opened:
23
+ | ((curOpened: Record<string, boolean>) => Record<string, boolean>)
24
+ | Record<string, boolean>
25
+ ) => void;
26
+ }
27
+
28
+ export function useTogglableNav({
29
+ toggleProperty,
30
+ toggleOpenClose,
31
+ toggleParentOpen,
32
+ onToggleProperty,
33
+ initial,
34
+ ariaNavigation,
35
+ toggleHook,
36
+ }: UseTogglableNavInterface): UseTogglableNavReturn {
37
+ const [opened, setOpened] = useState(initial || {});
38
+ const registered = useRef<Record<string, { el: HTMLElement; type: string }>>(
39
+ {}
40
+ );
41
+ const openedKeys = useRef<string[]>([]);
42
+
43
+ const registerButtonRef = useCallback((el) => {
44
+ if (!el) return;
45
+ const key = el.getAttribute('aria-controls') as string;
46
+ if (registered.current[key]) return;
47
+ registered.current[key] = {
48
+ el,
49
+ type: 'button',
50
+ };
51
+ }, []);
52
+
53
+ const registerLinkRef = useCallback((el) => {
54
+ if (!el) return;
55
+ const key = el.getAttribute('aria-controls') as string;
56
+ if (registered.current[key]) return;
57
+ registered.current[key] = {
58
+ el,
59
+ type: 'link',
60
+ };
61
+ }, []);
62
+
63
+ const toggle = useCallback((e) => {
64
+ const key = e.currentTarget.getAttribute('aria-controls') as string;
65
+ const selected = ((e.currentTarget.getAttribute(
66
+ 'aria-selected'
67
+ ) as string) === 'true') as boolean;
68
+ if (toggleHook) {
69
+ toggleHook(key);
70
+ }
71
+ e.preventDefault();
72
+ if (toggleOpenClose) {
73
+ if (toggleParentOpen) {
74
+ const items = key.split('__');
75
+ const currentKey = items.slice(0, items.length).join('__');
76
+ const totalKeys = items.map((_, index) => {
77
+ return items.slice(0, index + 1).join('__');
78
+ });
79
+
80
+ if (!selected && !openedKeys.current.includes(currentKey)) {
81
+ openedKeys.current.push(currentKey);
82
+ }
83
+ if (selected && openedKeys.current.includes(currentKey)) {
84
+ openedKeys.current = openedKeys.current.filter(
85
+ (k) => k !== currentKey
86
+ );
87
+ }
88
+
89
+ setOpened((_) => ({
90
+ ...totalKeys.reduce((acc, cur) => {
91
+ acc[cur] = cur === currentKey ? !selected : true;
92
+ return acc;
93
+ }, {}),
94
+ }));
95
+ } else {
96
+ setOpened({ [key]: !selected });
97
+ }
98
+ } else {
99
+ setOpened({ [key]: true });
100
+ }
101
+ }, []);
102
+
103
+ const getMenuItems = (element) => {
104
+ if (element) {
105
+ if (element?.role === 'menuitem') {
106
+ return element;
107
+ } else {
108
+ const childrenArray = Array.from(element?.children);
109
+ let menuItemsArray: any[] = [];
110
+ childrenArray.forEach((child) => {
111
+ const menuItem = getMenuItems(child);
112
+ if (menuItem && !menuItemsArray.includes(menuItem)) {
113
+ menuItemsArray.push(menuItem);
114
+ }
115
+ });
116
+ return menuItemsArray.flatMap((x) => x);
117
+ }
118
+ }
119
+ return null;
120
+ };
121
+
122
+ const findChildren = (parent, items) => {
123
+ return items
124
+ ? items.filter(
125
+ (child) => child.slice(0, child.lastIndexOf('__')) === parent
126
+ )
127
+ : items;
128
+ };
129
+
130
+ const findParent = (child, items) => {
131
+ const parent = child.slice(0, child.lastIndexOf('__'));
132
+ return items.find((item) => item === parent) ? parent : null;
133
+ };
134
+
135
+ const findSiblings = (key, items) => {
136
+ const parent = key.slice(0, key.lastIndexOf('__'));
137
+ if (key.lastIndexOf('__') > 0) {
138
+ return items.filter(
139
+ (child) => child.slice(0, child.lastIndexOf('__')) === parent
140
+ );
141
+ }
142
+ return items.filter((child) => !child.includes('__'));
143
+ };
144
+
145
+ const findLeftSibling = (key, items) => {
146
+ const siblings = findSiblings(key, items);
147
+ if (siblings.length > 0) {
148
+ const keyIndex = siblings.findIndex((item) => item === key);
149
+ return keyIndex > 0 ? siblings[keyIndex - 1] : null;
150
+ }
151
+ return null;
152
+ };
153
+
154
+ const findRightSibling = (key, items) => {
155
+ const siblings = findSiblings(key, items);
156
+ if (siblings.length > 0) {
157
+ const keyIndex = siblings.findIndex((item) => item === key);
158
+ return keyIndex < siblings.length - 1 ? siblings[keyIndex + 1] : null;
159
+ }
160
+ return null;
161
+ };
162
+
163
+ const getOpenItemChildren = (currentItem, items) => {
164
+ const itemChildrenArray: any[] = [];
165
+ const itemChildren = findChildren(currentItem, items);
166
+ itemChildren.forEach((item) => {
167
+ if (openedKeys.current.includes(item)) {
168
+ itemChildrenArray.push(item);
169
+ const internChildren = getOpenItemChildren(item, items);
170
+ if (internChildren.length > 0) {
171
+ itemChildrenArray.push(internChildren);
172
+ }
173
+ } else {
174
+ itemChildrenArray.push(item);
175
+ }
176
+ });
177
+ return itemChildrenArray.flatMap((x) => x);
178
+ };
179
+
180
+ const onKeyDown = useCallback((e) => {
181
+ const orientation = document
182
+ .querySelector(`[aria-orientation]`)
183
+ ?.getAttribute('aria-orientation');
184
+ const key = e.target.getAttribute('aria-controls');
185
+ const keys = Object.entries(registered.current).map(
186
+ ([entryKey, _]) => entryKey
187
+ );
188
+
189
+ const handleArrowRight = () => {
190
+ const arrowRightItem = findRightSibling(key, keys);
191
+ if (arrowRightItem) {
192
+ registered.current[arrowRightItem].el.focus();
193
+ }
194
+ };
195
+
196
+ const handleArrowLeft = () => {
197
+ const arrowLeftItem = findLeftSibling(key, keys);
198
+ if (arrowLeftItem) {
199
+ registered.current[arrowLeftItem].el.focus();
200
+ }
201
+ };
202
+
203
+ switch (e.key) {
204
+ case 'ArrowRight':
205
+ handleArrowRight();
206
+ break;
207
+ case 'ArrowDown':
208
+ const openItem = getOpenItemChildren(key, keys);
209
+ const arrowDownItems = findChildren(key, openItem);
210
+ const menuItems = getMenuItems(document.getElementById(key));
211
+
212
+ if (arrowDownItems.length > 0) {
213
+ registered.current[arrowDownItems[0]].el.focus();
214
+ } else {
215
+ if (orientation === 'vertical') {
216
+ if (
217
+ document.activeElement?.getAttribute('aria-selected') ===
218
+ 'true' &&
219
+ menuItems &&
220
+ menuItems.length > 0
221
+ ) {
222
+ menuItems[0].focus();
223
+ } else {
224
+ handleArrowRight();
225
+ }
226
+ } else {
227
+ if (menuItems && menuItems.length > 0) {
228
+ menuItems[0].focus();
229
+ }
230
+ }
231
+ }
232
+
233
+ break;
234
+ case 'ArrowLeft':
235
+ handleArrowLeft();
236
+ break;
237
+ case 'ArrowUp':
238
+ if (orientation === 'vertical') {
239
+ handleArrowLeft();
240
+ } else {
241
+ const arrowUpItem = findParent(key, keys);
242
+ if (arrowUpItem) {
243
+ registered.current[arrowUpItem].el.focus();
244
+ }
245
+ }
246
+ break;
247
+ case ' ':
248
+ case 'Enter':
249
+ if (registered.current[key].type === 'link') {
250
+ registered.current[key].el.click();
251
+ } else {
252
+ toggle(e);
253
+ }
254
+ break;
255
+ }
256
+ }, []);
257
+
258
+ const registerButton = useCallback(
259
+ (key) => {
260
+ const isOpen = !!opened[key];
261
+ return {
262
+ ref: registerButtonRef,
263
+ [toggleProperty]: isOpen,
264
+ [onToggleProperty]: toggle,
265
+ 'aria-controls': `${key}`,
266
+ ...(ariaNavigation && { onKeyDown }),
267
+ };
268
+ },
269
+ [opened]
270
+ );
271
+
272
+ const registerLink = useCallback(
273
+ (key) => {
274
+ return {
275
+ ref: registerLinkRef,
276
+ 'aria-controls': `${key}`,
277
+ ...(ariaNavigation && { onKeyDown }),
278
+ };
279
+ },
280
+ [opened]
281
+ );
282
+
283
+ return useMemo(
284
+ () => ({
285
+ registerButton,
286
+ registerLink,
287
+ registered,
288
+ opened,
289
+ toggle,
290
+ setOpened,
291
+ }),
292
+ [opened]
293
+ );
294
+ }
@@ -1,17 +1,18 @@
1
1
  /* eslint-disable react-hooks/exhaustive-deps */
2
2
  import { useRef, useState, useCallback, useMemo } from 'react';
3
3
 
4
- export interface UseTogglableSectionsInterface {
4
+ export interface UseTogglableTabInterface {
5
5
  toggleProperty: string;
6
6
  singleOpen?: boolean;
7
7
  toggleOpenClose?: boolean;
8
+ toggleParentOpen?: boolean;
8
9
  onToggleProperty: string;
9
10
  initial?: Record<string, boolean>;
10
11
  firstOpen?: boolean;
11
12
  ariaNavigation?: boolean;
12
13
  toggleHook?: (id: string) => void;
13
14
  }
14
- export interface UseTogglableSectionsReturn {
15
+ export interface UseTogglableTabReturn {
15
16
  register: (el: string) => any;
16
17
  registered: { current: Record<string, HTMLElement> };
17
18
  opened: Record<string, boolean>;
@@ -22,19 +23,20 @@ export interface UseTogglableSectionsReturn {
22
23
  | Record<string, boolean>
23
24
  ) => void;
24
25
  }
25
- export function useTogglableSections({
26
+
27
+ export function useTogglableTab({
26
28
  toggleProperty,
27
29
  singleOpen,
28
- toggleOpenClose,
29
30
  onToggleProperty,
30
31
  initial,
31
32
  firstOpen,
32
33
  ariaNavigation,
33
34
  toggleHook,
34
- }: UseTogglableSectionsInterface): UseTogglableSectionsReturn {
35
+ }: UseTogglableTabInterface): UseTogglableTabReturn {
35
36
  const [opened, setOpened] = useState(initial || {});
36
37
  const registered = useRef<Record<string, HTMLElement>>({});
37
38
  const sectionsOrder = useRef<string[]>([]);
39
+
38
40
  const registerRef = useCallback((el) => {
39
41
  if (!el) return;
40
42
  const key = el.getAttribute('aria-controls') as string;
@@ -47,25 +49,20 @@ export function useTogglableSections({
47
49
  });
48
50
  }
49
51
  }, []);
52
+
50
53
  const toggle = useCallback((e) => {
51
54
  const key = e.currentTarget.getAttribute('aria-controls') as string;
52
- const selected = ((e.currentTarget.getAttribute(
53
- 'aria-selected'
54
- ) as string) === 'true') as boolean;
55
55
  if (toggleHook) {
56
56
  toggleHook(key);
57
57
  }
58
58
  e.preventDefault();
59
59
  if (singleOpen) {
60
- if (toggleOpenClose) {
61
- setOpened({ [key]: !selected });
62
- } else {
63
- setOpened({ [key]: true });
64
- }
60
+ setOpened({ [key]: true });
65
61
  } else {
66
62
  setOpened((prev) => ({ ...prev, [key]: !prev[key] }));
67
63
  }
68
64
  }, []);
65
+
69
66
  const onKeyDown = useCallback((e) => {
70
67
  const key = e.target.getAttribute('aria-controls');
71
68
  const currentIndex = sectionsOrder.current.findIndex((k) => k === key);
@@ -90,6 +87,7 @@ export function useTogglableSections({
90
87
  break;
91
88
  }
92
89
  }, []);
90
+
93
91
  const register = useCallback(
94
92
  (key) => {
95
93
  const isOpen = !!opened[key];
@@ -103,6 +101,7 @@ export function useTogglableSections({
103
101
  },
104
102
  [opened]
105
103
  );
104
+
106
105
  return useMemo(
107
106
  () => ({
108
107
  register,
@@ -0,0 +1,35 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ export interface VariantVarsOptions {
4
+ name: string;
5
+ variables: string[];
6
+ variants: string[];
7
+ }
8
+
9
+ export type UseVariantVarsResult<T> = [
10
+ value: T,
11
+ changeValue: (value: T) => void
12
+ ];
13
+
14
+ function useVariantVars({
15
+ name,
16
+ variables,
17
+ variants,
18
+ }: VariantVarsOptions): UseVariantVarsResult<any> {
19
+ const root = document.documentElement;
20
+ const storedValue = localStorage.getItem(`--theme-${name}`);
21
+ const [value, setValue] = useState(storedValue || variants[0]);
22
+
23
+ useEffect(() => {
24
+ localStorage.setItem(`--theme-${name}`, value);
25
+ variables.forEach((varName) => {
26
+ root.style.setProperty(`--${varName}`, `var(--${varName}-${value})`);
27
+ });
28
+ }, [value]);
29
+ function changeValue(v: string) {
30
+ setValue(v);
31
+ }
32
+ return [value, changeValue];
33
+ }
34
+
35
+ export default useVariantVars;
@@ -1,18 +1,18 @@
1
1
  import React from 'react';
2
2
  import { Layout } from '@digigov/ui/layouts/Basic';
3
- import { Content } from '@digigov/ui/layouts/Basic/Content';
3
+ import { Container } from '@digigov/ui/layouts/Basic/Container';
4
4
  import { Main } from '@digigov/ui/layouts/Basic/Main';
5
5
  import { Heading, Paragraph } from '@digigov/ui/typography';
6
6
  export const Default = () => (
7
7
  <Layout>
8
- <Content>
8
+ <Container>
9
9
  <Main>
10
10
  <Heading>Two-thirds column</Heading>
11
11
  <Paragraph>
12
12
  This is a paragraph inside a two-thirds wide column
13
13
  </Paragraph>
14
14
  </Main>
15
- </Content>
15
+ </Container>
16
16
  </Layout>
17
17
  );
18
18