@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.
Files changed (62) hide show
  1. package/@types/common/AbstractNotificationBanner.d.ts +17 -0
  2. package/@types/components/Table.d.ts +8 -0
  3. package/@types/components/Tabs.d.ts +22 -0
  4. package/@types/components/TaskList.d.ts +1 -1
  5. package/dist/common/abstract-notification-banner.jsx +63 -0
  6. package/dist/components/accordion/accordion.jsx +2 -3
  7. package/dist/components/breadcrumbs/breadcrumbs.jsx +2 -2
  8. package/dist/components/cookie-banner/cookie-banner.jsx +21 -0
  9. package/dist/components/notification-banner/notification-banner.jsx +7 -34
  10. package/dist/components/page-metadata/page-metadata.jsx +2 -3
  11. package/dist/components/table/table.jsx +24 -0
  12. package/dist/components/tabs/tabs.jsx +99 -0
  13. package/dist/components/task-list/task-list.jsx +6 -7
  14. package/dist/tsconfig.tsbuildinfo +1 -1
  15. package/dist/utils/slugify.js +15 -0
  16. package/package.json +1 -1
  17. package/src/common/abstract-notification-banner.test.tsx +126 -0
  18. package/src/common/abstract-notification-banner.tsx +87 -0
  19. package/src/common/conditional-wrapper.test.tsx +1 -1
  20. package/src/common/screen-reader-text.test.tsx +1 -1
  21. package/src/common/wrapper-tag.test.tsx +3 -3
  22. package/src/components/accordion/accordion.test.tsx +40 -40
  23. package/src/components/accordion/accordion.tsx +4 -2
  24. package/src/components/aspect-box/aspect-box.test.tsx +7 -7
  25. package/src/components/breadcrumbs/breadcrumbs.tsx +0 -2
  26. package/src/components/checkbox/checkbox.test.tsx +8 -8
  27. package/src/components/confirmation-message/confirmation-message.test.tsx +1 -1
  28. package/src/components/cookie-banner/cookie-banner.test.tsx +25 -0
  29. package/src/components/cookie-banner/cookie-banner.tsx +36 -0
  30. package/src/components/details/details.test.tsx +7 -7
  31. package/src/components/inset-text/inset-text.test.tsx +1 -1
  32. package/src/components/notification-banner/notification-banner.test.tsx +13 -73
  33. package/src/components/notification-banner/notification-banner.tsx +13 -41
  34. package/src/components/notification-panel/notification-panel.test.tsx +6 -6
  35. package/src/components/page-header/page-header.test.tsx +2 -2
  36. package/src/components/page-metadata/page-metadata.test.tsx +12 -12
  37. package/src/components/page-metadata/page-metadata.tsx +4 -2
  38. package/src/components/pagination/pagination.test.tsx +28 -30
  39. package/src/components/phase-banner/phase-banner.test.tsx +8 -8
  40. package/src/components/question/question.test.tsx +3 -3
  41. package/src/components/radio-button/radio-button.test.tsx +7 -7
  42. package/src/components/select/select.test.tsx +9 -9
  43. package/src/components/sequential-navigation/sequential-navigation.test.tsx +4 -4
  44. package/src/components/side-navigation/side-navigation.test.tsx +1 -1
  45. package/src/components/site-header/site-header.test.tsx +22 -22
  46. package/src/components/site-search/site-search.test.tsx +9 -9
  47. package/src/components/skip-links/skip-links.test.tsx +3 -3
  48. package/src/components/summary-card/summary-card.test.tsx +2 -2
  49. package/src/components/summary-list/summary-list.test.tsx +35 -16
  50. package/src/components/table/table.test.tsx +77 -0
  51. package/src/components/table/table.tsx +36 -0
  52. package/src/components/tabs/tabs.test.tsx +258 -0
  53. package/src/components/tabs/tabs.tsx +110 -0
  54. package/src/components/task-list/task-list.test.tsx +81 -83
  55. package/src/components/task-list/task-list.tsx +9 -5
  56. package/src/components/text-input/text-input.test.tsx +6 -6
  57. package/src/components/textarea/textarea.test.tsx +2 -2
  58. package/src/components/warning-text/warning-text.test.tsx +1 -1
  59. package/src/utils/slugify.ts +13 -0
  60. package/vite.config.ts +6 -1
  61. package/vitest-setup.ts +1 -1
  62. package/@types/components/NotificationBanner.d.ts +0 -9
@@ -1,18 +1,17 @@
1
1
  import { useEffect, useRef } from 'react';
2
-
2
+ import AbstractNotificationBanner from '../../common/abstract-notification-banner';
3
3
  // @ts-ignore
4
4
  import DSNotificationBanner from '@scottish-government/design-system/src/components/notification-banner/notification-banner';
5
- import Icon from '../../common/icon';
6
- import ScreenReaderText from '../../common/screen-reader-text';
7
5
 
8
- const NotificationBanner: React.FC<SGDS.Component.NotificationBanner> = ({
6
+ const NotificationBanner: React.FC<SGDS.Common.AbstractNotificationBanner>
7
+ & { Buttons?: React.FC<SGDS.Common.AbstractNotificationBanner.Buttons> } = ({
9
8
  children,
10
9
  className,
11
10
  close,
12
11
  icon,
13
12
  iconColour,
14
13
  iconInverse,
15
- title = 'Information',
14
+ title,
16
15
  ...props
17
16
  }) => {
18
17
  const ref = useRef(null);
@@ -24,52 +23,25 @@ const NotificationBanner: React.FC<SGDS.Component.NotificationBanner> = ({
24
23
  }, [ref]);
25
24
 
26
25
  return (
27
- <div
26
+ <AbstractNotificationBanner
28
27
  className={[
29
- 'ds_notification',
30
28
  'ds_reversed',
31
29
  className
32
30
  ].join(' ')}
33
- data-module="ds-notification"
31
+ close={close}
32
+ icon={icon ? "PriorityHigh" : undefined}
33
+ iconColour={iconColour}
34
+ iconInverse={iconInverse}
34
35
  ref={ref}
36
+ title="Information"
35
37
  {...props}
36
38
  >
37
- <div className="ds_wrapper">
38
- <div className={
39
- [
40
- 'ds_notification__content',
41
- close && 'ds_notification__content--has-close'
42
- ].join(' ')}
43
- >
44
- <h2 className="visually-hidden">{title}</h2>
45
-
46
- {icon &&
47
- <span
48
- className={[
49
- 'ds_notification__icon',
50
- iconInverse && 'ds_notification__icon--inverse',
51
- iconColour && 'ds_notification__icon--colour'
52
- ].join(' ')} aria-hidden="true">
53
- <Icon icon="PriorityHigh" />
54
- </span>
55
- }
56
-
57
- <div className="ds_notification__text">
58
- {children}
59
- </div>
60
-
61
- {close &&
62
- <button type="button" className="ds_notification__close js-close-notification">
63
- <ScreenReaderText>Close this notification</ScreenReaderText>
64
- <Icon fill icon="Close" aria-hidden="true" />
65
- </button>
66
- }
67
- </div>
68
- </div>
69
- </div>
39
+ {children}
40
+ </AbstractNotificationBanner>
70
41
  );
71
42
  };
72
43
 
73
44
  NotificationBanner.displayName = 'NotificationBanner';
45
+ NotificationBanner.Buttons = AbstractNotificationBanner.Buttons;
74
46
 
75
47
  export default NotificationBanner;
@@ -13,15 +13,15 @@ test('notification banner renders correctly', () => {
13
13
  );
14
14
 
15
15
  const notificationPanelHeading = screen.getByRole('heading');
16
- const notificationPanelContent = notificationPanelHeading.nextSibling;
17
- const notificationPanel = notificationPanelHeading.parentNode;
16
+ const notificationPanelContent = notificationPanelHeading.nextElementSibling;
17
+ const notificationPanel = notificationPanelHeading.parentElement;
18
18
 
19
19
  expect(notificationPanel).toHaveClass('ds_notification-panel');
20
20
  expect(notificationPanelHeading).toHaveClass('ds_notification-panel__title');
21
21
  expect(notificationPanelHeading.textContent).toEqual(headingText);
22
22
  expect(notificationPanelHeading.tagName).toEqual('H1');
23
23
  expect(notificationPanelContent).toHaveClass('ds_notification-panel__content');
24
- expect(notificationPanelContent.textContent).toEqual(text);
24
+ expect(notificationPanelContent?.textContent).toEqual(text);
25
25
  });
26
26
 
27
27
  test('notification banner with custom heading level', () => {
@@ -47,7 +47,7 @@ test('notification banner with aria-live', () => {
47
47
  );
48
48
 
49
49
  const notificationPanelHeading = screen.getByRole('heading');
50
- const notificationPanel = notificationPanelHeading.parentNode;
50
+ const notificationPanel = notificationPanelHeading.parentElement;
51
51
 
52
52
  expect(notificationPanel).toHaveAttribute('aria-live', ariaLive);
53
53
  });
@@ -72,7 +72,7 @@ test('passing additional props', () => {
72
72
  )
73
73
 
74
74
  const notificationPanelHeading = screen.getByRole('heading');
75
- const notificationPanel = notificationPanelHeading.parentNode;
75
+ const notificationPanel = notificationPanelHeading.parentElement;
76
76
  expect(notificationPanel?.dataset.test).toEqual('foo');
77
77
  });
78
78
 
@@ -84,6 +84,6 @@ test('passing additional CSS classes', () => {
84
84
  )
85
85
 
86
86
  const notificationPanelHeading = screen.getByRole('heading');
87
- const notificationPanel = notificationPanelHeading.parentNode;
87
+ const notificationPanel = notificationPanelHeading.parentElement;
88
88
  expect(notificationPanel).toHaveClass('foo', 'ds_notification-panel');
89
89
  });
@@ -12,7 +12,7 @@ test('notification banner renders correctly', () => {
12
12
 
13
13
  const header = screen.getByRole('banner');
14
14
  const title = within(header).getByRole('heading');
15
- const label = title.previousSibling;;
15
+ const label = title.previousElementSibling;
16
16
 
17
17
  expect(header).toHaveClass('ds_page-header');
18
18
  expect(header.tagName).toEqual('HEADER');
@@ -33,7 +33,7 @@ test('header with no label', () => {
33
33
 
34
34
  const header = screen.getByRole('banner');
35
35
  const title = within(header).getByRole('heading');
36
- const label = title.previousSibling;
36
+ const label = title.previousElementSibling;
37
37
 
38
38
  expect(label).not.toBeInTheDocument();
39
39
  });
@@ -1,6 +1,6 @@
1
1
  import { test, expect } from 'vitest';
2
- import { render, screen, within } from '@testing-library/react';
3
- import Metadata, {MetadataItem} from './page-metadata';
2
+ import { render, screen } from '@testing-library/react';
3
+ import Metadata from './page-metadata';
4
4
 
5
5
  const name = 'Directorate';
6
6
  const value = 'Equality, Inclusion and Human Rights Directorate';
@@ -8,9 +8,9 @@ const value = 'Equality, Inclusion and Human Rights Directorate';
8
8
  test('metadata renders correctly', () => {
9
9
  render(
10
10
  <Metadata>
11
- <MetadataItem name={name}>
11
+ <Metadata.Item name={name}>
12
12
  {value}
13
- </MetadataItem>
13
+ </Metadata.Item>
14
14
  </Metadata>
15
15
  );
16
16
 
@@ -30,9 +30,9 @@ test('metadata renders correctly', () => {
30
30
  test('inline metadata', () => {
31
31
  render(
32
32
  <Metadata inline>
33
- <MetadataItem name={name}>
33
+ <Metadata.Item name={name}>
34
34
  {value}
35
- </MetadataItem>
35
+ </Metadata.Item>
36
36
  </Metadata>
37
37
  );
38
38
 
@@ -43,14 +43,14 @@ test('inline metadata', () => {
43
43
  test('passing additional props', () => {
44
44
  render(
45
45
  <Metadata data-test="foo">
46
- <MetadataItem data-test="bar" name="Last updated">
46
+ <Metadata.Item data-test="bar" name="Last updated">
47
47
  21/04/2020
48
- </MetadataItem>
48
+ </Metadata.Item>
49
49
  </Metadata>
50
50
  )
51
51
 
52
- const metadata = document.querySelector('.ds_metadata');
53
- const metadataItem = document.querySelector('.ds_metadata__item');
52
+ const metadata = document.querySelector('.ds_metadata') as HTMLElement;
53
+ const metadataItem = document.querySelector('.ds_metadata__item') as HTMLElement;
54
54
  expect(metadata?.dataset.test).toEqual('foo');
55
55
  expect(metadataItem?.dataset.test).toEqual('bar');
56
56
  });
@@ -58,9 +58,9 @@ test('passing additional props', () => {
58
58
  test('passing additional CSS classes', () => {
59
59
  render(
60
60
  <Metadata className="foo">
61
- <MetadataItem className="bar" name="Last updated">
61
+ <Metadata.Item className="bar" name="Last updated">
62
62
  21/04/2020
63
- </MetadataItem>
63
+ </Metadata.Item>
64
64
  </Metadata>
65
65
  )
66
66
 
@@ -1,4 +1,4 @@
1
- export const MetadataItem: React.FC<SGDS.Component.Metadata.Item> = ({
1
+ const MetadataItem: React.FC<SGDS.Component.Metadata.Item> = ({
2
2
  children,
3
3
  className,
4
4
  name,
@@ -19,7 +19,8 @@ export const MetadataItem: React.FC<SGDS.Component.Metadata.Item> = ({
19
19
  );
20
20
  };
21
21
 
22
- const Metadata: React.FC<SGDS.Component.Metadata> = ({
22
+ const Metadata: React.FC<SGDS.Component.Metadata>
23
+ & { Item: React.FC<SGDS.Component.Metadata.Item> } = ({
23
24
  children,
24
25
  className,
25
26
  inline,
@@ -41,5 +42,6 @@ const Metadata: React.FC<SGDS.Component.Metadata> = ({
41
42
 
42
43
  Metadata.displayName = 'Metadata';
43
44
  MetadataItem.displayName = 'MetadataItem';
45
+ Metadata.Item = MetadataItem;
44
46
 
45
47
  export default Metadata;
@@ -89,28 +89,28 @@ test('pagination renders correctly', () => {
89
89
  const paginationNav = screen.getByRole('navigation');
90
90
  const paginationList = within(paginationNav).getByRole('list');
91
91
  const prevLabel = within(paginationList).getByText('Previous');
92
- const prevLink = prevLabel.parentNode;
93
- const prevIcon = prevLabel.previousSibling;
94
- const prevItem = prevLink?.parentNode;
92
+ const prevLink = prevLabel.parentElement;
93
+ const prevIcon = prevLabel.previousElementSibling;
94
+ const prevItem = prevLink?.parentElement;
95
95
  const nextLabel = within(paginationList).getByText('Next');
96
- const nextLink = nextLabel.parentNode;
97
- const nextIcon = nextLabel.nextSibling;
98
- const nextItem = nextLink?.parentNode;
96
+ const nextLink = nextLabel.parentElement;
97
+ const nextIcon = nextLabel.nextElementSibling;
98
+ const nextItem = nextLink?.parentElement;
99
99
 
100
100
  const firstPageLabel = within(paginationList).getByText('1');
101
- const firstPageLink = firstPageLabel.parentNode;
102
- const firstPageItem = firstPageLink?.parentNode;
101
+ const firstPageLink = firstPageLabel.parentElement;
102
+ const firstPageItem = firstPageLink?.parentElement;
103
103
  const lastPageLabel = within(paginationList).getByText(totalPages);
104
- const lastPageLink = lastPageLabel.parentNode;
105
- const lastPageItem = lastPageLink?.parentNode;
104
+ const lastPageLink = lastPageLabel.parentElement;
105
+ const lastPageItem = lastPageLink?.parentElement;
106
106
 
107
- const firstPageEllipsisItem = firstPageItem?.nextSibling;
107
+ const firstPageEllipsisItem = firstPageItem?.nextElementSibling;
108
108
  const firstPageEllipsis = firstPageEllipsisItem?.children[0];
109
- const lastPageEllipsisItem = lastPageItem?.previousSibling;
109
+ const lastPageEllipsisItem = lastPageItem?.previousElementSibling;
110
110
  const lastPageEllipsis = lastPageEllipsisItem?.children[0];
111
111
 
112
112
  const currentPageLink = document.querySelector('.ds_current');
113
- const currentPageItem = currentPageLink?.parentNode;
113
+ const currentPageItem = currentPageLink?.parentElement;
114
114
 
115
115
  const paginationItems = within(paginationList).getAllByRole('listitem', { hidden: true });
116
116
 
@@ -122,7 +122,7 @@ test('pagination renders correctly', () => {
122
122
 
123
123
  expect(prevItem).toHaveClass('ds_pagination__item');
124
124
  expect(prevItem?.tagName).toEqual('LI');
125
- expect(prevItem?.parentNode).toEqual(paginationList);
125
+ expect(prevItem?.parentElement).toEqual(paginationList);
126
126
  expect(prevLink).toHaveClass('ds_pagination__link', 'ds_pagination__link--text', 'ds_pagination__link--icon')
127
127
  expect(prevLink).toHaveAttribute('aria-label', 'Previous page');
128
128
  expect(prevLink).toHaveAttribute('href', `/search?page=${currentPage - 1}`);
@@ -135,7 +135,7 @@ test('pagination renders correctly', () => {
135
135
 
136
136
  expect(nextItem).toHaveClass('ds_pagination__item');
137
137
  expect(nextItem?.tagName).toEqual('LI');
138
- expect(nextItem?.parentNode).toEqual(paginationList);
138
+ expect(nextItem?.parentElement).toEqual(paginationList);
139
139
  expect(nextLink).toHaveClass('ds_pagination__link', 'ds_pagination__link--text', 'ds_pagination__link--icon')
140
140
  expect(nextLink).toHaveAttribute('aria-label', 'Next page');
141
141
  expect(nextLink).toHaveAttribute('href', `/search?page=${currentPage + 1}`);
@@ -148,7 +148,7 @@ test('pagination renders correctly', () => {
148
148
 
149
149
  expect(firstPageItem).toHaveClass('ds_pagination__item');
150
150
  expect(firstPageItem?.tagName).toEqual('LI');
151
- expect(firstPageItem?.parentNode).toEqual(paginationList);
151
+ expect(firstPageItem?.parentElement).toEqual(paginationList);
152
152
  expect(firstPageLink).toHaveClass('ds_pagination__link')
153
153
  expect(firstPageLink).toHaveAttribute('aria-label', 'Page 1');
154
154
  expect(firstPageLink).toHaveAttribute('href', `/search?page=1`);
@@ -158,7 +158,7 @@ test('pagination renders correctly', () => {
158
158
 
159
159
  expect(lastPageItem).toHaveClass('ds_pagination__item');
160
160
  expect(lastPageItem?.tagName).toEqual('LI');
161
- expect(lastPageItem?.parentNode).toEqual(paginationList);
161
+ expect(lastPageItem?.parentElement).toEqual(paginationList);
162
162
  expect(lastPageLink).toHaveClass('ds_pagination__link')
163
163
  expect(lastPageLink).toHaveAttribute('aria-label', `Page ${totalPages}`);
164
164
  expect(lastPageLink).toHaveAttribute('href', `/search?page=${totalPages}`);
@@ -170,28 +170,28 @@ test('pagination renders correctly', () => {
170
170
 
171
171
  expect(firstPageEllipsisItem).toHaveClass('ds_pagination__item');
172
172
  expect(firstPageEllipsisItem).toHaveAttribute('aria-hidden', 'true');
173
- expect(firstPageEllipsisItem.tagName).toEqual('LI');
173
+ expect(firstPageEllipsisItem?.tagName).toEqual('LI');
174
174
  expect(firstPageEllipsis).toHaveClass('ds_pagination__link', 'ds_pagination__link--ellipsis');
175
- expect(firstPageEllipsis.tagName).toEqual('SPAN');
176
- expect(firstPageEllipsis.textContent).toEqual('…');
175
+ expect(firstPageEllipsis?.tagName).toEqual('SPAN');
176
+ expect(firstPageEllipsis?.textContent).toEqual('…');
177
177
 
178
178
  expect(lastPageEllipsisItem).toHaveClass('ds_pagination__item');
179
179
  expect(lastPageEllipsisItem).toHaveAttribute('aria-hidden', 'true');
180
- expect(lastPageEllipsisItem.tagName).toEqual('LI');
180
+ expect(lastPageEllipsisItem?.tagName).toEqual('LI');
181
181
  expect(lastPageEllipsis).toHaveClass('ds_pagination__link', 'ds_pagination__link--ellipsis');
182
- expect(lastPageEllipsis.tagName).toEqual('SPAN');
183
- expect(lastPageEllipsis.textContent).toEqual('…');
182
+ expect(lastPageEllipsis?.tagName).toEqual('SPAN');
183
+ expect(lastPageEllipsis?.textContent).toEqual('…');
184
184
 
185
185
  expect(currentPageItem).toHaveClass('ds_pagination__item');
186
186
  expect(currentPageLink).toHaveClass('ds_pagination__link', 'ds_current');
187
- expect(currentPageLink.textContent).toEqual(currentPage.toString());
187
+ expect(currentPageLink?.textContent).toEqual(currentPage.toString());
188
188
 
189
189
  // expect one link either side of the current (default padding)
190
- expect(currentPageItem.previousSibling.querySelector('a')).toHaveAttribute('aria-label', 'Page 9');
191
- expect(currentPageItem.previousSibling.previousSibling.querySelector('a')).toBeNull();
190
+ expect(currentPageItem?.previousElementSibling?.querySelector('a')).toHaveAttribute('aria-label', 'Page 9');
191
+ expect(currentPageItem?.previousElementSibling?.previousElementSibling?.querySelector('a')).toBeNull();
192
192
 
193
- expect(currentPageItem.nextSibling.querySelector('a')).toHaveAttribute('aria-label', 'Page 11');
194
- expect(currentPageItem.nextSibling.nextSibling.querySelector('a')).toBeNull();
193
+ expect(currentPageItem?.nextElementSibling?.querySelector('a')).toHaveAttribute('aria-label', 'Page 11');
194
+ expect(currentPageItem?.nextElementSibling?.nextElementSibling?.querySelector('a')).toBeNull();
195
195
 
196
196
  // 9 is: previous, first, ellipsis, current page and 1 padding either side, ellipsis, last, next
197
197
  expect(paginationItems.length).toEqual(9);
@@ -243,8 +243,6 @@ test('pagination passes onclick event to child links', () => {
243
243
  />
244
244
  );
245
245
 
246
- const paginationNav = screen.getByRole('navigation');
247
-
248
246
  // pick an arbitrary link
249
247
  const link = [].slice.call(document.querySelectorAll('.ds_pagination__link'))[4];
250
248
  link.setAttribute('href', '#foo');
@@ -14,16 +14,16 @@ test('phase banner renders correctly', () => {
14
14
 
15
15
  const phaseBanner = document.querySelector('.ds_phase-banner');
16
16
  const phaseBannerContent = phaseBanner?.querySelector('.ds_phase-banner__content');
17
- const phaseBannerWrapper = phaseBannerContent?.parentNode;
17
+ const phaseBannerWrapper = phaseBannerContent?.parentElement;
18
18
  const phaseBannerText = phaseBannerContent?.querySelector('.ds_phase-banner__text');
19
19
 
20
20
  expect(phaseBanner).toBeInTheDocument();
21
21
  expect(phaseBanner?.tagName).toEqual('DIV');
22
22
  expect(phaseBannerWrapper).toHaveClass('ds_wrapper');
23
- expect(phaseBannerWrapper.tagName).toEqual('DIV');
24
- expect(phaseBannerContent.tagName).toEqual('P');
25
- expect(phaseBannerText.tagName).toEqual('SPAN');
26
- expect(phaseBannerText.textContent).toEqual(text);
23
+ expect(phaseBannerWrapper?.tagName).toEqual('DIV');
24
+ expect(phaseBannerContent?.tagName).toEqual('P');
25
+ expect(phaseBannerText?.tagName).toEqual('SPAN');
26
+ expect(phaseBannerText?.textContent).toEqual(text);
27
27
  });
28
28
 
29
29
  test('phase banner with default text', () => {
@@ -50,9 +50,9 @@ test('phase banner with phase tag', () => {
50
50
  const phaseBannerTag = phaseBanner?.querySelector('.ds_phase-banner__tag');
51
51
 
52
52
  expect(phaseBannerTag).toBeInTheDocument();
53
- expect(phaseBannerTag.tagName).toEqual('SPAN');
53
+ expect(phaseBannerTag?.tagName).toEqual('SPAN');
54
54
  expect(phaseBannerTag).toHaveClass('ds_tag', 'ds_phase-banner__tag');
55
- expect(phaseBannerTag.textContent).toEqual(phase);
55
+ expect(phaseBannerTag?.textContent).toEqual(phase);
56
56
  });
57
57
 
58
58
  test('passing additional props', () => {
@@ -62,7 +62,7 @@ test('passing additional props', () => {
62
62
  </PhaseBanner>
63
63
  )
64
64
 
65
- const phaseBanner = document.querySelector('.ds_phase-banner');
65
+ const phaseBanner = document.querySelector('.ds_phase-banner') as HTMLElement;
66
66
  expect(phaseBanner?.dataset.test).toEqual('foo');
67
67
  });
68
68
 
@@ -51,11 +51,11 @@ test('question with error', () => {
51
51
  );
52
52
 
53
53
  const questionElement = document.querySelector('.ds_question');
54
- const errorMessageElement = questionElement.querySelector('.ds_question__error-message');
54
+ const errorMessageElement = questionElement?.querySelector('.ds_question__error-message');
55
55
 
56
56
  expect(questionElement).toHaveClass('ds_question--error');
57
57
  expect(errorMessageElement).toBeInTheDocument();
58
- expect(errorMessageElement.textContent).toEqual(errorMessage);
58
+ expect(errorMessageElement?.textContent).toEqual(errorMessage);
59
59
  });
60
60
 
61
61
  test('passing additional props', () => {
@@ -64,7 +64,7 @@ test('passing additional props', () => {
64
64
  </Question>
65
65
  )
66
66
 
67
- const questionElement = document.querySelector('.ds_question');
67
+ const questionElement = document.querySelector('.ds_question') as HTMLElement;
68
68
  expect(questionElement?.dataset.test).toEqual('foo');
69
69
  });
70
70
 
@@ -29,7 +29,7 @@ test('radio group renders correct children', () => {
29
29
  );
30
30
 
31
31
  const radios = screen.getAllByRole('radio');
32
- const groupContainer = radios[0].parentNode.parentNode;
32
+ const groupContainer = radios[0].parentElement?.parentElement;
33
33
  expect(radios.length).toEqual(items.length);
34
34
  expect(groupContainer).toHaveClass('ds_radios', 'ds_field-group');
35
35
  });
@@ -53,7 +53,7 @@ test('inline radio group', () => {
53
53
 
54
54
 
55
55
  const radio = screen.getAllByRole('radio')[0];
56
- const groupContainer = radio.parentNode.parentNode;
56
+ const groupContainer = radio.parentElement?.parentElement;
57
57
  expect(groupContainer).toHaveClass('ds_field-group--inline');
58
58
  });
59
59
 
@@ -78,7 +78,7 @@ test('radio group passes all expected item params', () => {
78
78
  );
79
79
 
80
80
  const radio = screen.getByRole('radio');
81
- const radioContainer = radio.parentNode;
81
+ const radioContainer = radio.parentElement;
82
82
  const hintText = screen.getByText('hint text');
83
83
 
84
84
  expect(radio).toHaveAttribute('checked');
@@ -101,7 +101,7 @@ test('individual radio renders correctly', () => {
101
101
  );
102
102
 
103
103
  const radio = screen.getByRole('radio');
104
- const radioContainer = radio.parentNode;
104
+ const radioContainer = radio.parentElement;
105
105
  const label = screen.getByText('Pension Credit');
106
106
 
107
107
  expect(radioContainer).toHaveClass('ds_radio');
@@ -171,7 +171,7 @@ test('small radio', () => {
171
171
  );
172
172
 
173
173
  const radio = screen.getByRole('radio');
174
- const radioContainer = radio.parentNode;
174
+ const radioContainer = radio.parentElement;
175
175
 
176
176
  expect(radioContainer).toHaveClass('ds_radio--small');
177
177
  });
@@ -185,7 +185,7 @@ test('passing additional props', () => {
185
185
  );
186
186
 
187
187
  const radios = screen.getAllByRole('radio');
188
- const groupContainer = radios[0]?.parentNode?.parentNode;
188
+ const groupContainer = radios[0]?.parentElement?.parentElement;
189
189
  expect(groupContainer?.dataset.test).toEqual('foo');
190
190
  });
191
191
 
@@ -198,6 +198,6 @@ test('passing additional CSS classes', () => {
198
198
  );
199
199
 
200
200
  const radios = screen.getAllByRole('radio');
201
- const groupContainer = radios[0]?.parentNode?.parentNode;
201
+ const groupContainer = radios[0]?.parentElement?.parentElement;
202
202
  expect(groupContainer).toHaveClass('foo', 'ds_radios');
203
203
  });
@@ -29,23 +29,23 @@ test('select renders correctly', () => {
29
29
  );
30
30
 
31
31
  const select = screen.getByRole('combobox');
32
- const selectWrapper = select.parentNode;
33
- const label = selectWrapper?.previousSibling;
34
- const selectArrow = select.nextSibling;
32
+ const selectWrapper = select.parentElement;
33
+ const label = selectWrapper?.previousElementSibling;
34
+ const selectArrow = select.nextElementSibling;
35
35
 
36
36
  expect(select).toHaveClass('ds_select');
37
37
  expect(select.id).toEqual(id);
38
38
  expect(select).toHaveAttribute('name', id);
39
39
 
40
40
  expect(selectWrapper).toHaveClass('ds_select-wrapper');
41
- expect(selectWrapper.tagName).toEqual('DIV');
41
+ expect(selectWrapper?.tagName).toEqual('DIV');
42
42
 
43
43
  expect(label).toHaveClass('ds_label');
44
44
  expect(label).toHaveAttribute('for', id);
45
45
 
46
46
  expect(selectArrow).toHaveClass('ds_select-arrow');
47
47
  expect(selectArrow).toHaveAttribute('aria-hidden');
48
- expect(selectArrow.textContent).toEqual('');
48
+ expect(selectArrow?.textContent).toEqual('');
49
49
  });
50
50
 
51
51
  test('select with width', () => {
@@ -60,7 +60,7 @@ test('select with width', () => {
60
60
  />
61
61
  );
62
62
 
63
- const selectWrapper = screen.getByRole('combobox').parentNode;
63
+ const selectWrapper = screen.getByRole('combobox').parentElement;
64
64
  expect(selectWrapper).toHaveClass(`ds_input--${width}`);
65
65
  });
66
66
 
@@ -183,7 +183,7 @@ test('select with error message', () => {
183
183
  );
184
184
 
185
185
  const select = screen.getByRole('combobox');
186
- const selectWrapper = select.parentNode;
186
+ const selectWrapper = select.parentElement;
187
187
  const errorMessageElement = screen.getByText(errorMessage);
188
188
 
189
189
  expect(selectWrapper).toHaveClass('ds_input--error')
@@ -204,7 +204,7 @@ test('passing additional props', () => {
204
204
  );
205
205
 
206
206
  const select = screen.getByRole('combobox');
207
- const selectWrapper = select.parentNode;
207
+ const selectWrapper = select.parentElement;
208
208
  expect(selectWrapper?.dataset.test).toEqual('foo');
209
209
  });
210
210
 
@@ -219,6 +219,6 @@ test('passing additional CSS classes', () => {
219
219
  );
220
220
 
221
221
  const select = screen.getByRole('combobox');
222
- const selectWrapper = select.parentNode;
222
+ const selectWrapper = select.parentElement;
223
223
  expect(selectWrapper).toHaveClass('foo', 'ds_select-wrapper');
224
224
  });
@@ -15,9 +15,9 @@ test('sequential navigation renders correctly', () => {
15
15
 
16
16
  const sequentialNavigation = screen.getByRole('navigation');
17
17
  const prevLink = screen.getAllByRole('link')[0];
18
- const prevLinkWrapper = prevLink.parentNode;
18
+ const prevLinkWrapper = prevLink.parentElement;
19
19
  const nextLink = screen.getAllByRole('link')[1];
20
- const nextLinkWrapper = nextLink.parentNode;
20
+ const nextLinkWrapper = nextLink.parentElement;
21
21
 
22
22
  expect(sequentialNavigation).toHaveClass('ds_sequential-nav');
23
23
  expect(sequentialNavigation).toHaveAttribute('aria-label', 'Article navigation');
@@ -26,14 +26,14 @@ test('sequential navigation renders correctly', () => {
26
26
  expect(prevLink).toHaveAttribute('href', prevLinkObj.href);
27
27
  expect(prevLink.textContent).toEqual(prevLinkObj.title);
28
28
  expect(prevLinkWrapper).toHaveClass('ds_sequential-nav__item', 'ds_sequential-nav__item--prev');
29
- expect(prevLinkWrapper.tagName).toEqual('DIV');
29
+ expect(prevLinkWrapper?.tagName).toEqual('DIV');
30
30
  expect(prevLink.childNodes[0]).toHaveAttribute('data-label', 'Previous')
31
31
 
32
32
  expect(nextLink).toHaveClass('ds_sequential-nav__button', 'ds_sequential-nav__button--right');
33
33
  expect(nextLink).toHaveAttribute('href', nextLinkObj.href);
34
34
  expect(nextLink.textContent).toEqual(nextLinkObj.title);
35
35
  expect(nextLinkWrapper).toHaveClass('ds_sequential-nav__item', 'ds_sequential-nav__item--next');
36
- expect(nextLinkWrapper.tagName).toEqual('DIV');
36
+ expect(nextLinkWrapper?.tagName).toEqual('DIV');
37
37
  expect(nextLink.childNodes[0]).toHaveAttribute('data-label', 'Next')
38
38
  });
39
39
 
@@ -60,7 +60,7 @@ test('side navigation renders correctly', () => {
60
60
 
61
61
  expect(label).toHaveClass('ds_link');
62
62
  expect(label).toHaveAttribute('for', toggle.id);
63
- expect(label.textContent).toEqual('Show all Pages in this section');
63
+ expect(label?.textContent).toEqual('Show all Pages in this section');
64
64
 
65
65
  expect(rootList).toHaveAttribute('id', 'side-navigation-root');
66
66