@scottish-government/designsystem-react 0.3.0 → 0.4.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/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/task-list/task-list.jsx +6 -7
- package/dist/tsconfig.tsbuildinfo +1 -1
- 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/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/vitest-setup.ts +1 -1
- package/@types/components/NotificationBanner.d.ts +0 -9
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { test, expect } from 'vitest';
|
|
2
|
+
import { render, screen, within } from '@testing-library/react';
|
|
3
|
+
import AbstractNotificationBanner from './abstract-notification-banner';
|
|
4
|
+
import Button from '../components/button/button';
|
|
5
|
+
|
|
6
|
+
const text = 'We need to tell you about something';
|
|
7
|
+
|
|
8
|
+
test('abstract notification banner renders correctly', () => {
|
|
9
|
+
render(
|
|
10
|
+
<AbstractNotificationBanner>
|
|
11
|
+
{text}
|
|
12
|
+
</AbstractNotificationBanner>
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const bannerTitle = screen.getByRole('heading');
|
|
16
|
+
const bannerText = bannerTitle.nextElementSibling;
|
|
17
|
+
const bannerContent = bannerTitle.parentElement;
|
|
18
|
+
const bannerWrapper = bannerContent?.parentElement;
|
|
19
|
+
const bannerContainer = bannerWrapper?.parentElement;
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
expect(bannerTitle.textContent).toEqual('Information');
|
|
23
|
+
expect(bannerTitle.tagName).toEqual('H2');
|
|
24
|
+
expect(bannerTitle).toHaveClass('visually-hidden');
|
|
25
|
+
|
|
26
|
+
expect(bannerText).toHaveClass('ds_notification__text');
|
|
27
|
+
expect(bannerText?.textContent).toEqual(text);
|
|
28
|
+
|
|
29
|
+
expect(bannerContent).toHaveClass('ds_notification__content');
|
|
30
|
+
expect(bannerWrapper).toHaveClass('ds_wrapper');
|
|
31
|
+
expect(bannerContainer).toHaveClass('ds_notification');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('abstract notification banner with close button', () => {
|
|
35
|
+
render(
|
|
36
|
+
<AbstractNotificationBanner close>
|
|
37
|
+
{text}
|
|
38
|
+
</AbstractNotificationBanner>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const bannerTitle = screen.getByRole('heading');
|
|
42
|
+
const bannerContent = bannerTitle.parentElement;
|
|
43
|
+
const closeButton = screen.getByRole('button');
|
|
44
|
+
const closeButtonLabel = within(closeButton).getByText('Close this notification');
|
|
45
|
+
const closeButtonIcon = within(closeButton).getByRole('img', { hidden: true });
|
|
46
|
+
|
|
47
|
+
expect(bannerContent).toHaveClass('ds_notification__content--has-close');
|
|
48
|
+
expect(closeButton).toHaveClass('ds_notification__close', 'js-close-notification');
|
|
49
|
+
expect(closeButton).toHaveAttribute('type', 'button');
|
|
50
|
+
|
|
51
|
+
expect(closeButtonLabel).toBeInTheDocument();
|
|
52
|
+
expect(closeButtonLabel).toHaveClass('visually-hidden');
|
|
53
|
+
|
|
54
|
+
expect(closeButtonIcon).toHaveClass('ds_icon', 'ds_icon--fill');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('abstract notification banner with icon', () => {
|
|
58
|
+
render(
|
|
59
|
+
<AbstractNotificationBanner icon="Search">
|
|
60
|
+
{text}
|
|
61
|
+
</AbstractNotificationBanner>
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const bannerTitle = screen.getByRole('heading');
|
|
65
|
+
const bannerIconContainer = bannerTitle.nextElementSibling as HTMLElement;
|
|
66
|
+
const bannerIcon = within(bannerIconContainer).getByRole('img', { hidden: true });
|
|
67
|
+
|
|
68
|
+
expect(bannerIconContainer).toHaveClass('ds_notification__icon');
|
|
69
|
+
expect(bannerIcon).toHaveClass('ds_icon');
|
|
70
|
+
expect(bannerIcon).toHaveAttribute('aria-hidden');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('abstract notification banner with icon modifier classes', () => {
|
|
74
|
+
render(
|
|
75
|
+
<AbstractNotificationBanner icon="Search" iconColour iconInverse>
|
|
76
|
+
{text}
|
|
77
|
+
</AbstractNotificationBanner>
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const bannerTitle = screen.getByRole('heading');
|
|
81
|
+
const bannerIconContainer = bannerTitle.nextElementSibling;
|
|
82
|
+
|
|
83
|
+
expect(bannerIconContainer).toHaveClass('ds_notification__icon', 'ds_notification__icon--inverse', 'ds_notification__icon--colour');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('abstract notification banner with buttons', () => {
|
|
87
|
+
render(
|
|
88
|
+
<AbstractNotificationBanner>
|
|
89
|
+
{text}
|
|
90
|
+
<AbstractNotificationBanner.Buttons>
|
|
91
|
+
<Button data-testid="button">Foo</Button>
|
|
92
|
+
</AbstractNotificationBanner.Buttons>
|
|
93
|
+
</AbstractNotificationBanner>
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const bannerContainer = document.querySelector('.ds_notification');
|
|
97
|
+
const button = screen.getByTestId('button');
|
|
98
|
+
const buttonContainer = button.parentElement;
|
|
99
|
+
const textContainer = bannerContainer?.querySelector('.ds_notification__text');
|
|
100
|
+
|
|
101
|
+
expect(buttonContainer).toHaveClass('ds_button-group');
|
|
102
|
+
expect(buttonContainer?.tagName).toEqual('DIV');
|
|
103
|
+
expect(buttonContainer?.previousElementSibling).toEqual(textContainer);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('passing additional props', () => {
|
|
107
|
+
render(
|
|
108
|
+
<AbstractNotificationBanner data-test="foo">
|
|
109
|
+
{text}
|
|
110
|
+
</AbstractNotificationBanner>
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
const bannerContainer = document.querySelector('.ds_notification') as HTMLElement;
|
|
114
|
+
expect(bannerContainer?.dataset.test).toEqual('foo');
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('passing additional CSS classes', () => {
|
|
118
|
+
render(
|
|
119
|
+
<AbstractNotificationBanner className="foo">
|
|
120
|
+
{text}
|
|
121
|
+
</AbstractNotificationBanner>
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
const bannerContainer = document.querySelector('.ds_notification');
|
|
125
|
+
expect(bannerContainer).toHaveClass('foo', 'ds_notification');
|
|
126
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Children, isValidElement } from 'react';
|
|
2
|
+
import Icon from './icon';
|
|
3
|
+
import ScreenReaderText from './screen-reader-text';
|
|
4
|
+
|
|
5
|
+
const Buttons: React.FC<SGDS.Common.AbstractNotificationBanner.Buttons> = ({
|
|
6
|
+
children
|
|
7
|
+
}) => {
|
|
8
|
+
return (<>{children}</>);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const AbstractNotificationBanner: React.FC<SGDS.Common.AbstractNotificationBanner>
|
|
12
|
+
& { Buttons: React.FC<SGDS.Common.AbstractNotificationBanner.Buttons> } = ({
|
|
13
|
+
children,
|
|
14
|
+
className,
|
|
15
|
+
close,
|
|
16
|
+
icon,
|
|
17
|
+
iconColour,
|
|
18
|
+
iconInverse,
|
|
19
|
+
title = 'Information',
|
|
20
|
+
...props
|
|
21
|
+
}) => {
|
|
22
|
+
let content: any[] = [];
|
|
23
|
+
let buttons;
|
|
24
|
+
|
|
25
|
+
Children.forEach(children, (child) => {
|
|
26
|
+
if (isValidElement(child) && child.type === Buttons) {
|
|
27
|
+
buttons = child;
|
|
28
|
+
} else {
|
|
29
|
+
content.push(child);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
className={[
|
|
36
|
+
'ds_notification',
|
|
37
|
+
className
|
|
38
|
+
].join(' ')}
|
|
39
|
+
data-module="ds-notification"
|
|
40
|
+
{...props}
|
|
41
|
+
>
|
|
42
|
+
<div className="ds_wrapper">
|
|
43
|
+
<div className={
|
|
44
|
+
[
|
|
45
|
+
'ds_notification__content',
|
|
46
|
+
close && 'ds_notification__content--has-close'
|
|
47
|
+
].join(' ')}
|
|
48
|
+
>
|
|
49
|
+
<h2 className="visually-hidden">{title}</h2>
|
|
50
|
+
|
|
51
|
+
{icon &&
|
|
52
|
+
<span
|
|
53
|
+
className={[
|
|
54
|
+
'ds_notification__icon',
|
|
55
|
+
iconInverse && 'ds_notification__icon--inverse',
|
|
56
|
+
iconColour && 'ds_notification__icon--colour'
|
|
57
|
+
].join(' ')} aria-hidden="true">
|
|
58
|
+
<Icon icon={icon} />
|
|
59
|
+
</span>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
<div className="ds_notification__text">
|
|
63
|
+
{content}
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
{close &&
|
|
67
|
+
<button type="button" className="ds_notification__close js-close-notification">
|
|
68
|
+
<ScreenReaderText>Close this notification</ScreenReaderText>
|
|
69
|
+
<Icon fill icon="Close" aria-hidden="true" />
|
|
70
|
+
</button>
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
{buttons &&
|
|
74
|
+
<div className="ds_button-group">
|
|
75
|
+
{buttons}
|
|
76
|
+
</div>
|
|
77
|
+
}
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
AbstractNotificationBanner.displayName = 'AbstractNotificationBanner';
|
|
85
|
+
AbstractNotificationBanner.Buttons = Buttons;
|
|
86
|
+
|
|
87
|
+
export default AbstractNotificationBanner;
|
|
@@ -16,7 +16,7 @@ test('conditional wrapper true', () => {
|
|
|
16
16
|
const elementParent = screen.getByTestId('wrapper');
|
|
17
17
|
expect(element).toBeInTheDocument();
|
|
18
18
|
expect(elementParent).toBeInTheDocument();
|
|
19
|
-
expect(element.
|
|
19
|
+
expect(element.parentElement).toEqual(elementParent)
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
test('conditional wrapper false', () => {
|
|
@@ -14,7 +14,7 @@ test('screen reader text renders correctly', () => {
|
|
|
14
14
|
const srtext = document.querySelector('span');
|
|
15
15
|
|
|
16
16
|
expect(srtext).toHaveClass('visually-hidden');
|
|
17
|
-
expect(srtext
|
|
17
|
+
expect(srtext?.textContent).toEqual(content)
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
test('passing additional props', () => {
|
|
@@ -13,7 +13,7 @@ test('wrapper tag renders correctly', () => {
|
|
|
13
13
|
|
|
14
14
|
const wrapper = document.querySelector('#foo');
|
|
15
15
|
|
|
16
|
-
expect(wrapper
|
|
16
|
+
expect(wrapper?.tagName).toEqual('DIV');
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
test('wrapper tag widh tag name', () => {
|
|
@@ -27,7 +27,7 @@ test('wrapper tag widh tag name', () => {
|
|
|
27
27
|
|
|
28
28
|
const wrapper = document.querySelector('#foo');
|
|
29
29
|
|
|
30
|
-
expect(wrapper
|
|
30
|
+
expect(wrapper?.tagName).toEqual('SECTION');
|
|
31
31
|
});
|
|
32
32
|
|
|
33
33
|
test('passing additional props', () => {
|
|
@@ -37,6 +37,6 @@ test('passing additional props', () => {
|
|
|
37
37
|
</WrapperTag>
|
|
38
38
|
);
|
|
39
39
|
|
|
40
|
-
const wrapper = document.querySelector('#foo');
|
|
40
|
+
const wrapper = document.querySelector('#foo') as HTMLElement;
|
|
41
41
|
expect(wrapper?.dataset.test).toEqual('foo');
|
|
42
42
|
});
|
|
@@ -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
|
|