@scottish-government/designsystem-react 0.3.0 → 0.5.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.
- package/@types/common/AbstractNotificationBanner.d.ts +17 -0
- package/@types/components/Table.d.ts +8 -0
- package/@types/components/Tabs.d.ts +22 -0
- package/@types/components/TaskList.d.ts +1 -1
- package/dist/common/abstract-notification-banner.jsx +63 -0
- package/dist/components/accordion/accordion.jsx +2 -3
- package/dist/components/breadcrumbs/breadcrumbs.jsx +2 -2
- package/dist/components/cookie-banner/cookie-banner.jsx +21 -0
- package/dist/components/notification-banner/notification-banner.jsx +7 -34
- package/dist/components/page-metadata/page-metadata.jsx +2 -3
- package/dist/components/table/table.jsx +24 -0
- package/dist/components/tabs/tabs.jsx +99 -0
- package/dist/components/task-list/task-list.jsx +6 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/slugify.js +15 -0
- package/package.json +1 -1
- package/src/common/abstract-notification-banner.test.tsx +126 -0
- package/src/common/abstract-notification-banner.tsx +87 -0
- package/src/common/conditional-wrapper.test.tsx +1 -1
- package/src/common/screen-reader-text.test.tsx +1 -1
- package/src/common/wrapper-tag.test.tsx +3 -3
- package/src/components/accordion/accordion.test.tsx +40 -40
- package/src/components/accordion/accordion.tsx +4 -2
- package/src/components/aspect-box/aspect-box.test.tsx +7 -7
- package/src/components/breadcrumbs/breadcrumbs.tsx +0 -2
- package/src/components/checkbox/checkbox.test.tsx +8 -8
- package/src/components/confirmation-message/confirmation-message.test.tsx +1 -1
- package/src/components/cookie-banner/cookie-banner.test.tsx +25 -0
- package/src/components/cookie-banner/cookie-banner.tsx +36 -0
- package/src/components/details/details.test.tsx +7 -7
- package/src/components/inset-text/inset-text.test.tsx +1 -1
- package/src/components/notification-banner/notification-banner.test.tsx +13 -73
- package/src/components/notification-banner/notification-banner.tsx +13 -41
- package/src/components/notification-panel/notification-panel.test.tsx +6 -6
- package/src/components/page-header/page-header.test.tsx +2 -2
- package/src/components/page-metadata/page-metadata.test.tsx +12 -12
- package/src/components/page-metadata/page-metadata.tsx +4 -2
- package/src/components/pagination/pagination.test.tsx +28 -30
- package/src/components/phase-banner/phase-banner.test.tsx +8 -8
- package/src/components/question/question.test.tsx +3 -3
- package/src/components/radio-button/radio-button.test.tsx +7 -7
- package/src/components/select/select.test.tsx +9 -9
- package/src/components/sequential-navigation/sequential-navigation.test.tsx +4 -4
- package/src/components/side-navigation/side-navigation.test.tsx +1 -1
- package/src/components/site-header/site-header.test.tsx +22 -22
- package/src/components/site-search/site-search.test.tsx +9 -9
- package/src/components/skip-links/skip-links.test.tsx +3 -3
- package/src/components/summary-card/summary-card.test.tsx +2 -2
- package/src/components/summary-list/summary-list.test.tsx +35 -16
- package/src/components/table/table.test.tsx +77 -0
- package/src/components/table/table.tsx +36 -0
- package/src/components/tabs/tabs.test.tsx +258 -0
- package/src/components/tabs/tabs.tsx +110 -0
- package/src/components/task-list/task-list.test.tsx +81 -83
- package/src/components/task-list/task-list.tsx +9 -5
- package/src/components/text-input/text-input.test.tsx +6 -6
- package/src/components/textarea/textarea.test.tsx +2 -2
- package/src/components/warning-text/warning-text.test.tsx +1 -1
- package/src/utils/slugify.ts +13 -0
- package/vite.config.ts +6 -1
- package/vitest-setup.ts +1 -1
- package/@types/components/NotificationBanner.d.ts +0 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { test, expect } from 'vitest';
|
|
2
2
|
import { render, screen, within } from '@testing-library/react';
|
|
3
|
-
import Accordion
|
|
3
|
+
import Accordion from './accordion';
|
|
4
4
|
|
|
5
5
|
const id = 'my-accordion';
|
|
6
6
|
const itemId = 'my-accordion-item';
|
|
@@ -13,20 +13,20 @@ test('accordion renders correctly', () => {
|
|
|
13
13
|
|
|
14
14
|
render(
|
|
15
15
|
<Accordion id={id} data-testid={id}>
|
|
16
|
-
<
|
|
16
|
+
<Accordion.Item id="accordion-1" title="Healthcare for veterans">
|
|
17
17
|
<p>Veterans are entitled to the same healthcare as any citizen. And there
|
|
18
18
|
are health care options and support available specifically for veterans.</p>
|
|
19
19
|
<p>If you have a health condition that’s related to your service, you’re
|
|
20
20
|
entitled to priority treatment based on clinical need.</p>
|
|
21
|
-
</
|
|
22
|
-
<
|
|
21
|
+
</Accordion.Item>
|
|
22
|
+
<Accordion.Item open id="accordion-2" title="Employability for veterans">
|
|
23
23
|
<p>If you're looking for a job, there are several organisations that can help
|
|
24
24
|
you <a href="#accordion-link">find a job or develop new skills</a>.</p>
|
|
25
|
-
</
|
|
26
|
-
<
|
|
25
|
+
</Accordion.Item>
|
|
26
|
+
<Accordion.Item id="accordion-3" title="Housing for veterans">
|
|
27
27
|
<p>If you need <a href="#accordion-link">help finding a place to live</a>{' '}
|
|
28
28
|
there's support specifically for veterans.</p>
|
|
29
|
-
</
|
|
29
|
+
</Accordion.Item>
|
|
30
30
|
</Accordion>
|
|
31
31
|
);
|
|
32
32
|
|
|
@@ -40,31 +40,31 @@ test('accordion renders correctly', () => {
|
|
|
40
40
|
|
|
41
41
|
expect(openAllButton).toHaveClass('ds_accordion__open-all', 'ds_link', 'js-open-all');
|
|
42
42
|
expect(openAllButton).toHaveAttribute('type', 'button');
|
|
43
|
-
expect(openAllButton
|
|
44
|
-
expect(openAllButton
|
|
43
|
+
expect(openAllButton?.textContent).toEqual('Open all sections');
|
|
44
|
+
expect(openAllButton?.innerHTML).toEqual('Open all <span class="visually-hidden">sections</span>');
|
|
45
45
|
|
|
46
46
|
expect(accordionItems.length).toEqual(3);
|
|
47
47
|
|
|
48
|
-
expect(firstAccordionTitle
|
|
48
|
+
expect(firstAccordionTitle?.tagName).toEqual(defaultHeaderLevel.toUpperCase());
|
|
49
49
|
});
|
|
50
50
|
|
|
51
51
|
test('accordion without open all', () => {
|
|
52
52
|
render(
|
|
53
53
|
<Accordion id={id} data-testid={id} hideOpenAll>
|
|
54
|
-
<
|
|
54
|
+
<Accordion.Item id="accordion-1" title="Healthcare for veterans">
|
|
55
55
|
<p>Veterans are entitled to the same healthcare as any citizen. And there
|
|
56
56
|
are health care options and support available specifically for veterans.</p>
|
|
57
57
|
<p>If you have a health condition that’s related to your service, you’re
|
|
58
58
|
entitled to priority treatment based on clinical need.</p>
|
|
59
|
-
</
|
|
60
|
-
<
|
|
59
|
+
</Accordion.Item>
|
|
60
|
+
<Accordion.Item id="accordion-2" title="Employability for veterans">
|
|
61
61
|
<p>If you're looking for a job, there are several organisations that can help
|
|
62
62
|
you <a href="#accordion-link">find a job or develop new skills</a>.</p>
|
|
63
|
-
</
|
|
64
|
-
<
|
|
63
|
+
</Accordion.Item>
|
|
64
|
+
<Accordion.Item id="accordion-3" title="Housing for veterans">
|
|
65
65
|
<p>If you need <a href="#accordion-link">help finding a place to live</a>{' '}
|
|
66
66
|
there's support specifically for veterans.</p>
|
|
67
|
-
</
|
|
67
|
+
</Accordion.Item>
|
|
68
68
|
</Accordion>
|
|
69
69
|
);
|
|
70
70
|
|
|
@@ -89,12 +89,12 @@ test('accordion with custom header level', () => {
|
|
|
89
89
|
|
|
90
90
|
render(
|
|
91
91
|
<Accordion id={id} data-testid={id} headerLevel={headerLevel}>
|
|
92
|
-
<
|
|
92
|
+
<Accordion.Item id="accordion-1" title="Healthcare for veterans">
|
|
93
93
|
<p>Veterans are entitled to the same healthcare as any citizen. And there
|
|
94
94
|
are health care options and support available specifically for veterans.</p>
|
|
95
95
|
<p>If you have a health condition that’s related to your service, you’re
|
|
96
96
|
entitled to priority treatment based on clinical need.</p>
|
|
97
|
-
</
|
|
97
|
+
</Accordion.Item>
|
|
98
98
|
</Accordion>
|
|
99
99
|
);
|
|
100
100
|
|
|
@@ -124,9 +124,9 @@ test('passing additional CSS classes', () => {
|
|
|
124
124
|
|
|
125
125
|
test('accordion item renders correctly', () => {
|
|
126
126
|
render(
|
|
127
|
-
<
|
|
127
|
+
<Accordion.Item id={itemId} data-testid={itemId} title={titleText}>
|
|
128
128
|
<p>{contentText}</p>
|
|
129
|
-
</
|
|
129
|
+
</Accordion.Item>
|
|
130
130
|
);
|
|
131
131
|
|
|
132
132
|
const accordionItem = screen.getByTestId(itemId);
|
|
@@ -134,7 +134,7 @@ test('accordion item renders correctly', () => {
|
|
|
134
134
|
const header = document.querySelector('.ds_accordion-item__header');
|
|
135
135
|
const title = header?.querySelector('.ds_accordion-item__title');
|
|
136
136
|
const indicator = header?.querySelector('.ds_accordion-item__indicator');
|
|
137
|
-
const label = header
|
|
137
|
+
const label = header?.querySelector('.ds_accordion-item__label');
|
|
138
138
|
const body = document.querySelector('.ds_accordion-item__body');
|
|
139
139
|
|
|
140
140
|
expect(accordionItem).toHaveClass('ds_accordion-item');
|
|
@@ -143,39 +143,39 @@ test('accordion item renders correctly', () => {
|
|
|
143
143
|
expect(input).toHaveClass('ds_accordion-item__control', 'visually-hidden')
|
|
144
144
|
expect(input).toHaveAttribute('id', `${itemId}-control`);
|
|
145
145
|
|
|
146
|
-
expect(header
|
|
146
|
+
expect(header?.tagName).toEqual('DIV');
|
|
147
147
|
|
|
148
148
|
expect(title).toHaveAttribute('id', `panel-${itemId}-heading`);
|
|
149
|
-
expect(title
|
|
150
|
-
expect(title
|
|
149
|
+
expect(title?.tagName).toEqual('H3');
|
|
150
|
+
expect(title?.textContent).toEqual(titleText);
|
|
151
151
|
|
|
152
|
-
expect(indicator
|
|
152
|
+
expect(indicator?.tagName).toEqual('SPAN');
|
|
153
153
|
|
|
154
154
|
expect(label).toHaveAttribute('for', input.id);
|
|
155
|
-
expect(label
|
|
156
|
-
expect(label
|
|
155
|
+
expect(label?.tagName).toEqual('LABEL');
|
|
156
|
+
expect(label?.textContent).toEqual('Show this section');
|
|
157
157
|
expect(label?.children[0]).toHaveClass('visually-hidden');
|
|
158
158
|
|
|
159
|
-
expect(body
|
|
159
|
+
expect(body?.innerHTML).toEqual(`<p>${contentText}</p>`);
|
|
160
160
|
});
|
|
161
161
|
|
|
162
162
|
test('accordion items without ID are given unique IDs', () => {
|
|
163
163
|
render(
|
|
164
164
|
<Accordion id={id} data-testid={id} hideOpenAll>
|
|
165
|
-
<
|
|
165
|
+
<Accordion.Item data-testid="item1" title="Healthcare for veterans">
|
|
166
166
|
<p>Veterans are entitled to the same healthcare as any citizen. And there
|
|
167
167
|
are health care options and support available specifically for veterans.</p>
|
|
168
168
|
<p>If you have a health condition that’s related to your service, you’re
|
|
169
169
|
entitled to priority treatment based on clinical need.</p>
|
|
170
|
-
</
|
|
171
|
-
<
|
|
170
|
+
</Accordion.Item>
|
|
171
|
+
<Accordion.Item data-testid="item2" title="Employability for veterans">
|
|
172
172
|
<p>If you're looking for a job, there are several organisations that can help
|
|
173
173
|
you <a href="#accordion-link">find a job or develop new skills</a>.</p>
|
|
174
|
-
</
|
|
175
|
-
<
|
|
174
|
+
</Accordion.Item>
|
|
175
|
+
<Accordion.Item data-testid="item3" title="Housing for veterans">
|
|
176
176
|
<p>If you need <a href="#accordion-link">help finding a place to live</a>{' '}
|
|
177
177
|
there's support specifically for veterans.</p>
|
|
178
|
-
</
|
|
178
|
+
</Accordion.Item>
|
|
179
179
|
</Accordion>
|
|
180
180
|
);
|
|
181
181
|
|
|
@@ -194,9 +194,9 @@ test('accordion items without ID are given unique IDs', () => {
|
|
|
194
194
|
|
|
195
195
|
test('open accordion item', () => {
|
|
196
196
|
render(
|
|
197
|
-
<
|
|
197
|
+
<Accordion.Item open id={itemId} data-testid={itemId} title={titleText}>
|
|
198
198
|
<p>{contentText}</p>
|
|
199
|
-
</
|
|
199
|
+
</Accordion.Item>
|
|
200
200
|
);
|
|
201
201
|
|
|
202
202
|
const accordionItem = screen.getByTestId(itemId);
|
|
@@ -207,12 +207,12 @@ test('open accordion item', () => {
|
|
|
207
207
|
|
|
208
208
|
test('passing additional props to accordion item', () => {
|
|
209
209
|
render(
|
|
210
|
-
<
|
|
210
|
+
<Accordion.Item id={itemId} data-testid={itemId} title="Healthcare for veterans" data-test="foo">
|
|
211
211
|
<p>Veterans are entitled to the same healthcare as any citizen. And there
|
|
212
212
|
are health care options and support available specifically for veterans.</p>
|
|
213
213
|
<p>If you have a health condition that’s related to your service, you’re
|
|
214
214
|
entitled to priority treatment based on clinical need.</p>
|
|
215
|
-
</
|
|
215
|
+
</Accordion.Item>
|
|
216
216
|
);
|
|
217
217
|
|
|
218
218
|
const accordionItem = screen.getByTestId(itemId);
|
|
@@ -221,12 +221,12 @@ test('passing additional props to accordion item', () => {
|
|
|
221
221
|
|
|
222
222
|
test('passing additional CSS classes', () => {
|
|
223
223
|
render(
|
|
224
|
-
<
|
|
224
|
+
<Accordion.Item id={itemId} data-testid={itemId} title="Healthcare for veterans" className="foo">
|
|
225
225
|
<p>Veterans are entitled to the same healthcare as any citizen. And there
|
|
226
226
|
are health care options and support available specifically for veterans.</p>
|
|
227
227
|
<p>If you have a health condition that’s related to your service, you’re
|
|
228
228
|
entitled to priority treatment based on clinical need.</p>
|
|
229
|
-
</
|
|
229
|
+
</Accordion.Item>
|
|
230
230
|
);
|
|
231
231
|
|
|
232
232
|
const accordionItem = screen.getByTestId(itemId);
|
|
@@ -5,7 +5,7 @@ import DSAccordion from '@scottish-government/design-system/src/components/accor
|
|
|
5
5
|
|
|
6
6
|
let accordionItemCounter = 0;
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const AccordionItem: React.FC<SGDS.Component.Accordion.Item> = ({
|
|
9
9
|
children,
|
|
10
10
|
className,
|
|
11
11
|
headerLevel = 'h3',
|
|
@@ -58,7 +58,8 @@ export const AccordionItem: React.FC<SGDS.Component.Accordion.Item> = ({
|
|
|
58
58
|
);
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
const Accordion: React.FC<SGDS.Component.Accordion>
|
|
61
|
+
const Accordion: React.FC<SGDS.Component.Accordion>
|
|
62
|
+
& { Item: React.FC<SGDS.Component.Accordion.Item> } = ({
|
|
62
63
|
children,
|
|
63
64
|
className,
|
|
64
65
|
headerLevel = 'h3',
|
|
@@ -112,5 +113,6 @@ const Accordion: React.FC<SGDS.Component.Accordion> = ({
|
|
|
112
113
|
|
|
113
114
|
Accordion.displayName = 'Accordion';
|
|
114
115
|
AccordionItem.displayName = 'AccordionItem';
|
|
116
|
+
Accordion.Item = AccordionItem;
|
|
115
117
|
|
|
116
118
|
export default Accordion;
|
|
@@ -10,7 +10,7 @@ test('aspect box renders correctly', () => {
|
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
const image = document.querySelector('img');
|
|
13
|
-
const imageContainer = image?.
|
|
13
|
+
const imageContainer = image?.parentElement;
|
|
14
14
|
|
|
15
15
|
expect(image).toHaveClass('ds_aspect-box__inner');
|
|
16
16
|
expect(imageContainer).toHaveClass('ds_aspect-box');
|
|
@@ -24,7 +24,7 @@ test('1:1 ratio', () => {
|
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
const image = document.querySelector('img');
|
|
27
|
-
const imageContainer = image?.
|
|
27
|
+
const imageContainer = image?.parentElement;
|
|
28
28
|
|
|
29
29
|
expect(imageContainer).toHaveClass('ds_aspect-box--square');
|
|
30
30
|
});
|
|
@@ -37,7 +37,7 @@ test('square ratio', () => {
|
|
|
37
37
|
);
|
|
38
38
|
|
|
39
39
|
const image = document.querySelector('img');
|
|
40
|
-
const imageContainer = image?.
|
|
40
|
+
const imageContainer = image?.parentElement;
|
|
41
41
|
|
|
42
42
|
expect(imageContainer).toHaveClass('ds_aspect-box--square');
|
|
43
43
|
});
|
|
@@ -50,7 +50,7 @@ test('4:3 ratio', () => {
|
|
|
50
50
|
);
|
|
51
51
|
|
|
52
52
|
const image = document.querySelector('img');
|
|
53
|
-
const imageContainer = image?.
|
|
53
|
+
const imageContainer = image?.parentElement;
|
|
54
54
|
|
|
55
55
|
expect(imageContainer).toHaveClass('ds_aspect-box--43');
|
|
56
56
|
});
|
|
@@ -63,7 +63,7 @@ test('21:9 ratio', () => {
|
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
const image = document.querySelector('img');
|
|
66
|
-
const imageContainer = image?.
|
|
66
|
+
const imageContainer = image?.parentElement;
|
|
67
67
|
|
|
68
68
|
expect(imageContainer).toHaveClass('ds_aspect-box--219');
|
|
69
69
|
});
|
|
@@ -76,7 +76,7 @@ test('passing additional props', () => {
|
|
|
76
76
|
);
|
|
77
77
|
|
|
78
78
|
const image = document.querySelector('img');
|
|
79
|
-
const imageContainer = image?.
|
|
79
|
+
const imageContainer = image?.parentElement;
|
|
80
80
|
expect(imageContainer?.dataset.test).toEqual('foo');
|
|
81
81
|
});
|
|
82
82
|
|
|
@@ -88,6 +88,6 @@ test('passing additional CSS classes', () => {
|
|
|
88
88
|
);
|
|
89
89
|
|
|
90
90
|
const image = document.querySelector('img');
|
|
91
|
-
const imageContainer = image?.
|
|
91
|
+
const imageContainer = image?.parentElement;
|
|
92
92
|
expect(imageContainer).toHaveClass('foo', 'ds_aspect-box');
|
|
93
93
|
});
|
|
@@ -25,7 +25,6 @@ const Breadcrumb: React.FC<SGDS.Component.Breadcrumbs.Item> = ({
|
|
|
25
25
|
* @returns {JSX.Element} - The element
|
|
26
26
|
*/
|
|
27
27
|
const Breadcrumbs: React.FC<SGDS.Component.Breadcrumbs> = ({
|
|
28
|
-
className,
|
|
29
28
|
hideLastItem,
|
|
30
29
|
items,
|
|
31
30
|
...props
|
|
@@ -33,7 +32,6 @@ const Breadcrumbs: React.FC<SGDS.Component.Breadcrumbs> = ({
|
|
|
33
32
|
return (
|
|
34
33
|
<nav
|
|
35
34
|
aria-label="Breadcrumb"
|
|
36
|
-
className={className}
|
|
37
35
|
{...props}
|
|
38
36
|
>
|
|
39
37
|
<ol className="ds_breadcrumbs">
|
|
@@ -29,7 +29,7 @@ test('checkbox group renders correct children', () => {
|
|
|
29
29
|
);
|
|
30
30
|
|
|
31
31
|
const checkboxes = screen.getAllByRole('checkbox');
|
|
32
|
-
const groupContainer = checkboxes[0].
|
|
32
|
+
const groupContainer = checkboxes[0].parentElement?.parentElement;
|
|
33
33
|
expect(checkboxes.length).toEqual(items.length);
|
|
34
34
|
expect(groupContainer).toHaveClass('ds_checkboxes', 'ds_field-group');
|
|
35
35
|
});
|
|
@@ -54,7 +54,7 @@ test('checkbox group passes all expected item params', () => {
|
|
|
54
54
|
);
|
|
55
55
|
|
|
56
56
|
const checkbox = screen.getByRole('checkbox');
|
|
57
|
-
const checkboxContainer = checkbox.
|
|
57
|
+
const checkboxContainer = checkbox.parentElement;
|
|
58
58
|
const hintText = screen.getByText('hint text');
|
|
59
59
|
|
|
60
60
|
expect(checkbox).toHaveAttribute('data-behaviour', 'exclusive');
|
|
@@ -77,7 +77,7 @@ test('individual checkbox renders correctly', () => {
|
|
|
77
77
|
);
|
|
78
78
|
|
|
79
79
|
const checkbox = screen.getByRole('checkbox');
|
|
80
|
-
const checkboxContainer = checkbox.
|
|
80
|
+
const checkboxContainer = checkbox.parentElement;
|
|
81
81
|
const label = screen.getByText('Pension Credit');
|
|
82
82
|
|
|
83
83
|
expect(checkboxContainer).toHaveClass('ds_checkbox');
|
|
@@ -107,12 +107,12 @@ test('exclusive checkbox', () => {
|
|
|
107
107
|
);
|
|
108
108
|
|
|
109
109
|
const checkbox = screen.getByRole('checkbox');
|
|
110
|
-
const separator = checkbox.
|
|
110
|
+
const separator = checkbox.parentElement?.previousSibling;
|
|
111
111
|
|
|
112
112
|
expect(checkbox).toHaveAttribute('data-behaviour', 'exclusive');
|
|
113
113
|
expect(separator).toBeInTheDocument();
|
|
114
114
|
expect(separator).toHaveClass('ds_checkbox-separator');
|
|
115
|
-
expect(separator
|
|
115
|
+
expect(separator?.textContent).toEqual('or');
|
|
116
116
|
});
|
|
117
117
|
|
|
118
118
|
test('checkbox with blur fn', () => {
|
|
@@ -161,7 +161,7 @@ test('small checkbox', () => {
|
|
|
161
161
|
);
|
|
162
162
|
|
|
163
163
|
const checkbox = screen.getByRole('checkbox');
|
|
164
|
-
const checkboxContainer = checkbox.
|
|
164
|
+
const checkboxContainer = checkbox.parentElement;
|
|
165
165
|
|
|
166
166
|
expect(checkboxContainer).toHaveClass('ds_checkbox--small');
|
|
167
167
|
});
|
|
@@ -175,7 +175,7 @@ test('passing additional props', () => {
|
|
|
175
175
|
);
|
|
176
176
|
|
|
177
177
|
const checkboxes = screen.getAllByRole('checkbox');
|
|
178
|
-
const groupContainer = checkboxes[0]?.
|
|
178
|
+
const groupContainer = checkboxes[0]?.parentElement?.parentElement;
|
|
179
179
|
expect(groupContainer?.dataset.test).toEqual('foo');
|
|
180
180
|
});
|
|
181
181
|
|
|
@@ -188,6 +188,6 @@ test('passing additional CSS classes', () => {
|
|
|
188
188
|
);
|
|
189
189
|
|
|
190
190
|
const checkboxes = screen.getAllByRole('checkbox');
|
|
191
|
-
const groupContainer = checkboxes[0]?.
|
|
191
|
+
const groupContainer = checkboxes[0]?.parentElement?.parentElement;
|
|
192
192
|
expect(groupContainer).toHaveClass('foo', 'ds_checkboxes');
|
|
193
193
|
});
|
|
@@ -52,7 +52,7 @@ test('passing additional props', () => {
|
|
|
52
52
|
</ConfirmationMessage>
|
|
53
53
|
);
|
|
54
54
|
|
|
55
|
-
const container = document.querySelector('.ds_confirmation-message');
|
|
55
|
+
const container = document.querySelector('.ds_confirmation-message') as HTMLElement;
|
|
56
56
|
expect(container?.dataset.test).toEqual('foo');
|
|
57
57
|
});
|
|
58
58
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Most of the functionality for CookieBanner is covered in AbstractNotificationBanner.
|
|
3
|
+
* Differences are specifically tested here.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { test, expect } from 'vitest';
|
|
7
|
+
import { render } from '@testing-library/react';
|
|
8
|
+
import CookieBanner from './cookie-banner';
|
|
9
|
+
|
|
10
|
+
const text = 'We need to tell you about something';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* CookieBanner has additional classNames
|
|
14
|
+
*/
|
|
15
|
+
test('cookie banner renders correctly', () => {
|
|
16
|
+
render(
|
|
17
|
+
<CookieBanner>
|
|
18
|
+
{text}
|
|
19
|
+
</CookieBanner>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const bannerContainer = document.querySelector('.ds_notification');
|
|
23
|
+
|
|
24
|
+
expect(bannerContainer).toHaveClass('ds_notification', 'ds_notification--large', 'ds_notification--cookie', 'js-initial-cookie-content');
|
|
25
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
import AbstractNotificationBanner from '../../common/abstract-notification-banner';
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import DSCookieBanner from '@scottish-government/design-system/src/components/cookie-notification/cookie-notification.js';
|
|
5
|
+
|
|
6
|
+
const CookieBanner: React.FC<SGDS.Common.AbstractNotificationBanner>
|
|
7
|
+
& { Buttons?: React.FC<SGDS.Common.AbstractNotificationBanner.Buttons> } = ({
|
|
8
|
+
children,
|
|
9
|
+
className,
|
|
10
|
+
title,
|
|
11
|
+
...props
|
|
12
|
+
}) => {
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
<AbstractNotificationBanner
|
|
17
|
+
className={[
|
|
18
|
+
'ds_notification--large',
|
|
19
|
+
'ds_notification--cookie',
|
|
20
|
+
'js-initial-cookie-content',
|
|
21
|
+
className
|
|
22
|
+
].join(' ')}
|
|
23
|
+
data-module="ds-cookie-notification"
|
|
24
|
+
title={title}
|
|
25
|
+
{...props}
|
|
26
|
+
>
|
|
27
|
+
{children}
|
|
28
|
+
</AbstractNotificationBanner>
|
|
29
|
+
</>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
CookieBanner.displayName = 'CookieBanner';
|
|
34
|
+
CookieBanner.Buttons = AbstractNotificationBanner.Buttons;
|
|
35
|
+
|
|
36
|
+
export default CookieBanner;
|
|
@@ -14,15 +14,15 @@ test('details renders correctly', () => {
|
|
|
14
14
|
);
|
|
15
15
|
|
|
16
16
|
const summaryElement = screen.getByText(summaryText);
|
|
17
|
-
const detailsElement = summaryElement.
|
|
18
|
-
const textElement = summaryElement.
|
|
17
|
+
const detailsElement = summaryElement.parentElement;
|
|
18
|
+
const textElement = summaryElement.nextElementSibling;
|
|
19
19
|
|
|
20
20
|
expect(detailsElement).toHaveClass('ds_details');
|
|
21
|
-
expect(detailsElement
|
|
21
|
+
expect(detailsElement?.tagName).toEqual('DETAILS');
|
|
22
22
|
expect(summaryElement).toHaveClass('ds_details__summary');
|
|
23
|
-
expect(summaryElement
|
|
23
|
+
expect(summaryElement?.tagName).toEqual('SUMMARY');
|
|
24
24
|
expect(textElement).toHaveClass('ds_details__text');
|
|
25
|
-
expect(textElement
|
|
25
|
+
expect(textElement?.innerHTML).toEqual(content);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
test('passing additional props', () => {
|
|
@@ -33,7 +33,7 @@ test('passing additional props', () => {
|
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
const summaryElement = screen.getByText(summaryText);
|
|
36
|
-
const detailsElement = summaryElement.
|
|
36
|
+
const detailsElement = summaryElement.parentElement;
|
|
37
37
|
expect(detailsElement?.dataset.test).toEqual('foo');
|
|
38
38
|
});
|
|
39
39
|
|
|
@@ -45,6 +45,6 @@ test('passing additional CSS classes', () => {
|
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
const summaryElement = screen.getByText(summaryText);
|
|
48
|
-
const detailsElement = summaryElement.
|
|
48
|
+
const detailsElement = summaryElement.parentElement;
|
|
49
49
|
expect(detailsElement).toHaveClass('foo', 'ds_details');
|
|
50
50
|
});
|
|
@@ -28,7 +28,7 @@ test('passing additional props', () => {
|
|
|
28
28
|
</InsetText>
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
const insetTextOuter = document.querySelector('.ds_inset-text');
|
|
31
|
+
const insetTextOuter = document.querySelector('.ds_inset-text') as HTMLElement;
|
|
32
32
|
expect(insetTextOuter?.dataset.test).toEqual('foo');
|
|
33
33
|
});
|
|
34
34
|
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Most of the functionality for NotificationBanner is covered in AbstractNotificationBanner.
|
|
3
|
+
* Differences are specifically tested here.
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
import { test, expect } from 'vitest';
|
|
2
7
|
import { render, screen, within } from '@testing-library/react';
|
|
3
8
|
import NotificationBanner from './notification-banner';
|
|
4
9
|
|
|
5
10
|
const text = 'We need to tell you about something';
|
|
6
11
|
|
|
12
|
+
/**
|
|
13
|
+
* NotificationBanner has the ds_reversed class
|
|
14
|
+
*/
|
|
7
15
|
test('notification banner renders correctly', () => {
|
|
8
16
|
render(
|
|
9
17
|
<NotificationBanner>
|
|
@@ -11,47 +19,14 @@ test('notification banner renders correctly', () => {
|
|
|
11
19
|
</NotificationBanner>
|
|
12
20
|
);
|
|
13
21
|
|
|
14
|
-
const
|
|
15
|
-
const bannerText = bannerTitle.nextSibling;
|
|
16
|
-
const bannerContent = bannerTitle.parentNode;
|
|
17
|
-
const bannerWrapper = bannerContent?.parentNode;
|
|
18
|
-
const bannerContainer = bannerWrapper?.parentNode;
|
|
19
|
-
|
|
20
|
-
expect(bannerTitle.textContent).toEqual('Information');
|
|
21
|
-
expect(bannerTitle.tagName).toEqual('H2');
|
|
22
|
-
expect(bannerTitle).toHaveClass('visually-hidden');
|
|
23
|
-
|
|
24
|
-
expect(bannerText).toHaveClass('ds_notification__text');
|
|
25
|
-
expect(bannerText.textContent).toEqual(text);
|
|
22
|
+
const bannerContainer = document.querySelector('.ds_notification');
|
|
26
23
|
|
|
27
|
-
expect(bannerContent).toHaveClass('ds_notification__content');
|
|
28
|
-
expect(bannerWrapper).toHaveClass('ds_wrapper');
|
|
29
24
|
expect(bannerContainer).toHaveClass('ds_notification', 'ds_reversed');
|
|
30
25
|
});
|
|
31
26
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
{text}
|
|
36
|
-
</NotificationBanner>
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
const bannerTitle = screen.getByRole('heading');
|
|
40
|
-
const bannerContent = bannerTitle.parentNode;
|
|
41
|
-
const closeButton = screen.getByRole('button');
|
|
42
|
-
const closeButtonLabel = within(closeButton).getByText('Close this notification');
|
|
43
|
-
const closeButtonIcon = within(closeButton).getByRole('img', { hidden: true });
|
|
44
|
-
|
|
45
|
-
expect(bannerContent).toHaveClass('ds_notification__content--has-close');
|
|
46
|
-
expect(closeButton).toHaveClass('ds_notification__close', 'js-close-notification');
|
|
47
|
-
expect(closeButton).toHaveAttribute('type', 'button');
|
|
48
|
-
|
|
49
|
-
expect(closeButtonLabel).toBeInTheDocument();
|
|
50
|
-
expect(closeButtonLabel).toHaveClass('visually-hidden');
|
|
51
|
-
|
|
52
|
-
expect(closeButtonIcon).toHaveClass('ds_icon', 'ds_icon--fill');
|
|
53
|
-
});
|
|
54
|
-
|
|
27
|
+
/**
|
|
28
|
+
* NotificationBanner uses a boolean to toggle icon display, as only a single icon (PriorityHigh) is expected.
|
|
29
|
+
*/
|
|
55
30
|
test('notification banner with icon', () => {
|
|
56
31
|
render(
|
|
57
32
|
<NotificationBanner icon>
|
|
@@ -60,45 +35,10 @@ test('notification banner with icon', () => {
|
|
|
60
35
|
);
|
|
61
36
|
|
|
62
37
|
const bannerTitle = screen.getByRole('heading');
|
|
63
|
-
const bannerIconContainer = bannerTitle.
|
|
38
|
+
const bannerIconContainer = bannerTitle.nextElementSibling as HTMLElement;
|
|
64
39
|
const bannerIcon = within(bannerIconContainer).getByRole('img', { hidden: true });
|
|
65
40
|
|
|
66
41
|
expect(bannerIconContainer).toHaveClass('ds_notification__icon');
|
|
67
42
|
expect(bannerIcon).toHaveClass('ds_icon');
|
|
68
43
|
expect(bannerIcon).toHaveAttribute('aria-hidden');
|
|
69
44
|
});
|
|
70
|
-
|
|
71
|
-
test('notification banner with icon modifier classes', () => {
|
|
72
|
-
render(
|
|
73
|
-
<NotificationBanner icon iconColour iconInverse>
|
|
74
|
-
{text}
|
|
75
|
-
</NotificationBanner>
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
const bannerTitle = screen.getByRole('heading');
|
|
79
|
-
const bannerIconContainer = bannerTitle.nextSibling;
|
|
80
|
-
|
|
81
|
-
expect(bannerIconContainer).toHaveClass('ds_notification__icon', 'ds_notification__icon--inverse', 'ds_notification__icon--colour');
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test('passing additional props', () => {
|
|
85
|
-
render(
|
|
86
|
-
<NotificationBanner data-test="foo">
|
|
87
|
-
{text}
|
|
88
|
-
</NotificationBanner>
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
const bannerContainer = document.querySelector('.ds_notification');
|
|
92
|
-
expect(bannerContainer?.dataset.test).toEqual('foo');
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
test('passing additional CSS classes', () => {
|
|
96
|
-
render(
|
|
97
|
-
<NotificationBanner className="foo">
|
|
98
|
-
{text}
|
|
99
|
-
</NotificationBanner>
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
const bannerContainer = document.querySelector('.ds_notification');
|
|
103
|
-
expect(bannerContainer).toHaveClass('foo', 'ds_notification');
|
|
104
|
-
});
|