@khanacademy/wonder-blocks-form 3.0.0 → 3.1.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 +6 -0
- package/dist/es/index.js +4 -2
- package/dist/index.js +4 -2
- package/package.json +1 -1
- package/src/components/__docs__/checkbox-group.stories.js +35 -0
- package/src/components/__docs__/radio-group.stories.js +35 -0
- package/src/components/__tests__/checkbox-group.test.js +26 -0
- package/src/components/__tests__/radio-group.test.js +60 -36
- package/src/components/checkbox-group.js +4 -2
- package/src/components/radio-group.js +4 -2
package/CHANGELOG.md
CHANGED
package/dist/es/index.js
CHANGED
|
@@ -550,6 +550,7 @@ class CheckboxGroup extends React.Component {
|
|
|
550
550
|
style,
|
|
551
551
|
testId
|
|
552
552
|
} = this.props;
|
|
553
|
+
const allChildren = React.Children.toArray(children).filter(Boolean);
|
|
553
554
|
return React.createElement(StyledFieldset$1, {
|
|
554
555
|
"data-test-id": testId,
|
|
555
556
|
style: styles$2.fieldset
|
|
@@ -563,7 +564,7 @@ class CheckboxGroup extends React.Component {
|
|
|
563
564
|
style: styles$2.error
|
|
564
565
|
}, errorMessage), (label || description || errorMessage) && React.createElement(Strut, {
|
|
565
566
|
size: Spacing.small_12
|
|
566
|
-
}),
|
|
567
|
+
}), allChildren.map((child, index) => {
|
|
567
568
|
const {
|
|
568
569
|
style,
|
|
569
570
|
value
|
|
@@ -602,6 +603,7 @@ class RadioGroup extends React.Component {
|
|
|
602
603
|
style,
|
|
603
604
|
testId
|
|
604
605
|
} = this.props;
|
|
606
|
+
const allChildren = React.Children.toArray(children).filter(Boolean);
|
|
605
607
|
return React.createElement(StyledFieldset, {
|
|
606
608
|
"data-test-id": testId,
|
|
607
609
|
style: styles$2.fieldset
|
|
@@ -615,7 +617,7 @@ class RadioGroup extends React.Component {
|
|
|
615
617
|
style: styles$2.error
|
|
616
618
|
}, errorMessage), (label || description || errorMessage) && React.createElement(Strut, {
|
|
617
619
|
size: Spacing.small_12
|
|
618
|
-
}),
|
|
620
|
+
}), allChildren.map((child, index) => {
|
|
619
621
|
const {
|
|
620
622
|
style,
|
|
621
623
|
value
|
package/dist/index.js
CHANGED
|
@@ -848,6 +848,7 @@ class CheckboxGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
848
848
|
style,
|
|
849
849
|
testId
|
|
850
850
|
} = this.props;
|
|
851
|
+
const allChildren = react__WEBPACK_IMPORTED_MODULE_0__["Children"].toArray(children).filter(Boolean);
|
|
851
852
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledFieldset, {
|
|
852
853
|
"data-test-id": testId,
|
|
853
854
|
style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].fieldset
|
|
@@ -861,7 +862,7 @@ class CheckboxGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
861
862
|
style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].error
|
|
862
863
|
}, errorMessage), (label || description || errorMessage) && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["Strut"], {
|
|
863
864
|
size: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_3___default.a.small_12
|
|
864
|
-
}),
|
|
865
|
+
}), allChildren.map((child, index) => {
|
|
865
866
|
const {
|
|
866
867
|
style,
|
|
867
868
|
value
|
|
@@ -959,6 +960,7 @@ class RadioGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
959
960
|
style,
|
|
960
961
|
testId
|
|
961
962
|
} = this.props;
|
|
963
|
+
const allChildren = react__WEBPACK_IMPORTED_MODULE_0__["Children"].toArray(children).filter(Boolean);
|
|
962
964
|
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledFieldset, {
|
|
963
965
|
"data-test-id": testId,
|
|
964
966
|
style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].fieldset
|
|
@@ -972,7 +974,7 @@ class RadioGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
|
|
|
972
974
|
style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].error
|
|
973
975
|
}, errorMessage), (label || description || errorMessage) && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["Strut"], {
|
|
974
976
|
size: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_3___default.a.small_12
|
|
975
|
-
}),
|
|
977
|
+
}), allChildren.map((child, index) => {
|
|
976
978
|
const {
|
|
977
979
|
style,
|
|
978
980
|
value
|
package/package.json
CHANGED
|
@@ -232,6 +232,41 @@ MultipleChoiceStyling.parameters = {
|
|
|
232
232
|
},
|
|
233
233
|
};
|
|
234
234
|
|
|
235
|
+
export const FiltersOutFalsyChildren: StoryComponentType = () => {
|
|
236
|
+
return (
|
|
237
|
+
<CheckboxGroup
|
|
238
|
+
groupName="pokemon"
|
|
239
|
+
selectedValues={["pepperoni", "sausage"]}
|
|
240
|
+
onChange={() => {}}
|
|
241
|
+
label="Pokemon"
|
|
242
|
+
description="Your first Pokemon."
|
|
243
|
+
>
|
|
244
|
+
<Choice label="Pepperoni" value="pepperoni" />
|
|
245
|
+
<Choice
|
|
246
|
+
label="Sausage"
|
|
247
|
+
value="sausage"
|
|
248
|
+
description="Imported from Italy"
|
|
249
|
+
/>
|
|
250
|
+
<Choice label="Extra cheese" value="cheese" />
|
|
251
|
+
<Choice label="Green pepper" value="pepper" />
|
|
252
|
+
{false && <Choice label="Mushroom" value="mushroom" />}
|
|
253
|
+
</CheckboxGroup>
|
|
254
|
+
);
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
FiltersOutFalsyChildren.parameters = {
|
|
258
|
+
docs: {
|
|
259
|
+
storyDescription: `This example shows that children can be falsy values and
|
|
260
|
+
that those falsy values are filtered out when rendering children. In this
|
|
261
|
+
case, one of the children is \`{false && <Choice .../>}\` which results in
|
|
262
|
+
that choice being filtered out.`,
|
|
263
|
+
},
|
|
264
|
+
chromatic: {
|
|
265
|
+
// The unit tests already verify that false-y children aren't rendered.
|
|
266
|
+
disableSnapshot: true,
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
235
270
|
const styles = StyleSheet.create({
|
|
236
271
|
// Row styling
|
|
237
272
|
wrapper: {
|
|
@@ -166,6 +166,41 @@ MultipleChoiceStyling.parameters = {
|
|
|
166
166
|
},
|
|
167
167
|
};
|
|
168
168
|
|
|
169
|
+
export const FiltersOutFalsyChildren: StoryComponentType = () => {
|
|
170
|
+
return (
|
|
171
|
+
<RadioGroup
|
|
172
|
+
groupName="pokemon"
|
|
173
|
+
selectedValue="bulbasaur"
|
|
174
|
+
onChange={() => {}}
|
|
175
|
+
label="Pokemon"
|
|
176
|
+
description="Your first Pokemon."
|
|
177
|
+
>
|
|
178
|
+
<Choice label="Bulbasaur" value="bulbasaur" />
|
|
179
|
+
<Choice
|
|
180
|
+
label="Charmander"
|
|
181
|
+
value="charmander"
|
|
182
|
+
description="Oops, we ran out of Charmanders"
|
|
183
|
+
disabled
|
|
184
|
+
/>
|
|
185
|
+
<Choice label="Squirtle" value="squirtle" />
|
|
186
|
+
{false && <Choice label="Pikachu" value="pikachu" />}
|
|
187
|
+
</RadioGroup>
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
FiltersOutFalsyChildren.parameters = {
|
|
192
|
+
docs: {
|
|
193
|
+
storyDescription: `This example shows that children can be falsy values and
|
|
194
|
+
that those falsy values are filtered out when rendering children. In this
|
|
195
|
+
case, one of the children is \`{false && <Choice .../>}\` which results in
|
|
196
|
+
that choice being filtered out.`,
|
|
197
|
+
},
|
|
198
|
+
chromatic: {
|
|
199
|
+
// The unit tests already verify that false-y children aren't rendered.
|
|
200
|
+
disableSnapshot: true,
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
|
|
169
204
|
const styles = StyleSheet.create({
|
|
170
205
|
choice: {
|
|
171
206
|
margin: 0,
|
|
@@ -132,5 +132,31 @@ describe("CheckboxGroup", () => {
|
|
|
132
132
|
// Assert
|
|
133
133
|
expect(screen.getByText("strong")).toBeInTheDocument();
|
|
134
134
|
});
|
|
135
|
+
|
|
136
|
+
it("should filter out false-y children when rendering", () => {
|
|
137
|
+
// Arrange, Act
|
|
138
|
+
render(
|
|
139
|
+
<CheckboxGroup
|
|
140
|
+
label="label"
|
|
141
|
+
description="description"
|
|
142
|
+
groupName="test"
|
|
143
|
+
onChange={() => {}}
|
|
144
|
+
selectedValues={[]}
|
|
145
|
+
>
|
|
146
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
147
|
+
{false && (
|
|
148
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
149
|
+
)}
|
|
150
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
151
|
+
{undefined}
|
|
152
|
+
{null}
|
|
153
|
+
</CheckboxGroup>,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
// Assert
|
|
157
|
+
const checkboxes = screen.getAllByRole("checkbox");
|
|
158
|
+
|
|
159
|
+
expect(checkboxes).toHaveLength(2);
|
|
160
|
+
});
|
|
135
161
|
});
|
|
136
162
|
});
|
|
@@ -108,51 +108,75 @@ describe("RadioGroup", () => {
|
|
|
108
108
|
describe("flexible props", () => {
|
|
109
109
|
it("should render with a React.Node label", () => {
|
|
110
110
|
// Arrange, Act
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
);
|
|
111
|
+
render(
|
|
112
|
+
<RadioGroup
|
|
113
|
+
label={
|
|
114
|
+
<span>
|
|
115
|
+
label with <strong>strong</strong> text
|
|
116
|
+
</span>
|
|
117
|
+
}
|
|
118
|
+
groupName="test"
|
|
119
|
+
onChange={() => {}}
|
|
120
|
+
selectedValue={"a"}
|
|
121
|
+
>
|
|
122
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
123
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
124
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
125
|
+
</RadioGroup>,
|
|
126
|
+
);
|
|
128
127
|
|
|
129
128
|
// Assert
|
|
130
|
-
expect(
|
|
129
|
+
expect(screen.getByText("strong")).toBeInTheDocument();
|
|
131
130
|
});
|
|
132
131
|
|
|
133
132
|
it("should render with a React.Node description", () => {
|
|
134
133
|
// Arrange, Act
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
134
|
+
render(
|
|
135
|
+
<RadioGroup
|
|
136
|
+
label="label"
|
|
137
|
+
description={
|
|
138
|
+
<span>
|
|
139
|
+
description with <strong>strong</strong> text
|
|
140
|
+
</span>
|
|
141
|
+
}
|
|
142
|
+
groupName="test"
|
|
143
|
+
onChange={() => {}}
|
|
144
|
+
selectedValue={"a"}
|
|
145
|
+
>
|
|
146
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
147
|
+
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
148
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
149
|
+
</RadioGroup>,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
// Assert
|
|
153
|
+
expect(screen.getByText("strong")).toBeInTheDocument();
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("should filter out false-y children when rendering", () => {
|
|
157
|
+
// Arrange, Act
|
|
158
|
+
render(
|
|
159
|
+
<RadioGroup
|
|
160
|
+
label="label"
|
|
161
|
+
description="description"
|
|
162
|
+
groupName="test"
|
|
163
|
+
onChange={() => {}}
|
|
164
|
+
selectedValue={"a"}
|
|
165
|
+
>
|
|
166
|
+
<Choice label="a" value="a" aria-labelledby="test-a" />
|
|
167
|
+
{false && (
|
|
149
168
|
<Choice label="b" value="b" aria-labelledby="test-b" />
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
169
|
+
)}
|
|
170
|
+
<Choice label="c" value="c" aria-labelledby="test-c" />
|
|
171
|
+
{undefined}
|
|
172
|
+
{null}
|
|
173
|
+
</RadioGroup>,
|
|
174
|
+
);
|
|
153
175
|
|
|
154
176
|
// Assert
|
|
155
|
-
|
|
177
|
+
const radios = screen.getAllByRole("radio");
|
|
178
|
+
|
|
179
|
+
expect(radios).toHaveLength(2);
|
|
156
180
|
});
|
|
157
181
|
});
|
|
158
182
|
});
|
|
@@ -16,7 +16,7 @@ type CheckboxGroupProps = {|
|
|
|
16
16
|
/**
|
|
17
17
|
* Children should be Choice components.
|
|
18
18
|
*/
|
|
19
|
-
children: Array
|
|
19
|
+
children: Array<?(React.Element<Choice> | false)>,
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Group name for this checkbox or radio group. Should be unique for all
|
|
@@ -128,6 +128,8 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps> {
|
|
|
128
128
|
testId,
|
|
129
129
|
} = this.props;
|
|
130
130
|
|
|
131
|
+
const allChildren = React.Children.toArray(children).filter(Boolean);
|
|
132
|
+
|
|
131
133
|
return (
|
|
132
134
|
<StyledFieldset data-test-id={testId} style={styles.fieldset}>
|
|
133
135
|
{/* We have a View here because fieldset cannot be used with flexbox*/}
|
|
@@ -151,7 +153,7 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps> {
|
|
|
151
153
|
<Strut size={Spacing.small_12} />
|
|
152
154
|
)}
|
|
153
155
|
|
|
154
|
-
{
|
|
156
|
+
{allChildren.map((child, index) => {
|
|
155
157
|
const {style, value} = child.props;
|
|
156
158
|
const checked = selectedValues.includes(value);
|
|
157
159
|
return (
|
|
@@ -16,7 +16,7 @@ type RadioGroupProps = {|
|
|
|
16
16
|
/**
|
|
17
17
|
* Children should be Choice components.
|
|
18
18
|
*/
|
|
19
|
-
children: Array
|
|
19
|
+
children: Array<?(React.Element<Choice> | false)>,
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Group name for this checkbox or radio group. Should be unique for all
|
|
@@ -118,6 +118,8 @@ export default class RadioGroup extends React.Component<RadioGroupProps> {
|
|
|
118
118
|
testId,
|
|
119
119
|
} = this.props;
|
|
120
120
|
|
|
121
|
+
const allChildren = React.Children.toArray(children).filter(Boolean);
|
|
122
|
+
|
|
121
123
|
return (
|
|
122
124
|
<StyledFieldset data-test-id={testId} style={styles.fieldset}>
|
|
123
125
|
{/* We have a View here because fieldset cannot be used with flexbox*/}
|
|
@@ -141,7 +143,7 @@ export default class RadioGroup extends React.Component<RadioGroupProps> {
|
|
|
141
143
|
<Strut size={Spacing.small_12} />
|
|
142
144
|
)}
|
|
143
145
|
|
|
144
|
-
{
|
|
146
|
+
{allChildren.map((child, index) => {
|
|
145
147
|
const {style, value} = child.props;
|
|
146
148
|
const checked = selectedValue === value;
|
|
147
149
|
return (
|