@scottish-government/designsystem-react 0.7.0 → 0.8.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 (203) hide show
  1. package/@types/common/AbstractNotificationBanner.d.ts +2 -2
  2. package/@types/common/ActionLink.d.ts +8 -0
  3. package/@types/common/FileIcon.d.ts +1 -1
  4. package/@types/common/Icon.d.ts +1 -1
  5. package/@types/components/Breadcrumbs.d.ts +2 -5
  6. package/@types/components/Checkbox.d.ts +0 -2
  7. package/@types/components/ConfirmationMessage.d.ts +1 -1
  8. package/@types/components/ContentsNav.d.ts +4 -6
  9. package/@types/components/DatePicker.d.ts +1 -1
  10. package/@types/components/ErrorSummary.d.ts +3 -4
  11. package/@types/components/NotificationPanel.d.ts +1 -1
  12. package/@types/components/Pagination.d.ts +5 -4
  13. package/@types/components/PhaseBanner.d.ts +0 -1
  14. package/@types/components/Question.d.ts +1 -1
  15. package/@types/components/RadioButton.d.ts +0 -1
  16. package/@types/components/Select.d.ts +0 -7
  17. package/@types/components/SequentialNavigation.d.ts +4 -4
  18. package/@types/components/SideNavigation.d.ts +4 -5
  19. package/@types/components/SiteFooter.d.ts +25 -0
  20. package/@types/components/SiteHeader.d.ts +10 -3
  21. package/@types/components/SiteNavigation.d.ts +2 -3
  22. package/@types/components/SkipLinks.d.ts +3 -4
  23. package/@types/components/SummaryCard.d.ts +0 -2
  24. package/@types/components/SummaryList.d.ts +0 -13
  25. package/@types/components/Tabs.d.ts +0 -1
  26. package/@types/components/Tag.d.ts +1 -3
  27. package/@types/components/TaskList.d.ts +1 -0
  28. package/@types/sgds.d.ts +13 -2
  29. package/CHANGELOG.md +63 -1
  30. package/dist/common/AbstractNotificationBanner.jsx +8 -6
  31. package/dist/common/ActionLink.jsx +19 -0
  32. package/dist/common/FileIcon.jsx +2 -7
  33. package/dist/common/Icon.jsx +3 -9
  34. package/dist/components/Accordion/Accordion.jsx +2 -2
  35. package/dist/components/Breadcrumbs/Breadcrumbs.jsx +20 -15
  36. package/dist/components/Checkbox/Checkbox.jsx +2 -30
  37. package/dist/components/{aspect-box/aspect-box.jsx → Checkbox/CheckboxGroup.jsx} +19 -29
  38. package/dist/components/ContentsNav/ContentsNav.jsx +27 -16
  39. package/dist/components/CookieBanner/CookieBanner.jsx +1 -0
  40. package/dist/components/DatePicker/DatePicker.jsx +5 -5
  41. package/dist/components/ErrorSummary/ErrorSummary.jsx +28 -18
  42. package/dist/components/NotificationBanner/NotificationBanner.jsx +2 -2
  43. package/dist/components/Pagination/Pagination.jsx +42 -22
  44. package/dist/components/PhaseBanner/PhaseBanner.jsx +3 -3
  45. package/dist/components/Question/Question.jsx +3 -3
  46. package/dist/components/RadioButton/RadioButton.jsx +3 -17
  47. package/dist/{common/icon.jsx → components/RadioButton/RadioGroup.jsx} +22 -18
  48. package/dist/components/Select/Select.jsx +4 -7
  49. package/dist/components/SequentialNavigation/SequentialNavigation.jsx +31 -18
  50. package/dist/components/SideNavigation/SideNavigation.jsx +17 -16
  51. package/dist/components/SiteFooter/SiteFooter.jsx +104 -0
  52. package/dist/components/SiteHeader/SiteHeader.jsx +113 -32
  53. package/dist/components/SiteNavigation/SiteNavigation.jsx +20 -7
  54. package/dist/components/SkipLinks/SkipLinks.jsx +10 -10
  55. package/dist/components/SummaryCard/SummaryCard.jsx +25 -14
  56. package/dist/components/SummaryList/SummaryList.jsx +65 -47
  57. package/dist/components/Tabs/Tabs.jsx +6 -6
  58. package/dist/components/Tag/Tag.jsx +2 -2
  59. package/dist/components/TaskList/TaskList.jsx +14 -3
  60. package/dist/components/TextInput/TextInput.jsx +3 -3
  61. package/dist/components/Textarea/Textarea.jsx +3 -3
  62. package/dist/tsconfig.tsbuildinfo +1 -1
  63. package/package.json +1 -1
  64. package/src/common/AbstractNotificationBanner.test.tsx +1 -1
  65. package/src/common/AbstractNotificationBanner.tsx +14 -13
  66. package/src/common/ActionLink.test.tsx +80 -0
  67. package/src/common/ActionLink.tsx +27 -0
  68. package/src/common/ConditionalWrapper.tsx +1 -1
  69. package/src/common/FileIcon.tsx +7 -11
  70. package/src/common/HintText.tsx +2 -2
  71. package/src/common/Icon.tsx +13 -17
  72. package/src/common/ScreenReaderText.tsx +2 -2
  73. package/src/common/WrapperTag.tsx +2 -2
  74. package/src/components/Accordion/Accordion.test.tsx +1 -1
  75. package/src/components/Accordion/Accordion.tsx +6 -7
  76. package/src/components/AspectBox/AspectBox.tsx +2 -2
  77. package/src/components/BackToTop/BackToTop.tsx +2 -2
  78. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +79 -47
  79. package/src/components/Breadcrumbs/Breadcrumbs.tsx +31 -31
  80. package/src/components/Button/Button.tsx +2 -2
  81. package/src/components/Checkbox/Checkbox.test.tsx +1 -96
  82. package/src/components/Checkbox/Checkbox.tsx +3 -55
  83. package/src/components/Checkbox/CheckboxGroup.test.tsx +37 -0
  84. package/src/components/Checkbox/CheckboxGroup.tsx +46 -0
  85. package/src/components/ConfirmationMessage/ConfirmationMessage.tsx +2 -2
  86. package/src/components/ContentsNav/ContentsNav.test.tsx +40 -51
  87. package/src/components/ContentsNav/ContentsNav.tsx +32 -25
  88. package/src/components/CookieBanner/CookieBanner.tsx +3 -3
  89. package/src/components/DatePicker/DatePicker.test.tsx +1 -1
  90. package/src/components/DatePicker/DatePicker.tsx +7 -7
  91. package/src/components/Details/Details.tsx +2 -2
  92. package/src/components/ErrorMessage/ErrorMessage.tsx +2 -2
  93. package/src/components/ErrorSummary/ErrorSummary.test.tsx +40 -34
  94. package/src/components/ErrorSummary/ErrorSummary.tsx +40 -32
  95. package/src/components/FileDownload/FileDownload.tsx +2 -2
  96. package/src/components/HideThisPage/HideThisPage.tsx +2 -2
  97. package/src/components/InsetText/InsetText.tsx +2 -2
  98. package/src/components/NotificationBanner/NotificationBanner.tsx +6 -7
  99. package/src/components/NotificationPanel/NotificationPanel.tsx +2 -2
  100. package/src/components/PageHeader/PageHeader.tsx +2 -2
  101. package/src/components/PageMetadata/PageMetadata.tsx +4 -5
  102. package/src/components/Pagination/Pagination.test.tsx +26 -7
  103. package/src/components/Pagination/Pagination.tsx +70 -36
  104. package/src/components/PhaseBanner/PhaseBanner.tsx +4 -5
  105. package/src/components/Question/Question.test.tsx +1 -1
  106. package/src/components/Question/Question.tsx +5 -5
  107. package/src/components/RadioButton/RadioButton.test.tsx +7 -126
  108. package/src/components/RadioButton/RadioButton.tsx +4 -41
  109. package/src/components/RadioButton/RadioGroup.test.tsx +65 -0
  110. package/src/components/RadioButton/RadioGroup.tsx +38 -0
  111. package/src/components/Select/Select.test.tsx +39 -37
  112. package/src/components/Select/Select.tsx +7 -22
  113. package/src/components/SequentialNavigation/SequentialNavigation.test.tsx +32 -21
  114. package/src/components/SequentialNavigation/SequentialNavigation.tsx +52 -30
  115. package/src/components/SideNavigation/SideNavigation.test.tsx +39 -85
  116. package/src/components/SideNavigation/SideNavigation.tsx +27 -29
  117. package/src/components/SiteFooter/SiteFooter.test.tsx +153 -0
  118. package/src/components/SiteFooter/SiteFooter.tsx +107 -0
  119. package/src/components/SiteHeader/SiteHeader.test.tsx +87 -79
  120. package/src/components/SiteHeader/SiteHeader.tsx +103 -40
  121. package/src/components/SiteNavigation/SiteNavigation.test.tsx +42 -23
  122. package/src/components/SiteNavigation/SiteNavigation.tsx +28 -16
  123. package/src/components/SiteSearch/SiteSearch.tsx +2 -2
  124. package/src/components/SkipLinks/SkipLinks.test.tsx +22 -10
  125. package/src/components/SkipLinks/SkipLinks.tsx +16 -15
  126. package/src/components/SummaryCard/SummaryCard.test.tsx +31 -35
  127. package/src/components/SummaryCard/SummaryCard.tsx +39 -28
  128. package/src/components/SummaryList/SummaryList.test.tsx +49 -148
  129. package/src/components/SummaryList/SummaryList.tsx +54 -92
  130. package/src/components/Table/Table.tsx +2 -2
  131. package/src/components/Tabs/Tabs.tsx +14 -15
  132. package/src/components/Tag/Tag.test.tsx +4 -4
  133. package/src/components/Tag/Tag.tsx +4 -4
  134. package/src/components/TaskList/TaskList.test.tsx +26 -0
  135. package/src/components/TaskList/TaskList.tsx +21 -11
  136. package/src/components/TextInput/TextInput.test.tsx +1 -1
  137. package/src/components/TextInput/TextInput.tsx +5 -5
  138. package/src/components/Textarea/Textarea.test.tsx +1 -1
  139. package/src/components/Textarea/Textarea.tsx +5 -5
  140. package/src/components/WarningText/WarningText.tsx +2 -2
  141. package/dist/common/abstract-notification-banner.jsx +0 -63
  142. package/dist/common/conditional-wrapper.jsx +0 -8
  143. package/dist/common/file-icon.jsx +0 -51
  144. package/dist/common/hint-text.jsx +0 -9
  145. package/dist/common/screen-reader-text.jsx +0 -9
  146. package/dist/common/wrapper-tag.jsx +0 -11
  147. package/dist/components/accordion/accordion.jsx +0 -102
  148. package/dist/components/back-to-top/back-to-top.jsx +0 -27
  149. package/dist/components/breadcrumbs/breadcrumbs.jsx +0 -28
  150. package/dist/components/button/button.jsx +0 -30
  151. package/dist/components/checkbox/checkbox.jsx +0 -62
  152. package/dist/components/confirmation-message/confirmation-message.jsx +0 -24
  153. package/dist/components/contents-nav/contents-nav.jsx +0 -33
  154. package/dist/components/cookie-banner/cookie-banner.jsx +0 -21
  155. package/dist/components/date-picker/date-picker.jsx +0 -54
  156. package/dist/components/details/details.jsx +0 -17
  157. package/dist/components/error-message/error-message.jsx +0 -12
  158. package/dist/components/error-summary/error-summary.jsx +0 -27
  159. package/dist/components/file-download/file-download.jsx +0 -50
  160. package/dist/components/hide-this-page/hide-this-page.jsx +0 -71
  161. package/dist/components/inset-text/inset-text.jsx +0 -14
  162. package/dist/components/notification-banner/notification-banner.jsx +0 -26
  163. package/dist/components/notification-panel/notification-panel.jsx +0 -21
  164. package/dist/components/page-header/page-header.jsx +0 -15
  165. package/dist/components/page-metadata/page-metadata.jsx +0 -26
  166. package/dist/components/pagination/pagination.jsx +0 -97
  167. package/dist/components/phase-banner/phase-banner.jsx +0 -23
  168. package/dist/components/question/question.jsx +0 -22
  169. package/dist/components/radio-button/radio-button.jsx +0 -43
  170. package/dist/components/select/select.jsx +0 -52
  171. package/dist/components/sequential-navigation/sequential-navigation.jsx +0 -31
  172. package/dist/components/side-navigation/side-navigation.jsx +0 -52
  173. package/dist/components/site-header/site-header.jsx +0 -68
  174. package/dist/components/site-navigation/site-navigation.jsx +0 -22
  175. package/dist/components/site-search/site-search.jsx +0 -55
  176. package/dist/components/skip-links/skip-links.jsx +0 -21
  177. package/dist/components/summary-card/summary-card.jsx +0 -67
  178. package/dist/components/summary-list/summary-list.jsx +0 -75
  179. package/dist/components/table/table.jsx +0 -24
  180. package/dist/components/tabs/tabs.jsx +0 -99
  181. package/dist/components/tag/tag.jsx +0 -13
  182. package/dist/components/task-list/task-list.jsx +0 -95
  183. package/dist/components/text-input/text-input.jsx +0 -58
  184. package/dist/components/textarea/textarea.jsx +0 -54
  185. package/dist/components/warning-text/warning-text.jsx +0 -16
  186. package/dist/icons/ArrowUpward.jsx +0 -41
  187. package/dist/icons/CalendarToday.jsx +0 -41
  188. package/dist/icons/Cancel.jsx +0 -40
  189. package/dist/icons/CheckCircle.jsx +0 -41
  190. package/dist/icons/ChevronLeft.jsx +0 -41
  191. package/dist/icons/ChevronRight.jsx +0 -41
  192. package/dist/icons/Close.jsx +0 -41
  193. package/dist/icons/Description.jsx +0 -41
  194. package/dist/icons/DoubleChevronLeft.jsx +0 -40
  195. package/dist/icons/DoubleChevronRight.jsx +0 -40
  196. package/dist/icons/Error.jsx +0 -41
  197. package/dist/icons/ExpandLess.jsx +0 -41
  198. package/dist/icons/ExpandMore.jsx +0 -41
  199. package/dist/icons/List.jsx +0 -44
  200. package/dist/icons/Menu.jsx +0 -41
  201. package/dist/icons/PriorityHigh.jsx +0 -42
  202. package/dist/icons/Search.jsx +0 -41
  203. package/dist/icons/index.js +0 -40
@@ -2,29 +2,29 @@ import ErrorMessage from '../ErrorMessage/ErrorMessage';
2
2
  import HintText from '../../common/HintText';
3
3
  import WrapperTag from '../../common/WrapperTag';
4
4
 
5
- const Question: React.FC<SGDS.Component.Question> = function ({
5
+ const Question = function ({
6
6
  children,
7
7
  className,
8
- error,
9
8
  errorMessage,
9
+ hasError,
10
10
  hintText,
11
11
  legend,
12
12
  tagName = 'div',
13
13
  ...props
14
- }) {
14
+ }: SGDS.Component.Question) {
15
15
  return (
16
16
  <WrapperTag
17
17
  tagName={tagName}
18
18
  className={[
19
19
  'ds_question',
20
- error && 'ds_question--error',
20
+ hasError && 'ds_question--error',
21
21
  className
22
22
  ].join(' ')}
23
23
  {...props}
24
24
  >
25
25
  {legend && <legend>{legend}</legend>}
26
26
  {hintText && <HintText text={hintText} />}
27
- {error && errorMessage && <ErrorMessage text={errorMessage} />}
27
+ {hasError && errorMessage && <ErrorMessage text={errorMessage} />}
28
28
  {children}
29
29
  </WrapperTag>
30
30
  );
@@ -1,103 +1,10 @@
1
1
  import { test, expect, vi } from 'vitest';
2
2
  import { render, screen, fireEvent } from '@testing-library/react';
3
- import RadioGroup, { Radio } from './RadioButton';
4
-
5
- test('radio group renders correct children', () => {
6
- const ITEMS = [
7
- {
8
- id: 'universal-credit',
9
- label: 'Universal Credit',
10
- checked: true
11
- },
12
- {
13
- id: 'pensioncredit',
14
- label: 'Pension Credit'
15
- },
16
- {
17
- id: 'jsa',
18
- label: 'Income-based Job Seeker\'s Allowance',
19
- },
20
- {
21
- id: 'none',
22
- label: 'I do not receive any of these benefits',
23
- }
24
- ];
25
- const GROUP_NAME = "foo"
26
-
27
- render(
28
- <RadioGroup name={GROUP_NAME} items={ITEMS} />
29
- );
30
-
31
- const radios = screen.getAllByRole('radio');
32
- const groupContainer = radios[0].parentElement?.parentElement;
33
- expect(radios.length).toEqual(ITEMS.length);
34
- expect(groupContainer).toHaveClass('ds_radios', 'ds_field-group');
35
- });
36
-
37
- test('inline radio group', () => {
38
- const ITEMS = [
39
- {
40
- id: 'radio-yes',
41
- label: 'Yes'
42
- },
43
- {
44
- id: 'radio-no',
45
- label: 'No'
46
- }
47
- ];
48
- const GROUP_NAME = "yesno"
49
-
50
- render(
51
- <RadioGroup inline name={GROUP_NAME} items={ITEMS} />
52
- );
53
-
54
-
55
- const radio = screen.getAllByRole('radio')[0];
56
- const groupContainer = radio.parentElement?.parentElement;
57
- expect(groupContainer).toHaveClass('ds_field-group--inline');
58
- });
59
-
60
- test('radio group passes all expected item params', () => {
61
- const ONBLUR_FUNCTION = vi.fn();
62
- const ONCHANGE_FUNCTION = vi.fn();
63
- const GROUP_NAME = "foo"
64
-
65
- render(
66
- <RadioGroup name={GROUP_NAME} small items={[
67
- {
68
- checked: true,
69
- exclusive: true,
70
- hintText: 'hint text',
71
- id: 'myid',
72
- label: 'label text',
73
- onBlur: {ONBLUR_FUNCTION},
74
- onChange: {ONCHANGE_FUNCTION},
75
- small: true
76
- }
77
- ]}/>
78
- );
79
-
80
- const radio = screen.getByRole('radio');
81
- const radioContainer = radio.parentElement;
82
- const hintText = screen.getByText('hint text');
83
-
84
- expect(radio).toHaveAttribute('checked');
85
- expect(radio).toHaveAttribute('name', GROUP_NAME);
86
- expect(radio.id).toEqual('myid');
87
- expect(radioContainer).toHaveClass('ds_radio--small');
88
- expect(hintText).toBeInTheDocument();
89
- expect(radio).toHaveAttribute('aria-describedby', hintText.id);
90
-
91
- // fireEvent.blur(radio);
92
- // expect(ONBLUR_FUNCTION).toHaveBeenCalled();
93
-
94
- // fireEvent.click(radio);
95
- // expect(ONCHANGE_FUNCTION).toHaveBeenCalled();
96
- });
3
+ import RadioButton from './RadioButton';
97
4
 
98
5
  test('individual radio renders correctly', () => {
99
6
  render(
100
- <Radio name="benefitType" label="Pension Credit" id="pensioncredit" />
7
+ <RadioButton name="benefitType" label="Pension Credit" id="pensioncredit" />
101
8
  );
102
9
 
103
10
  const radio = screen.getByRole('radio');
@@ -117,7 +24,7 @@ test('individual radio renders correctly', () => {
117
24
 
118
25
  test('checked radio', () => {
119
26
  render(
120
- <Radio name="benefitType" checked label="Pension Credit" id="pensioncredit" />
27
+ <RadioButton name="benefitType" checked label="Pension Credit" id="pensioncredit" />
121
28
  );
122
29
 
123
30
  const radio = screen.getByRole('radio');
@@ -129,7 +36,7 @@ test('radio with blur fn', () => {
129
36
  const ONBLUR_FUNCTION = vi.fn();
130
37
 
131
38
  render(
132
- <Radio onBlur={ONBLUR_FUNCTION} name="benefitType" label="Pension Credit" id="pensioncredit" />
39
+ <RadioButton onBlur={ONBLUR_FUNCTION} name="benefitType" label="Pension Credit" id="pensioncredit" />
133
40
  );
134
41
 
135
42
  const radio = screen.getByRole('radio');
@@ -143,7 +50,7 @@ test('radio with change fn', () => {
143
50
  const ONCHANGE_FUNCTION = vi.fn();
144
51
 
145
52
  render(
146
- <Radio onChange={ONCHANGE_FUNCTION} name="benefitType" label="Pension Credit" id="pensioncredit" />
53
+ <RadioButton onChange={ONCHANGE_FUNCTION} name="benefitType" label="Pension Credit" id="pensioncredit" />
147
54
  );
148
55
 
149
56
  const radio = screen.getByRole('radio');
@@ -155,7 +62,7 @@ test('radio with change fn', () => {
155
62
 
156
63
  test('radio with hint text', () => {
157
64
  render(
158
- <Radio hintText="hint text" name="benefitType" label="Pension Credit" id="pensioncredit" />
65
+ <RadioButton hintText="hint text" name="benefitType" label="Pension Credit" id="pensioncredit" />
159
66
  );
160
67
 
161
68
  const hintText = screen.getByText('hint text');
@@ -167,7 +74,7 @@ test('radio with hint text', () => {
167
74
 
168
75
  test('small radio', () => {
169
76
  render(
170
- <Radio small name="benefitType" label="Pension Credit" id="pensioncredit" />
77
+ <RadioButton small name="benefitType" label="Pension Credit" id="pensioncredit" />
171
78
  );
172
79
 
173
80
  const radio = screen.getByRole('radio');
@@ -175,29 +82,3 @@ test('small radio', () => {
175
82
 
176
83
  expect(radioContainer).toHaveClass('ds_radio--small');
177
84
  });
178
-
179
- test('passing additional props', () => {
180
- render(
181
- <RadioGroup data-test="foo" items={[{
182
- id: 'universal-credit',
183
- label: 'Universal Credit'
184
- }]} />
185
- );
186
-
187
- const radios = screen.getAllByRole('radio');
188
- const groupContainer = radios[0]?.parentElement?.parentElement;
189
- expect(groupContainer?.dataset.test).toEqual('foo');
190
- });
191
-
192
- test('passing additional CSS classes', () => {
193
- render(
194
- <RadioGroup className="foo" items={[{
195
- id: 'universal-credit',
196
- label: 'Universal Credit'
197
- }]} />
198
- );
199
-
200
- const radios = screen.getAllByRole('radio');
201
- const groupContainer = radios[0]?.parentElement?.parentElement;
202
- expect(groupContainer).toHaveClass('foo', 'ds_radios');
203
- });
@@ -1,6 +1,6 @@
1
1
  import HintText from '../../common/HintText';
2
2
 
3
- export const Radio: React.FC<SGDS.Component.RadioButton> = ({
3
+ const RadioButton = ({
4
4
  checked,
5
5
  hintText,
6
6
  id,
@@ -9,7 +9,7 @@ export const Radio: React.FC<SGDS.Component.RadioButton> = ({
9
9
  onBlur,
10
10
  onChange,
11
11
  small
12
- }) => {
12
+ }: SGDS.Component.RadioButton) => {
13
13
  const hintTextId = `hint-text-${id}`;
14
14
 
15
15
  function handleBlur(event: React.FocusEvent) {
@@ -48,43 +48,6 @@ export const Radio: React.FC<SGDS.Component.RadioButton> = ({
48
48
  );
49
49
  };
50
50
 
51
- const RadioGroup: React.FC<SGDS.Component.RadioButton.Group> = ({
52
- className,
53
- inline,
54
- items,
55
- name,
56
- small,
57
- ...props
58
- }) => {
59
- return (
60
- <div
61
- className={[
62
- 'ds_radios',
63
- 'ds_field-group',
64
- inline && 'ds_field-group--inline',
65
- className
66
- ].join(' ')}
67
- {...props}
68
- >
69
-
70
- {items && items.map((item, index: number) => (
71
- <Radio
72
- checked={item.checked}
73
- hintText={item.hintText}
74
- id={item.id}
75
- key={'radio' + index}
76
- label={item.label}
77
- name={name}
78
- onBlur={item.onBlur}
79
- onChange={item.onChange}
80
- small={small || item.small}
81
- />
82
- ))}
83
- </div>
84
- )
85
- };
86
-
87
- Radio.displayName = 'Radio';
88
- RadioGroup.displayName = 'RadioGroup';
51
+ RadioButton.displayName = 'RadioButton';
89
52
 
90
- export default RadioGroup;
53
+ export default RadioButton;
@@ -0,0 +1,65 @@
1
+ import { test, expect } from 'vitest';
2
+ import { render, screen } from '@testing-library/react';
3
+ import RadioButton from './RadioButton';
4
+ import RadioGroup from './RadioGroup';
5
+
6
+ test('radio group renders correctly', () => {
7
+ render(
8
+ <RadioGroup name="foo" data-testid="radiogroup">
9
+ <RadioButton id="banana" label="Banana" />
10
+ </RadioGroup>
11
+ );
12
+ const radioGroup = screen.getByTestId('radiogroup');
13
+ expect(radioGroup).toHaveClass('ds_radios', 'ds_field-group');
14
+ expect(radioGroup).not.toHaveClass('ds_field-group--inline');
15
+
16
+ const radio = screen.getByRole('radio');
17
+ const radioContainer = radio.parentElement;
18
+ expect(radioContainer).not.toHaveClass('ds_radio--small');
19
+ });
20
+
21
+ test('radio group passes all expected item params', () => {
22
+ const RADIO_NAME = 'radioname';
23
+
24
+ render(
25
+ <RadioGroup name={RADIO_NAME} small>
26
+ <RadioButton id="banana" />
27
+ <p>foo</p>
28
+ </RadioGroup>
29
+ );
30
+
31
+ const radio = screen.getByRole('radio');
32
+ const radioContainer = radio.parentElement;
33
+ expect(radio).toHaveAttribute('name', RADIO_NAME);
34
+ expect(radioContainer).toHaveClass('ds_radio--small');
35
+ });
36
+
37
+ test('inline radio group', () => {
38
+ render(
39
+ <RadioGroup inline>
40
+ <RadioButton id="banana" />
41
+ </RadioGroup>
42
+ );
43
+
44
+ const radio = screen.getAllByRole('radio')[0];
45
+ const groupContainer = radio.parentElement?.parentElement;
46
+ expect(groupContainer).toHaveClass('ds_field-group--inline');
47
+ });
48
+
49
+ test('passing additional props', () => {
50
+ render(
51
+ <RadioGroup data-test="foo" data-testid="radiogroup"/>
52
+ );
53
+
54
+ const radioGroup = screen.getByTestId('radiogroup');
55
+ expect(radioGroup?.dataset.test).toEqual('foo');
56
+ });
57
+
58
+ test('passing additional CSS classes', () => {
59
+ render(
60
+ <RadioGroup className="foo" data-testid="radiogroup"/>
61
+ );
62
+
63
+ const radioGroup = screen.getByTestId('radiogroup');
64
+ expect(radioGroup).toHaveClass('foo');
65
+ });
@@ -0,0 +1,38 @@
1
+ import React, { Children } from 'react';
2
+ import RadioButton from './RadioButton';
3
+
4
+ const RadioGroup = ({
5
+ children,
6
+ className,
7
+ inline,
8
+ name,
9
+ small,
10
+ ...props
11
+ }: SGDS.Component.RadioButton.Group) => {
12
+ function processChild(child: any) {
13
+ if (child && child.type === RadioButton) {
14
+ return React.cloneElement(child as React.ReactElement<SGDS.Component.RadioButton>, { small: small, name: name });
15
+ } else {
16
+ return child;
17
+ }
18
+ }
19
+
20
+ return (
21
+ <div
22
+ className={[
23
+ 'ds_radios',
24
+ 'ds_field-group',
25
+ inline && 'ds_field-group--inline',
26
+ className
27
+ ].join(' ')}
28
+ {...props}
29
+ >
30
+
31
+ {Children.map(children, child => processChild(child))}
32
+ </div>
33
+ );
34
+ };
35
+
36
+ RadioGroup.displayName = 'RadioGroup';
37
+
38
+ export default RadioGroup;
@@ -4,28 +4,20 @@ import Select from './Select';
4
4
 
5
5
  const SELECT_ID = 'select-component';
6
6
  const LABEL_TEXT = 'choose a component';
7
- const OPTIONS = [
8
- {
9
- text: 'Accordion',
10
- value: 'accordion'
11
- },
12
- {
13
- text: 'Breadcrumbs',
14
- value: 'breadcrumbs'
15
- },
16
- {
17
- text: 'Button',
18
- value: 'button'
19
- }
20
- ];
7
+ const OPTIONS = <>
8
+ <option value="accordion">Accordion</option>
9
+ <option value="breadcrumbs">Breadcrumbs</option>
10
+ <option value="button">Button</option>
11
+ </>;
21
12
 
22
13
  test('select renders correctly', () => {
23
14
  render(
24
15
  <Select
25
16
  id={SELECT_ID}
26
17
  label={LABEL_TEXT}
27
- options={OPTIONS}
28
- />
18
+ >
19
+ {OPTIONS}
20
+ </Select>
29
21
  );
30
22
 
31
23
  const select = screen.getByRole('combobox');
@@ -55,9 +47,10 @@ test('select with width', () => {
55
47
  <Select
56
48
  id={SELECT_ID}
57
49
  label={LABEL_TEXT}
58
- options={OPTIONS}
59
50
  width={SELECTWIDTH}
60
- />
51
+ >
52
+ {OPTIONS}
53
+ </Select>
61
54
  );
62
55
 
63
56
  const selectWrapper = screen.getByRole('combobox').parentElement;
@@ -71,9 +64,10 @@ test('select with hint text', () => {
71
64
  <Select
72
65
  id={SELECT_ID}
73
66
  label={LABEL_TEXT}
74
- options={OPTIONS}
75
67
  hintText={HINT_TEXT}
76
- />
68
+ >
69
+ {OPTIONS}
70
+ </Select>
77
71
  );
78
72
 
79
73
  const hintTextEl = screen.getByText(HINT_TEXT);
@@ -90,9 +84,10 @@ test('select with custom name', () => {
90
84
  <Select
91
85
  id={SELECT_ID}
92
86
  label={LABEL_TEXT}
93
- options={OPTIONS}
94
87
  name={SELECT_NAME}
95
- />
88
+ >
89
+ {OPTIONS}
90
+ </Select>
96
91
  );
97
92
 
98
93
  const select = screen.getByRole('combobox');
@@ -106,9 +101,10 @@ test('select with blur function', () => {
106
101
  <Select
107
102
  id={SELECT_ID}
108
103
  label={LABEL_TEXT}
109
- options={OPTIONS}
110
104
  onBlur={ONBLUR_FUNCTION}
111
- />
105
+ >
106
+ {OPTIONS}
107
+ </Select>
112
108
  );
113
109
 
114
110
  const select = screen.getByRole('combobox');
@@ -125,9 +121,10 @@ test('select with change function', () => {
125
121
  <Select
126
122
  id={SELECT_ID}
127
123
  label={LABEL_TEXT}
128
- options={OPTIONS}
129
124
  onChange={ONCHANGE_FUNCTION}
130
- />
125
+ >
126
+ {OPTIONS}
127
+ </Select>
131
128
  );
132
129
 
133
130
  const select = screen.getByRole('combobox');
@@ -144,9 +141,10 @@ test('select with placeholder option', () => {
144
141
  <Select
145
142
  id={SELECT_ID}
146
143
  label={LABEL_TEXT}
147
- options={OPTIONS}
148
144
  placeholder={PLACEHOLDER_TEXT}
149
- />
145
+ >
146
+ {OPTIONS}
147
+ </Select>
150
148
  );
151
149
 
152
150
  const select = screen.getByRole('combobox');
@@ -162,9 +160,10 @@ test('select with initial value', () => {
162
160
  <Select
163
161
  id={SELECT_ID}
164
162
  label={LABEL_TEXT}
165
- options={OPTIONS}
166
163
  defaultValue={INITIAL_VALUE}
167
- />
164
+ >
165
+ {OPTIONS}
166
+ </Select>
168
167
  );
169
168
 
170
169
  const select = screen.getByRole('combobox');
@@ -179,10 +178,11 @@ test('select with error message', () => {
179
178
  <Select
180
179
  id={SELECT_ID}
181
180
  label={LABEL_TEXT}
182
- options={OPTIONS}
183
- error
184
181
  errorMessage={ERROR_MESSAGE_TEXT}
185
- />
182
+ hasError
183
+ >
184
+ {OPTIONS}
185
+ </Select>
186
186
  );
187
187
 
188
188
  const select = screen.getByRole('combobox');
@@ -201,9 +201,10 @@ test('passing additional props', () => {
201
201
  <Select
202
202
  id={SELECT_ID}
203
203
  label={LABEL_TEXT}
204
- options={OPTIONS}
205
204
  data-test="foo"
206
- />
205
+ >
206
+ {OPTIONS}
207
+ </Select>
207
208
  );
208
209
 
209
210
  const select = screen.getByRole('combobox');
@@ -216,9 +217,10 @@ test('passing additional CSS classes', () => {
216
217
  <Select
217
218
  id={SELECT_ID}
218
219
  label={LABEL_TEXT}
219
- options={OPTIONS}
220
220
  className="foo"
221
- />
221
+ >
222
+ {OPTIONS}
223
+ </Select>
222
224
  );
223
225
 
224
226
  const select = screen.getByRole('combobox');
@@ -1,31 +1,22 @@
1
1
  import ErrorMessage from '../ErrorMessage/ErrorMessage';
2
2
  import HintText from '../../common/HintText';
3
3
 
4
- const Option: React.FC<SGDS.Component.Select.Option> = function ({
5
- text,
6
- value
7
- }) {
8
- return (
9
- <option value={value}>{text}</option>
10
- );
11
- };
12
-
13
- const Select: React.FC<SGDS.Component.Select> = function ({
4
+ const Select = function ({
5
+ children,
14
6
  className,
15
7
  defaultValue,
16
- error,
17
8
  errorMessage,
9
+ hasError,
18
10
  hintText,
19
11
  id,
20
12
  label,
21
13
  name,
22
14
  onBlur,
23
15
  onChange,
24
- options,
25
16
  placeholder,
26
17
  width,
27
18
  ...props
28
- }) {
19
+ }: SGDS.Component.Select) {
29
20
  const errorMessageId = `error-message-${id}`;
30
21
  const hintTextId = `hint-text-${id}`;
31
22
  const describedbys: string[] = [];
@@ -53,7 +44,7 @@ const Select: React.FC<SGDS.Component.Select> = function ({
53
44
  <div
54
45
  className={[
55
46
  "ds_select-wrapper",
56
- error && 'ds_input--error',
47
+ hasError && 'ds_input--error',
57
48
  width && `ds_input--${width}`,
58
49
  className
59
50
  ].join(' ')}
@@ -61,7 +52,7 @@ const Select: React.FC<SGDS.Component.Select> = function ({
61
52
  >
62
53
  <select
63
54
  aria-describedby={describedbys.join(' ')}
64
- aria-invalid={error}
55
+ aria-invalid={hasError}
65
56
  className="ds_select"
66
57
  defaultValue={defaultValue}
67
58
  id={id}
@@ -70,13 +61,7 @@ const Select: React.FC<SGDS.Component.Select> = function ({
70
61
  onChange={handleChange}
71
62
  >
72
63
  <option value="">{placeholder}</option>
73
- {options && options.map((option, index: number) => (
74
- <Option
75
- value={option.value}
76
- text={option.text}
77
- key={`option-${index}`}
78
- />
79
- ))}
64
+ {children}
80
65
  </select>
81
66
  <span className="ds_select-arrow" aria-hidden="true"></span>
82
67
  </div>