uikit-react-public 0.17.4 → 0.21.9

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 (282) hide show
  1. package/README.md +2 -4
  2. package/dist/components/Accordion/Accordion.Heading.d.ts +1 -0
  3. package/dist/components/AppHeader/AppHeader.d.ts +1 -1
  4. package/dist/components/AppHeader/AppHeaderBottom.d.ts +1 -1
  5. package/dist/components/AppHeader/AppHeaderNav.d.ts +1 -1
  6. package/dist/components/AppHeader/AppHeaderTop.d.ts +1 -1
  7. package/dist/components/Breadcrumbs/Breadcrumb.d.ts +3 -4
  8. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +1 -1
  9. package/dist/components/Breadcrumbs/Breadcrumbs.stories.d.ts +1 -1
  10. package/dist/components/Button/Button.d.ts +7 -3
  11. package/dist/components/Button/Button.stories.d.ts +17 -7
  12. package/dist/components/Button/style/buttonAccentStyle.d.ts +4 -0
  13. package/dist/components/Button/style/buttonPrimaryDestructiveStyle.d.ts +4 -0
  14. package/dist/components/Button/style/buttonPrimaryStyle.d.ts +4 -0
  15. package/dist/components/Button/style/buttonPrimarySubtleStyle.d.ts +4 -0
  16. package/dist/components/Button/style/buttonPrimaryWarningStyle.d.ts +4 -0
  17. package/dist/components/Button/style/buttonSecondaryDestructiveStyle.d.ts +4 -0
  18. package/dist/components/Button/style/buttonSecondaryStyle.d.ts +4 -0
  19. package/dist/components/Button/style/buttonSecondarySubtleStyle.d.ts +4 -0
  20. package/dist/components/Button/style/buttonTertiaryDestructiveStyle.d.ts +4 -0
  21. package/dist/components/Button/style/buttonTertiaryNoPaddingStyle.d.ts +4 -0
  22. package/dist/components/Button/style/buttonTertiaryStyle.d.ts +4 -0
  23. package/dist/components/Checkbox/Checkbox.d.ts +1 -0
  24. package/dist/components/FooterNew/BackToTop.d.ts +8 -0
  25. package/dist/components/FooterNew/Footer.d.ts +23 -0
  26. package/dist/components/FooterNew/FooterColumn.d.ts +8 -0
  27. package/dist/components/FooterNew/FooterLinks.d.ts +7 -0
  28. package/dist/components/FooterNew/FooterNavLink.d.ts +8 -0
  29. package/dist/components/FooterNew/LegalAndCopyright.d.ts +14 -0
  30. package/dist/components/FooterNew/LogoAddressAndSocial.d.ts +10 -0
  31. package/dist/components/FooterNew/SocialLink.d.ts +8 -0
  32. package/dist/components/FooterNew/__tests__/Footer.test.d.ts +1 -0
  33. package/dist/components/FooterNew/index.d.ts +2 -0
  34. package/dist/components/HeaderNew/Header.d.ts +18 -0
  35. package/dist/components/HeaderNew/HeaderBorder.d.ts +7 -0
  36. package/dist/components/HeaderNew/HeaderLogo.d.ts +9 -0
  37. package/dist/components/HeaderNew/HeaderMenuContainer.d.ts +7 -0
  38. package/dist/components/HeaderNew/HeaderTitle.d.ts +9 -0
  39. package/dist/components/HeaderNew/__tests__/Header.test.d.ts +1 -0
  40. package/dist/components/HeaderNew/constants.d.ts +3 -0
  41. package/dist/components/HeaderNew/index.d.ts +3 -0
  42. package/dist/components/Heading/Heading.d.ts +6 -4
  43. package/dist/components/Heading/Heading.stories.d.ts +8 -6
  44. package/dist/components/Icon/svgImports.d.ts +7 -881
  45. package/dist/components/Link/BaseLink.d.ts +14 -5
  46. package/dist/components/Link/Link.d.ts +8 -3
  47. package/dist/components/Link/Link.stories.d.ts +3 -1
  48. package/dist/components/MenuNew/Menu.context.d.ts +14 -0
  49. package/dist/components/MenuNew/Menu.d.ts +20 -0
  50. package/dist/components/MenuNew/MenuContent.d.ts +9 -0
  51. package/dist/components/MenuNew/MenuItem.d.ts +10 -0
  52. package/dist/components/MenuNew/MenuSection.d.ts +7 -0
  53. package/dist/components/MenuNew/index.d.ts +6 -0
  54. package/dist/components/MenuNew/trigger/ButtonMenuTrigger.d.ts +8 -0
  55. package/dist/components/MenuNew/trigger/IconMenuTrigger.d.ts +8 -0
  56. package/dist/components/Overlay/Overlay.stories.d.ts +12 -12
  57. package/dist/components/Paragraph/Paragraph.d.ts +5 -2
  58. package/dist/components/Paragraph/Paragraph.stories.d.ts +6 -3
  59. package/dist/components/Select/Select.d.ts +2 -1
  60. package/dist/components/Select/Select.stories.d.ts +13 -1
  61. package/dist/components/Select/Select.types.d.ts +40 -13
  62. package/dist/components/Select/subcomponents/CustomSelect.d.ts +3 -3
  63. package/dist/components/Select/subcomponents/FilterInput.d.ts +3 -1
  64. package/dist/components/Select/subcomponents/NativeSelect.d.ts +2 -2
  65. package/dist/components/Select/subcomponents/VisibleField.d.ts +4 -1
  66. package/dist/components/Spinner/Spinner.d.ts +2 -0
  67. package/dist/components/StandaloneLink/StandaloneLink.d.ts +8 -5
  68. package/dist/components/StandaloneLink/StandaloneLink.stories.d.ts +3 -1
  69. package/dist/components/Table/Table.d.ts +3 -3
  70. package/dist/components/Table/Table.stories.d.ts +3 -3
  71. package/dist/components/Table/Table.types.d.ts +1 -0
  72. package/dist/components/Table/subcomponents/Cell/Cell.d.ts +5 -1
  73. package/dist/components/Table/subcomponents/Cell/Cell.stories.d.ts +15 -13
  74. package/dist/components/Table/subcomponents/Cell/CellContent.d.ts +5 -1
  75. package/dist/components/Table/subcomponents/HeadCell/HeadCell.d.ts +2 -1
  76. package/dist/components/Table/subcomponents/HeadCell/HeadCell.stories.d.ts +14 -13
  77. package/dist/components/Table/subcomponents/HeadCell/HeadCellContent.d.ts +2 -1
  78. package/dist/components/Table/subcomponents/__tests__/Row.test.d.ts +1 -0
  79. package/dist/components/UclLogoNew/UclLogo.d.ts +8 -0
  80. package/dist/components/UclLogoNew/index.d.ts +2 -0
  81. package/dist/components/index.d.ts +12 -0
  82. package/dist/index.js +20104 -15317
  83. package/dist/theme/__tests__/fonts.test.d.ts +1 -0
  84. package/dist/theme/common/themeCommon.d.ts +904 -0
  85. package/dist/theme/fonts.d.ts +18 -0
  86. package/dist/theme/index.d.ts +6 -3
  87. package/dist/theme/light/lightColour.d.ts +126 -0
  88. package/dist/theme/light/lightTheme.d.ts +3 -0
  89. package/dist/theme/original/color.d.ts +166 -0
  90. package/dist/theme/original/defaultTheme.d.ts +1340 -0
  91. package/dist/theme/original/originalColourNewStructure.d.ts +126 -0
  92. package/dist/theme/useTheme.d.ts +2174 -0
  93. package/dist/utils/addAlphaToHex.d.ts +5 -0
  94. package/dist/utils/scrollToTop.d.ts +2 -0
  95. package/lib/components/Accordion/Accordion.Heading.tsx +51 -39
  96. package/lib/components/Accordion/Accordion.Panel.tsx +0 -4
  97. package/lib/components/Accordion/Accordion.tsx +34 -28
  98. package/lib/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap +12 -10
  99. package/lib/components/Alert/Alert.tsx +12 -12
  100. package/lib/components/Alert/__tests__/__snapshots__/Alert.test.tsx.snap +13 -39
  101. package/lib/components/AppHeader/AppHeader.tsx +6 -11
  102. package/lib/components/AppHeader/AppHeaderBottom.tsx +2 -3
  103. package/lib/components/AppHeader/AppHeaderNav.tsx +2 -3
  104. package/lib/components/AppHeader/AppHeaderTop.tsx +1 -1
  105. package/lib/components/AppHeader/__tests__/__snapshots__/AppHeader.test.tsx.snap +2 -2
  106. package/lib/components/AppMenu/__tests__/__snapshots__/AppMenu.test.tsx.snap +6 -19
  107. package/lib/components/Badge/Badge.stories.tsx +1 -1
  108. package/lib/components/Breadcrumbs/Breadcrumb.tsx +26 -12
  109. package/lib/components/Breadcrumbs/Breadcrumbs.tsx +1 -1
  110. package/lib/components/Breadcrumbs/__tests__/Breadcrumbs.test.tsx +9 -27
  111. package/lib/components/Breadcrumbs/__tests__/__snapshots__/Breadcrumbs.test.tsx.snap +24 -20
  112. package/lib/components/Button/Button.mdx +32 -279
  113. package/lib/components/Button/Button.stories.tsx +43 -50
  114. package/lib/components/Button/Button.tsx +165 -25
  115. package/lib/components/Button/__tests__/Button.test.tsx +49 -15
  116. package/lib/components/Button/__tests__/__snapshots__/Button.test.tsx.snap +80 -73
  117. package/lib/components/Button/style/buttonAccentStyle.ts +53 -0
  118. package/lib/components/Button/style/buttonPrimaryDestructiveStyle.ts +55 -0
  119. package/lib/components/Button/style/buttonPrimaryStyle.ts +53 -0
  120. package/lib/components/Button/style/buttonPrimarySubtleStyle.ts +64 -0
  121. package/lib/components/Button/style/buttonPrimaryWarningStyle.ts +56 -0
  122. package/lib/components/Button/style/buttonSecondaryDestructiveStyle.ts +63 -0
  123. package/lib/components/Button/style/buttonSecondaryStyle.ts +62 -0
  124. package/lib/components/Button/style/buttonSecondarySubtleStyle.ts +72 -0
  125. package/lib/components/Button/style/buttonTertiaryDestructiveStyle.ts +65 -0
  126. package/lib/components/Button/style/buttonTertiaryNoPaddingStyle.ts +52 -0
  127. package/lib/components/Button/style/buttonTertiaryStyle.ts +62 -0
  128. package/lib/components/Calendar/Calendar.stories.tsx +33 -13
  129. package/lib/components/Calendar/Calendar.tsx +2 -2
  130. package/lib/components/Calendar/__tests__/__snapshots__/Calendar.test.tsx.snap +99 -95
  131. package/lib/components/Calendar/subcomponents/AcademicWeek.tsx +2 -1
  132. package/lib/components/Calendar/subcomponents/AcademicWeeks.tsx +2 -3
  133. package/lib/components/Calendar/subcomponents/ColumnHeading.tsx +3 -7
  134. package/lib/components/Calendar/subcomponents/Controls.tsx +1 -1
  135. package/lib/components/Calendar/subcomponents/Day.stories.tsx +1 -1
  136. package/lib/components/Calendar/subcomponents/Day.tsx +7 -9
  137. package/lib/components/Calendar/subcomponents/EventDot.tsx +4 -8
  138. package/lib/components/Checkbox/Checkbox.stories.tsx +1 -1
  139. package/lib/components/Checkbox/Checkbox.tsx +12 -10
  140. package/lib/components/Checkbox/__tests__/Checkbox.test.tsx +29 -0
  141. package/lib/components/Checkbox/__tests__/__snapshots__/Checkbox.test.tsx.snap +4 -4
  142. package/lib/components/Datepicker/__tests__/Datepicker.test.tsx +117 -0
  143. package/lib/components/Datepicker/__tests__/__snapshots__/Datepicker.test.tsx.snap +16 -44
  144. package/lib/components/Datepicker/subcomponents/CustomDatepicker.tsx +10 -1
  145. package/lib/components/Datepicker/subcomponents/VisibleField.tsx +24 -23
  146. package/lib/components/Dialog/BaseDialog.tsx +2 -2
  147. package/lib/components/Dialog/Dialog.stories.tsx +1 -1
  148. package/lib/components/Divider/__tests__/__snapshots__/Breadcrumbs.test.tsx.snap +12 -12
  149. package/lib/components/FeedbackDialog/FeedbackDialog.stories.tsx +1 -1
  150. package/lib/components/FeedbackDialog/FeedbackDialog.tsx +4 -6
  151. package/lib/components/Field/CharacterCount.tsx +2 -2
  152. package/lib/components/Field/ErrorText.tsx +1 -1
  153. package/lib/components/Field/Field.tsx +1 -1
  154. package/lib/components/Field/HelperText.tsx +3 -1
  155. package/lib/components/FileInput/FileInput.stories.tsx +1 -1
  156. package/lib/components/FileInput/__tests__/__snapshots__/FileInput.test.tsx.snap +4 -20
  157. package/lib/components/Footer/__tests__/__snapshots__/Footer.test.tsx.snap +70 -79
  158. package/lib/components/FooterNew/BackToTop.tsx +83 -0
  159. package/lib/components/FooterNew/Footer.tsx +110 -0
  160. package/lib/components/FooterNew/FooterColumn.tsx +79 -0
  161. package/lib/components/FooterNew/FooterLinks.tsx +44 -0
  162. package/lib/components/FooterNew/FooterNavLink.tsx +63 -0
  163. package/lib/components/FooterNew/LegalAndCopyright.tsx +150 -0
  164. package/lib/components/FooterNew/LogoAddressAndSocial.tsx +154 -0
  165. package/lib/components/FooterNew/SocialLink.tsx +108 -0
  166. package/lib/components/FooterNew/__tests__/Footer.test.tsx +51 -0
  167. package/lib/components/FooterNew/__tests__/__snapshots__/Footer.test.tsx.snap +1107 -0
  168. package/lib/components/FooterNew/index.ts +2 -0
  169. package/lib/components/HeaderDraft/__tests__/__snapshots__/Header.test.tsx.snap +3 -2
  170. package/lib/components/HeaderNew/Header.tsx +93 -0
  171. package/lib/components/HeaderNew/HeaderBorder.tsx +55 -0
  172. package/lib/components/HeaderNew/HeaderLogo.tsx +70 -0
  173. package/lib/components/HeaderNew/HeaderMenuContainer.tsx +35 -0
  174. package/lib/components/HeaderNew/HeaderTitle.tsx +53 -0
  175. package/lib/components/HeaderNew/__tests__/Header.test.tsx +42 -0
  176. package/lib/components/HeaderNew/__tests__/__snapshots__/Header.test.tsx.snap +79 -0
  177. package/lib/components/HeaderNew/constants.ts +3 -0
  178. package/lib/components/HeaderNew/index.ts +7 -0
  179. package/lib/components/Heading/Heading.stories.tsx +34 -41
  180. package/lib/components/Heading/Heading.tsx +180 -49
  181. package/lib/components/Heading/__tests__/__snapshots__/Heading.test.tsx.snap +4 -4
  182. package/lib/components/Icon/__tests__/__snapshots__/Icon.test.tsx.snap +16 -12
  183. package/lib/components/Icon/svgImports.ts +318 -296
  184. package/lib/components/IconButton/IconButton.tsx +3 -4
  185. package/lib/components/IconButton/__tests__/__snapshots__/IconButton.test.tsx.snap +12 -9
  186. package/lib/components/Link/BaseLink.tsx +114 -71
  187. package/lib/components/Link/Link.stories.tsx +1 -1
  188. package/lib/components/Link/Link.tsx +120 -109
  189. package/lib/components/Link/__tests__/__snapshots__/link.test.tsx.snap +2 -2
  190. package/lib/components/MenuNew/Menu.context.tsx +149 -0
  191. package/lib/components/MenuNew/Menu.tsx +75 -0
  192. package/lib/components/MenuNew/MenuContent.tsx +140 -0
  193. package/lib/components/MenuNew/MenuItem.tsx +101 -0
  194. package/lib/components/MenuNew/MenuSection.tsx +47 -0
  195. package/lib/components/MenuNew/index.ts +8 -0
  196. package/lib/components/MenuNew/trigger/ButtonMenuTrigger.tsx +42 -0
  197. package/lib/components/MenuNew/trigger/IconMenuTrigger.tsx +40 -0
  198. package/lib/components/Pagination/Pagination.stories.tsx +1 -1
  199. package/lib/components/Pagination/PaginationControls.tsx +4 -5
  200. package/lib/components/Pagination/PaginationInfo.tsx +2 -3
  201. package/lib/components/Paragraph/Paragraph.stories.tsx +29 -27
  202. package/lib/components/Paragraph/Paragraph.tsx +212 -81
  203. package/lib/components/Paragraph/__tests__/__snapshots__/Paragraph.test.tsx.snap +5 -5
  204. package/lib/components/Radio/Radio.stories.tsx +1 -1
  205. package/lib/components/Radio/Radio.tsx +8 -8
  206. package/lib/components/Radio/__tests__/__snapshots__/Radio.test.tsx.snap +4 -4
  207. package/lib/components/Search/__tests__/__snapshots__/Search.test.tsx.snap +12 -32
  208. package/lib/components/Select/Select.mdx +23 -0
  209. package/lib/components/Select/Select.stories.tsx +43 -10
  210. package/lib/components/Select/Select.tsx +14 -3
  211. package/lib/components/Select/Select.types.ts +53 -16
  212. package/lib/components/Select/__tests__/Select.test.tsx +250 -1
  213. package/lib/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +5 -4
  214. package/lib/components/Select/subcomponents/CustomOption.tsx +10 -3
  215. package/lib/components/Select/subcomponents/CustomSelect.tsx +110 -10
  216. package/lib/components/Select/subcomponents/FilterInput.tsx +13 -3
  217. package/lib/components/Select/subcomponents/NativeSelect.tsx +10 -18
  218. package/lib/components/Select/subcomponents/Panel.tsx +2 -2
  219. package/lib/components/Select/subcomponents/VisibleField.tsx +48 -3
  220. package/lib/components/Snackbar/__tests__/__snapshots__/Snackbar.test.tsx.snap +9 -15
  221. package/lib/components/Spinner/Spinner.tsx +24 -5
  222. package/lib/components/Spinner/__tests__/Spinner.test.tsx +35 -5
  223. package/lib/components/Spinner/__tests__/__snapshots__/Spinner.test.tsx.snap +40 -16
  224. package/lib/components/StandaloneLink/StandaloneLink.stories.tsx +1 -1
  225. package/lib/components/StandaloneLink/StandaloneLink.tsx +180 -163
  226. package/lib/components/StandaloneLink/__tests__/__snapshots__/StandaloneLink.test.tsx.snap +2 -2
  227. package/lib/components/Table/Table.stories.tsx +1 -1
  228. package/lib/components/Table/Table.tsx +2 -0
  229. package/lib/components/Table/Table.types.ts +1 -0
  230. package/lib/components/Table/__tests__/Table.test.tsx +19 -0
  231. package/lib/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +7 -3
  232. package/lib/components/Table/subcomponents/Cell/Cell.stories.tsx +1 -1
  233. package/lib/components/Table/subcomponents/Cell/Cell.tsx +23 -2
  234. package/lib/components/Table/subcomponents/Cell/CellContent.tsx +12 -1
  235. package/lib/components/Table/subcomponents/Cell/__tests__/Cell.test.tsx +106 -0
  236. package/lib/components/Table/subcomponents/Cell/__tests__/__snapshots__/Cell.test.tsx.snap +4 -3
  237. package/lib/components/Table/subcomponents/HeadCell/HeadCell.stories.tsx +1 -1
  238. package/lib/components/Table/subcomponents/HeadCell/HeadCell.tsx +28 -6
  239. package/lib/components/Table/subcomponents/HeadCell/HeadCellContent.tsx +3 -0
  240. package/lib/components/Table/subcomponents/HeadCell/__tests__/HeadCell.test.tsx +221 -2
  241. package/lib/components/Table/subcomponents/HeadCell/__tests__/__snapshots__/HeadCell.test.tsx.snap +6 -4
  242. package/lib/components/Table/subcomponents/Row.tsx +2 -2
  243. package/lib/components/Table/subcomponents/SortIcon.tsx +1 -0
  244. package/lib/components/Table/subcomponents/__tests__/Row.test.tsx +59 -0
  245. package/lib/components/Tabs/Tab.tsx +3 -3
  246. package/lib/components/Tabs/Tabs.stories.tsx +1 -1
  247. package/lib/components/Tabs/Tabs.tsx +5 -3
  248. package/lib/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap +4 -4
  249. package/lib/components/Timepicker/Timepicker.stories.tsx +1 -1
  250. package/lib/components/Toggle/Toggle.tsx +5 -5
  251. package/lib/components/Toggle/ToggleHandle.tsx +2 -3
  252. package/lib/components/Tooltip/Tooltip.tsx +2 -2
  253. package/lib/components/Tooltip/__tests__/__snapshots__/tooltip.test.tsx.snap +2 -2
  254. package/lib/components/UclLogoNew/UclLogo.tsx +42 -0
  255. package/lib/components/UclLogoNew/index.ts +2 -0
  256. package/lib/components/WeekPicker/WeekPicker.stories.tsx +3 -5
  257. package/lib/components/common/Common.mdx +0 -1
  258. package/lib/components/index.ts +19 -1
  259. package/lib/theme/Colours.mdx +1 -1
  260. package/lib/theme/Theme.mdx +1 -1
  261. package/lib/theme/Typography.mdx +1 -1
  262. package/lib/theme/__tests__/fonts.test.ts +37 -0
  263. package/lib/theme/common/themeCommon.ts +515 -0
  264. package/lib/theme/fonts.ts +110 -0
  265. package/lib/theme/index.ts +6 -6
  266. package/lib/theme/light/lightColour.ts +232 -0
  267. package/lib/theme/light/lightTheme.ts +37 -0
  268. package/lib/theme/{defaultTheme.ts → original/color.ts} +17 -199
  269. package/lib/theme/original/defaultTheme.ts +207 -0
  270. package/lib/theme/original/originalColourNewStructure.ts +185 -0
  271. package/lib/theme/useTheme.tsx +72 -15
  272. package/lib/types/assets.d.ts +10 -0
  273. package/lib/utils/addAlphaToHex.ts +29 -0
  274. package/lib/utils/scrollToTop.ts +5 -0
  275. package/package.json +11 -6
  276. package/dist/components/Button/buttonPrimaryStyle.d.ts +0 -4
  277. package/dist/components/Button/buttonSecondaryStyle.d.ts +0 -4
  278. package/dist/components/Button/buttonTertiaryStyle.d.ts +0 -4
  279. package/dist/theme/defaultTheme.d.ts +0 -274
  280. package/lib/components/Button/buttonPrimaryStyle.ts +0 -62
  281. package/lib/components/Button/buttonSecondaryStyle.ts +0 -65
  282. package/lib/components/Button/buttonTertiaryStyle.ts +0 -54
@@ -0,0 +1,75 @@
1
+ import { HTMLAttributes, memo } from 'react';
2
+ import { css, cx } from '@emotion/css';
3
+ import { useTheme } from '../../theme';
4
+ import MenuProvider from './Menu.context';
5
+ import MenuContent from './MenuContent';
6
+ import MenuItem from './MenuItem';
7
+ import MenuSection from './MenuSection';
8
+ import ButtonMenuTrigger, { ButtonMenuTriggerProps } from './trigger/ButtonMenuTrigger';
9
+
10
+ export const NAME = 'ucl-uikit-menu';
11
+
12
+ export interface MenuProps extends HTMLAttributes<HTMLDivElement> {
13
+ defaultOpen?: boolean;
14
+ title?: string;
15
+ menuId?: string;
16
+ position?: 'left' | 'right';
17
+ trigger?: React.ComponentType<ButtonMenuTriggerProps>;
18
+ testId?: string;
19
+ }
20
+
21
+ const Menu = ({
22
+ defaultOpen = false,
23
+ title,
24
+ position = 'right',
25
+ trigger,
26
+ menuId = NAME,
27
+ testId = NAME,
28
+ children,
29
+ className,
30
+ ...props
31
+ }: MenuProps) => {
32
+ const [theme] = useTheme();
33
+
34
+ const baseStyle = css`
35
+ position: relative;
36
+ font-family: ${theme.font.family.primary};
37
+ `;
38
+
39
+ const style = cx(NAME, baseStyle, className);
40
+
41
+ const TriggerComp = trigger ?? ButtonMenuTrigger;
42
+
43
+ return (
44
+ <nav
45
+ className={style}
46
+ data-testid={testId}
47
+ {...props}
48
+ >
49
+ <MenuProvider defaultOpen={defaultOpen}>
50
+ <TriggerComp aria-controls={menuId} />
51
+ <MenuContent
52
+ id={menuId}
53
+ title={title}
54
+ position={position}
55
+ >
56
+ {children}
57
+ </MenuContent>
58
+ </MenuProvider>
59
+ </nav>
60
+ );
61
+ };
62
+
63
+ export interface IMenuSubComponents {
64
+ Section: typeof MenuSection;
65
+ Item: typeof MenuItem;
66
+ }
67
+
68
+ const MemoMenu = memo(Menu);
69
+
70
+ const MenuWithSubComponents = MemoMenu as typeof MemoMenu & IMenuSubComponents;
71
+
72
+ MenuWithSubComponents.Section = MenuSection;
73
+ MenuWithSubComponents.Item = MenuItem;
74
+
75
+ export default MenuWithSubComponents;
@@ -0,0 +1,140 @@
1
+ import React, { HTMLAttributes, memo, useEffect } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import { css, cx } from '@emotion/css';
4
+ import useTheme from '../../theme/useTheme';
5
+ import useMediaQuery from '../../hooks/useMediaQuery';
6
+ import Icon from '../Icon';
7
+ import IconButton from '../IconButton';
8
+ import { useAppMenu } from './Menu.context';
9
+
10
+ export const NAME = 'ucl-uikit-menu__content';
11
+
12
+ export interface MenuContentProps extends HTMLAttributes<HTMLUListElement> {
13
+ title?: string;
14
+ testId?: string;
15
+ position?: 'left' | 'right';
16
+ }
17
+
18
+ const MenuContent: React.FC<MenuContentProps> = ({
19
+ title,
20
+ testId = NAME,
21
+ position = 'right',
22
+ children,
23
+ className,
24
+ ...props
25
+ }) => {
26
+ const { isOpen, contentRef, toggleMenu } = useAppMenu();
27
+
28
+ const [theme] = useTheme();
29
+
30
+ const { padding } = theme;
31
+
32
+ const isDesktop = useMediaQuery(
33
+ `(min-width: ${theme.breakpoints.desktop}px)`
34
+ );
35
+
36
+ const baseStyle = css`
37
+ display: none;
38
+ z-index: 100;
39
+ ${position === 'left' ? 'left: 0;' : 'right: 0;'}
40
+ white-space: nowrap;
41
+ background-color: ${theme.color.neutral.white};
42
+ color: ${theme.color.text.primary};
43
+
44
+ position: fixed;
45
+ height: 100vh;
46
+ border: none;
47
+ box-shadow: none;
48
+ padding: 0;
49
+ margin: 0;
50
+ overflow-y: auto;
51
+ min-width: 100%;
52
+
53
+ a {
54
+ height: auto;
55
+ }
56
+
57
+ @media (min-width: ${theme.breakpoints.desktop}px) {
58
+ position: absolute;
59
+ height: auto;
60
+ min-width: 600px;
61
+ border: ${theme.border.b1} solid ${theme.color.neutral.grey20};
62
+ box-shadow: ${theme.boxShadow.y1};
63
+ }
64
+ `;
65
+
66
+ const openStyle = css`
67
+ display: block;
68
+ `;
69
+
70
+ const style = cx(NAME, baseStyle, isOpen && openStyle, className);
71
+
72
+ const headerStyle = css`
73
+ display: flex;
74
+ justify-content: space-between;
75
+ padding: ${padding.p64} ${padding.p24} ${padding.p16};
76
+
77
+ @media (min-width: ${theme.breakpoints.desktop}px) {
78
+ padding: ${padding.p32} ${padding.p48} ${padding.p16} ${padding.p64};
79
+ justify-content: flex-end;
80
+ }
81
+ `;
82
+
83
+ const titleStyle = css`
84
+ @media (min-width: ${theme.breakpoints.desktop}px) {
85
+ display: none;
86
+ }
87
+ `;
88
+
89
+ const bodyStyle = css`
90
+ padding: 0 ${padding.p24};
91
+ list-style: none;
92
+
93
+ @media (min-width: ${theme.breakpoints.desktop}px) {
94
+ margin: 0 ${padding.p64};
95
+ padding: 0;
96
+ }
97
+ `;
98
+
99
+ useEffect(() => {
100
+ const rootDiv = document.getElementById('root');
101
+ if (rootDiv) {
102
+ if (!isDesktop && isOpen) {
103
+ rootDiv.style.display = 'none';
104
+ } else {
105
+ rootDiv.style.display = '';
106
+ }
107
+ }
108
+ }, [isOpen, isDesktop]);
109
+
110
+ const menuContent = (
111
+ <div
112
+ ref={contentRef}
113
+ className={style}
114
+ >
115
+ <header className={headerStyle}>
116
+ <h3 className={titleStyle}>{title}</h3>
117
+ <IconButton
118
+ onClick={toggleMenu}
119
+ aria-label='Close menu'
120
+ >
121
+ <Icon.X size={40} />
122
+ </IconButton>
123
+ </header>
124
+ <ul
125
+ role='menu'
126
+ aria-labelledby='app-menu-button'
127
+ className={bodyStyle}
128
+ data-testid={testId}
129
+ tabIndex={-1}
130
+ {...props}
131
+ >
132
+ {children}
133
+ </ul>
134
+ </div>
135
+ );
136
+
137
+ return !isDesktop ? createPortal(menuContent, document.body) : menuContent;
138
+ };
139
+
140
+ export default memo(MenuContent);
@@ -0,0 +1,101 @@
1
+ import React, { LiHTMLAttributes, memo } from 'react';
2
+ import { css, cx } from '@emotion/css';
3
+ import useTheme from '../../theme/useTheme';
4
+ import Icon from '../Icon/Icon';
5
+
6
+ export const NAME = 'ucl-uikit-menu__item';
7
+
8
+ export interface MenuItemProps extends LiHTMLAttributes<HTMLLIElement> {
9
+ testId?: string;
10
+ icon?: React.ReactNode;
11
+ secondary?: boolean;
12
+ externalLink?: boolean;
13
+ }
14
+
15
+ const MenuItem: React.FC<MenuItemProps> = ({
16
+ testId = NAME,
17
+ icon,
18
+ children,
19
+ className,
20
+ onClick,
21
+ secondary,
22
+ externalLink,
23
+ ...props
24
+ }) => {
25
+ const isClickable = !!onClick;
26
+ const [theme] = useTheme();
27
+
28
+ const baseStyle = css`
29
+ height: 40px;
30
+ margin-bottom: ${theme.margin.m16};
31
+ display: flex;
32
+ align-items: center;
33
+ font-family: ${theme.font.family.primary};
34
+ font-size: ${theme.font.size.f16};
35
+ font-weight: ${secondary
36
+ ? `${theme.font.weight.medium}`
37
+ : `${theme.font.weight.bold}`};
38
+ color: ${theme.color.text.secondary};
39
+ `;
40
+
41
+ const clickableMenuItemStyle = css`
42
+ color: ${secondary
43
+ ? `${theme.color.text.secondary}`
44
+ : `${theme.color.text.primary}`};
45
+ cursor: pointer;
46
+ &:hover {
47
+ background-color: ${theme.color.interaction.blue5};
48
+ }
49
+ &:focus-visible {
50
+ outline: none;
51
+ box-shadow: ${theme.boxShadow.focus};
52
+ z-index: 1;
53
+ }
54
+ `;
55
+
56
+ const iconContainerStyle = css`
57
+ display: inline-flex;
58
+ align-items: center;
59
+ margin-right: ${theme.margin.m32};
60
+ `;
61
+
62
+ const style = cx(
63
+ NAME,
64
+ baseStyle,
65
+ isClickable && clickableMenuItemStyle,
66
+ className
67
+ );
68
+
69
+ const content = (
70
+ <>
71
+ {React.isValidElement(icon) && (
72
+ <span className={iconContainerStyle}>{icon}</span>
73
+ )}
74
+ {children}
75
+ </>
76
+ );
77
+
78
+ return (
79
+ <li
80
+ tabIndex={isClickable ? 0 : -1}
81
+ role='menuitem'
82
+ aria-disabled={!isClickable}
83
+ className={style}
84
+ data-testid={testId}
85
+ onClick={onClick}
86
+ {...props}
87
+ >
88
+ {content}
89
+ {externalLink && (
90
+ <Icon.ExternalLink
91
+ size={16}
92
+ className={css`
93
+ margin-left: 8px;
94
+ `}
95
+ />
96
+ )}
97
+ </li>
98
+ );
99
+ };
100
+
101
+ export default memo(MenuItem);
@@ -0,0 +1,47 @@
1
+ import React, { HTMLAttributes } from 'react';
2
+ import { css, cx } from '@emotion/css';
3
+ import { useTheme } from '../../theme';
4
+
5
+ export const NAME = 'ucl-uikit-menu__section';
6
+
7
+ export interface MenuSectionProps extends HTMLAttributes<HTMLLIElement> {
8
+ testId?: string;
9
+ }
10
+
11
+ const MenuSection: React.FC<MenuSectionProps> = ({
12
+ className,
13
+ children,
14
+ ...props
15
+ }) => {
16
+ const [theme] = useTheme();
17
+
18
+ const baseStyle = css`
19
+ padding: 0;
20
+ margin-top: 0;
21
+ margin-bottom: ${theme.margin.m32};
22
+
23
+ &:not(:last-of-type) {
24
+ border-bottom: 1px solid ${theme.color.neutral.grey10};
25
+ }
26
+ `;
27
+
28
+ const style = cx(NAME, baseStyle, className);
29
+
30
+ const listStyle = css`
31
+ list-style: none;
32
+ margin: 0;
33
+ padding: 0;
34
+ `;
35
+
36
+ return (
37
+ <li
38
+ role='presentation'
39
+ className={style}
40
+ {...props}
41
+ >
42
+ <ul className={listStyle}>{children}</ul>
43
+ </li>
44
+ );
45
+ };
46
+
47
+ export default MenuSection;
@@ -0,0 +1,8 @@
1
+ export { default } from './Menu';
2
+ export type { MenuProps } from './Menu';
3
+
4
+ export { default as MenuContent } from './MenuContent';
5
+ export type { MenuContentProps } from './MenuContent';
6
+
7
+ export { default as ButtonMenuTrigger } from './trigger/ButtonMenuTrigger';
8
+ export type { ButtonMenuTriggerProps } from './trigger/ButtonMenuTrigger';
@@ -0,0 +1,42 @@
1
+ import { memo } from 'react';
2
+ import { cx } from '@emotion/css';
3
+ import { IconButtonProps } from '../../IconButton';
4
+ import { useAppMenu } from '../Menu.context';
5
+ import { Button, Icon } from '../..';
6
+
7
+ export const NAME = 'ucl-uikit-menu__trigger--button';
8
+ export const DEFAULT_ARIA_LABEL = 'Menu button';
9
+
10
+ export interface ButtonMenuTriggerProps extends IconButtonProps {
11
+ ariaLabel?: string;
12
+ }
13
+
14
+ const ButtonMenuTrigger = ({
15
+ id = 'menu-trigger',
16
+ ariaLabel = DEFAULT_ARIA_LABEL,
17
+ className,
18
+ ...props
19
+ }: ButtonMenuTriggerProps) => {
20
+ const { toggleMenu, isOpen, triggerRef } = useAppMenu();
21
+
22
+ const style = cx(NAME, className);
23
+
24
+ return (
25
+ <Button
26
+ id={id}
27
+ ref={triggerRef}
28
+ className={style}
29
+ size='small'
30
+ icon={<Icon.Menu />}
31
+ onClick={toggleMenu}
32
+ aria-label={ariaLabel}
33
+ aria-haspopup='true'
34
+ aria-expanded={isOpen ? 'true' : 'false'}
35
+ {...props}
36
+ >
37
+ Menu
38
+ </Button>
39
+ );
40
+ };
41
+
42
+ export default memo(ButtonMenuTrigger);
@@ -0,0 +1,40 @@
1
+ import { memo } from 'react';
2
+ import { cx } from '@emotion/css';
3
+ import IconButton, { IconButtonProps } from '../../IconButton';
4
+ import { useAppMenu } from '../Menu.context';
5
+ import { Icon } from '../..';
6
+
7
+ export const NAME = 'ucl-uikit-menu__trigger--icon';
8
+ export const DEFAULT_ARIA_LABEL = 'Menu button';
9
+
10
+ export interface IconMenuTriggerProps extends IconButtonProps {
11
+ ariaLabel?: string;
12
+ }
13
+
14
+ const IconMenuTrigger = ({
15
+ id = 'menu-trigger',
16
+ ariaLabel = DEFAULT_ARIA_LABEL,
17
+ className,
18
+ ...props
19
+ }: IconMenuTriggerProps) => {
20
+ const { toggleMenu, isOpen, triggerRef } = useAppMenu();
21
+
22
+ const style = cx(NAME, className);
23
+
24
+ return (
25
+ <IconButton
26
+ id={id}
27
+ ref={triggerRef}
28
+ className={style}
29
+ onClick={toggleMenu}
30
+ aria-label={ariaLabel}
31
+ aria-haspopup='true'
32
+ aria-expanded={isOpen ? 'true' : 'false'}
33
+ {...props}
34
+ >
35
+ <Icon.Menu/>
36
+ </IconButton>
37
+ );
38
+ };
39
+
40
+ export default memo(IconMenuTrigger);
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
2
2
  import Pagination from './Pagination';
3
3
 
4
4
  const meta = {
5
- title: 'Components/Work in progress/Pagination',
5
+ title: 'Components/Pagination',
6
6
  component: Pagination,
7
7
  parameters: {
8
8
  docs: {
@@ -9,8 +9,7 @@ import { useMediaQuery } from '../../hooks';
9
9
  export const NAME = 'ucl-ukit-pagination__controls';
10
10
  export const DEFAULT_MAX_BUTTONS = 9;
11
11
 
12
- export interface PaginationControlsProps
13
- extends HTMLAttributes<HTMLDivElement> {
12
+ export interface PaginationControlsProps extends HTMLAttributes<HTMLDivElement> {
14
13
  maxNumberButtons?: number;
15
14
  testId?: string;
16
15
  }
@@ -123,15 +122,15 @@ const PaginationControls = ({
123
122
  pageNumberButtonBaseStyle,
124
123
  css`
125
124
  border: none;
126
- color: ${theme.color.text.secondary};
125
+ color: ${theme.colour.text.secondary};
127
126
  `
128
127
  );
129
128
 
130
129
  const currentPageNumberButtonStyle = cx(
131
130
  pageNumberButtonBaseStyle,
132
131
  css`
133
- color: ${theme.color.interaction.blue70};
134
- border-color: ${theme.color.interaction.blue70};
132
+ color: ${theme.colour.text.brand};
133
+ border-color: ${theme.colour.border.brand};
135
134
  `
136
135
  );
137
136
 
@@ -5,8 +5,7 @@ import { PaginationContext } from './Pagination';
5
5
 
6
6
  export const NAME = 'ucl-uikit-pagination__info';
7
7
 
8
- export interface PaginationInfoProps
9
- extends React.HTMLAttributes<HTMLDivElement> {
8
+ export interface PaginationInfoProps extends React.HTMLAttributes<HTMLDivElement> {
10
9
  format?: 'pages' | 'items';
11
10
  itemsPluralName?: string;
12
11
  testId?: string;
@@ -42,7 +41,7 @@ const PaginationInfo = ({
42
41
  const baseStyle = css`
43
42
  margin: ${theme.margin.m16} 0;
44
43
  text-align: center;
45
- color: ${theme.color.text.secondary};
44
+ color: ${theme.colour.text.secondary};
46
45
  font-family: ${theme.font.family.primary};
47
46
  font-size: ${theme.font.size.f16};
48
47
 
@@ -18,38 +18,40 @@ type Story = StoryObj<typeof meta>;
18
18
 
19
19
  export const Default: Story = {};
20
20
 
21
- export const WithMargins: Story = {
22
- name: 'With margins',
21
+ export const LevelLg: Story = {
23
22
  args: {
24
- margins: true,
25
- children: 'This is a paragraph with margins.',
23
+ level: 'lg',
24
+ children: 'This is large paragraph text.',
25
+ },
26
+ };
27
+
28
+ export const LevelMd: Story = {
29
+ args: {
30
+ level: 'md',
31
+ children: 'This is medium paragraph text.',
32
+ },
33
+ };
34
+
35
+ export const LevelSm: Story = {
36
+ args: {
37
+ level: 'sm',
38
+ children: 'This is small paragraph text.',
39
+ },
40
+ };
41
+
42
+ export const AsSpan: Story = {
43
+ args: {
44
+ as: 'span',
45
+ level: 'md-semibold',
46
+ children: 'This paragraph is rendered as a span.',
26
47
  },
27
- decorators: [
28
- (Story) => (
29
- <>
30
- <div
31
- style={{
32
- height: '16px',
33
- backgroundColor: '#CA0007',
34
- }}
35
- />
36
- <Story />
37
- <div
38
- style={{
39
- height: '16px',
40
- backgroundColor: '#CA0007',
41
- }}
42
- />
43
- </>
44
- ),
45
- ],
46
48
  };
47
49
 
48
- export const WithoutMargins: Story = {
49
- name: 'Without margins',
50
+ export const NoMargins: Story = {
51
+ name: 'No margins',
50
52
  args: {
51
- margins: false,
52
- children: 'This is a paragraph without margins.',
53
+ noMargins: true,
54
+ children: 'This paragraph has no margins.',
53
55
  },
54
56
  decorators: [
55
57
  (Story) => (