@khanacademy/wonder-blocks-form 2.4.8 → 3.0.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/CHANGELOG.md +12 -0
- package/dist/es/index.js +11 -11
- package/dist/index.js +71 -75
- package/docs.md +5 -1
- package/package.json +2 -2
- package/src/__docs__/_overview_.stories.mdx +15 -0
- package/src/components/__docs__/checkbox-group.stories.js +0 -1
- package/src/components/__docs__/labeled-text-field.argtypes.js +2 -2
- package/src/components/__docs__/labeled-text-field.stories.js +25 -0
- package/src/components/__docs__/radio.stories.js +3 -2
- package/src/components/__tests__/checkbox-group.test.js +118 -67
- package/src/components/__tests__/field-heading.test.js +40 -0
- package/src/components/__tests__/radio-group.test.js +131 -58
- package/src/components/checkbox-group.js +5 -13
- package/src/components/checkbox.js +2 -2
- package/src/components/choice-internal.js +5 -3
- package/src/components/choice.js +2 -2
- package/src/components/field-heading.js +27 -43
- package/src/components/labeled-text-field.js +2 -3
- package/src/components/radio-group.js +2 -2
- package/src/components/radio.js +2 -2
- package/src/index.js +0 -2
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +0 -6126
- package/src/__tests__/generated-snapshot.test.js +0 -654
- package/src/components/checkbox-group.md +0 -200
- package/src/components/checkbox.md +0 -134
- package/src/components/field-heading.md +0 -43
- package/src/components/labeled-text-field.md +0 -535
- package/src/components/radio-group.md +0 -129
- package/src/components/radio.md +0 -26
- package/src/components/text-field.md +0 -770
|
@@ -1,85 +1,136 @@
|
|
|
1
1
|
//@flow
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import {
|
|
4
|
-
import "
|
|
3
|
+
import {render, screen} from "@testing-library/react";
|
|
4
|
+
import userEvent from "@testing-library/user-event";
|
|
5
5
|
|
|
6
6
|
import CheckboxGroup from "../checkbox-group.js";
|
|
7
7
|
import Choice from "../choice.js";
|
|
8
8
|
|
|
9
9
|
describe("CheckboxGroup", () => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
describe("behavior", () => {
|
|
11
|
+
const TestComponent = ({errorMessage}: {|errorMessage?: string|}) => {
|
|
12
|
+
const [selectedValues, setSelectedValue] = React.useState([
|
|
13
|
+
"a",
|
|
14
|
+
"b",
|
|
15
|
+
]);
|
|
16
|
+
const handleChange = (selectedValues) => {
|
|
17
|
+
setSelectedValue(selectedValues);
|
|
18
|
+
};
|
|
19
|
+
return (
|
|
20
|
+
<CheckboxGroup
|
|
21
|
+
label="Test"
|
|
22
|
+
description="test description"
|
|
23
|
+
groupName="test"
|
|
24
|
+
onChange={handleChange}
|
|
25
|
+
selectedValues={selectedValues}
|
|
26
|
+
errorMessage={errorMessage}
|
|
27
|
+
>
|
|
28
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
29
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
30
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
31
|
+
</CheckboxGroup>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const c = group.find(Choice).at(2);
|
|
35
|
+
it("has the correct items checked", () => {
|
|
36
|
+
// Arrange, Act
|
|
37
|
+
render(<TestComponent />);
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
expect(a.prop("checked")).toEqual(true);
|
|
36
|
-
expect(b.prop("checked")).toEqual(true);
|
|
37
|
-
expect(c.prop("checked")).toEqual(false);
|
|
38
|
-
});
|
|
39
|
+
const checkboxes = screen.getAllByRole("checkbox");
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
// Assert
|
|
42
|
+
// a starts off checked
|
|
43
|
+
expect(checkboxes[0]).toBeChecked();
|
|
44
|
+
expect(checkboxes[1]).toBeChecked();
|
|
45
|
+
expect(checkboxes[2]).not.toBeChecked();
|
|
46
|
+
});
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
expect(c.prop("checked")).toEqual(false);
|
|
50
|
-
});
|
|
48
|
+
it("clicking a selected choice deselects it", () => {
|
|
49
|
+
// Arrange
|
|
50
|
+
render(<TestComponent />);
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
group.setProps({errorMessage: "there's an error"});
|
|
54
|
-
const a = group.find(Choice).at(0);
|
|
55
|
-
const b = group.find(Choice).at(1);
|
|
56
|
-
const c = group.find(Choice).at(2);
|
|
52
|
+
const checkboxes = screen.getAllByRole("checkbox");
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
// Act
|
|
55
|
+
userEvent.click(checkboxes[0]);
|
|
56
|
+
|
|
57
|
+
// Assert
|
|
58
|
+
expect(checkboxes[0]).not.toBeChecked();
|
|
59
|
+
expect(checkboxes[1]).toBeChecked();
|
|
60
|
+
expect(checkboxes[2]).not.toBeChecked();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should set aria-invalid on choices when there's an error message", () => {
|
|
64
|
+
// Arrange, Act
|
|
65
|
+
render(<TestComponent errorMessage="there's an error" />);
|
|
66
|
+
|
|
67
|
+
const checkboxes = screen.getAllByRole("checkbox");
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
// Assert
|
|
70
|
+
expect(checkboxes[0]).toHaveAttribute("aria-invalid", "true");
|
|
71
|
+
expect(checkboxes[1]).toHaveAttribute("aria-invalid", "true");
|
|
72
|
+
expect(checkboxes[2]).toHaveAttribute("aria-invalid", "true");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("checks that aria attributes have been added correctly", () => {
|
|
76
|
+
// Arrange, Act
|
|
77
|
+
render(<TestComponent />);
|
|
78
|
+
|
|
79
|
+
const checkboxes = screen.getAllByRole("checkbox");
|
|
80
|
+
|
|
81
|
+
// Assert
|
|
82
|
+
expect(checkboxes[0]).toHaveAttribute("aria-labelledby", "test-a");
|
|
83
|
+
expect(checkboxes[1]).toHaveAttribute("aria-labelledby", "test-b");
|
|
84
|
+
expect(checkboxes[2]).toHaveAttribute("aria-labelledby", "test-c");
|
|
85
|
+
});
|
|
75
86
|
});
|
|
76
87
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
88
|
+
describe("flexible props", () => {
|
|
89
|
+
it("should render with a React.Node label", () => {
|
|
90
|
+
// Arrange, Act
|
|
91
|
+
render(
|
|
92
|
+
<CheckboxGroup
|
|
93
|
+
label={
|
|
94
|
+
<span>
|
|
95
|
+
label with <strong>strong</strong> text
|
|
96
|
+
</span>
|
|
97
|
+
}
|
|
98
|
+
groupName="test"
|
|
99
|
+
onChange={() => {}}
|
|
100
|
+
selectedValues={[]}
|
|
101
|
+
>
|
|
102
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
103
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
104
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
105
|
+
</CheckboxGroup>,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// Assert
|
|
109
|
+
expect(screen.getByText("strong")).toBeInTheDocument();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("should render with a React.Node description", () => {
|
|
113
|
+
// Arrange, Act
|
|
114
|
+
render(
|
|
115
|
+
<CheckboxGroup
|
|
116
|
+
label="label"
|
|
117
|
+
description={
|
|
118
|
+
<span>
|
|
119
|
+
description with <strong>strong</strong> text
|
|
120
|
+
</span>
|
|
121
|
+
}
|
|
122
|
+
groupName="test"
|
|
123
|
+
onChange={() => {}}
|
|
124
|
+
selectedValues={[]}
|
|
125
|
+
>
|
|
126
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
127
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
128
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
129
|
+
</CheckboxGroup>,
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Assert
|
|
133
|
+
expect(screen.getByText("strong")).toBeInTheDocument();
|
|
134
|
+
});
|
|
84
135
|
});
|
|
85
136
|
});
|
|
@@ -4,6 +4,13 @@ import {mount} from "enzyme";
|
|
|
4
4
|
import "jest-enzyme";
|
|
5
5
|
import {StyleSheet} from "aphrodite";
|
|
6
6
|
|
|
7
|
+
import {I18nInlineMarkup} from "@khanacademy/wonder-blocks-i18n";
|
|
8
|
+
import {
|
|
9
|
+
Body,
|
|
10
|
+
LabelMedium,
|
|
11
|
+
LabelSmall,
|
|
12
|
+
} from "@khanacademy/wonder-blocks-typography";
|
|
13
|
+
|
|
7
14
|
import FieldHeading from "../field-heading.js";
|
|
8
15
|
import TextField from "../text-field.js";
|
|
9
16
|
|
|
@@ -180,4 +187,37 @@ describe("FieldHeading", () => {
|
|
|
180
187
|
const container = wrapper.find("View").at(0);
|
|
181
188
|
expect(container).toHaveStyle(styles.style1);
|
|
182
189
|
});
|
|
190
|
+
|
|
191
|
+
it("should render a LabelSmall when the 'label' prop is a I18nInlineMarkup", () => {
|
|
192
|
+
// Arrange
|
|
193
|
+
|
|
194
|
+
// Act
|
|
195
|
+
const wrapper = mount(
|
|
196
|
+
<FieldHeading
|
|
197
|
+
field={<TextField id="tf-1" value="" onChange={() => {}} />}
|
|
198
|
+
label={<I18nInlineMarkup>Hello, world!</I18nInlineMarkup>}
|
|
199
|
+
/>,
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
// Assert
|
|
203
|
+
const label = wrapper.find(LabelMedium);
|
|
204
|
+
expect(label).toExist();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it("should render a LabelSmall when the 'description' prop is a I18nInlineMarkup", () => {
|
|
208
|
+
// Arrange
|
|
209
|
+
|
|
210
|
+
// Act
|
|
211
|
+
const wrapper = mount(
|
|
212
|
+
<FieldHeading
|
|
213
|
+
field={<TextField id="tf-1" value="" onChange={() => {}} />}
|
|
214
|
+
label={<Body>Hello, world</Body>}
|
|
215
|
+
description={<I18nInlineMarkup>description</I18nInlineMarkup>}
|
|
216
|
+
/>,
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
// Assert
|
|
220
|
+
const label = wrapper.find(LabelSmall);
|
|
221
|
+
expect(label).toExist();
|
|
222
|
+
});
|
|
183
223
|
});
|
|
@@ -1,85 +1,158 @@
|
|
|
1
1
|
//@flow
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
import {
|
|
4
|
-
import "
|
|
3
|
+
import {render, screen} from "@testing-library/react";
|
|
4
|
+
import userEvent from "@testing-library/user-event";
|
|
5
5
|
|
|
6
6
|
import RadioGroup from "../radio-group.js";
|
|
7
7
|
import Choice from "../choice.js";
|
|
8
8
|
|
|
9
9
|
describe("RadioGroup", () => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const TestComponent = ({
|
|
11
|
+
errorMessage,
|
|
12
|
+
onChange,
|
|
13
|
+
}: {|
|
|
14
|
+
errorMessage?: string,
|
|
15
|
+
onChange?: () => mixed,
|
|
16
|
+
|}) => {
|
|
17
|
+
const [selectedValue, setSelectedValue] = React.useState("a");
|
|
18
|
+
const handleChange = (selectedValue) => {
|
|
19
|
+
setSelectedValue(selectedValue);
|
|
20
|
+
onChange?.();
|
|
21
|
+
};
|
|
22
|
+
return (
|
|
15
23
|
<RadioGroup
|
|
16
24
|
label="Test"
|
|
17
25
|
description="test description"
|
|
18
26
|
groupName="test"
|
|
19
|
-
onChange={
|
|
20
|
-
selectedValue=
|
|
27
|
+
onChange={handleChange}
|
|
28
|
+
selectedValue={selectedValue}
|
|
29
|
+
errorMessage={errorMessage}
|
|
21
30
|
>
|
|
22
31
|
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
23
32
|
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
24
33
|
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
25
|
-
</RadioGroup
|
|
34
|
+
</RadioGroup>
|
|
26
35
|
);
|
|
27
|
-
}
|
|
36
|
+
};
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
describe("behavior", () => {
|
|
39
|
+
it("selects only one item at a time", () => {
|
|
40
|
+
// Arrange, Act
|
|
41
|
+
render(<TestComponent />);
|
|
33
42
|
|
|
34
|
-
|
|
35
|
-
expect(a.prop("checked")).toEqual(true);
|
|
36
|
-
expect(b.prop("checked")).toEqual(false);
|
|
37
|
-
expect(c.prop("checked")).toEqual(false);
|
|
38
|
-
});
|
|
43
|
+
const radios = screen.getAllByRole("radio");
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
// Assert
|
|
46
|
+
// a starts off checked
|
|
47
|
+
expect(radios[0]).toBeChecked();
|
|
48
|
+
expect(radios[1]).not.toBeChecked();
|
|
49
|
+
expect(radios[2]).not.toBeChecked();
|
|
50
|
+
});
|
|
45
51
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
expect(c.prop("checked")).toEqual(false);
|
|
50
|
-
});
|
|
52
|
+
it("changes selection when selectedValue changes", () => {
|
|
53
|
+
// Arrange
|
|
54
|
+
render(<TestComponent />);
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
group.setProps({errorMessage: "there's an error"});
|
|
54
|
-
const a = group.find(Choice).at(0);
|
|
55
|
-
const b = group.find(Choice).at(1);
|
|
56
|
-
const c = group.find(Choice).at(2);
|
|
56
|
+
const radios = screen.getAllByRole("radio");
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
// Act
|
|
59
|
+
userEvent.click(radios[1]);
|
|
60
|
+
|
|
61
|
+
// Assert
|
|
62
|
+
// a starts off checked
|
|
63
|
+
expect(radios[0]).not.toBeChecked();
|
|
64
|
+
expect(radios[1]).toBeChecked();
|
|
65
|
+
expect(radios[2]).not.toBeChecked();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should set aria-invalid on choices when there's an error message", () => {
|
|
69
|
+
// Arrange, Act
|
|
70
|
+
render(<TestComponent errorMessage="there's an error" />);
|
|
71
|
+
|
|
72
|
+
const radios = screen.getAllByRole("radio");
|
|
73
|
+
|
|
74
|
+
// Assert
|
|
75
|
+
expect(radios[0]).toHaveAttribute("aria-invalid", "true");
|
|
76
|
+
expect(radios[1]).toHaveAttribute("aria-invalid", "true");
|
|
77
|
+
expect(radios[2]).toHaveAttribute("aria-invalid", "true");
|
|
78
|
+
});
|
|
62
79
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
it("doesn't change when an already selected item is reselected", () => {
|
|
81
|
+
// Arrange
|
|
82
|
+
const handleChange = jest.fn();
|
|
83
|
+
render(<TestComponent onChange={handleChange} />);
|
|
84
|
+
|
|
85
|
+
const radios = screen.getAllByRole("radio");
|
|
86
|
+
|
|
87
|
+
// Act
|
|
88
|
+
// a is already selected, onChange shouldn't be called
|
|
89
|
+
userEvent.click(radios[0]);
|
|
90
|
+
|
|
91
|
+
// Assert
|
|
92
|
+
expect(handleChange).toHaveBeenCalledTimes(0);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("checks that aria attributes have been added correctly", () => {
|
|
96
|
+
// Arrange, Act
|
|
97
|
+
render(<TestComponent />);
|
|
98
|
+
|
|
99
|
+
const radios = screen.getAllByRole("radio");
|
|
100
|
+
|
|
101
|
+
// Assert
|
|
102
|
+
expect(radios[0]).toHaveAttribute("aria-labelledby", "test-a");
|
|
103
|
+
expect(radios[1]).toHaveAttribute("aria-labelledby", "test-b");
|
|
104
|
+
expect(radios[2]).toHaveAttribute("aria-labelledby", "test-c");
|
|
105
|
+
});
|
|
75
106
|
});
|
|
76
107
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
108
|
+
describe("flexible props", () => {
|
|
109
|
+
it("should render with a React.Node label", () => {
|
|
110
|
+
// Arrange, Act
|
|
111
|
+
const action = () =>
|
|
112
|
+
render(
|
|
113
|
+
<RadioGroup
|
|
114
|
+
label={
|
|
115
|
+
<span>
|
|
116
|
+
label with <strong>strong</strong> text
|
|
117
|
+
</span>
|
|
118
|
+
}
|
|
119
|
+
groupName="test"
|
|
120
|
+
onChange={() => {}}
|
|
121
|
+
selectedValue={"a"}
|
|
122
|
+
>
|
|
123
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
124
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
125
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
126
|
+
</RadioGroup>,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
// Assert
|
|
130
|
+
expect(action).not.toThrow();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("should render with a React.Node description", () => {
|
|
134
|
+
// Arrange, Act
|
|
135
|
+
const action = () =>
|
|
136
|
+
render(
|
|
137
|
+
<RadioGroup
|
|
138
|
+
label="label"
|
|
139
|
+
description={
|
|
140
|
+
<span>
|
|
141
|
+
description with <strong>strong</strong> text
|
|
142
|
+
</span>
|
|
143
|
+
}
|
|
144
|
+
groupName="test"
|
|
145
|
+
onChange={() => {}}
|
|
146
|
+
selectedValue={"a"}
|
|
147
|
+
>
|
|
148
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
149
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
150
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
151
|
+
</RadioGroup>,
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
// Assert
|
|
155
|
+
expect(action).not.toThrow();
|
|
156
|
+
});
|
|
84
157
|
});
|
|
85
158
|
});
|
|
@@ -5,11 +5,7 @@ import * as React from "react";
|
|
|
5
5
|
import {View, addStyle} from "@khanacademy/wonder-blocks-core";
|
|
6
6
|
import {Strut} from "@khanacademy/wonder-blocks-layout";
|
|
7
7
|
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
8
|
-
import {
|
|
9
|
-
type Typography,
|
|
10
|
-
LabelMedium,
|
|
11
|
-
LabelSmall,
|
|
12
|
-
} from "@khanacademy/wonder-blocks-typography";
|
|
8
|
+
import {LabelMedium, LabelSmall} from "@khanacademy/wonder-blocks-typography";
|
|
13
9
|
import type {StyleType} from "@khanacademy/wonder-blocks-core";
|
|
14
10
|
|
|
15
11
|
import styles from "./group-styles.js";
|
|
@@ -32,12 +28,12 @@ type CheckboxGroupProps = {|
|
|
|
32
28
|
* Optional label for the group. This label is optional to allow for
|
|
33
29
|
* greater flexibility in implementing checkbox and radio groups.
|
|
34
30
|
*/
|
|
35
|
-
label?:
|
|
31
|
+
label?: React.Node,
|
|
36
32
|
|
|
37
33
|
/**
|
|
38
34
|
* Optional description for the group.
|
|
39
35
|
*/
|
|
40
|
-
description?:
|
|
36
|
+
description?: React.Node,
|
|
41
37
|
|
|
42
38
|
/**
|
|
43
39
|
* Optional error message. If supplied, the group will be displayed in an
|
|
@@ -136,19 +132,15 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps> {
|
|
|
136
132
|
<StyledFieldset data-test-id={testId} style={styles.fieldset}>
|
|
137
133
|
{/* We have a View here because fieldset cannot be used with flexbox*/}
|
|
138
134
|
<View style={style}>
|
|
139
|
-
{
|
|
135
|
+
{label && (
|
|
140
136
|
<StyledLegend style={styles.legend}>
|
|
141
137
|
<LabelMedium>{label}</LabelMedium>
|
|
142
138
|
</StyledLegend>
|
|
143
|
-
) : (
|
|
144
|
-
label && label
|
|
145
139
|
)}
|
|
146
|
-
{
|
|
140
|
+
{description && (
|
|
147
141
|
<LabelSmall style={styles.description}>
|
|
148
142
|
{description}
|
|
149
143
|
</LabelSmall>
|
|
150
|
-
) : (
|
|
151
|
-
description && description
|
|
152
144
|
)}
|
|
153
145
|
{errorMessage && (
|
|
154
146
|
<LabelSmall style={styles.error}>
|
|
@@ -33,12 +33,12 @@ type ChoiceComponentProps = {|
|
|
|
33
33
|
/**
|
|
34
34
|
* Optional label for the field.
|
|
35
35
|
*/
|
|
36
|
-
label?:
|
|
36
|
+
label?: React.Node,
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Optional description for the field.
|
|
40
40
|
*/
|
|
41
|
-
description?:
|
|
41
|
+
description?: React.Node,
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
44
|
* Unique identifier attached to the HTML input element. If used, need to
|
|
@@ -52,10 +52,10 @@ type Props = {|
|
|
|
52
52
|
/**
|
|
53
53
|
* Label for the field.
|
|
54
54
|
*/
|
|
55
|
-
label?:
|
|
55
|
+
label?: React.Node,
|
|
56
56
|
|
|
57
57
|
/** Optional description for the field. */
|
|
58
|
-
description?:
|
|
58
|
+
description?: React.Node,
|
|
59
59
|
|
|
60
60
|
/** Auto-populated by parent's groupName prop if in a group. */
|
|
61
61
|
groupName?: string,
|
|
@@ -142,7 +142,9 @@ type DefaultProps = {|
|
|
|
142
142
|
return (
|
|
143
143
|
<UniqueIDProvider mockOnFirstRender={true} scope="choice">
|
|
144
144
|
{(ids) => {
|
|
145
|
-
const descriptionId = description
|
|
145
|
+
const descriptionId = description
|
|
146
|
+
? ids.get("description")
|
|
147
|
+
: undefined;
|
|
146
148
|
|
|
147
149
|
return (
|
|
148
150
|
<View style={style} className={className}>
|
package/src/components/choice.js
CHANGED
|
@@ -10,10 +10,10 @@ type Props = {|
|
|
|
10
10
|
...AriaProps,
|
|
11
11
|
|
|
12
12
|
/** User-defined. Label for the field. */
|
|
13
|
-
label:
|
|
13
|
+
label: React.Node,
|
|
14
14
|
|
|
15
15
|
/** User-defined. Optional description for the field. */
|
|
16
|
-
description?:
|
|
16
|
+
description?: React.Node,
|
|
17
17
|
|
|
18
18
|
/** User-defined. Should be distinct for each item in the group. */
|
|
19
19
|
value: string,
|