@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.
- package/@types/common/AbstractNotificationBanner.d.ts +2 -2
- package/@types/common/ActionLink.d.ts +8 -0
- package/@types/common/FileIcon.d.ts +1 -1
- package/@types/common/Icon.d.ts +1 -1
- package/@types/components/Breadcrumbs.d.ts +2 -5
- package/@types/components/Checkbox.d.ts +0 -2
- package/@types/components/ConfirmationMessage.d.ts +1 -1
- package/@types/components/ContentsNav.d.ts +4 -6
- package/@types/components/DatePicker.d.ts +1 -1
- package/@types/components/ErrorSummary.d.ts +3 -4
- package/@types/components/NotificationPanel.d.ts +1 -1
- package/@types/components/Pagination.d.ts +5 -4
- package/@types/components/PhaseBanner.d.ts +0 -1
- package/@types/components/Question.d.ts +1 -1
- package/@types/components/RadioButton.d.ts +0 -1
- package/@types/components/Select.d.ts +0 -7
- package/@types/components/SequentialNavigation.d.ts +4 -4
- package/@types/components/SideNavigation.d.ts +4 -5
- package/@types/components/SiteFooter.d.ts +25 -0
- package/@types/components/SiteHeader.d.ts +10 -3
- package/@types/components/SiteNavigation.d.ts +2 -3
- package/@types/components/SkipLinks.d.ts +3 -4
- package/@types/components/SummaryCard.d.ts +0 -2
- package/@types/components/SummaryList.d.ts +0 -13
- package/@types/components/Tabs.d.ts +0 -1
- package/@types/components/Tag.d.ts +1 -3
- package/@types/components/TaskList.d.ts +1 -0
- package/@types/sgds.d.ts +13 -2
- package/CHANGELOG.md +63 -1
- package/dist/common/AbstractNotificationBanner.jsx +8 -6
- package/dist/common/ActionLink.jsx +19 -0
- package/dist/common/FileIcon.jsx +2 -7
- package/dist/common/Icon.jsx +3 -9
- package/dist/components/Accordion/Accordion.jsx +2 -2
- package/dist/components/Breadcrumbs/Breadcrumbs.jsx +20 -15
- package/dist/components/Checkbox/Checkbox.jsx +2 -30
- package/dist/components/{aspect-box/aspect-box.jsx → Checkbox/CheckboxGroup.jsx} +19 -29
- package/dist/components/ContentsNav/ContentsNav.jsx +27 -16
- package/dist/components/CookieBanner/CookieBanner.jsx +1 -0
- package/dist/components/DatePicker/DatePicker.jsx +5 -5
- package/dist/components/ErrorSummary/ErrorSummary.jsx +28 -18
- package/dist/components/NotificationBanner/NotificationBanner.jsx +2 -2
- package/dist/components/Pagination/Pagination.jsx +42 -22
- package/dist/components/PhaseBanner/PhaseBanner.jsx +3 -3
- package/dist/components/Question/Question.jsx +3 -3
- package/dist/components/RadioButton/RadioButton.jsx +3 -17
- package/dist/{common/icon.jsx → components/RadioButton/RadioGroup.jsx} +22 -18
- package/dist/components/Select/Select.jsx +4 -7
- package/dist/components/SequentialNavigation/SequentialNavigation.jsx +31 -18
- package/dist/components/SideNavigation/SideNavigation.jsx +17 -16
- package/dist/components/SiteFooter/SiteFooter.jsx +104 -0
- package/dist/components/SiteHeader/SiteHeader.jsx +113 -32
- package/dist/components/SiteNavigation/SiteNavigation.jsx +20 -7
- package/dist/components/SkipLinks/SkipLinks.jsx +10 -10
- package/dist/components/SummaryCard/SummaryCard.jsx +25 -14
- package/dist/components/SummaryList/SummaryList.jsx +65 -47
- package/dist/components/Tabs/Tabs.jsx +6 -6
- package/dist/components/Tag/Tag.jsx +2 -2
- package/dist/components/TaskList/TaskList.jsx +14 -3
- package/dist/components/TextInput/TextInput.jsx +3 -3
- package/dist/components/Textarea/Textarea.jsx +3 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/common/AbstractNotificationBanner.test.tsx +1 -1
- package/src/common/AbstractNotificationBanner.tsx +14 -13
- package/src/common/ActionLink.test.tsx +80 -0
- package/src/common/ActionLink.tsx +27 -0
- package/src/common/ConditionalWrapper.tsx +1 -1
- package/src/common/FileIcon.tsx +7 -11
- package/src/common/HintText.tsx +2 -2
- package/src/common/Icon.tsx +13 -17
- package/src/common/ScreenReaderText.tsx +2 -2
- package/src/common/WrapperTag.tsx +2 -2
- package/src/components/Accordion/Accordion.test.tsx +1 -1
- package/src/components/Accordion/Accordion.tsx +6 -7
- package/src/components/AspectBox/AspectBox.tsx +2 -2
- package/src/components/BackToTop/BackToTop.tsx +2 -2
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +79 -47
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +31 -31
- package/src/components/Button/Button.tsx +2 -2
- package/src/components/Checkbox/Checkbox.test.tsx +1 -96
- package/src/components/Checkbox/Checkbox.tsx +3 -55
- package/src/components/Checkbox/CheckboxGroup.test.tsx +37 -0
- package/src/components/Checkbox/CheckboxGroup.tsx +46 -0
- package/src/components/ConfirmationMessage/ConfirmationMessage.tsx +2 -2
- package/src/components/ContentsNav/ContentsNav.test.tsx +40 -51
- package/src/components/ContentsNav/ContentsNav.tsx +32 -25
- package/src/components/CookieBanner/CookieBanner.tsx +3 -3
- package/src/components/DatePicker/DatePicker.test.tsx +1 -1
- package/src/components/DatePicker/DatePicker.tsx +7 -7
- package/src/components/Details/Details.tsx +2 -2
- package/src/components/ErrorMessage/ErrorMessage.tsx +2 -2
- package/src/components/ErrorSummary/ErrorSummary.test.tsx +40 -34
- package/src/components/ErrorSummary/ErrorSummary.tsx +40 -32
- package/src/components/FileDownload/FileDownload.tsx +2 -2
- package/src/components/HideThisPage/HideThisPage.tsx +2 -2
- package/src/components/InsetText/InsetText.tsx +2 -2
- package/src/components/NotificationBanner/NotificationBanner.tsx +6 -7
- package/src/components/NotificationPanel/NotificationPanel.tsx +2 -2
- package/src/components/PageHeader/PageHeader.tsx +2 -2
- package/src/components/PageMetadata/PageMetadata.tsx +4 -5
- package/src/components/Pagination/Pagination.test.tsx +26 -7
- package/src/components/Pagination/Pagination.tsx +70 -36
- package/src/components/PhaseBanner/PhaseBanner.tsx +4 -5
- package/src/components/Question/Question.test.tsx +1 -1
- package/src/components/Question/Question.tsx +5 -5
- package/src/components/RadioButton/RadioButton.test.tsx +7 -126
- package/src/components/RadioButton/RadioButton.tsx +4 -41
- package/src/components/RadioButton/RadioGroup.test.tsx +65 -0
- package/src/components/RadioButton/RadioGroup.tsx +38 -0
- package/src/components/Select/Select.test.tsx +39 -37
- package/src/components/Select/Select.tsx +7 -22
- package/src/components/SequentialNavigation/SequentialNavigation.test.tsx +32 -21
- package/src/components/SequentialNavigation/SequentialNavigation.tsx +52 -30
- package/src/components/SideNavigation/SideNavigation.test.tsx +39 -85
- package/src/components/SideNavigation/SideNavigation.tsx +27 -29
- package/src/components/SiteFooter/SiteFooter.test.tsx +153 -0
- package/src/components/SiteFooter/SiteFooter.tsx +107 -0
- package/src/components/SiteHeader/SiteHeader.test.tsx +87 -79
- package/src/components/SiteHeader/SiteHeader.tsx +103 -40
- package/src/components/SiteNavigation/SiteNavigation.test.tsx +42 -23
- package/src/components/SiteNavigation/SiteNavigation.tsx +28 -16
- package/src/components/SiteSearch/SiteSearch.tsx +2 -2
- package/src/components/SkipLinks/SkipLinks.test.tsx +22 -10
- package/src/components/SkipLinks/SkipLinks.tsx +16 -15
- package/src/components/SummaryCard/SummaryCard.test.tsx +31 -35
- package/src/components/SummaryCard/SummaryCard.tsx +39 -28
- package/src/components/SummaryList/SummaryList.test.tsx +49 -148
- package/src/components/SummaryList/SummaryList.tsx +54 -92
- package/src/components/Table/Table.tsx +2 -2
- package/src/components/Tabs/Tabs.tsx +14 -15
- package/src/components/Tag/Tag.test.tsx +4 -4
- package/src/components/Tag/Tag.tsx +4 -4
- package/src/components/TaskList/TaskList.test.tsx +26 -0
- package/src/components/TaskList/TaskList.tsx +21 -11
- package/src/components/TextInput/TextInput.test.tsx +1 -1
- package/src/components/TextInput/TextInput.tsx +5 -5
- package/src/components/Textarea/Textarea.test.tsx +1 -1
- package/src/components/Textarea/Textarea.tsx +5 -5
- package/src/components/WarningText/WarningText.tsx +2 -2
- package/dist/common/abstract-notification-banner.jsx +0 -63
- package/dist/common/conditional-wrapper.jsx +0 -8
- package/dist/common/file-icon.jsx +0 -51
- package/dist/common/hint-text.jsx +0 -9
- package/dist/common/screen-reader-text.jsx +0 -9
- package/dist/common/wrapper-tag.jsx +0 -11
- package/dist/components/accordion/accordion.jsx +0 -102
- package/dist/components/back-to-top/back-to-top.jsx +0 -27
- package/dist/components/breadcrumbs/breadcrumbs.jsx +0 -28
- package/dist/components/button/button.jsx +0 -30
- package/dist/components/checkbox/checkbox.jsx +0 -62
- package/dist/components/confirmation-message/confirmation-message.jsx +0 -24
- package/dist/components/contents-nav/contents-nav.jsx +0 -33
- package/dist/components/cookie-banner/cookie-banner.jsx +0 -21
- package/dist/components/date-picker/date-picker.jsx +0 -54
- package/dist/components/details/details.jsx +0 -17
- package/dist/components/error-message/error-message.jsx +0 -12
- package/dist/components/error-summary/error-summary.jsx +0 -27
- package/dist/components/file-download/file-download.jsx +0 -50
- package/dist/components/hide-this-page/hide-this-page.jsx +0 -71
- package/dist/components/inset-text/inset-text.jsx +0 -14
- package/dist/components/notification-banner/notification-banner.jsx +0 -26
- package/dist/components/notification-panel/notification-panel.jsx +0 -21
- package/dist/components/page-header/page-header.jsx +0 -15
- package/dist/components/page-metadata/page-metadata.jsx +0 -26
- package/dist/components/pagination/pagination.jsx +0 -97
- package/dist/components/phase-banner/phase-banner.jsx +0 -23
- package/dist/components/question/question.jsx +0 -22
- package/dist/components/radio-button/radio-button.jsx +0 -43
- package/dist/components/select/select.jsx +0 -52
- package/dist/components/sequential-navigation/sequential-navigation.jsx +0 -31
- package/dist/components/side-navigation/side-navigation.jsx +0 -52
- package/dist/components/site-header/site-header.jsx +0 -68
- package/dist/components/site-navigation/site-navigation.jsx +0 -22
- package/dist/components/site-search/site-search.jsx +0 -55
- package/dist/components/skip-links/skip-links.jsx +0 -21
- package/dist/components/summary-card/summary-card.jsx +0 -67
- package/dist/components/summary-list/summary-list.jsx +0 -75
- package/dist/components/table/table.jsx +0 -24
- package/dist/components/tabs/tabs.jsx +0 -99
- package/dist/components/tag/tag.jsx +0 -13
- package/dist/components/task-list/task-list.jsx +0 -95
- package/dist/components/text-input/text-input.jsx +0 -58
- package/dist/components/textarea/textarea.jsx +0 -54
- package/dist/components/warning-text/warning-text.jsx +0 -16
- package/dist/icons/ArrowUpward.jsx +0 -41
- package/dist/icons/CalendarToday.jsx +0 -41
- package/dist/icons/Cancel.jsx +0 -40
- package/dist/icons/CheckCircle.jsx +0 -41
- package/dist/icons/ChevronLeft.jsx +0 -41
- package/dist/icons/ChevronRight.jsx +0 -41
- package/dist/icons/Close.jsx +0 -41
- package/dist/icons/Description.jsx +0 -41
- package/dist/icons/DoubleChevronLeft.jsx +0 -40
- package/dist/icons/DoubleChevronRight.jsx +0 -40
- package/dist/icons/Error.jsx +0 -41
- package/dist/icons/ExpandLess.jsx +0 -41
- package/dist/icons/ExpandMore.jsx +0 -41
- package/dist/icons/List.jsx +0 -44
- package/dist/icons/Menu.jsx +0 -41
- package/dist/icons/PriorityHigh.jsx +0 -42
- package/dist/icons/Search.jsx +0 -41
- 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
|
|
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
|
-
|
|
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
|
-
{
|
|
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
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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
|
|
5
|
-
|
|
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
|
-
|
|
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={
|
|
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
|
-
{
|
|
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>
|