uikit-react-public 0.11.24 → 0.14.21
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.
- package/dist/components/Badge/Badge.d.ts +6 -0
- package/dist/components/Badge/Badge.stories.d.ts +15 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Button/Button.d.ts +2 -1
- package/dist/components/CookieNotice/CookieNotice.d.ts +16 -0
- package/dist/components/CookieNotice/index.d.ts +2 -0
- package/dist/components/Dialog/BaseDialog.d.ts +7 -2
- package/dist/components/FileInput/FileInput.d.ts +8 -0
- package/dist/components/FileInput/FileInput.stories.d.ts +16 -0
- package/dist/components/FileInput/__tests__/FileInput.test.d.ts +1 -0
- package/dist/components/FileInput/index.d.ts +2 -0
- package/dist/components/Header/Header.d.ts +4 -1
- package/dist/components/Heading/Heading.d.ts +1 -1
- package/dist/components/Link/BaseLink.d.ts +10 -0
- package/dist/components/Link/Link.d.ts +5 -10
- package/dist/components/Link/Link.stories.d.ts +1 -1
- package/dist/components/Link/index.d.ts +1 -1
- package/dist/components/Menu/MenuContent.d.ts +1 -1
- package/dist/components/Menu/MenuItem.d.ts +2 -0
- package/dist/components/Menu/MenuSection.d.ts +1 -1
- package/dist/components/Search/Search.d.ts +16 -0
- package/dist/components/Search/Search.stories.d.ts +34 -0
- package/dist/components/Search/__tests__/Search.test.d.ts +1 -0
- package/dist/components/Search/index.d.ts +2 -0
- package/dist/components/Select/Select.d.ts +1 -1
- package/dist/components/Select/Select.stories.d.ts +3 -7
- package/dist/components/Select/Select.types.d.ts +19 -14
- package/dist/components/Select/subcomponents/CustomOption.d.ts +1 -1
- package/dist/components/Select/subcomponents/CustomSelect.d.ts +1 -2
- package/dist/components/Select/subcomponents/Panel.d.ts +1 -1
- package/dist/components/Select/subcomponents/VisibleField.d.ts +4 -4
- package/dist/components/StandaloneLink/StandaloneLink.d.ts +12 -0
- package/dist/components/StandaloneLink/StandaloneLink.stories.d.ts +13 -0
- package/dist/components/StandaloneLink/__tests__/StandaloneLink.test.d.ts +1 -0
- package/dist/components/StandaloneLink/index.d.ts +2 -0
- package/dist/components/Table/Table.d.ts +10 -8
- package/dist/components/Table/Table.stories.d.ts +21 -0
- package/dist/components/Table/Table.types.d.ts +11 -0
- package/dist/components/Table/__tests__/Table.test.d.ts +1 -0
- package/dist/components/Table/index.d.ts +2 -1
- package/dist/components/Table/subcomponents/Body.d.ts +4 -0
- package/dist/components/Table/subcomponents/Cell/Cell.d.ts +12 -0
- package/dist/components/Table/subcomponents/Cell/Cell.stories.d.ts +313 -0
- package/dist/components/Table/subcomponents/Cell/CellContent.d.ts +10 -0
- package/dist/components/Table/subcomponents/Cell/__tests__/Cell.test.d.ts +1 -0
- package/dist/components/Table/subcomponents/Head.d.ts +4 -0
- package/dist/components/Table/subcomponents/HeadCell/HeadCell.d.ts +13 -0
- package/dist/components/Table/subcomponents/HeadCell/HeadCell.stories.d.ts +312 -0
- package/dist/components/Table/subcomponents/HeadCell/HeadCellContent.d.ts +10 -0
- package/dist/components/Table/subcomponents/HeadCell/__tests__/HeadCell.test.d.ts +1 -0
- package/dist/components/Table/subcomponents/Row.d.ts +5 -0
- package/dist/components/Table/subcomponents/SortIcon.d.ts +7 -0
- package/dist/components/Table/subcomponents/index.d.ts +10 -0
- package/dist/components/Tabs/Tab.d.ts +1 -1
- package/dist/components/Tabs/TabContext.d.ts +1 -0
- package/dist/components/Tabs/Tabs.d.ts +3 -1
- package/dist/components/Tabs/Tabs.stories.d.ts +3 -0
- package/dist/components/Timepicker/Timepicker.d.ts +10 -0
- package/dist/components/Timepicker/Timepicker.stories.d.ts +7 -0
- package/dist/components/Timepicker/__tests__/Timepicker.test.d.ts +1 -0
- package/dist/components/Timepicker/index.d.ts +2 -0
- package/dist/components/Timepicker/utils/convertDateToTimeString.d.ts +2 -0
- package/dist/components/Timepicker/utils/convertDateToTimeString.test.d.ts +1 -0
- package/dist/components/Timepicker/utils/index.d.ts +1 -0
- package/dist/components/WeekPicker/WeekPicker.d.ts +3 -0
- package/dist/components/WeekPicker/index.d.ts +1 -0
- package/dist/components/WeekPicker/subcomponents/CustomDatepicker.d.ts +17 -0
- package/dist/components/WeekPicker/subcomponents/DatepickerInput.d.ts +13 -0
- package/dist/components/WeekPicker/subcomponents/VisibleField.d.ts +15 -0
- package/dist/components/WeekPicker/subcomponents/index.d.ts +3 -0
- package/dist/components/index.d.ts +11 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useFocusTrap.d.ts +9 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5703 -4448
- package/dist/theme/defaultTheme.d.ts +7 -0
- package/dist/theme/useTheme.d.ts +14 -0
- package/dist/utils/__tests__/capitalise.test.d.ts +1 -0
- package/dist/utils/capitalise.d.ts +2 -0
- package/lib/components/Alert/Alert.tsx +7 -1
- package/lib/components/Alert/__tests__/__snapshots__/Alert.test.tsx.snap +4 -0
- package/lib/components/Badge/Badge.stories.tsx +19 -0
- package/lib/components/Badge/Badge.tsx +48 -0
- package/lib/components/Badge/index.ts +2 -0
- package/lib/components/Breadcrumbs/__tests__/__snapshots__/Breadcrumbs.test.tsx.snap +4 -4
- package/lib/components/Button/Button.tsx +5 -2
- package/lib/components/Calendar/subcomponents/Grid.tsx +0 -1
- package/lib/components/CookieNotice/CookieNotice.tsx +114 -0
- package/lib/components/CookieNotice/index.ts +2 -0
- package/lib/components/Dialog/BaseDialog.tsx +44 -4
- package/lib/components/Field/__tests__/Field.test.tsx +148 -148
- package/lib/components/FileInput/FileInput.stories.tsx +70 -0
- package/lib/components/FileInput/FileInput.tsx +68 -0
- package/lib/components/FileInput/__tests__/FileInput.test.tsx +99 -0
- package/lib/components/FileInput/__tests__/__snapshots__/FileInput.test.tsx.snap +91 -0
- package/lib/components/FileInput/index.ts +2 -0
- package/lib/components/Footer/__tests__/__snapshots__/Footer.test.tsx.snap +25 -25
- package/lib/components/Header/Header.tsx +19 -2
- package/lib/components/Header/__tests__/__snapshots__/Header.test.tsx.snap +4 -4
- package/lib/components/Heading/Documentation.mdx +1 -1
- package/lib/components/Heading/Heading.tsx +1 -1
- package/lib/components/Heading/__tests__/Heading.test.tsx +7 -19
- package/lib/components/Heading/__tests__/__snapshots__/Heading.test.tsx.snap +7 -7
- package/lib/components/Label/Label.tsx +0 -2
- package/lib/components/Label/__tests__/__snapshots__/Label.test.tsx.snap +7 -7
- package/lib/components/Link/BaseLink.tsx +84 -0
- package/lib/components/Link/Link.tsx +72 -32
- package/lib/components/Link/__tests__/__snapshots__/link.test.tsx.snap +3 -3
- package/lib/components/Link/__tests__/link.test.tsx +6 -13
- package/lib/components/Link/index.ts +1 -1
- package/lib/components/Menu/Menu.context.tsx +3 -1
- package/lib/components/Menu/Menu.tsx +2 -2
- package/lib/components/Menu/MenuContent.tsx +5 -5
- package/lib/components/Menu/MenuItem.tsx +20 -3
- package/lib/components/Menu/MenuSection.tsx +4 -3
- package/lib/components/Pagination/PaginationControls.tsx +1 -3
- package/lib/components/Search/Search.stories.tsx +41 -0
- package/lib/components/Search/Search.tsx +167 -0
- package/lib/components/Search/__tests__/Search.test.tsx +94 -0
- package/lib/components/Search/__tests__/__snapshots__/Search.test.tsx.snap +179 -0
- package/lib/components/Search/index.ts +2 -0
- package/lib/components/Select/Select.stories.tsx +8 -35
- package/lib/components/Select/Select.tsx +2 -2
- package/lib/components/Select/Select.types.ts +20 -15
- package/lib/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +3 -3
- package/lib/components/Select/subcomponents/CustomOption.tsx +22 -9
- package/lib/components/Select/subcomponents/CustomSelect.tsx +31 -20
- package/lib/components/Select/subcomponents/Panel.tsx +4 -5
- package/lib/components/Select/subcomponents/VisibleField.tsx +26 -22
- package/lib/components/StandaloneLink/StandaloneLink.stories.tsx +32 -0
- package/lib/components/StandaloneLink/StandaloneLink.tsx +183 -0
- package/lib/components/StandaloneLink/__tests__/StandaloneLink.test.tsx +57 -0
- package/lib/components/StandaloneLink/__tests__/__snapshots__/StandaloneLink.test.tsx.snap +19 -0
- package/lib/components/StandaloneLink/index.ts +2 -0
- package/lib/components/Table/Table.stories.tsx +337 -0
- package/lib/components/Table/Table.tsx +42 -67
- package/lib/components/Table/Table.types.ts +14 -0
- package/lib/components/Table/__tests__/Table.test.tsx +121 -0
- package/lib/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +210 -0
- package/lib/components/Table/index.ts +8 -1
- package/lib/components/Table/subcomponents/Body.tsx +18 -0
- package/lib/components/Table/subcomponents/Cell/Cell.stories.tsx +151 -0
- package/lib/components/Table/subcomponents/Cell/Cell.tsx +72 -0
- package/lib/components/Table/subcomponents/Cell/CellContent.tsx +91 -0
- package/lib/components/Table/subcomponents/Cell/__tests__/Cell.test.tsx +115 -0
- package/lib/components/Table/subcomponents/Cell/__tests__/__snapshots__/Cell.test.tsx.snap +107 -0
- package/lib/components/Table/subcomponents/Head.tsx +34 -0
- package/lib/components/Table/subcomponents/HeadCell/HeadCell.stories.tsx +85 -0
- package/lib/components/Table/subcomponents/HeadCell/HeadCell.tsx +99 -0
- package/lib/components/Table/subcomponents/HeadCell/HeadCellContent.tsx +61 -0
- package/lib/components/Table/subcomponents/HeadCell/__tests__/HeadCell.test.tsx +137 -0
- package/lib/components/Table/subcomponents/HeadCell/__tests__/__snapshots__/HeadCell.test.tsx.snap +110 -0
- package/lib/components/Table/subcomponents/Row.tsx +49 -0
- package/lib/components/Table/subcomponents/SortIcon.tsx +63 -0
- package/lib/components/Table/subcomponents/index.ts +14 -0
- package/lib/components/Tabs/Tab.tsx +3 -3
- package/lib/components/Tabs/TabContext.tsx +1 -0
- package/lib/components/Tabs/Tabs.stories.tsx +9 -3
- package/lib/components/Tabs/Tabs.tsx +10 -32
- package/lib/components/Tabs/__tests__/Tabs.test.tsx +10 -4
- package/lib/components/Tabs/__tests__/__snapshots__/Tabs.test.tsx.snap +32 -32
- package/lib/components/Timepicker/Timepicker.stories.tsx +43 -0
- package/lib/components/Timepicker/Timepicker.tsx +96 -0
- package/lib/components/Timepicker/__tests__/Timepicker.test.tsx +55 -0
- package/lib/components/Timepicker/__tests__/__snapshots__/Timepicker.test.tsx.snap +19 -0
- package/lib/components/Timepicker/index.tsx +2 -0
- package/lib/components/Timepicker/utils/convertDateToTimeString.test.ts +54 -0
- package/lib/components/Timepicker/utils/convertDateToTimeString.ts +10 -0
- package/lib/components/Timepicker/utils/index.ts +1 -0
- package/lib/components/WeekPicker/WeekPicker.tsx +26 -0
- package/lib/components/WeekPicker/index.ts +1 -0
- package/lib/components/WeekPicker/subcomponents/CustomDatepicker.tsx +298 -0
- package/lib/components/WeekPicker/subcomponents/DatepickerInput.tsx +111 -0
- package/lib/components/WeekPicker/subcomponents/VisibleField.tsx +126 -0
- package/lib/components/WeekPicker/subcomponents/index.ts +3 -0
- package/lib/components/index.ts +17 -0
- package/lib/hooks/index.ts +2 -0
- package/lib/hooks/useFocusTrap.ts +123 -0
- package/lib/index.ts +1 -0
- package/lib/theme/defaultTheme.ts +7 -0
- package/lib/utils/__tests__/capitalise.test.ts +40 -0
- package/lib/utils/capitalise.ts +4 -0
- package/package.json +1 -1
- package/lib/components/Field/__tests__/__snapshots__/Field.test.tsx.snap +0 -300
|
@@ -20,6 +20,7 @@ declare const blackAndWhite: {
|
|
|
20
20
|
white: string;
|
|
21
21
|
};
|
|
22
22
|
declare const theme: {
|
|
23
|
+
p0: number;
|
|
23
24
|
p2: string;
|
|
24
25
|
p4: string;
|
|
25
26
|
p6: string;
|
|
@@ -35,6 +36,7 @@ declare const theme: {
|
|
|
35
36
|
p64: string;
|
|
36
37
|
p72: string;
|
|
37
38
|
p80: string;
|
|
39
|
+
m0: number;
|
|
38
40
|
m2: string;
|
|
39
41
|
m4: string;
|
|
40
42
|
m6: string;
|
|
@@ -114,7 +116,9 @@ declare const theme: {
|
|
|
114
116
|
};
|
|
115
117
|
link: {
|
|
116
118
|
default: string;
|
|
119
|
+
secondaryDefault: string;
|
|
117
120
|
hover: string;
|
|
121
|
+
secondaryHover: string;
|
|
118
122
|
visited: string;
|
|
119
123
|
disabled: string;
|
|
120
124
|
};
|
|
@@ -122,6 +126,7 @@ declare const theme: {
|
|
|
122
126
|
black: string;
|
|
123
127
|
grey90: string;
|
|
124
128
|
grey80: string;
|
|
129
|
+
grey70: string;
|
|
125
130
|
grey60: string;
|
|
126
131
|
grey40: string;
|
|
127
132
|
grey20: string;
|
|
@@ -153,6 +158,7 @@ declare const theme: {
|
|
|
153
158
|
h80: string;
|
|
154
159
|
};
|
|
155
160
|
margin: {
|
|
161
|
+
m0: number;
|
|
156
162
|
m2: string;
|
|
157
163
|
m4: string;
|
|
158
164
|
m6: string;
|
|
@@ -170,6 +176,7 @@ declare const theme: {
|
|
|
170
176
|
m80: string;
|
|
171
177
|
};
|
|
172
178
|
padding: {
|
|
179
|
+
p0: number;
|
|
173
180
|
p2: string;
|
|
174
181
|
p4: string;
|
|
175
182
|
p6: string;
|
package/dist/theme/useTheme.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare const ThemeContextProvider: React.FC<{
|
|
|
3
3
|
children: ReactNode;
|
|
4
4
|
}>;
|
|
5
5
|
declare const useTheme: () => [{
|
|
6
|
+
p0: number;
|
|
6
7
|
p2: string;
|
|
7
8
|
p4: string;
|
|
8
9
|
p6: string;
|
|
@@ -18,6 +19,7 @@ declare const useTheme: () => [{
|
|
|
18
19
|
p64: string;
|
|
19
20
|
p72: string;
|
|
20
21
|
p80: string;
|
|
22
|
+
m0: number;
|
|
21
23
|
m2: string;
|
|
22
24
|
m4: string;
|
|
23
25
|
m6: string;
|
|
@@ -97,7 +99,9 @@ declare const useTheme: () => [{
|
|
|
97
99
|
};
|
|
98
100
|
link: {
|
|
99
101
|
default: string;
|
|
102
|
+
secondaryDefault: string;
|
|
100
103
|
hover: string;
|
|
104
|
+
secondaryHover: string;
|
|
101
105
|
visited: string;
|
|
102
106
|
disabled: string;
|
|
103
107
|
};
|
|
@@ -105,6 +109,7 @@ declare const useTheme: () => [{
|
|
|
105
109
|
black: string;
|
|
106
110
|
grey90: string;
|
|
107
111
|
grey80: string;
|
|
112
|
+
grey70: string;
|
|
108
113
|
grey60: string;
|
|
109
114
|
grey40: string;
|
|
110
115
|
grey20: string;
|
|
@@ -136,6 +141,7 @@ declare const useTheme: () => [{
|
|
|
136
141
|
h80: string;
|
|
137
142
|
};
|
|
138
143
|
margin: {
|
|
144
|
+
m0: number;
|
|
139
145
|
m2: string;
|
|
140
146
|
m4: string;
|
|
141
147
|
m6: string;
|
|
@@ -153,6 +159,7 @@ declare const useTheme: () => [{
|
|
|
153
159
|
m80: string;
|
|
154
160
|
};
|
|
155
161
|
padding: {
|
|
162
|
+
p0: number;
|
|
156
163
|
p2: string;
|
|
157
164
|
p4: string;
|
|
158
165
|
p6: string;
|
|
@@ -244,6 +251,7 @@ declare const useTheme: () => [{
|
|
|
244
251
|
custom: (breakpoint: number) => string;
|
|
245
252
|
};
|
|
246
253
|
}, import('react').Dispatch<import('react').SetStateAction<{
|
|
254
|
+
p0: number;
|
|
247
255
|
p2: string;
|
|
248
256
|
p4: string;
|
|
249
257
|
p6: string;
|
|
@@ -259,6 +267,7 @@ declare const useTheme: () => [{
|
|
|
259
267
|
p64: string;
|
|
260
268
|
p72: string;
|
|
261
269
|
p80: string;
|
|
270
|
+
m0: number;
|
|
262
271
|
m2: string;
|
|
263
272
|
m4: string;
|
|
264
273
|
m6: string;
|
|
@@ -338,7 +347,9 @@ declare const useTheme: () => [{
|
|
|
338
347
|
};
|
|
339
348
|
link: {
|
|
340
349
|
default: string;
|
|
350
|
+
secondaryDefault: string;
|
|
341
351
|
hover: string;
|
|
352
|
+
secondaryHover: string;
|
|
342
353
|
visited: string;
|
|
343
354
|
disabled: string;
|
|
344
355
|
};
|
|
@@ -346,6 +357,7 @@ declare const useTheme: () => [{
|
|
|
346
357
|
black: string;
|
|
347
358
|
grey90: string;
|
|
348
359
|
grey80: string;
|
|
360
|
+
grey70: string;
|
|
349
361
|
grey60: string;
|
|
350
362
|
grey40: string;
|
|
351
363
|
grey20: string;
|
|
@@ -377,6 +389,7 @@ declare const useTheme: () => [{
|
|
|
377
389
|
h80: string;
|
|
378
390
|
};
|
|
379
391
|
margin: {
|
|
392
|
+
m0: number;
|
|
380
393
|
m2: string;
|
|
381
394
|
m4: string;
|
|
382
395
|
m6: string;
|
|
@@ -394,6 +407,7 @@ declare const useTheme: () => [{
|
|
|
394
407
|
m80: string;
|
|
395
408
|
};
|
|
396
409
|
padding: {
|
|
410
|
+
p0: number;
|
|
397
411
|
p2: string;
|
|
398
412
|
p4: string;
|
|
399
413
|
p6: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -5,6 +5,7 @@ import AlertMessage from './AlertMessage';
|
|
|
5
5
|
import AlertTitle from './AlertTitle';
|
|
6
6
|
import marginsStyle, { MarginProps } from '../common/marginsStyle';
|
|
7
7
|
import { useTheme } from '../../theme';
|
|
8
|
+
import capitalise from '../../utils/capitalise';
|
|
8
9
|
|
|
9
10
|
export const NAME = 'ucl-uikit-alert';
|
|
10
11
|
|
|
@@ -38,6 +39,8 @@ const Alert = ({
|
|
|
38
39
|
className,
|
|
39
40
|
...props
|
|
40
41
|
}: AlertProps) => {
|
|
42
|
+
const typeName = capitalise(type);
|
|
43
|
+
|
|
41
44
|
const [theme] = useTheme();
|
|
42
45
|
|
|
43
46
|
const { padding } = theme;
|
|
@@ -117,7 +120,10 @@ const Alert = ({
|
|
|
117
120
|
role='alert'
|
|
118
121
|
{...props}
|
|
119
122
|
>
|
|
120
|
-
<IconComp
|
|
123
|
+
<IconComp
|
|
124
|
+
className={iconStyle}
|
|
125
|
+
aria-label={typeName}
|
|
126
|
+
/>
|
|
121
127
|
<div>{children}</div>
|
|
122
128
|
</div>
|
|
123
129
|
</AlertContext.Provider>
|
|
@@ -7,6 +7,7 @@ exports[`Alert > snapshot: type=error 1`] = `
|
|
|
7
7
|
role="alert"
|
|
8
8
|
>
|
|
9
9
|
<svg
|
|
10
|
+
aria-label="Error"
|
|
10
11
|
class="ucl-uikit-icon css-nysdxe"
|
|
11
12
|
data-testid="ucl-uikit-icon"
|
|
12
13
|
fill="none"
|
|
@@ -61,6 +62,7 @@ exports[`Alert > snapshot: type=info, no title 1`] = `
|
|
|
61
62
|
role="alert"
|
|
62
63
|
>
|
|
63
64
|
<svg
|
|
65
|
+
aria-label="Info"
|
|
64
66
|
class="ucl-uikit-icon css-1oh4ubr"
|
|
65
67
|
data-testid="ucl-uikit-icon"
|
|
66
68
|
fill="none"
|
|
@@ -109,6 +111,7 @@ exports[`Alert > snapshot: type=success 1`] = `
|
|
|
109
111
|
role="alert"
|
|
110
112
|
>
|
|
111
113
|
<svg
|
|
114
|
+
aria-label="Success"
|
|
112
115
|
class="ucl-uikit-icon css-4xbsfp"
|
|
113
116
|
data-testid="ucl-uikit-icon"
|
|
114
117
|
fill="none"
|
|
@@ -152,6 +155,7 @@ exports[`Alert > snapshot: type=warning 1`] = `
|
|
|
152
155
|
role="alert"
|
|
153
156
|
>
|
|
154
157
|
<svg
|
|
158
|
+
aria-label="Warning"
|
|
155
159
|
class="ucl-uikit-icon css-dwkbnw"
|
|
156
160
|
data-testid="ucl-uikit-icon"
|
|
157
161
|
fill="none"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import Badge from './Badge';
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Components/Work in progress/Badge',
|
|
6
|
+
component: Badge,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: 'centered',
|
|
9
|
+
},
|
|
10
|
+
args: {
|
|
11
|
+
children: 'Badge',
|
|
12
|
+
},
|
|
13
|
+
tags: ['autodocs'],
|
|
14
|
+
} satisfies Meta<typeof Badge>;
|
|
15
|
+
|
|
16
|
+
export default meta;
|
|
17
|
+
type Story = StoryObj<typeof meta>;
|
|
18
|
+
|
|
19
|
+
export const Default: Story = {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { css, cx } from '@emotion/css';
|
|
2
|
+
import { useTheme } from '../../theme';
|
|
3
|
+
|
|
4
|
+
export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
testId?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const NAME = 'ucl-uikit-badge';
|
|
10
|
+
|
|
11
|
+
const Badge = ({
|
|
12
|
+
testId = NAME,
|
|
13
|
+
className,
|
|
14
|
+
children,
|
|
15
|
+
...props
|
|
16
|
+
}: BadgeProps) => {
|
|
17
|
+
const [theme] = useTheme();
|
|
18
|
+
|
|
19
|
+
const baseStyle = css`
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
justify-content: center;
|
|
23
|
+
box-sizing: border-box;
|
|
24
|
+
height: 24px;
|
|
25
|
+
padding: ${theme.padding.p8};
|
|
26
|
+
color: ${theme.color.text.secondary};
|
|
27
|
+
background-color: #e4e4e4; // TODO: Add design token
|
|
28
|
+
font-family: ${theme.font.family.primary};
|
|
29
|
+
font-size: ${theme.font.size.f14};
|
|
30
|
+
font-weight: ${theme.font.weight.regular};
|
|
31
|
+
border-radius: ${theme.radius.r4};
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
const style = cx(baseStyle, NAME, className);
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
data-testid={testId}
|
|
40
|
+
className={style}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export default Badge;
|
|
@@ -36,7 +36,7 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
|
|
|
36
36
|
class="css-4ys53n"
|
|
37
37
|
>
|
|
38
38
|
<a
|
|
39
|
-
class="ucl-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-
|
|
39
|
+
class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
|
|
40
40
|
data-testid="ucl-timetable-breadcrumb"
|
|
41
41
|
href="/showcase"
|
|
42
42
|
>
|
|
@@ -64,7 +64,7 @@ exports[`Breadcrumbs > Snapshot: No props 1`] = `
|
|
|
64
64
|
class="css-4ys53n"
|
|
65
65
|
>
|
|
66
66
|
<a
|
|
67
|
-
class="ucl-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-
|
|
67
|
+
class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
|
|
68
68
|
data-testid="ucl-timetable-breadcrumb"
|
|
69
69
|
href="/showcase/breadcrumbs"
|
|
70
70
|
>
|
|
@@ -110,7 +110,7 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
|
|
|
110
110
|
class="css-4ys53n"
|
|
111
111
|
>
|
|
112
112
|
<a
|
|
113
|
-
class="ucl-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-
|
|
113
|
+
class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
|
|
114
114
|
data-testid="custom-testid-2"
|
|
115
115
|
href="/showcase"
|
|
116
116
|
>
|
|
@@ -138,7 +138,7 @@ exports[`Breadcrumbs > snapshot: Custom Test ID 1`] = `
|
|
|
138
138
|
class="css-4ys53n"
|
|
139
139
|
>
|
|
140
140
|
<a
|
|
141
|
-
class="ucl-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-
|
|
141
|
+
class="ucl-uikit-base-link ucl-uikit-link ucl-timetable-breadcrumb ucl-timetable-breadcrumb--inactive css-c7kkpi"
|
|
142
142
|
data-testid="custom-testid-3"
|
|
143
143
|
href="/showcase/breadcrumbs"
|
|
144
144
|
>
|
|
@@ -11,8 +11,10 @@ import useTheme from '../../theme/useTheme';
|
|
|
11
11
|
import buttonPrimaryStyle from './buttonPrimaryStyle';
|
|
12
12
|
import buttonSecondaryStyle from './buttonSecondaryStyle';
|
|
13
13
|
import buttonTertiaryStyle from './buttonTertiaryStyle';
|
|
14
|
-
import
|
|
15
|
-
import
|
|
14
|
+
import Spinner from '../Spinner/Spinner';
|
|
15
|
+
import Overlay from '../Overlay/Overlay';
|
|
16
|
+
import Tooltip from '../Tooltip/Tooltip';
|
|
17
|
+
import marginsStyle, { MarginProps } from '../common/marginsStyle';
|
|
16
18
|
|
|
17
19
|
export const NAME = 'ucl-uikit-button';
|
|
18
20
|
|
|
@@ -35,6 +37,7 @@ export type ButtonProps<C extends ElementType = 'button'> = {
|
|
|
35
37
|
as?: C;
|
|
36
38
|
ref?: PolymorphicRef<C>;
|
|
37
39
|
} & ButtonBaseProps &
|
|
40
|
+
MarginProps &
|
|
38
41
|
Omit<ComponentPropsWithRef<C>, keyof ButtonBaseProps | 'as'>;
|
|
39
42
|
|
|
40
43
|
const Button = <C extends ElementType = 'button'>({
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { HTMLAttributes, useRef } from 'react';
|
|
2
|
+
import { css, cx } from '@emotion/css';
|
|
3
|
+
import useTheme from '../../theme/useTheme';
|
|
4
|
+
import marginsStyle, { MarginProps } from '../common/marginsStyle';
|
|
5
|
+
import Paragraph from '../Paragraph';
|
|
6
|
+
import { Button, Icon, Link } from '..';
|
|
7
|
+
import { useFocusTrap } from '../../hooks/useFocusTrap';
|
|
8
|
+
|
|
9
|
+
export const NAME = 'ucl-uikit-cookie-notice';
|
|
10
|
+
export const DEFAULT_POLICY_HREF =
|
|
11
|
+
'https://www.ucl.ac.uk/legal-services/privacy/cookie-policy';
|
|
12
|
+
export const DEFAULT_TEXT =
|
|
13
|
+
'We use necessary cookies to manage your session and essential site functions. We also use Google Analytics cookies to understand how our site is used. You can accept or reject non-essential cookies.';
|
|
14
|
+
|
|
15
|
+
export interface CookieNoticeBaseProps extends HTMLAttributes<HTMLDivElement> {
|
|
16
|
+
policyHref?: string;
|
|
17
|
+
text?: string;
|
|
18
|
+
onAccept?: () => void;
|
|
19
|
+
onReject?: () => void;
|
|
20
|
+
trapFocus?: boolean;
|
|
21
|
+
testId?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type CookieNoticeProps = CookieNoticeBaseProps & MarginProps;
|
|
25
|
+
|
|
26
|
+
const CookieNotice = ({
|
|
27
|
+
policyHref = DEFAULT_POLICY_HREF,
|
|
28
|
+
text = DEFAULT_TEXT,
|
|
29
|
+
onAccept,
|
|
30
|
+
onReject,
|
|
31
|
+
trapFocus = false,
|
|
32
|
+
testId = NAME,
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
}: CookieNoticeProps) => {
|
|
36
|
+
const [theme] = useTheme();
|
|
37
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
38
|
+
|
|
39
|
+
useFocusTrap({
|
|
40
|
+
isActive: trapFocus,
|
|
41
|
+
containerRef,
|
|
42
|
+
restoreFocus: true,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const baseStyle = css`
|
|
46
|
+
position: fixed;
|
|
47
|
+
left: 0;
|
|
48
|
+
right: 0;
|
|
49
|
+
bottom: 0;
|
|
50
|
+
height: auto;
|
|
51
|
+
background-color: ${theme.color.neutral.grey40};
|
|
52
|
+
padding: ${theme.padding.p20} ${theme.padding.p24};
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
const style = cx(NAME, baseStyle, marginsStyle(props, theme), className);
|
|
56
|
+
|
|
57
|
+
const buttonsStyle = css`
|
|
58
|
+
margin-top: ${theme.margin.m16};
|
|
59
|
+
display: flex;
|
|
60
|
+
align-items: center;
|
|
61
|
+
gap: ${theme.margin.m8};
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
const policyLinkStyle = css`
|
|
65
|
+
margin-left: ${theme.margin.m16};
|
|
66
|
+
display: inline-flex;
|
|
67
|
+
color: ${theme.color.text.primary};
|
|
68
|
+
&:visited {
|
|
69
|
+
color: ${theme.color.text.primary};
|
|
70
|
+
}
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
const policyLinkIconStyle = css`
|
|
74
|
+
margin-top: -1px;
|
|
75
|
+
margin-left: ${theme.margin.m4};
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
ref={containerRef}
|
|
81
|
+
className={style}
|
|
82
|
+
data-testid={testId}
|
|
83
|
+
{...props}
|
|
84
|
+
>
|
|
85
|
+
<Paragraph noMargins>{text}</Paragraph>
|
|
86
|
+
|
|
87
|
+
<div className={buttonsStyle}>
|
|
88
|
+
<Button
|
|
89
|
+
size='small'
|
|
90
|
+
onClick={onAccept}
|
|
91
|
+
>
|
|
92
|
+
Accept
|
|
93
|
+
</Button>
|
|
94
|
+
|
|
95
|
+
<Button
|
|
96
|
+
size='small'
|
|
97
|
+
onClick={onReject}
|
|
98
|
+
>
|
|
99
|
+
Reject
|
|
100
|
+
</Button>
|
|
101
|
+
<Link
|
|
102
|
+
className={policyLinkStyle}
|
|
103
|
+
noVisited
|
|
104
|
+
href={policyHref}
|
|
105
|
+
target='_blank'
|
|
106
|
+
>
|
|
107
|
+
Cookies policy <Icon.ExternalLink className={policyLinkIconStyle} />
|
|
108
|
+
</Link>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export default CookieNotice;
|
|
@@ -7,6 +7,7 @@ import React, {
|
|
|
7
7
|
} from 'react';
|
|
8
8
|
import { css, cx } from '@emotion/css';
|
|
9
9
|
import useTheme from '../../theme/useTheme';
|
|
10
|
+
import { useFocusTrap } from '../../hooks/useFocusTrap';
|
|
10
11
|
|
|
11
12
|
export const NAME = 'ucl-uikit-base-dialog';
|
|
12
13
|
export const SMALL_WIDTH = 495;
|
|
@@ -19,7 +20,13 @@ export interface BaseDialogProps extends HTMLAttributes<HTMLDialogElement> {
|
|
|
19
20
|
modal?: boolean;
|
|
20
21
|
closeOnClickOutside?: boolean;
|
|
21
22
|
closeOnClickOutsideStopPropagation?: boolean;
|
|
22
|
-
|
|
23
|
+
nonModalCloseOnEscape?: boolean;
|
|
24
|
+
onClose?: (ev: React.MouseEvent | KeyboardEvent) => void;
|
|
25
|
+
// Focus trap related props
|
|
26
|
+
initialFocusRef?: React.RefObject<HTMLElement>;
|
|
27
|
+
finalFocusRef?: React.RefObject<HTMLElement>;
|
|
28
|
+
disableFocusTrap?: boolean;
|
|
29
|
+
restoreFocus?: boolean;
|
|
23
30
|
testId?: string;
|
|
24
31
|
}
|
|
25
32
|
|
|
@@ -29,10 +36,15 @@ const BaseDialog = ({
|
|
|
29
36
|
modal = true,
|
|
30
37
|
closeOnClickOutside = true,
|
|
31
38
|
closeOnClickOutsideStopPropagation = true,
|
|
39
|
+
nonModalCloseOnEscape = false,
|
|
32
40
|
onClose,
|
|
33
|
-
testId = NAME,
|
|
34
41
|
className,
|
|
35
42
|
children,
|
|
43
|
+
initialFocusRef,
|
|
44
|
+
finalFocusRef,
|
|
45
|
+
disableFocusTrap = false,
|
|
46
|
+
restoreFocus = true,
|
|
47
|
+
testId = NAME,
|
|
36
48
|
...props
|
|
37
49
|
}: BaseDialogProps) => {
|
|
38
50
|
const width = {
|
|
@@ -46,6 +58,15 @@ const BaseDialog = ({
|
|
|
46
58
|
const dialogRef = useRef<HTMLDialogElement>(null);
|
|
47
59
|
const previousActiveElement = useRef<HTMLElement | null>(null);
|
|
48
60
|
|
|
61
|
+
// Use the focus trap hook
|
|
62
|
+
useFocusTrap({
|
|
63
|
+
isActive: open && modal && !disableFocusTrap,
|
|
64
|
+
containerRef: dialogRef,
|
|
65
|
+
initialFocusRef,
|
|
66
|
+
finalFocusRef,
|
|
67
|
+
restoreFocus,
|
|
68
|
+
});
|
|
69
|
+
|
|
49
70
|
const hideBodyScroll = css`
|
|
50
71
|
overflow: hidden;
|
|
51
72
|
`;
|
|
@@ -75,9 +96,27 @@ const BaseDialog = ({
|
|
|
75
96
|
}
|
|
76
97
|
} else if (!open && dialogElement.hasAttribute('open')) {
|
|
77
98
|
dialogElement.close();
|
|
78
|
-
|
|
99
|
+
// Focus restoration is handled by the focus trap hook for modal dialogs,
|
|
100
|
+
// but we keep the fallback for non-modal dialogs or when focus trap is disabled
|
|
101
|
+
if ((!modal || disableFocusTrap) && restoreFocus) {
|
|
102
|
+
previousActiveElement.current?.focus();
|
|
103
|
+
}
|
|
79
104
|
}
|
|
80
|
-
}, [open, modal]);
|
|
105
|
+
}, [open, modal, disableFocusTrap, restoreFocus]);
|
|
106
|
+
|
|
107
|
+
// Handle Escape key to close dialog
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (!open || modal || !nonModalCloseOnEscape) return;
|
|
110
|
+
|
|
111
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
112
|
+
if (event.key === 'Escape' && onClose) {
|
|
113
|
+
onClose(event);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
118
|
+
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
119
|
+
}, [open, modal, nonModalCloseOnEscape, onClose]);
|
|
81
120
|
|
|
82
121
|
const handleClick = useCallback(
|
|
83
122
|
(ev: React.MouseEvent<HTMLDialogElement>) => {
|
|
@@ -150,6 +189,7 @@ const BaseDialog = ({
|
|
|
150
189
|
data-testid={testId}
|
|
151
190
|
onClick={handleClick}
|
|
152
191
|
onClose={handleDialogClose}
|
|
192
|
+
aria-modal={modal ? 'true' : 'false'}
|
|
153
193
|
{...props}
|
|
154
194
|
>
|
|
155
195
|
{children}
|