uikit-react-public 0.37.0 → 0.38.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 (128) hide show
  1. package/dist/components/Alert/Alert.d.ts +1 -1
  2. package/dist/components/Alert/Alert.stories.d.ts +1 -1
  3. package/dist/components/Alert/AlertTitle.d.ts +1 -1
  4. package/dist/components/Pagination/Pagination.stories.d.ts +1 -0
  5. package/dist/components/Pagination/PaginationControls.d.ts +2 -1
  6. package/dist/components/Pagination/__tests__/PaginationControls.test.d.ts +1 -0
  7. package/dist/components/Pagination/subcomponents/PaginationCompactControls.d.ts +7 -0
  8. package/dist/components/Pagination/subcomponents/PaginationStandardControls.d.ts +8 -0
  9. package/dist/components/Pagination/subcomponents/index.d.ts +2 -0
  10. package/dist/components/Toggle/ToggleHandle.d.ts +1 -1
  11. package/dist/components/UclLogoNew/UclLogo.d.ts +2 -1
  12. package/dist/components/UclLogoNew/__tests__/UclLogo.test.d.ts +1 -0
  13. package/dist/components/WeekPicker/__tests__/WeekPicker.test.d.ts +1 -0
  14. package/dist/index.js +5383 -5149
  15. package/dist/theme/dark/darkColour.d.ts +1 -0
  16. package/dist/theme/index.d.ts +1 -1
  17. package/dist/theme/light/lightColour.d.ts +1 -0
  18. package/dist/theme/original/defaultTheme.d.ts +7 -0
  19. package/dist/theme/original/originalColourNewStructure.d.ts +1 -0
  20. package/dist/theme/useTheme.d.ts +12 -0
  21. package/lib/components/Alert/AlertMessage.tsx +5 -4
  22. package/lib/components/Alert/AlertTitle.tsx +6 -8
  23. package/lib/components/AppHeader/AppHeader.stories.tsx +3 -3
  24. package/lib/components/AppHeader/AppHeader.tsx +2 -2
  25. package/lib/components/AppHeader/AppHeaderBottom.tsx +2 -3
  26. package/lib/components/AppHeader/AppHeaderTop.tsx +1 -1
  27. package/lib/components/AppHeader/__tests__/__snapshots__/AppHeader.test.tsx.snap +1 -1
  28. package/lib/components/AppMenu/AppMenuContent.tsx +4 -5
  29. package/lib/components/AppMenu/AppMenuDivider.tsx +5 -6
  30. package/lib/components/AppMenu/AppMenuItem.tsx +6 -6
  31. package/lib/components/AppMenu/__tests__/__snapshots__/AppMenu.test.tsx.snap +1 -1
  32. package/lib/components/Avatar/Avatar.tsx +7 -5
  33. package/lib/components/Avatar/__tests__/__snapshots__/Avatar.test.tsx.snap +18 -18
  34. package/lib/components/Badge/Badge.tsx +12 -12
  35. package/lib/components/Badge/__tests__/Badge.test.tsx +84 -1
  36. package/lib/components/Badge/__tests__/__snapshots__/Badge.test.tsx.snap +2 -2
  37. package/lib/components/Blanket/Blanket.tsx +1 -1
  38. package/lib/components/Blanket/__tests__/__snapshots__/Blanket.test.tsx.snap +1 -1
  39. package/lib/components/Button/__tests__/Button.test.tsx +46 -1
  40. package/lib/components/Button/__tests__/__snapshots__/Button.test.tsx.snap +2 -2
  41. package/lib/components/Button/style/buttonAccentStyle.ts +1 -1
  42. package/lib/components/Button/style/buttonPrimaryDestructiveStyle.ts +1 -1
  43. package/lib/components/Button/style/buttonPrimaryWarningStyle.ts +1 -1
  44. package/lib/components/Button/style/buttonSecondarySubtleStyle.ts +1 -1
  45. package/lib/components/Calendar/Calendar.tsx +1 -0
  46. package/lib/components/Calendar/__tests__/__snapshots__/Calendar.test.tsx.snap +17 -17
  47. package/lib/components/Calendar/subcomponents/AcademicWeek.tsx +0 -1
  48. package/lib/components/Calendar/subcomponents/Day.tsx +2 -2
  49. package/lib/components/Chip/Chip.tsx +7 -8
  50. package/lib/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap +5 -5
  51. package/lib/components/CookieNotice/CookieNotice.tsx +3 -3
  52. package/lib/components/Datepicker/__tests__/Datepicker.test.tsx +34 -1
  53. package/lib/components/Datepicker/__tests__/__snapshots__/Datepicker.test.tsx.snap +6 -6
  54. package/lib/components/Datepicker/subcomponents/DatepickerInput.tsx +7 -6
  55. package/lib/components/Datepicker/subcomponents/VisibleField.tsx +6 -8
  56. package/lib/components/Dialog/BaseDialog.tsx +3 -3
  57. package/lib/components/Divider/Divider.tsx +5 -3
  58. package/lib/components/FileInput/FileInput.tsx +1 -1
  59. package/lib/components/FileInput/__tests__/__snapshots__/FileInput.test.tsx.snap +2 -2
  60. package/lib/components/Footer/Footer.tsx +17 -17
  61. package/lib/components/Footer/FooterNavLink.tsx +3 -3
  62. package/lib/components/Footer/SocialLink.tsx +3 -3
  63. package/lib/components/Footer/__tests__/__snapshots__/Footer.test.tsx.snap +55 -55
  64. package/lib/components/FooterNew/BackToTop.tsx +1 -1
  65. package/lib/components/FooterNew/FooterColumn.tsx +1 -2
  66. package/lib/components/FooterNew/FooterNavLink.tsx +6 -5
  67. package/lib/components/FooterNew/LegalAndCopyright.tsx +15 -15
  68. package/lib/components/FooterNew/LogoAddressAndSocial.tsx +8 -6
  69. package/lib/components/FooterNew/SocialLink.tsx +4 -4
  70. package/lib/components/FooterNew/__tests__/__snapshots__/Footer.test.tsx.snap +44 -44
  71. package/lib/components/Header/Header.tsx +3 -3
  72. package/lib/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +2 -2
  73. package/lib/components/HeaderDraft/HeaderBottomBreadcrumbs.tsx +3 -4
  74. package/lib/components/HeaderDraft/HeaderBottomHeadingAndAvatar.tsx +7 -7
  75. package/lib/components/HeaderDraft/HeaderBreadcrumb.tsx +4 -4
  76. package/lib/components/HeaderDraft/HeaderDraft.tsx +7 -7
  77. package/lib/components/HeaderDraft/__tests__/__snapshots__/Header.test.tsx.snap +5 -5
  78. package/lib/components/HeaderNew/Header.tsx +2 -2
  79. package/lib/components/HeaderNew/__tests__/__snapshots__/Header.test.tsx.snap +2 -2
  80. package/lib/components/Input/Input.tsx +6 -6
  81. package/lib/components/Input/__tests__/__snapshots__/Input.test.tsx.snap +4 -4
  82. package/lib/components/Label/Label.tsx +2 -2
  83. package/lib/components/Label/__tests__/__snapshots__/Label.test.tsx.snap +1 -1
  84. package/lib/components/Layout/Layout.stories.tsx +12 -12
  85. package/lib/components/Link/Link.tsx +4 -4
  86. package/lib/components/Menu/MenuContent.tsx +3 -3
  87. package/lib/components/Menu/MenuItem.tsx +10 -8
  88. package/lib/components/Menu/MenuSection.tsx +1 -1
  89. package/lib/components/Modal/Modal.tsx +5 -15
  90. package/lib/components/Modal/__tests__/__snapshots__/Modal.test.tsx.snap +2 -2
  91. package/lib/components/NativeDatepicker/NativeDatepicker.tsx +9 -7
  92. package/lib/components/Pagination/Pagination.stories.tsx +9 -0
  93. package/lib/components/Pagination/PaginationControls.tsx +17 -245
  94. package/lib/components/Pagination/__tests__/PaginationControls.test.tsx +213 -0
  95. package/lib/components/Pagination/subcomponents/PaginationCompactControls.tsx +266 -0
  96. package/lib/components/Pagination/subcomponents/PaginationStandardControls.tsx +246 -0
  97. package/lib/components/Pagination/subcomponents/index.ts +2 -0
  98. package/lib/components/Radio/Radio.tsx +13 -4
  99. package/lib/components/Radio/__tests__/__snapshots__/Radio.test.tsx.snap +3 -3
  100. package/lib/components/Search/Search.tsx +2 -2
  101. package/lib/components/Search/__tests__/__snapshots__/Search.test.tsx.snap +2 -2
  102. package/lib/components/Select/subcomponents/CustomSelect.tsx +4 -4
  103. package/lib/components/Spinner/Spinner.stories.tsx +3 -3
  104. package/lib/components/Spinner/Spinner.tsx +1 -1
  105. package/lib/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +3 -3
  106. package/lib/components/Table/subcomponents/Head.tsx +2 -2
  107. package/lib/components/Table/subcomponents/Row.tsx +1 -1
  108. package/lib/components/Textarea/Textarea.tsx +7 -8
  109. package/lib/components/Textarea/__tests__/__snapshots__/Textarea.test.tsx.snap +4 -4
  110. package/lib/components/Timepicker/Timepicker.tsx +6 -4
  111. package/lib/components/Toggle/Toggle.tsx +3 -1
  112. package/lib/components/Toggle/ToggleHandle.tsx +4 -2
  113. package/lib/components/Tooltip/Tooltip.tsx +8 -5
  114. package/lib/components/Tooltip/__tests__/__snapshots__/tooltip.test.tsx.snap +2 -2
  115. package/lib/components/UclLogo/UclLogoNegativeSpace.tsx +7 -3
  116. package/lib/components/UclLogoNew/UclLogo.tsx +8 -9
  117. package/lib/components/UclLogoNew/__tests__/UclLogo.test.tsx +41 -0
  118. package/lib/components/WeekPicker/__tests__/WeekPicker.test.tsx +36 -0
  119. package/lib/components/WeekPicker/subcomponents/DatepickerInput.tsx +6 -6
  120. package/lib/components/WeekPicker/subcomponents/VisibleField.tsx +9 -9
  121. package/lib/theme/dark/darkColour.ts +2 -1
  122. package/lib/theme/dark/darkTheme.ts +8 -1
  123. package/lib/theme/index.ts +1 -0
  124. package/lib/theme/light/lightColour.ts +2 -1
  125. package/lib/theme/light/lightTheme.ts +7 -0
  126. package/lib/theme/original/defaultTheme.ts +10 -0
  127. package/lib/theme/original/originalColourNewStructure.ts +2 -1
  128. package/package.json +6 -6
@@ -0,0 +1,266 @@
1
+ import {
2
+ ChangeEvent,
3
+ HTMLAttributes,
4
+ KeyboardEvent,
5
+ memo,
6
+ useContext,
7
+ useEffect,
8
+ useId,
9
+ useState,
10
+ } from 'react';
11
+ import { css, cx } from '@emotion/css';
12
+ import useTheme from '../../../theme/useTheme';
13
+ import { PaginationContext } from '../Pagination';
14
+ import Button from '../../Button';
15
+ import Icon from '../../Icon';
16
+ import Input from '../../Input';
17
+ import Text from '../../Text';
18
+ import announce from '../../../utils/announce';
19
+
20
+ export interface PaginationCompactControlsProps extends HTMLAttributes<HTMLDivElement> {
21
+ name: string;
22
+ testId: string;
23
+ }
24
+
25
+ const PaginationCompactControls = ({
26
+ name,
27
+ testId,
28
+ className,
29
+ ...props
30
+ }: PaginationCompactControlsProps) => {
31
+ const [theme] = useTheme();
32
+ const contextValue = useContext(PaginationContext);
33
+ const [pageInputValue, setPageInputValue] = useState(
34
+ String(contextValue?.currentPage ?? 1)
35
+ );
36
+ const [pageInputError, setPageInputError] = useState('');
37
+ const pageInputDescriptionId = useId();
38
+
39
+ useEffect(() => {
40
+ setPageInputValue(String(contextValue?.currentPage ?? 1));
41
+ setPageInputError('');
42
+ }, [contextValue?.currentPage]);
43
+
44
+ if (!contextValue) {
45
+ return null;
46
+ }
47
+
48
+ const {
49
+ mode,
50
+ limit,
51
+ total,
52
+ currentPage,
53
+ trackedMaxPage,
54
+ hasPreviousPage,
55
+ hasNextPage,
56
+ onPageChange,
57
+ onNextPage,
58
+ onPreviousPage,
59
+ } = contextValue;
60
+
61
+ const totalPages =
62
+ typeof total === 'number' ? Math.ceil(total / limit) : undefined;
63
+ const lastPageNumber = totalPages ?? trackedMaxPage;
64
+ const displayedCurrentPage = totalPages === 0 ? 0 : currentPage;
65
+
66
+ const handlePageChange = (newPage: number) => {
67
+ if (mode === 'tracked') {
68
+ if (newPage < 1 || newPage > trackedMaxPage || newPage === currentPage) {
69
+ return;
70
+ }
71
+ onPageChange?.(newPage);
72
+ return;
73
+ }
74
+
75
+ onPageChange?.((newPage - 1) * limit);
76
+ };
77
+
78
+ const handlePreviousPage = () => {
79
+ if (mode === 'tracked' && onPreviousPage) {
80
+ onPreviousPage();
81
+ return;
82
+ }
83
+ handlePageChange(currentPage - 1);
84
+ };
85
+
86
+ const handleNextPage = () => {
87
+ if (mode === 'tracked') {
88
+ onNextPage?.();
89
+ return;
90
+ }
91
+ handlePageChange(currentPage + 1);
92
+ };
93
+
94
+ const handlePageInputChange = (event: ChangeEvent<HTMLInputElement>) => {
95
+ setPageInputValue(event.target.value);
96
+ setPageInputError('');
97
+ };
98
+
99
+ const resetPageInput = () => {
100
+ setPageInputValue(String(currentPage));
101
+ setPageInputError('');
102
+ };
103
+
104
+ const handlePageInputKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
105
+ if (event.key === 'Escape') {
106
+ resetPageInput();
107
+ event.currentTarget.blur();
108
+ return;
109
+ }
110
+
111
+ if (event.key !== 'Enter') {
112
+ return;
113
+ }
114
+
115
+ event.preventDefault();
116
+
117
+ const isDigitsOnly = /^\d+$/.test(pageInputValue);
118
+ const newPageNumber = Number(pageInputValue);
119
+
120
+ if (
121
+ !isDigitsOnly ||
122
+ !Number.isInteger(newPageNumber) ||
123
+ newPageNumber < 1 ||
124
+ newPageNumber > lastPageNumber
125
+ ) {
126
+ const errorMessage = `Enter a page number from 1 to ${lastPageNumber}.`;
127
+ setPageInputError(errorMessage);
128
+ announce(errorMessage, true);
129
+ return;
130
+ }
131
+
132
+ setPageInputError('');
133
+ handlePageChange(newPageNumber);
134
+ event.currentTarget.blur();
135
+ };
136
+
137
+ const controlsListStyle = css`
138
+ margin: 0;
139
+ padding: 0;
140
+ display: flex;
141
+ justify-content: center;
142
+ align-items: center;
143
+ list-style: none;
144
+ gap: ${theme.margin.m8};
145
+ `;
146
+
147
+ const navigationButtonStyle = css`
148
+ gap: ${theme.margin.m8};
149
+ `;
150
+
151
+ const pageInputStyle = css`
152
+ height: 48px;
153
+ width: 48px;
154
+ box-sizing: border-box;
155
+ border: ${theme.thickness.t2} solid ${theme.colour.border.default};
156
+ border-radius: ${theme.radius.r4};
157
+ padding: 0;
158
+ text-align: center;
159
+ color: ${theme.colour.text.default};
160
+ font-family: ${theme.typography.body.md.fontFamily};
161
+ font-size: ${theme.typography.body.md.fontSize};
162
+
163
+ &[aria-invalid='true'] {
164
+ border-color: ${theme.colour.border.critical};
165
+ }
166
+ `;
167
+
168
+ const totalPagesLabelStyle = css`
169
+ color: ${theme.colour.text.secondary};
170
+ white-space: nowrap;
171
+ `;
172
+
173
+ const visuallyHiddenStyle = css`
174
+ position: absolute;
175
+ width: 1px;
176
+ height: 1px;
177
+ padding: 0;
178
+ margin: -1px;
179
+ overflow: hidden;
180
+ clip: rect(0, 0, 0, 0);
181
+ white-space: nowrap;
182
+ border: 0;
183
+ `;
184
+
185
+ const pageInputDescription =
186
+ typeof totalPages === 'number'
187
+ ? `Page ${displayedCurrentPage} of ${totalPages}.${
188
+ totalPages === 0 ? '' : ' Enter a page number and press Enter.'
189
+ }`
190
+ : `Page ${currentPage}. Enter a page number and press Enter.`;
191
+
192
+ const style = cx(name, className);
193
+
194
+ return (
195
+ <nav
196
+ {...props}
197
+ className={style}
198
+ aria-label={
199
+ typeof totalPages === 'number'
200
+ ? `Pagination, ${totalPages} pages total`
201
+ : 'Pagination'
202
+ }
203
+ data-testid={testId}
204
+ >
205
+ <ul className={controlsListStyle}>
206
+ <li>
207
+ <Button
208
+ className={navigationButtonStyle}
209
+ variant='tertiary'
210
+ icon={<Icon.ChevronLeft />}
211
+ aria-label='Go to previous page'
212
+ onClick={handlePreviousPage}
213
+ disabled={!hasPreviousPage}
214
+ >
215
+ Previous
216
+ </Button>
217
+ </li>
218
+ <li>
219
+ <Input
220
+ inputClassName={pageInputStyle}
221
+ type='text'
222
+ inputMode='numeric'
223
+ pattern='[0-9]*'
224
+ value={
225
+ totalPages === 0 ? String(displayedCurrentPage) : pageInputValue
226
+ }
227
+ aria-label='Page number'
228
+ aria-current={totalPages === 0 ? undefined : 'page'}
229
+ aria-describedby={pageInputDescriptionId}
230
+ aria-invalid={pageInputError ? true : undefined}
231
+ disabled={totalPages === 0}
232
+ onChange={handlePageInputChange}
233
+ onBlur={resetPageInput}
234
+ onKeyDown={handlePageInputKeyDown}
235
+ />
236
+ <span
237
+ id={pageInputDescriptionId}
238
+ className={visuallyHiddenStyle}
239
+ >
240
+ {pageInputDescription}
241
+ </span>
242
+ </li>
243
+ {typeof totalPages === 'number' && (
244
+ <li>
245
+ <Text className={totalPagesLabelStyle}>of {totalPages}</Text>
246
+ </li>
247
+ )}
248
+ <li>
249
+ <Button
250
+ className={navigationButtonStyle}
251
+ variant='tertiary'
252
+ icon={<Icon.ChevronRight />}
253
+ iconPosition='right'
254
+ aria-label='Go to next page'
255
+ onClick={handleNextPage}
256
+ disabled={!hasNextPage}
257
+ >
258
+ Next
259
+ </Button>
260
+ </li>
261
+ </ul>
262
+ </nav>
263
+ );
264
+ };
265
+
266
+ export default memo(PaginationCompactControls);
@@ -0,0 +1,246 @@
1
+ import { HTMLAttributes, memo, useContext } from 'react';
2
+ import { css, cx } from '@emotion/css';
3
+ import useTheme from '../../../theme/useTheme';
4
+ import { PaginationContext } from '../Pagination';
5
+ import Button from '../../Button';
6
+ import getPaginationButtons from '../getPaginationButtons';
7
+ import { useMediaQuery } from '../../../hooks';
8
+
9
+ export interface PaginationStandardControlsProps extends HTMLAttributes<HTMLDivElement> {
10
+ maxNumberButtons: number;
11
+ name: string;
12
+ testId: string;
13
+ }
14
+
15
+ const PaginationStandardControls = ({
16
+ maxNumberButtons,
17
+ name,
18
+ testId,
19
+ className,
20
+ ...props
21
+ }: PaginationStandardControlsProps) => {
22
+ const [theme] = useTheme();
23
+
24
+ const isTabletPlus = useMediaQuery(
25
+ `(min-width: ${theme.breakpoints.tablet}px)`
26
+ );
27
+
28
+ const contextValue = useContext(PaginationContext);
29
+
30
+ if (!contextValue) {
31
+ return null;
32
+ }
33
+
34
+ const {
35
+ mode,
36
+ limit,
37
+ total,
38
+ currentPage,
39
+ trackedMaxPage,
40
+ hasPreviousPage,
41
+ hasNextPage,
42
+ onPageChange,
43
+ onNextPage,
44
+ onPreviousPage,
45
+ } = contextValue;
46
+
47
+ const handlePageChange = (newPage: number) => {
48
+ if (mode === 'tracked') {
49
+ if (newPage < 1 || newPage > trackedMaxPage || newPage === currentPage) {
50
+ return;
51
+ }
52
+ onPageChange?.(newPage);
53
+ return;
54
+ }
55
+
56
+ onPageChange?.((newPage - 1) * limit);
57
+ };
58
+
59
+ const totalPages =
60
+ typeof total === 'number' ? Math.ceil(total / limit) : undefined;
61
+
62
+ const paginationButtons =
63
+ mode === 'tracked'
64
+ ? Array.from({ length: trackedMaxPage }, (_, i) => i + 1)
65
+ : getPaginationButtons(
66
+ currentPage,
67
+ totalPages ?? 0,
68
+ isTabletPlus ? maxNumberButtons : 5
69
+ );
70
+
71
+ const style = cx(name, className);
72
+
73
+ const listStyle = css`
74
+ margin: 0;
75
+ padding: 0;
76
+ display: flex;
77
+ justify-content: center;
78
+ align-items: center;
79
+ list-style: none;
80
+ gap: ${theme.margin.m4};
81
+ flex-wrap: nowrap;
82
+
83
+ @media (min-width: ${theme.breakpoints.tablet}px) {
84
+ gap: ${theme.margin.m8};
85
+ }
86
+ `;
87
+
88
+ const buttonBaseStyle = css`
89
+ @media (max-width: ${theme.breakpoints.tablet}px) {
90
+ gap: ${theme.margin.m4};
91
+ }
92
+ `;
93
+
94
+ const previousButtonStyle = cx(
95
+ buttonBaseStyle,
96
+ css`
97
+ margin-right: ${theme.margin.m16};
98
+ display: none;
99
+
100
+ @media (min-width: ${theme.breakpoints.tablet}px) {
101
+ display: inline-block;
102
+ }
103
+ `
104
+ );
105
+
106
+ const nextButtonStyle = cx(
107
+ buttonBaseStyle,
108
+ css`
109
+ margin-left: ${theme.margin.m16};
110
+ display: none;
111
+
112
+ @media (min-width: ${theme.breakpoints.tablet}px) {
113
+ display: inline-block;
114
+ }
115
+ `
116
+ );
117
+
118
+ const pageNumberButtonBaseStyle = cx(
119
+ buttonBaseStyle,
120
+ css`
121
+ height: 40px;
122
+ min-width: 40px;
123
+ padding: 0;
124
+
125
+ @media (min-width: ${theme.breakpoints.tablet}px) {
126
+ height: 48px;
127
+ min-width: 48px;
128
+ }
129
+ `
130
+ );
131
+
132
+ const pageNumberButtonStyle = cx(
133
+ pageNumberButtonBaseStyle,
134
+ css`
135
+ border: none;
136
+ color: ${theme.colour.text.secondary};
137
+ `
138
+ );
139
+
140
+ const currentPageNumberButtonStyle = cx(
141
+ pageNumberButtonBaseStyle,
142
+ css`
143
+ color: ${theme.colour.text.brand};
144
+ border-color: ${theme.colour.border.brand};
145
+ `
146
+ );
147
+
148
+ const buttonNumberLabelStyle = css`
149
+ padding: 0 ${theme.padding.p8};
150
+ `;
151
+
152
+ return (
153
+ <nav
154
+ {...props}
155
+ className={style}
156
+ aria-label={
157
+ typeof totalPages === 'number'
158
+ ? `Pagination, ${totalPages} pages total`
159
+ : 'Pagination'
160
+ }
161
+ data-testid={testId}
162
+ >
163
+ <ul className={listStyle}>
164
+ <li>
165
+ <Button
166
+ className={previousButtonStyle}
167
+ variant='tertiary'
168
+ size={isTabletPlus ? 'default' : 'small'}
169
+ aria-label='Go to previous page'
170
+ onClick={() => {
171
+ if (mode === 'tracked') {
172
+ if (onPreviousPage) {
173
+ onPreviousPage();
174
+ } else {
175
+ handlePageChange(currentPage - 1);
176
+ }
177
+ return;
178
+ }
179
+ handlePageChange(currentPage - 1);
180
+ }}
181
+ disabled={!hasPreviousPage}
182
+ >
183
+ Previous
184
+ </Button>
185
+ </li>
186
+
187
+ {paginationButtons.map((page) => (
188
+ <li key={page}>
189
+ {page === '...1' || page === '...2' ? (
190
+ <span aria-hidden>...</span>
191
+ ) : (
192
+ <>
193
+ {page !== currentPage && (
194
+ <Button
195
+ className={pageNumberButtonStyle}
196
+ variant='secondary'
197
+ size={isTabletPlus ? 'default' : 'small'}
198
+ aria-label={`Page ${page}`}
199
+ onClick={() => handlePageChange(page)}
200
+ >
201
+ <span className={buttonNumberLabelStyle}>{page}</span>
202
+ </Button>
203
+ )}
204
+ {page === currentPage && (
205
+ <Button
206
+ className={currentPageNumberButtonStyle}
207
+ variant='secondary'
208
+ size={isTabletPlus ? 'default' : 'small'}
209
+ aria-label={`Page ${page}, current page`}
210
+ aria-current='page'
211
+ disabled
212
+ onClick={() => handlePageChange(page)}
213
+ >
214
+ <span className={buttonNumberLabelStyle}>{page}</span>
215
+ </Button>
216
+ )}
217
+ </>
218
+ )}
219
+ </li>
220
+ ))}
221
+
222
+ <li>
223
+ <Button
224
+ className={nextButtonStyle}
225
+ variant='tertiary'
226
+ aria-label='Go to next page'
227
+ onClick={() => {
228
+ if (mode === 'tracked') {
229
+ if (onNextPage) {
230
+ onNextPage();
231
+ }
232
+ return;
233
+ }
234
+ handlePageChange(currentPage + 1);
235
+ }}
236
+ disabled={!hasNextPage}
237
+ >
238
+ Next
239
+ </Button>
240
+ </li>
241
+ </ul>
242
+ </nav>
243
+ );
244
+ };
245
+
246
+ export default memo(PaginationStandardControls);
@@ -0,0 +1,2 @@
1
+ export { default as PaginationCompactControls } from './PaginationCompactControls';
2
+ export { default as PaginationStandardControls } from './PaginationStandardControls';
@@ -50,7 +50,7 @@ const Radio = forwardRef<Ref, RadioProps>(
50
50
  border-style: solid;
51
51
  outline: none;
52
52
  box-sizing: border-box;
53
- color: ${theme.color.neutral.white};
53
+ color: ${theme.colour.icon.inverse};
54
54
  transition:
55
55
  background-color 0.15s ease-out,
56
56
  border-color 0.15s ease-out;
@@ -74,7 +74,13 @@ const Radio = forwardRef<Ref, RadioProps>(
74
74
  border-color: ${theme.colour.speciality.inputDefault};
75
75
  `;
76
76
 
77
- const disabledStyle = css`
77
+ const disabledUncheckedStyle = css`
78
+ background-color: ${theme.colour.icon.inverse};
79
+ border-color: ${theme.colour.border.disabled};
80
+ cursor: not-allowed;
81
+ `;
82
+
83
+ const disabledCheckedStyle = css`
78
84
  background-color: ${theme.colour.icon.disabled};
79
85
  border-color: ${theme.colour.icon.disabled};
80
86
  cursor: not-allowed;
@@ -87,7 +93,8 @@ const Radio = forwardRef<Ref, RadioProps>(
87
93
  !disabled && focusStyle,
88
94
  isChecked && checkedStyle,
89
95
  !isChecked && uncheckedStyle,
90
- disabled && disabledStyle,
96
+ disabled && !isChecked && disabledUncheckedStyle,
97
+ disabled && isChecked && disabledCheckedStyle,
91
98
  className
92
99
  );
93
100
 
@@ -112,7 +119,9 @@ const Radio = forwardRef<Ref, RadioProps>(
112
119
  width: 12px;
113
120
  height: 12px;
114
121
  border-radius: 50%;
115
- background-color: ${theme.colour.icon.inverse};
122
+ background-color: ${
123
+ disabled ? theme.colour.icon.brandInverse : theme.colour.icon.inverse
124
+ };
116
125
  user-select: none;
117
126
  pointer-events: none;
118
127
  `;
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`Radio > snapshot: checked prop 1`] = `
4
4
  <span
5
- class="ucl-uikit-radio css-1y63xt7"
5
+ class="ucl-uikit-radio css-1elh2am"
6
6
  >
7
7
  <input
8
8
  checked=""
@@ -18,7 +18,7 @@ exports[`Radio > snapshot: checked prop 1`] = `
18
18
 
19
19
  exports[`Radio > snapshot: no props 1`] = `
20
20
  <span
21
- class="ucl-uikit-radio css-121ivaw"
21
+ class="ucl-uikit-radio css-auet16"
22
22
  >
23
23
  <input
24
24
  class="css-19qtec1"
@@ -30,7 +30,7 @@ exports[`Radio > snapshot: no props 1`] = `
30
30
 
31
31
  exports[`Radio > snapshot: testId prop 1`] = `
32
32
  <span
33
- class="ucl-uikit-radio css-121ivaw"
33
+ class="ucl-uikit-radio css-auet16"
34
34
  >
35
35
  <input
36
36
  class="css-19qtec1"
@@ -119,7 +119,7 @@ const Search = ({
119
119
  `;
120
120
 
121
121
  const cancelIconButtonInactiveStyle = css`
122
- color: ${theme.color.neutral.grey20};
122
+ color: ${theme.colour.icon.disabled};
123
123
  `;
124
124
 
125
125
  const cancelButtonStyle = cx(
@@ -130,7 +130,7 @@ const Search = ({
130
130
  const dividerStyle = css`
131
131
  width: 1px;
132
132
  height: 38px;
133
- background-color: ${theme.color.neutral.grey20};
133
+ background-color: ${theme.colour.border.disabled};
134
134
  `;
135
135
 
136
136
  const submitButtonStyle = css`
@@ -8,7 +8,7 @@ exports[`Search > snapshot: no props 1`] = `
8
8
  class="ucl-uikit-input css-1bpb1dw"
9
9
  >
10
10
  <input
11
- class="ucl-uikit-input__input css-181a0dk"
11
+ class="ucl-uikit-input__input css-1g04erc"
12
12
  data-testid="ucl-uikit-search"
13
13
  id=""
14
14
  placeholder=""
@@ -87,7 +87,7 @@ exports[`Search > snapshot: testId prop 1`] = `
87
87
  class="ucl-uikit-input css-1bpb1dw"
88
88
  >
89
89
  <input
90
- class="ucl-uikit-input__input css-181a0dk"
90
+ class="ucl-uikit-input__input css-1g04erc"
91
91
  data-testid="test123"
92
92
  id=""
93
93
  placeholder=""
@@ -588,18 +588,18 @@ const CustomSelect = <T extends string | number>({
588
588
  `;
589
589
 
590
590
  const disabledStyle = css`
591
- color: ${theme.color.text.disabled};
592
- border: ${theme.border.b1} solid ${theme.color.neutral.grey20};
591
+ color: ${theme.colour.text.disabled};
592
+ border: ${theme.border.b1} solid ${theme.colour.border.disabled};
593
593
  cursor: not-allowed;
594
594
 
595
595
  &:hover {
596
- background-color: ${theme.color.neutral.white};
596
+ background-color: ${theme.colour.fill.inverse};
597
597
  }
598
598
  `;
599
599
 
600
600
  const noOptionsStyle = css`
601
601
  padding: ${theme.padding.p8} ${theme.padding.p16};
602
- color: ${theme.color.text.secondary};
602
+ color: ${theme.colour.text.secondary};
603
603
  `;
604
604
 
605
605
  // Visually hidden but available to assistive technology
@@ -25,7 +25,7 @@ export const White: Story = {
25
25
  },
26
26
  args: {
27
27
  className: css`
28
- color: ${theme.color.neutral.white};
28
+ color: ${theme.colour.fill.inverse};
29
29
  `,
30
30
  },
31
31
  };
@@ -33,7 +33,7 @@ export const White: Story = {
33
33
  export const Blue: Story = {
34
34
  args: {
35
35
  className: css`
36
- color: ${theme.color.system.blue70};
36
+ color: ${theme.colour.fill.brand};
37
37
  `,
38
38
  },
39
39
  };
@@ -41,7 +41,7 @@ export const Blue: Story = {
41
41
  export const Red: Story = {
42
42
  args: {
43
43
  className: css`
44
- color: ${theme.color.system.red70};
44
+ color: ${theme.colour.fill.critical};
45
45
  `,
46
46
  },
47
47
  };
@@ -27,7 +27,7 @@ const Spinner = ({
27
27
  const dashDuration = `2s`; // dash duration
28
28
 
29
29
  const baseStyle = css`
30
- color: ${inheritColour ? 'inherit' : theme.colour.icon.brand};
30
+ color: ${inheritColour ? 'inherit' : theme.colour.fill.brand};
31
31
  `;
32
32
 
33
33
  const gStyle = css`
@@ -6,11 +6,11 @@ exports[`Table > Snapshot: basic table 1`] = `
6
6
  data-testid="ucl-uikit-table"
7
7
  >
8
8
  <thead
9
- class="css-1ux39q6 ucl-uikit-table__head"
9
+ class="css-b9vb4h ucl-uikit-table__head"
10
10
  data-testid="ucl-uikit-table__head"
11
11
  >
12
12
  <tr
13
- class="css-1pr7kjy"
13
+ class="css-7kbd2r"
14
14
  >
15
15
  <th
16
16
  class="css-x1n4gt ucl-uikit-table__head-cell"
@@ -173,7 +173,7 @@ exports[`Table > Snapshot: basic table 1`] = `
173
173
  >
174
174
  <tr
175
175
  aria-selected="false"
176
- class="css-icxsp9 ucl-uikit-table__row"
176
+ class="css-h7fw6w ucl-uikit-table__row"
177
177
  data-mobile-expanded="true"
178
178
  data-testid="ucl-uikit-table__row"
179
179
  >