@khanacademy/wonder-blocks-form 2.4.8 → 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.
Files changed (32) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/es/index.js +15 -13
  3. package/dist/index.js +75 -77
  4. package/docs.md +5 -1
  5. package/package.json +2 -2
  6. package/src/__docs__/_overview_.stories.mdx +15 -0
  7. package/src/components/__docs__/checkbox-group.stories.js +35 -1
  8. package/src/components/__docs__/labeled-text-field.argtypes.js +2 -2
  9. package/src/components/__docs__/labeled-text-field.stories.js +25 -0
  10. package/src/components/__docs__/radio-group.stories.js +35 -0
  11. package/src/components/__docs__/radio.stories.js +3 -2
  12. package/src/components/__tests__/checkbox-group.test.js +144 -67
  13. package/src/components/__tests__/field-heading.test.js +40 -0
  14. package/src/components/__tests__/radio-group.test.js +155 -58
  15. package/src/components/checkbox-group.js +9 -15
  16. package/src/components/checkbox.js +2 -2
  17. package/src/components/choice-internal.js +5 -3
  18. package/src/components/choice.js +2 -2
  19. package/src/components/field-heading.js +27 -43
  20. package/src/components/labeled-text-field.js +2 -3
  21. package/src/components/radio-group.js +6 -4
  22. package/src/components/radio.js +2 -2
  23. package/src/index.js +0 -2
  24. package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +0 -6126
  25. package/src/__tests__/generated-snapshot.test.js +0 -654
  26. package/src/components/checkbox-group.md +0 -200
  27. package/src/components/checkbox.md +0 -134
  28. package/src/components/field-heading.md +0 -43
  29. package/src/components/labeled-text-field.md +0 -535
  30. package/src/components/radio-group.md +0 -129
  31. package/src/components/radio.md +0 -26
  32. package/src/components/text-field.md +0 -770
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @khanacademy/wonder-blocks-form
2
2
 
3
+ ## 3.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d3f459bf: Allow CheckboxGroup and RadioGroup to accept falsy children
8
+
9
+ ## 3.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - 3bae2aba: Remove Radio from wonder-blocks-form's exports so that RadioGroup is used
14
+
15
+ ### Patch Changes
16
+
17
+ - e91fb6c0: Update label, description, and error props in form components to accept React.Node
18
+ - Updated dependencies [3bae2aba]
19
+ - @khanacademy/wonder-blocks-icon@1.2.31
20
+
3
21
  ## 2.4.8
4
22
 
5
23
  ### Patch Changes
package/dist/es/index.js CHANGED
@@ -397,7 +397,7 @@ class ChoiceInternal extends React.Component {
397
397
  mockOnFirstRender: true,
398
398
  scope: "choice"
399
399
  }, ids => {
400
- const descriptionId = description && ids.get("description");
400
+ const descriptionId = description ? ids.get("description") : undefined;
401
401
  return React.createElement(View, {
402
402
  style: style,
403
403
  className: className
@@ -550,20 +550,21 @@ 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
556
557
  }, React.createElement(View, {
557
558
  style: style
558
- }, typeof label === "string" ? React.createElement(StyledLegend$1, {
559
+ }, label && React.createElement(StyledLegend$1, {
559
560
  style: styles$2.legend
560
- }, React.createElement(LabelMedium, null, label)) : label && label, typeof description === "string" ? React.createElement(LabelSmall, {
561
+ }, React.createElement(LabelMedium, null, label)), description && React.createElement(LabelSmall, {
561
562
  style: styles$2.description
562
- }, description) : description && description, errorMessage && React.createElement(LabelSmall, {
563
+ }, description), errorMessage && React.createElement(LabelSmall, {
563
564
  style: styles$2.error
564
565
  }, errorMessage), (label || description || errorMessage) && React.createElement(Strut, {
565
566
  size: Spacing.small_12
566
- }), React.Children.map(children, (child, index) => {
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
- }), React.Children.map(children, (child, index) => {
620
+ }), allChildren.map((child, index) => {
619
621
  const {
620
622
  style,
621
623
  value
@@ -832,12 +834,12 @@ class FieldHeading extends React.Component {
832
834
  style: styles.required,
833
835
  "aria-hidden": true
834
836
  }, " ", "*");
835
- return React.createElement(React.Fragment, null, typeof label === "string" ? React.createElement(LabelMedium, {
837
+ return React.createElement(React.Fragment, null, React.createElement(LabelMedium, {
836
838
  style: styles.label,
837
839
  tag: "label",
838
840
  htmlFor: id && `${id}-field`,
839
841
  testId: testId && `${testId}-label`
840
- }, label, required && requiredIcon) : label, React.createElement(Strut, {
842
+ }, label, required && requiredIcon), React.createElement(Strut, {
841
843
  size: Spacing.xxxSmall_4
842
844
  }));
843
845
  }
@@ -852,10 +854,10 @@ class FieldHeading extends React.Component {
852
854
  return null;
853
855
  }
854
856
 
855
- return React.createElement(React.Fragment, null, typeof description === "string" ? React.createElement(LabelSmall, {
857
+ return React.createElement(React.Fragment, null, React.createElement(LabelSmall, {
856
858
  style: styles.description,
857
859
  testId: testId && `${testId}-description`
858
- }, description) : description, React.createElement(Strut, {
860
+ }, description), React.createElement(Strut, {
859
861
  size: Spacing.xxxSmall_4
860
862
  }));
861
863
  }
@@ -873,12 +875,12 @@ class FieldHeading extends React.Component {
873
875
 
874
876
  return React.createElement(React.Fragment, null, React.createElement(Strut, {
875
877
  size: Spacing.small_12
876
- }), typeof error === "string" ? React.createElement(LabelSmall, {
878
+ }), React.createElement(LabelSmall, {
877
879
  style: styles.error,
878
880
  role: "alert",
879
881
  id: id && `${id}-error`,
880
882
  testId: testId && `${testId}-error`
881
- }, error) : error);
883
+ }, error));
882
884
  }
883
885
 
884
886
  render() {
@@ -1026,4 +1028,4 @@ const LabeledTextField = React.forwardRef((props, ref) => React.createElement(La
1026
1028
  forwardedRef: ref
1027
1029
  })));
1028
1030
 
1029
- export { Checkbox, CheckboxGroup, Choice, LabeledTextField, Radio, RadioGroup, TextField };
1031
+ export { Checkbox, CheckboxGroup, Choice, LabeledTextField, RadioGroup, TextField };
package/dist/index.js CHANGED
@@ -197,7 +197,7 @@ module.exports = require("@khanacademy/wonder-blocks-layout");
197
197
  /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);
198
198
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
199
199
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
200
- /* harmony import */ var _choice_internal_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12);
200
+ /* harmony import */ var _choice_internal_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11);
201
201
 
202
202
 
203
203
  // Keep synced with ChoiceComponentProps in ../util/types.js
@@ -240,41 +240,6 @@ Checkbox.defaultProps = {
240
240
  /* 10 */
241
241
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
242
242
 
243
- "use strict";
244
- /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Radio; });
245
- /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5);
246
- /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);
247
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
248
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
249
- /* harmony import */ var _choice_internal_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12);
250
-
251
-
252
- // Keep synced with ChoiceComponentProps in ../util/types.js
253
-
254
- /**
255
- * 🔘 A nicely styled radio button for all your non-AMFM radio button needs. Can
256
- * optionally take label and description props.
257
- *
258
- * This component should not really be used by itself because radio buttons are
259
- * often grouped together. See RadioGroup.
260
- */
261
- class Radio extends react__WEBPACK_IMPORTED_MODULE_1__["Component"] {
262
- render() {
263
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_choice_internal_js__WEBPACK_IMPORTED_MODULE_2__[/* default */ "a"], _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default()({
264
- variant: "radio"
265
- }, this.props));
266
- }
267
-
268
- }
269
- Radio.defaultProps = {
270
- disabled: false,
271
- error: false
272
- };
273
-
274
- /***/ }),
275
- /* 11 */
276
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
277
-
278
243
  "use strict";
279
244
  /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5);
280
245
  /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);
@@ -514,7 +479,7 @@ const TextField = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["forwardRef"](
514
479
  /* harmony default export */ __webpack_exports__["a"] = (TextField);
515
480
 
516
481
  /***/ }),
517
- /* 12 */
482
+ /* 11 */
518
483
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
519
484
 
520
485
  "use strict";
@@ -529,7 +494,7 @@ const TextField = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["forwardRef"](
529
494
  /* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3__);
530
495
  /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2);
531
496
  /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__);
532
- /* harmony import */ var _khanacademy_wonder_blocks_clickable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(17);
497
+ /* harmony import */ var _khanacademy_wonder_blocks_clickable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(16);
533
498
  /* harmony import */ var _khanacademy_wonder_blocks_clickable__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_clickable__WEBPACK_IMPORTED_MODULE_5__);
534
499
  /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(8);
535
500
  /* harmony import */ var _khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_6__);
@@ -537,8 +502,8 @@ const TextField = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["forwardRef"](
537
502
  /* harmony import */ var _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_7__);
538
503
  /* harmony import */ var _khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(4);
539
504
  /* harmony import */ var _khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_8__);
540
- /* harmony import */ var _checkbox_core_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(18);
541
- /* harmony import */ var _radio_core_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(20);
505
+ /* harmony import */ var _checkbox_core_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(17);
506
+ /* harmony import */ var _radio_core_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(19);
542
507
 
543
508
 
544
509
 
@@ -633,7 +598,7 @@ class ChoiceInternal extends react__WEBPACK_IMPORTED_MODULE_1__["Component"] {
633
598
  mockOnFirstRender: true,
634
599
  scope: "choice"
635
600
  }, ids => {
636
- const descriptionId = description && ids.get("description");
601
+ const descriptionId = description ? ids.get("description") : undefined;
637
602
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__["View"], {
638
603
  style: style,
639
604
  className: className
@@ -690,7 +655,7 @@ const styles = aphrodite__WEBPACK_IMPORTED_MODULE_2__["StyleSheet"].create({
690
655
  });
691
656
 
692
657
  /***/ }),
693
- /* 13 */
658
+ /* 12 */
694
659
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
695
660
 
696
661
  "use strict";
@@ -698,7 +663,7 @@ const styles = aphrodite__WEBPACK_IMPORTED_MODULE_2__["StyleSheet"].create({
698
663
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);
699
664
  /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
700
665
  /* harmony import */ var _checkbox_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9);
701
- /* harmony import */ var _radio_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10);
666
+ /* harmony import */ var _radio_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(20);
702
667
 
703
668
 
704
669
 
@@ -798,7 +763,7 @@ Choice.defaultProps = {
798
763
  };
799
764
 
800
765
  /***/ }),
801
- /* 14 */
766
+ /* 13 */
802
767
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
803
768
 
804
769
  "use strict";
@@ -883,20 +848,21 @@ class CheckboxGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
883
848
  style,
884
849
  testId
885
850
  } = this.props;
851
+ const allChildren = react__WEBPACK_IMPORTED_MODULE_0__["Children"].toArray(children).filter(Boolean);
886
852
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledFieldset, {
887
853
  "data-test-id": testId,
888
854
  style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].fieldset
889
855
  }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_1__["View"], {
890
856
  style: style
891
- }, typeof label === "string" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledLegend, {
857
+ }, label && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledLegend, {
892
858
  style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].legend
893
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_4__["LabelMedium"], null, label)) : label && label, typeof description === "string" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_4__["LabelSmall"], {
859
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_4__["LabelMedium"], null, label)), description && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_4__["LabelSmall"], {
894
860
  style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].description
895
- }, description) : description && description, errorMessage && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_4__["LabelSmall"], {
861
+ }, description), errorMessage && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_4__["LabelSmall"], {
896
862
  style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].error
897
863
  }, errorMessage), (label || description || errorMessage) && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["Strut"], {
898
864
  size: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_3___default.a.small_12
899
- }), react__WEBPACK_IMPORTED_MODULE_0__["Children"].map(children, (child, index) => {
865
+ }), allChildren.map((child, index) => {
900
866
  const {
901
867
  style,
902
868
  value
@@ -918,7 +884,7 @@ class CheckboxGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
918
884
  }
919
885
 
920
886
  /***/ }),
921
- /* 15 */
887
+ /* 14 */
922
888
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
923
889
 
924
890
  "use strict";
@@ -994,6 +960,7 @@ class RadioGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
994
960
  style,
995
961
  testId
996
962
  } = this.props;
963
+ const allChildren = react__WEBPACK_IMPORTED_MODULE_0__["Children"].toArray(children).filter(Boolean);
997
964
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](StyledFieldset, {
998
965
  "data-test-id": testId,
999
966
  style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].fieldset
@@ -1007,7 +974,7 @@ class RadioGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1007
974
  style: _group_styles_js__WEBPACK_IMPORTED_MODULE_5__[/* default */ "a"].error
1008
975
  }, errorMessage), (label || description || errorMessage) && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_2__["Strut"], {
1009
976
  size: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_3___default.a.small_12
1010
- }), react__WEBPACK_IMPORTED_MODULE_0__["Children"].map(children, (child, index) => {
977
+ }), allChildren.map((child, index) => {
1011
978
  const {
1012
979
  style,
1013
980
  value
@@ -1029,7 +996,7 @@ class RadioGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1029
996
  }
1030
997
 
1031
998
  /***/ }),
1032
- /* 16 */
999
+ /* 15 */
1033
1000
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
1034
1001
 
1035
1002
  "use strict";
@@ -1040,7 +1007,7 @@ class RadioGroup extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1040
1007
  /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2);
1041
1008
  /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_2__);
1042
1009
  /* harmony import */ var _field_heading_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(21);
1043
- /* harmony import */ var _text_field_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11);
1010
+ /* harmony import */ var _text_field_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
1044
1011
 
1045
1012
 
1046
1013
 
@@ -1193,13 +1160,13 @@ const LabeledTextField = /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["forwar
1193
1160
  /* harmony default export */ __webpack_exports__["a"] = (LabeledTextField);
1194
1161
 
1195
1162
  /***/ }),
1196
- /* 17 */
1163
+ /* 16 */
1197
1164
  /***/ (function(module, exports) {
1198
1165
 
1199
1166
  module.exports = require("@khanacademy/wonder-blocks-clickable");
1200
1167
 
1201
1168
  /***/ }),
1202
- /* 18 */
1169
+ /* 17 */
1203
1170
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
1204
1171
 
1205
1172
  "use strict";
@@ -1214,7 +1181,7 @@ module.exports = require("@khanacademy/wonder-blocks-clickable");
1214
1181
  /* harmony import */ var _khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_color__WEBPACK_IMPORTED_MODULE_3__);
1215
1182
  /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2);
1216
1183
  /* harmony import */ var _khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_core__WEBPACK_IMPORTED_MODULE_4__);
1217
- /* harmony import */ var _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(19);
1184
+ /* harmony import */ var _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(18);
1218
1185
  /* harmony import */ var _khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_khanacademy_wonder_blocks_icon__WEBPACK_IMPORTED_MODULE_5__);
1219
1186
 
1220
1187
 
@@ -1388,13 +1355,13 @@ const _generateStyles = (checked, error) => {
1388
1355
  };
1389
1356
 
1390
1357
  /***/ }),
1391
- /* 19 */
1358
+ /* 18 */
1392
1359
  /***/ (function(module, exports) {
1393
1360
 
1394
1361
  module.exports = require("@khanacademy/wonder-blocks-icon");
1395
1362
 
1396
1363
  /***/ }),
1397
- /* 20 */
1364
+ /* 19 */
1398
1365
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
1399
1366
 
1400
1367
  "use strict";
@@ -1580,6 +1547,41 @@ const _generateStyles = (checked, error) => {
1580
1547
  return styles[styleKey];
1581
1548
  };
1582
1549
 
1550
+ /***/ }),
1551
+ /* 20 */
1552
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
1553
+
1554
+ "use strict";
1555
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Radio; });
1556
+ /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5);
1557
+ /* harmony import */ var _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0__);
1558
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
1559
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
1560
+ /* harmony import */ var _choice_internal_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11);
1561
+
1562
+
1563
+ // Keep synced with ChoiceComponentProps in ../util/types.js
1564
+
1565
+ /**
1566
+ * 🔘 A nicely styled radio button for all your non-AMFM radio button needs. Can
1567
+ * optionally take label and description props.
1568
+ *
1569
+ * This component should not really be used by itself because radio buttons are
1570
+ * often grouped together. See RadioGroup.
1571
+ */
1572
+ class Radio extends react__WEBPACK_IMPORTED_MODULE_1__["Component"] {
1573
+ render() {
1574
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_1__["createElement"](_choice_internal_js__WEBPACK_IMPORTED_MODULE_2__[/* default */ "a"], _babel_runtime_helpers_extends__WEBPACK_IMPORTED_MODULE_0___default()({
1575
+ variant: "radio"
1576
+ }, this.props));
1577
+ }
1578
+
1579
+ }
1580
+ Radio.defaultProps = {
1581
+ disabled: false,
1582
+ error: false
1583
+ };
1584
+
1583
1585
  /***/ }),
1584
1586
  /* 21 */
1585
1587
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
@@ -1625,12 +1627,12 @@ class FieldHeading extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1625
1627
  style: styles.required,
1626
1628
  "aria-hidden": true
1627
1629
  }, " ", "*");
1628
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](react__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, typeof label === "string" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["LabelMedium"], {
1630
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](react__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["LabelMedium"], {
1629
1631
  style: styles.label,
1630
1632
  tag: "label",
1631
1633
  htmlFor: id && `${id}-field`,
1632
1634
  testId: testId && `${testId}-label`
1633
- }, label, required && requiredIcon) : label, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__["Strut"], {
1635
+ }, label, required && requiredIcon), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__["Strut"], {
1634
1636
  size: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.xxxSmall_4
1635
1637
  }));
1636
1638
  }
@@ -1645,10 +1647,10 @@ class FieldHeading extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1645
1647
  return null;
1646
1648
  }
1647
1649
 
1648
- return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](react__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, typeof description === "string" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["LabelSmall"], {
1650
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](react__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["LabelSmall"], {
1649
1651
  style: styles.description,
1650
1652
  testId: testId && `${testId}-description`
1651
- }, description) : description, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__["Strut"], {
1653
+ }, description), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__["Strut"], {
1652
1654
  size: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.xxxSmall_4
1653
1655
  }));
1654
1656
  }
@@ -1666,12 +1668,12 @@ class FieldHeading extends react__WEBPACK_IMPORTED_MODULE_0__["Component"] {
1666
1668
 
1667
1669
  return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](react__WEBPACK_IMPORTED_MODULE_0__["Fragment"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_layout__WEBPACK_IMPORTED_MODULE_4__["Strut"], {
1668
1670
  size: _khanacademy_wonder_blocks_spacing__WEBPACK_IMPORTED_MODULE_5___default.a.small_12
1669
- }), typeof error === "string" ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["LabelSmall"], {
1671
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_khanacademy_wonder_blocks_typography__WEBPACK_IMPORTED_MODULE_6__["LabelSmall"], {
1670
1672
  style: styles.error,
1671
1673
  role: "alert",
1672
1674
  id: id && `${id}-error`,
1673
1675
  testId: testId && `${testId}-error`
1674
- }, error) : error);
1676
+ }, error));
1675
1677
  }
1676
1678
 
1677
1679
  render() {
@@ -1711,24 +1713,20 @@ __webpack_require__.r(__webpack_exports__);
1711
1713
  /* harmony import */ var _components_checkbox_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9);
1712
1714
  /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Checkbox", function() { return _components_checkbox_js__WEBPACK_IMPORTED_MODULE_0__["a"]; });
1713
1715
 
1714
- /* harmony import */ var _components_radio_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
1715
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Radio", function() { return _components_radio_js__WEBPACK_IMPORTED_MODULE_1__["a"]; });
1716
-
1717
- /* harmony import */ var _components_choice_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13);
1718
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Choice", function() { return _components_choice_js__WEBPACK_IMPORTED_MODULE_2__["a"]; });
1719
-
1720
- /* harmony import */ var _components_checkbox_group_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(14);
1721
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CheckboxGroup", function() { return _components_checkbox_group_js__WEBPACK_IMPORTED_MODULE_3__["a"]; });
1716
+ /* harmony import */ var _components_choice_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12);
1717
+ /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Choice", function() { return _components_choice_js__WEBPACK_IMPORTED_MODULE_1__["a"]; });
1722
1718
 
1723
- /* harmony import */ var _components_radio_group_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(15);
1724
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RadioGroup", function() { return _components_radio_group_js__WEBPACK_IMPORTED_MODULE_4__["a"]; });
1719
+ /* harmony import */ var _components_checkbox_group_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13);
1720
+ /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CheckboxGroup", function() { return _components_checkbox_group_js__WEBPACK_IMPORTED_MODULE_2__["a"]; });
1725
1721
 
1726
- /* harmony import */ var _components_text_field_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(11);
1727
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextField", function() { return _components_text_field_js__WEBPACK_IMPORTED_MODULE_5__["a"]; });
1722
+ /* harmony import */ var _components_radio_group_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(14);
1723
+ /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RadioGroup", function() { return _components_radio_group_js__WEBPACK_IMPORTED_MODULE_3__["a"]; });
1728
1724
 
1729
- /* harmony import */ var _components_labeled_text_field_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(16);
1730
- /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LabeledTextField", function() { return _components_labeled_text_field_js__WEBPACK_IMPORTED_MODULE_6__["a"]; });
1725
+ /* harmony import */ var _components_text_field_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
1726
+ /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextField", function() { return _components_text_field_js__WEBPACK_IMPORTED_MODULE_4__["a"]; });
1731
1727
 
1728
+ /* harmony import */ var _components_labeled_text_field_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(15);
1729
+ /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "LabeledTextField", function() { return _components_labeled_text_field_js__WEBPACK_IMPORTED_MODULE_5__["a"]; });
1732
1730
 
1733
1731
 
1734
1732
 
package/docs.md CHANGED
@@ -1 +1,5 @@
1
- Form components, including TextBox, Choice, and FieldSet.
1
+ Documentation for `@khanacademy/wonder-blocks-form` is now in Storybook.
2
+
3
+ Visit the [Storybook
4
+ Form](https://khan.github.io/wonder-blocks/?path=/docs/form-overview--page) docs
5
+ on GitHub Pages.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-form",
3
- "version": "2.4.8",
3
+ "version": "3.1.0",
4
4
  "design": "v1",
5
5
  "description": "Form components for Wonder Blocks.",
6
6
  "main": "dist/index.js",
@@ -19,7 +19,7 @@
19
19
  "@khanacademy/wonder-blocks-clickable": "^2.3.1",
20
20
  "@khanacademy/wonder-blocks-color": "^1.2.0",
21
21
  "@khanacademy/wonder-blocks-core": "^4.4.0",
22
- "@khanacademy/wonder-blocks-icon": "^1.2.30",
22
+ "@khanacademy/wonder-blocks-icon": "^1.2.31",
23
23
  "@khanacademy/wonder-blocks-layout": "^1.4.11",
24
24
  "@khanacademy/wonder-blocks-spacing": "^3.0.5",
25
25
  "@khanacademy/wonder-blocks-typography": "^1.1.33"
@@ -0,0 +1,15 @@
1
+ import {Meta} from "@storybook/addon-docs";
2
+
3
+ <Meta
4
+ title="Form / Overview"
5
+ parameters={{
6
+ chromatic: {
7
+ disableSnapshot: true,
8
+ },
9
+ }}
10
+ />
11
+
12
+ # Form
13
+
14
+ `wonder-blocks-form` provides building blocks form Form components, including
15
+ TextField, Choice, Checkbox, RadioButton, etc.
@@ -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: {
@@ -257,7 +292,6 @@ const styles = StyleSheet.create({
257
292
  justifyContent: "center",
258
293
  },
259
294
  description: {
260
- marginTop: 5,
261
295
  color: Color.offBlack64,
262
296
  },
263
297
  last: {
@@ -34,7 +34,7 @@ export default {
34
34
  type: {required: true},
35
35
  table: {
36
36
  type: {
37
- summary: "string | React.Element<Typography>",
37
+ summary: "React.Node",
38
38
  },
39
39
  },
40
40
  control: {
@@ -45,7 +45,7 @@ export default {
45
45
  description: "Provide a description for the TextField.",
46
46
  table: {
47
47
  type: {
48
- summary: "string | React.Element<Typography>",
48
+ summary: "React.Node",
49
49
  },
50
50
  },
51
51
  control: {
@@ -9,6 +9,7 @@ import Color from "@khanacademy/wonder-blocks-color";
9
9
  import Spacing from "@khanacademy/wonder-blocks-spacing";
10
10
  import {Strut} from "@khanacademy/wonder-blocks-layout";
11
11
  import Button from "@khanacademy/wonder-blocks-button";
12
+ import Link from "@khanacademy/wonder-blocks-link";
12
13
 
13
14
  import type {StoryComponentType} from "@storybook/react";
14
15
 
@@ -528,6 +529,30 @@ CustomStyle.parameters = {
528
529
  },
529
530
  };
530
531
 
532
+ export const WithMarkup: StoryComponentType = (args) => {
533
+ return (
534
+ <LabeledTextField
535
+ {...args}
536
+ label="Name"
537
+ description={
538
+ <span>
539
+ Description with <strong>strong</strong> text and a{" "}
540
+ <Link href="/path/to/resource">link</Link>
541
+ </span>
542
+ }
543
+ />
544
+ );
545
+ };
546
+
547
+ WithMarkup.parameters = {
548
+ docs: {
549
+ storyDescription: `\`LabeledTextField\`'s \`label\` and \`description\` props
550
+ can accept \`React.Node\`s. This is helpful when you need to decorate or use
551
+ specific elements in your form field (e.g. including Popovers, Tooltips or
552
+ emphasized text)`,
553
+ },
554
+ };
555
+
531
556
  export const Ref: StoryComponentType = () => {
532
557
  const [value, setValue] = React.useState("Khan");
533
558
  const inputRef = React.createRef();