uikit-react-public 0.17.4 → 0.21.8

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 (280) 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/HeadingNew/Heading.d.ts +13 -0
  43. package/dist/components/HeadingNew/index.d.ts +2 -0
  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/ParagraphNew/Paragraph.d.ts +13 -0
  58. package/dist/components/ParagraphNew/index.d.ts +4 -0
  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 +20909 -16022
  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/HeadingNew/Heading.tsx +208 -0
  180. package/lib/components/HeadingNew/index.ts +2 -0
  181. package/lib/components/Icon/__tests__/__snapshots__/Icon.test.tsx.snap +16 -12
  182. package/lib/components/Icon/svgImports.ts +318 -296
  183. package/lib/components/IconButton/IconButton.tsx +3 -4
  184. package/lib/components/IconButton/__tests__/__snapshots__/IconButton.test.tsx.snap +12 -9
  185. package/lib/components/Link/BaseLink.tsx +114 -71
  186. package/lib/components/Link/Link.stories.tsx +1 -1
  187. package/lib/components/Link/Link.tsx +120 -109
  188. package/lib/components/Link/__tests__/__snapshots__/link.test.tsx.snap +2 -2
  189. package/lib/components/MenuNew/Menu.context.tsx +149 -0
  190. package/lib/components/MenuNew/Menu.tsx +75 -0
  191. package/lib/components/MenuNew/MenuContent.tsx +140 -0
  192. package/lib/components/MenuNew/MenuItem.tsx +101 -0
  193. package/lib/components/MenuNew/MenuSection.tsx +47 -0
  194. package/lib/components/MenuNew/index.ts +8 -0
  195. package/lib/components/MenuNew/trigger/ButtonMenuTrigger.tsx +42 -0
  196. package/lib/components/MenuNew/trigger/IconMenuTrigger.tsx +40 -0
  197. package/lib/components/Pagination/Pagination.stories.tsx +1 -1
  198. package/lib/components/Pagination/PaginationControls.tsx +4 -5
  199. package/lib/components/Pagination/PaginationInfo.tsx +2 -3
  200. package/lib/components/ParagraphNew/Paragraph.tsx +200 -0
  201. package/lib/components/ParagraphNew/index.ts +6 -0
  202. package/lib/components/Radio/Radio.stories.tsx +1 -1
  203. package/lib/components/Radio/Radio.tsx +8 -8
  204. package/lib/components/Radio/__tests__/__snapshots__/Radio.test.tsx.snap +4 -4
  205. package/lib/components/Search/__tests__/__snapshots__/Search.test.tsx.snap +12 -32
  206. package/lib/components/Select/Select.mdx +23 -0
  207. package/lib/components/Select/Select.stories.tsx +43 -10
  208. package/lib/components/Select/Select.tsx +14 -3
  209. package/lib/components/Select/Select.types.ts +53 -16
  210. package/lib/components/Select/__tests__/Select.test.tsx +250 -1
  211. package/lib/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +5 -4
  212. package/lib/components/Select/subcomponents/CustomOption.tsx +10 -3
  213. package/lib/components/Select/subcomponents/CustomSelect.tsx +110 -10
  214. package/lib/components/Select/subcomponents/FilterInput.tsx +13 -3
  215. package/lib/components/Select/subcomponents/NativeSelect.tsx +10 -18
  216. package/lib/components/Select/subcomponents/Panel.tsx +2 -2
  217. package/lib/components/Select/subcomponents/VisibleField.tsx +48 -3
  218. package/lib/components/Snackbar/__tests__/__snapshots__/Snackbar.test.tsx.snap +9 -15
  219. package/lib/components/Spinner/Spinner.tsx +24 -5
  220. package/lib/components/Spinner/__tests__/Spinner.test.tsx +35 -5
  221. package/lib/components/Spinner/__tests__/__snapshots__/Spinner.test.tsx.snap +40 -16
  222. package/lib/components/StandaloneLink/StandaloneLink.stories.tsx +1 -1
  223. package/lib/components/StandaloneLink/StandaloneLink.tsx +180 -163
  224. package/lib/components/StandaloneLink/__tests__/__snapshots__/StandaloneLink.test.tsx.snap +2 -2
  225. package/lib/components/Table/Table.stories.tsx +1 -1
  226. package/lib/components/Table/Table.tsx +2 -0
  227. package/lib/components/Table/Table.types.ts +1 -0
  228. package/lib/components/Table/__tests__/Table.test.tsx +19 -0
  229. package/lib/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +7 -3
  230. package/lib/components/Table/subcomponents/Cell/Cell.stories.tsx +1 -1
  231. package/lib/components/Table/subcomponents/Cell/Cell.tsx +23 -2
  232. package/lib/components/Table/subcomponents/Cell/CellContent.tsx +12 -1
  233. package/lib/components/Table/subcomponents/Cell/__tests__/Cell.test.tsx +106 -0
  234. package/lib/components/Table/subcomponents/Cell/__tests__/__snapshots__/Cell.test.tsx.snap +4 -3
  235. package/lib/components/Table/subcomponents/HeadCell/HeadCell.stories.tsx +1 -1
  236. package/lib/components/Table/subcomponents/HeadCell/HeadCell.tsx +28 -6
  237. package/lib/components/Table/subcomponents/HeadCell/HeadCellContent.tsx +3 -0
  238. package/lib/components/Table/subcomponents/HeadCell/__tests__/HeadCell.test.tsx +221 -2
  239. package/lib/components/Table/subcomponents/HeadCell/__tests__/__snapshots__/HeadCell.test.tsx.snap +6 -4
  240. package/lib/components/Table/subcomponents/Row.tsx +2 -2
  241. package/lib/components/Table/subcomponents/SortIcon.tsx +1 -0
  242. package/lib/components/Table/subcomponents/__tests__/Row.test.tsx +59 -0
  243. package/lib/components/Tabs/Tab.tsx +3 -3
  244. package/lib/components/Tabs/Tabs.stories.tsx +1 -1
  245. package/lib/components/Tabs/Tabs.tsx +5 -3
  246. package/lib/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap +4 -4
  247. package/lib/components/Timepicker/Timepicker.stories.tsx +1 -1
  248. package/lib/components/Toggle/Toggle.tsx +5 -5
  249. package/lib/components/Toggle/ToggleHandle.tsx +2 -3
  250. package/lib/components/Tooltip/Tooltip.tsx +2 -2
  251. package/lib/components/Tooltip/__tests__/__snapshots__/tooltip.test.tsx.snap +2 -2
  252. package/lib/components/UclLogoNew/UclLogo.tsx +42 -0
  253. package/lib/components/UclLogoNew/index.ts +2 -0
  254. package/lib/components/WeekPicker/WeekPicker.stories.tsx +3 -5
  255. package/lib/components/common/Common.mdx +0 -1
  256. package/lib/components/index.ts +19 -1
  257. package/lib/theme/Colours.mdx +1 -1
  258. package/lib/theme/Theme.mdx +1 -1
  259. package/lib/theme/Typography.mdx +1 -1
  260. package/lib/theme/__tests__/fonts.test.ts +37 -0
  261. package/lib/theme/common/themeCommon.ts +515 -0
  262. package/lib/theme/fonts.ts +110 -0
  263. package/lib/theme/index.ts +6 -6
  264. package/lib/theme/light/lightColour.ts +232 -0
  265. package/lib/theme/light/lightTheme.ts +37 -0
  266. package/lib/theme/{defaultTheme.ts → original/color.ts} +17 -199
  267. package/lib/theme/original/defaultTheme.ts +207 -0
  268. package/lib/theme/original/originalColourNewStructure.ts +185 -0
  269. package/lib/theme/useTheme.tsx +72 -15
  270. package/lib/types/assets.d.ts +10 -0
  271. package/lib/utils/addAlphaToHex.ts +29 -0
  272. package/lib/utils/scrollToTop.ts +5 -0
  273. package/package.json +11 -6
  274. package/dist/components/Button/buttonPrimaryStyle.d.ts +0 -4
  275. package/dist/components/Button/buttonSecondaryStyle.d.ts +0 -4
  276. package/dist/components/Button/buttonTertiaryStyle.d.ts +0 -4
  277. package/dist/theme/defaultTheme.d.ts +0 -274
  278. package/lib/components/Button/buttonPrimaryStyle.ts +0 -62
  279. package/lib/components/Button/buttonSecondaryStyle.ts +0 -65
  280. package/lib/components/Button/buttonTertiaryStyle.ts +0 -54
@@ -1,23 +1,24 @@
1
- import { memo } from 'react';
2
1
  import { css, cx } from '@emotion/css';
3
- import { Link, LinkProps } from '../';
4
-
5
- const NAME = 'ucl-timetable-breadcrumb';
6
- const ACTIVE_NAME = 'ucl-timetable-breadcrumb--active';
7
- const INACTIVE_NAME = 'ucl-timetable-breadcrumb--inactive';
2
+ import Link, { LinkProps } from '../Link';
3
+ import { memo } from 'react';
8
4
 
9
- export interface BreadcrumbProps extends LinkProps {
10
- testId?: string;
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ export interface BreadcrumbProps extends Omit<LinkProps<any>, 'href' | 'to'> {
11
7
  uri: string;
12
8
  isActive?: boolean;
13
9
  }
14
10
 
11
+ const NAME = 'ucl-uikit-breadcrumb';
12
+ const ACTIVE_NAME = 'ucl-uikit-breadcrumb--active';
13
+ const INACTIVE_NAME = 'ucl-uikit-breadcrumb--inactive';
14
+
15
15
  const Breadcrumb = ({
16
16
  testId = NAME,
17
17
  uri,
18
18
  className,
19
19
  children,
20
20
  isActive,
21
+ component,
21
22
  ...props
22
23
  }: BreadcrumbProps) => {
23
24
  const activeBreadcrumb =
@@ -56,23 +57,36 @@ const Breadcrumb = ({
56
57
  <span
57
58
  className={activeBreadcrumbStyle}
58
59
  data-testid={testId}
59
- {...props}
60
60
  >
61
61
  {children}
62
62
  </span>
63
63
  );
64
- } else {
64
+ }
65
+
66
+ if (component) {
65
67
  return (
66
68
  <Link
69
+ component={component}
67
70
  className={inactiveBreadcrumbStyle}
68
- data-testid={testId}
69
- href={uri}
71
+ testId={testId}
72
+ to={uri}
70
73
  {...props}
71
74
  >
72
75
  {children}
73
76
  </Link>
74
77
  );
75
78
  }
79
+
80
+ return (
81
+ <Link
82
+ className={inactiveBreadcrumbStyle}
83
+ testId={testId}
84
+ href={uri}
85
+ {...props}
86
+ >
87
+ {children}
88
+ </Link>
89
+ );
76
90
  };
77
91
 
78
92
  export default memo(Breadcrumb);
@@ -4,7 +4,7 @@ import { Icon } from '../';
4
4
  import Breadcrumb from './Breadcrumb';
5
5
  import { useTheme } from '../../theme';
6
6
 
7
- const NAME = 'ucl-timetable-breadcrumbs';
7
+ const NAME = 'ucl-uikit-breadcrumbs';
8
8
 
9
9
  export interface BreadcrumbsProps extends HTMLAttributes<HTMLElement> {
10
10
  testId?: string;
@@ -10,9 +10,7 @@ describe('Breadcrumbs', () => {
10
10
  const renderResult = render(
11
11
  <ThemeContextProvider>
12
12
  <Breadcrumbs>
13
- <Breadcrumbs.Breadcrumb uri='/'>
14
- Home
15
- </Breadcrumbs.Breadcrumb>
13
+ <Breadcrumbs.Breadcrumb uri='/'>Home</Breadcrumbs.Breadcrumb>
16
14
  <Breadcrumbs.Breadcrumb uri='/showcase'>
17
15
  Timetable
18
16
  </Breadcrumbs.Breadcrumb>
@@ -22,9 +20,7 @@ describe('Breadcrumbs', () => {
22
20
  </Breadcrumbs>
23
21
  </ThemeContextProvider>
24
22
  );
25
- expect(
26
- renderResult.container.firstChild
27
- ).toMatchSnapshot();
23
+ expect(renderResult.container.firstChild).toMatchSnapshot();
28
24
  });
29
25
 
30
26
  test('snapshot: Custom Test ID', () => {
@@ -52,9 +48,7 @@ describe('Breadcrumbs', () => {
52
48
  </Breadcrumbs>
53
49
  </ThemeContextProvider>
54
50
  );
55
- expect(
56
- renderResult.container.firstChild
57
- ).toMatchSnapshot();
51
+ expect(renderResult.container.firstChild).toMatchSnapshot();
58
52
  });
59
53
 
60
54
  // Interaction tests
@@ -63,9 +57,7 @@ describe('Breadcrumbs', () => {
63
57
  render(
64
58
  <ThemeContextProvider>
65
59
  <Breadcrumbs>
66
- <Breadcrumbs.Breadcrumb uri='/'>
67
- Home
68
- </Breadcrumbs.Breadcrumb>
60
+ <Breadcrumbs.Breadcrumb uri='/'>Home</Breadcrumbs.Breadcrumb>
69
61
  <Breadcrumbs.Breadcrumb uri='/showcase'>
70
62
  Timetable
71
63
  </Breadcrumbs.Breadcrumb>
@@ -75,12 +67,8 @@ describe('Breadcrumbs', () => {
75
67
  </Breadcrumbs>
76
68
  </ThemeContextProvider>
77
69
  );
78
- const breadcrumbs = screen.getByTestId(
79
- 'ucl-timetable-breadcrumbs'
80
- );
81
- const breadcrumb = screen.getAllByTestId(
82
- 'ucl-timetable-breadcrumb'
83
- );
70
+ const breadcrumbs = screen.getByTestId('ucl-uikit-breadcrumbs');
71
+ const breadcrumb = screen.getAllByTestId('ucl-uikit-breadcrumb');
84
72
  expect(breadcrumbs).toBeDefined();
85
73
  expect(breadcrumb).toBeDefined();
86
74
  });
@@ -111,15 +99,9 @@ describe('Breadcrumbs', () => {
111
99
  </ThemeContextProvider>
112
100
  );
113
101
  const breadcrumbs = screen.getByTestId('custom-testid');
114
- const breadcrumb1 = screen.getByTestId(
115
- 'custom-testid-1'
116
- );
117
- const breadcrumb2 = screen.getByTestId(
118
- 'custom-testid-2'
119
- );
120
- const breadcrumb3 = screen.getByTestId(
121
- 'custom-testid-3'
122
- );
102
+ const breadcrumb1 = screen.getByTestId('custom-testid-1');
103
+ const breadcrumb2 = screen.getByTestId('custom-testid-2');
104
+ const breadcrumb3 = screen.getByTestId('custom-testid-3');
123
105
  expect(breadcrumbs).toBeDefined();
124
106
  expect(breadcrumb1).toBeDefined();
125
107
  expect(breadcrumb2).toBeDefined();
@@ -2,15 +2,15 @@
2
2
 
3
3
  exports[`Breadcrumbs > Snapshot: No props 1`] = `
4
4
  <nav
5
- class="ucl-timetable-breadcrumbs"
6
- data-testid="ucl-timetable-breadcrumbs"
5
+ class="ucl-uikit-breadcrumbs"
6
+ data-testid="ucl-uikit-breadcrumbs"
7
7
  >
8
8
  <span
9
9
  class="css-4ys53n"
10
10
  >
11
11
  <span
12
- class="css-0 ucl-timetable-breadcrumb ucl-timetable-breadcrumb--active"
13
- data-testid="ucl-timetable-breadcrumb"
12
+ class="css-0 ucl-uikit-breadcrumb ucl-uikit-breadcrumb--active"
13
+ data-testid="ucl-uikit-breadcrumb"
14
14
  >
15
15
  Home
16
16
  </span>
@@ -18,6 +18,7 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
18
18
  class="ucl-uikit-icon css-1ez1cy1"
19
19
  data-testid="ucl-uikit-icon"
20
20
  fill="none"
21
+ focusable="false"
21
22
  height="24"
22
23
  stroke="currentColor"
23
24
  stroke-linecap="round"
@@ -27,8 +28,8 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
27
28
  width="24"
28
29
  xmlns="http://www.w3.org/2000/svg"
29
30
  >
30
- <polyline
31
- points="9 18 15 12 9 6"
31
+ <path
32
+ d="m9 18 6-6-6-6"
32
33
  />
33
34
  </svg>
34
35
  </span>
@@ -36,8 +37,8 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
36
37
  class="css-4ys53n"
37
38
  >
38
39
  <a
39
- class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
40
- data-testid="ucl-timetable-breadcrumb"
40
+ class="ucl-uikit-base-link ucl-uikit-link ucl-uikit-breadcrumb ucl-uikit-breadcrumb--inactive css-dh2n9h"
41
+ data-testid="ucl-uikit-breadcrumb"
41
42
  href="/showcase"
42
43
  >
43
44
  Timetable
@@ -46,6 +47,7 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
46
47
  class="ucl-uikit-icon css-1ez1cy1"
47
48
  data-testid="ucl-uikit-icon"
48
49
  fill="none"
50
+ focusable="false"
49
51
  height="24"
50
52
  stroke="currentColor"
51
53
  stroke-linecap="round"
@@ -55,8 +57,8 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
55
57
  width="24"
56
58
  xmlns="http://www.w3.org/2000/svg"
57
59
  >
58
- <polyline
59
- points="9 18 15 12 9 6"
60
+ <path
61
+ d="m9 18 6-6-6-6"
60
62
  />
61
63
  </svg>
62
64
  </span>
@@ -64,8 +66,8 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
64
66
  class="css-4ys53n"
65
67
  >
66
68
  <a
67
- class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
68
- data-testid="ucl-timetable-breadcrumb"
69
+ class="ucl-uikit-base-link ucl-uikit-link ucl-uikit-breadcrumb ucl-uikit-breadcrumb--inactive css-dh2n9h"
70
+ data-testid="ucl-uikit-breadcrumb"
69
71
  href="/showcase/breadcrumbs"
70
72
  >
71
73
  Personal
@@ -76,14 +78,14 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
76
78
 
77
79
  exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
78
80
  <nav
79
- class="ucl-timetable-breadcrumbs"
81
+ class="ucl-uikit-breadcrumbs"
80
82
  data-testid="custom-testid"
81
83
  >
82
84
  <span
83
85
  class="css-4ys53n"
84
86
  >
85
87
  <span
86
- class="css-0 ucl-timetable-breadcrumb ucl-timetable-breadcrumb--active"
88
+ class="css-0 ucl-uikit-breadcrumb ucl-uikit-breadcrumb--active"
87
89
  data-testid="custom-testid-1"
88
90
  >
89
91
  Home
@@ -92,6 +94,7 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
92
94
  class="ucl-uikit-icon css-1ez1cy1"
93
95
  data-testid="ucl-uikit-icon"
94
96
  fill="none"
97
+ focusable="false"
95
98
  height="24"
96
99
  stroke="currentColor"
97
100
  stroke-linecap="round"
@@ -101,8 +104,8 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
101
104
  width="24"
102
105
  xmlns="http://www.w3.org/2000/svg"
103
106
  >
104
- <polyline
105
- points="9 18 15 12 9 6"
107
+ <path
108
+ d="m9 18 6-6-6-6"
106
109
  />
107
110
  </svg>
108
111
  </span>
@@ -110,7 +113,7 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
110
113
  class="css-4ys53n"
111
114
  >
112
115
  <a
113
- class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
116
+ class="ucl-uikit-base-link ucl-uikit-link ucl-uikit-breadcrumb ucl-uikit-breadcrumb--inactive css-dh2n9h"
114
117
  data-testid="custom-testid-2"
115
118
  href="/showcase"
116
119
  >
@@ -120,6 +123,7 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
120
123
  class="ucl-uikit-icon css-1ez1cy1"
121
124
  data-testid="ucl-uikit-icon"
122
125
  fill="none"
126
+ focusable="false"
123
127
  height="24"
124
128
  stroke="currentColor"
125
129
  stroke-linecap="round"
@@ -129,8 +133,8 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
129
133
  width="24"
130
134
  xmlns="http://www.w3.org/2000/svg"
131
135
  >
132
- <polyline
133
- points="9 18 15 12 9 6"
136
+ <path
137
+ d="m9 18 6-6-6-6"
134
138
  />
135
139
  </svg>
136
140
  </span>
@@ -138,7 +142,7 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
138
142
  class="css-4ys53n"
139
143
  >
140
144
  <a
141
- class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
145
+ class="ucl-uikit-base-link ucl-uikit-link ucl-uikit-breadcrumb ucl-uikit-breadcrumb--inactive css-dh2n9h"
142
146
  data-testid="custom-testid-3"
143
147
  href="/showcase/breadcrumbs"
144
148
  >
@@ -1,25 +1,19 @@
1
- import * as ButtonStories from "./Button.stories";
1
+ import * as ButtonStories from './Button.stories';
2
2
  import {
3
3
  Meta,
4
4
  Title,
5
5
  Subtitle,
6
+ Description,
6
7
  Canvas,
7
8
  Controls,
8
9
  ArgTypes,
9
- } from "@storybook/blocks";
10
+ } from '@storybook/blocks';
10
11
 
11
12
  export const usage = {
12
13
  default: `<Button>Default Button</Button>`,
13
- primary: `<Button variant='primary'>Primary Button</Button>`,
14
14
  secondary: `<Button variant='secondary'>Secondary Button</Button>`,
15
- tertiary: `<Button variant='tertiary'>Tertiary Button</Button>`,
16
- destructive: `<Button destructive>Destructive Button</Button>`,
17
- destructiveSecondary: `<Button variant='secondary' destructive>Destructive Secondary Button</Button>`,
18
- disabled: `<Button disabled>Disabled Button</Button>`,
19
- disabledSecondary: `<Button variant='secondary' disabled>Disabled Secondary Button</Button>`,
20
- disabledTertiary: `<Button variant='tertiary' disabled>Disabled Tertiary Button</Button>`,
15
+ destructive: `<Button variant='primary-destructive'>Destructive Button</Button>`,
21
16
  withIcon: `<Button icon={<Icon.AlertTriangle />}>Button</Button>`,
22
- iconOnly: `<Button icon={<Icon.AlertTriangle />} aria-label='Button description' tooltip='Tooltip' />`,
23
17
  loading: `<Button loading>Loading Button</Button>`,
24
18
  link: `<Button as='a' href='https://www.ucl.ac.uk' target='_blank'>Go to UCL&#39;s website</Button>`,
25
19
  fullWidth: `<Button fullWidth>Full Width Button</Button>`,
@@ -28,298 +22,57 @@ export const usage = {
28
22
  <Meta of={ButtonStories} />
29
23
  <Title />
30
24
  <Subtitle>
31
- A polymorphic button component with multiple variants & lots of features
25
+ A polymorphic button component with modern variants and backwards-compatible legacy props
32
26
  </Subtitle>
33
27
 
34
- The primary use case for the `<Button>` component is to create a clickable button element on a screen — self-evidently a common UI/UX pattern that doesn't need much additional explanation.
28
+ <Description>
29
+ `Button` supports the richer variant set and still supports legacy props such as `destructive` and `size='default'` for compatibility.
30
+ </Description>
35
31
 
36
- Technically speaking, we mean the <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/button' target='_blank'>native HTML `<button>` element</a>, which accepts click events that can trigger changes in application state.
37
-
38
- The `<Button>` component is, therefore, essentially a wrapper for this native `<button>` element, with styling in accordance with UCL Design System guidelines.
39
-
40
- Use this component when you want a clear 'button' in your user interface that has an associated '_action_': e.g. 'Submit', 'Save', 'Delete', etc. An 'action' in this context triggers some kind of change in the application state.
41
-
42
- - **Design specifications** available in Figma: <a href="https://www.figma.com/design/8Sm5PxWOWJYpYXAzhRzUzt/UCL-Design-System-UI-Kit?node-id=2128-184" target="_blank">UCL Design System UI Kit | Buttons</a>
43
- - **Component files** located in `lib/component/Button/` in the UIKit-React repository: <a href='https://github.com/ucl-isd/uikit-react/tree/main/lib/components/Button' target='_blank'>ucl-isd/uikit-react | Button</a>
44
-
45
- <Canvas source={{ code: usage.default }} />
46
-
47
- [Interactive table of props available below.](#props)
48
-
49
- ## Contents
50
-
51
- - [Variants](#variants)
52
- - [Primary](#primary)
53
- - [Secondary](#secondary)
54
- - [Tertiary](#tertiary)
55
- - [Destructive buttons](#destructive-buttons)
56
- - [Disabled buttons](#disabled-buttons)
57
- - [Icons](#icons)
58
- - [Icon right](#icon-right)
59
- - [Icon only](#icon-only)
60
- - [Loading Spinner](#loading-spinner)
61
- - [Polymorphism](#polymorphism)
62
- - [Full width](#full-width)
63
- - [Props](#props)
32
+ <Canvas of={ButtonStories.Default} source={{ code: usage.default }} />
64
33
 
65
34
  ## Variants
66
35
 
67
- The `<Button>` component has three 'variants', which describe <a href='https://www.interaction-design.org/literature/topics/visual-hierarchy' target='_blank'>visual hierarchy</a>:
68
-
69
- - **primary** (default)
70
- - **secondary**
71
- - **tertiary**
72
-
73
- 'Primary' buttons are the most obvious, clear, and demand attention from the user. 'Secondary' buttons are less important, and 'tertiary' buttons are the least important.
74
-
75
- `variant?: 'primary' | 'secondary' | 'tertiary';`
76
-
77
- ### Primary
78
-
79
- The default variant of the button. The most important or most common actions should use this variant.
80
-
81
- <Canvas
82
- of={ButtonStories.Primary}
83
- sourceState="shown"
84
- source={{ code: usage.primary }}
85
- />
86
-
87
- ### Secondary
88
-
89
- The secondary variant is used for less important actions. It should be used when the primary action is already clear, and you want to provide an alternative action that is still visible but not as prominent.
90
-
91
- You might, for example, use a 'secondary' button that cancels an action, or takes the user on a path away from their most likely current goal.
92
-
93
- <Canvas
94
- of={ButtonStories.Secondary}
95
- sourceState="shown"
96
- source={{ code: usage.secondary }}
97
- />
98
-
99
- ## Tertiary
100
-
101
- Tertiary buttons add one final layer of diminishing importance. They are used for actions that are less important than the primary and secondary actions.
36
+ Use `variant` to control hierarchy and emphasis.
102
37
 
103
- <Canvas
104
- of={ButtonStories.Tertiary}
105
- sourceState="shown"
106
- source={{ code: usage.tertiary }}
107
- />
38
+ <Canvas of={ButtonStories.Primary} />
39
+ <Canvas of={ButtonStories.Secondary} source={{ code: usage.secondary }} />
40
+ <Canvas of={ButtonStories.Tertiary} />
41
+ <Canvas of={ButtonStories.Accent} />
42
+ <Canvas of={ButtonStories.PrimarySubtle} />
43
+ <Canvas of={ButtonStories.Destructive} source={{ code: usage.destructive }} />
108
44
 
109
- ## Destructive buttons
45
+ ## Sizes
110
46
 
111
- Actions that delete or remove something from the application should be clearly marked as 'destructive'. This is a UX pattern that makes it clear this action is _not reversible_.
47
+ <Canvas of={ButtonStories.Small} />
48
+ <Canvas of={ButtonStories.Large} />
112
49
 
113
- Note that only 'primary' and 'secondary' button variants can be marked as 'destructive'. This is intentional: any action that is destructive should be considered 'important' enough that using a tertiary button is not appropriate.
50
+ ## States
114
51
 
115
- `destructive?: boolean;`
116
-
117
- <Canvas
118
- of={ButtonStories.Destructive}
119
- sourceState="shown"
120
- source={{ code: usage.destructive }}
121
- />
122
- <Canvas
123
- of={ButtonStories.DestructiveSecondary}
124
- sourceState="shown"
125
- source={{ code: usage.destructiveSecondary }}
126
- />
127
-
128
- ## Disabled buttons
129
-
130
- A button that *could* be used but is *currently disabled* due to the application's state.
131
-
132
- A button in this state **cannot be pressed**, from a technical implementation: click events are not triggered, even if an `onClick` callback prop is passed to the `<Button>`.
133
-
134
- _Technical info_: The <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/disabled' target='_blank'>`disabled` attribute</a> is available on the native `<button>` element. The `<Button>` component simply passes this attribute to the underlying `<button>` element.
135
-
136
- All variants of the button can be disabled.
137
-
138
- `disabled?: boolean;`
139
-
140
- <Canvas
141
- of={ButtonStories.Disabled}
142
- sourceState="shown"
143
- source={{ code: usage.disabled }}
144
- />
145
- <Canvas
146
- of={ButtonStories.DisabledSecondary}
147
- sourceState="shown"
148
- source={{ code: usage.disabledSecondary }}
149
- />
150
- <Canvas
151
- of={ButtonStories.DisabledTertiary}
152
- sourceState="shown"
153
- source={{ code: usage.disabledTertiary }}
154
- />
52
+ <Canvas of={ButtonStories.Disabled} />
53
+ <Canvas of={ButtonStories.Loading} source={{ code: usage.loading }} />
155
54
 
156
55
  ## Icons
157
56
 
158
- Pass an <a href='?path=/docs/components-ready-to-use-icon--documentation' target='_blank'>icon</a> to the `<Button>` via the `icon` prop.
159
-
160
- **_Technical note:_** The `icon` prop takes **an actual `<Icon>` component, not an icon name** as a string.
161
-
162
- Any icon available in this component can be used — the `<Icon>` component also accepts custom SVG icons.
163
-
164
- Specify the position of the icon using the `iconPosition` prop. The default is `left`, and you can also specify `right`.
165
-
166
- `icon?: ReactNode;` <br />
167
- `iconPosition?: 'left' | 'right';`
168
-
169
- <Canvas
170
- of={ButtonStories.WithIcon}
171
- sourceState="shown"
172
- source={{ code: usage.withIcon }}
173
- />
174
-
175
- ### Icon right
176
-
177
- `iconPosition: 'right'`
178
-
179
- ```tsx
180
- <Button icon={<Icon.Upload />} iconPosition='right'>
181
- Upload
182
- </Button>
183
- ```
184
-
185
- [Check this component story to see the icon on the right.](?path=/story/components-ready-to-use-button--with-icon&args=iconPosition:right)
186
-
187
- ### Icon only
188
-
189
- To render a `<Button>` that _only_ displays an icon, you can simply not pass in any children.
190
-
191
- <Canvas
192
- of={ButtonStories.IconOnly}
193
- sourceState="shown"
194
- source={{ code: usage.iconOnly }}
195
- />
196
-
197
- _Background info:_ An HTML element that has no children is known as a '<a href='https://developer.mozilla.org/en-US/docs/Glossary/Void_element' target='_blank'>void element</a>', or an 'empty' element. We must 'self-close' these elements in React using the `/>` syntax: `<Button />`
198
-
199
- The component logic checks whether children are provided. An empty string will count as 'not provided'. The width of the `<Button>` is then set according to a single centred icon.
200
-
201
- UIKit-React also [provides an `<IconButton>` component](?path=/docs/components-ready-to-use-iconbutton--documentation), which is simply an `<Icon>` wrapped in a `<button>`. This is a more generic component, without the additional features of the `<Button>` component. If you **only want an icon that is clickable** (it can handle click events via an `onClick` callback prop), just use the `<IconButton>` component, instead.
202
-
203
- - **UX recommendation:** Include text to appear on hover via the `tooltip` prop, so users receive a text description alongside the icon: <br />`tooltip='Edit'`
204
- - **Accessibility recommendation:** Include text to be read by assistive technologies (<a href='https://abilitynet.org.uk/factsheets/introduction-screen-readers' target='_blank'>screen readers</a>) via an `aria-label` prop, so users with visual impairments understand the purpose of the button: <br />`aria-label='Edit item'`
205
-
206
- ```tsx
207
- <Button icon={<Icon.Edit />} aria-label="Edit item" tooltip="Edit" />
208
- ```
209
-
210
- More information about ARIA labels can be found here:
211
-
212
- - {<a
213
- href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-label"
214
- target="\_blank"
215
- > aria-label - ARIA | MDN</a>}
216
- - {<a
217
- href="https://www.aditus.io/aria/aria-label"
218
- target="\_blank"
219
- > aria-label - examples and best practices | Aditus</a>}
220
-
221
- ## Loading Spinner
222
-
223
- Pass a `loading` prop to the `<Button>` to show a [loading Spinner](?path=/docs/components-ready-to-use-spinner--documentation).
224
-
225
- The appropriate use case for this is to communicate to the user that an external process is happening and is not yet complete.
226
-
227
- We expect the most common example is handling asynchronous requests to servers: a 'Submit' button for a web form that awaits a success response from the server.
228
-
229
- Note that the button _cannot be pressed_ while `loading` is `true`. Click events will not be triggered. This is purposefully to prevent users triggering the same action multiple times while waiting.
230
-
231
- `loading?: boolean;`
232
-
233
- <Canvas
234
- of={ButtonStories.Loading}
235
- sourceState="shown"
236
- source={{ code: usage.loading }}
237
- />
238
-
239
- _Technical info:_ The `loading` prop would be bound to a stateful variable in the parent component. This 'loading' state is set to `true` when the button is pressed, and set to `false` when the server response is received:
240
-
241
- ```tsx
242
- <Button loading={loading}>Submit</Button>
243
- ```
57
+ <Canvas of={ButtonStories.WithIcon} source={{ code: usage.withIcon }} />
58
+ <Canvas of={ButtonStories.IconOnly} />
244
59
 
245
60
  ## Polymorphism
246
61
 
247
- We recognise that sometimes buttons are required to be used in a 'link-like' context. For example, instead of triggering a change in application state, the button takes a user to a screen in which this can be done. For flexibility, a different element to the native `<button>` element can be specified via the `as` prop.
62
+ <Canvas of={ButtonStories.Link} source={{ code: usage.link }} />
248
63
 
249
- This principle is known as '<a href='https://www.freecodecamp.org/news/build-strongly-typed-polymorphic-components-with-react-and-typescript/' target='_blank'>polymorphism</a>' in React.
64
+ ## Layout
250
65
 
251
- The `<Button>` component is polymorphic, and we expect developers may want to specify either:
66
+ <Canvas of={ButtonStories.FullWidth} source={{ code: usage.fullWidth }} />
252
67
 
253
- - an anchor `<a>` element
254
- - a custom routing component (e.g. `Link` from `wouter`)
68
+ ## Common Margins
255
69
 
256
- _We do not expect developers to use the `<Button>` component as a generic wrapper for any HTML element._
257
-
258
- The `as` prop supports either a string or a React component. If unspecified, the default is of course the native `<button>` element.
259
-
260
- Given we want the button element to be an anchor `<a>`, we provide: `as='a'`.
261
-
262
- ```tsx
263
- <Button as="a" href="https://www.ucl.ac.uk">
264
- Link
265
- </Button>
266
- ```
267
-
268
- Note we can also add in any other standard HTML attributes that are valid for the `<a>` element, such as `href`, `target`, etc. Particularly, `target='_blank'` usefully **opens the link in a new tab**.
269
-
270
- In the example below, the `<Button>` will take you to UCL's website when clicked:
271
-
272
- <Canvas
273
- of={ButtonStories.Link}
274
- sourceState="shown"
275
- source={{ code: usage.link }}
276
- />
277
-
278
- Using a custom routing component, such as <a href='https://github.com/molefrog/wouter?tab=readme-ov-file#link-hrefpath-' target='_blank'>`Link` from `wouter`</a>, we just need to import the component in the current file, then pass it directly to the `as` prop.
279
-
280
- ```tsx
281
- import { Link } from "wouter";
282
-
283
- // ...
284
-
285
- <Button as={Link} to="/">
286
- Link
287
- </Button>;
288
- ```
289
-
290
- _Technical note:_ The `disabled` attribute is not natively available on an anchor `<a>` element. To prevent link-like buttons from successfully triggering a redirect on click when the `<Button>` otherwise appears disabled, the `href` attribute of the anchor-button is removed. This has the same effect, and the underlying `<a>` tag will not redirect the user.
291
- **For custom routing components, this functionality would need to be implemented manually.**
292
-
293
- ## Full width
294
-
295
- A `fullWidth` prop sets the value of the `width` CSS property of the button to `100%`. This tells the button to take up the full width of its parent container — this could otherwise be set via a `className` prop.
296
-
297
- We recommend full width buttons be **no more than 350px wide** in practice, and used primarily on mobile devices.
298
-
299
- <div style={{ maxWidth: "350px", margin: "0 auto" }}>
300
- <Canvas
301
- of={ButtonStories.FullWidth}
302
- sourceState="none"
303
- source={{ code: usage.fullWidth }}
304
- />
305
- </div>
306
-
307
- ```tsx
308
- <Button fullWidth>Full Width Button</Button>
309
- ```
70
+ <Canvas of={ButtonStories.CommonMargins} />
310
71
 
311
72
  ## Props
312
73
 
313
- Full props specification for `<Button>` is below.
314
-
315
- Note that `<Button>` makes use of optional 'common' margin props, [as demonstrated in this component story](?path=/story/components-ready-to-use-button--common-margins&args=m:m24).
316
-
317
- <Canvas
318
- of={ButtonStories.Default}
319
- sourceState="hidden"
320
- source={{ code: usage.default }}
321
- />
74
+ <ArgTypes of={ButtonStories} />
322
75
 
323
- You can use the controls below to manipulate the `<Button>` component above.
76
+ ## Interactive Controls
324
77
 
325
- <Controls />
78
+ <Controls of={ButtonStories.Default} />