@khanacademy/wonder-blocks-form 2.2.1

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 (38) hide show
  1. package/LICENSE +21 -0
  2. package/dist/es/index.js +1100 -0
  3. package/dist/index.js +1419 -0
  4. package/dist/index.js.flow +2 -0
  5. package/docs.md +1 -0
  6. package/package.json +35 -0
  7. package/src/__tests__/__snapshots__/custom-snapshot.test.js.snap +1349 -0
  8. package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +6126 -0
  9. package/src/__tests__/custom-snapshot.test.js +66 -0
  10. package/src/__tests__/generated-snapshot.test.js +654 -0
  11. package/src/components/__tests__/checkbox-group.test.js +84 -0
  12. package/src/components/__tests__/field-heading.test.js +182 -0
  13. package/src/components/__tests__/labeled-text-field.test.js +442 -0
  14. package/src/components/__tests__/radio-group.test.js +84 -0
  15. package/src/components/__tests__/text-field.test.js +424 -0
  16. package/src/components/checkbox-core.js +201 -0
  17. package/src/components/checkbox-group.js +161 -0
  18. package/src/components/checkbox-group.md +200 -0
  19. package/src/components/checkbox.js +94 -0
  20. package/src/components/checkbox.md +134 -0
  21. package/src/components/choice-internal.js +206 -0
  22. package/src/components/choice.js +104 -0
  23. package/src/components/field-heading.js +157 -0
  24. package/src/components/field-heading.md +43 -0
  25. package/src/components/group-styles.js +35 -0
  26. package/src/components/labeled-text-field.js +265 -0
  27. package/src/components/labeled-text-field.md +535 -0
  28. package/src/components/labeled-text-field.stories.js +359 -0
  29. package/src/components/radio-core.js +176 -0
  30. package/src/components/radio-group.js +142 -0
  31. package/src/components/radio-group.md +129 -0
  32. package/src/components/radio.js +93 -0
  33. package/src/components/radio.md +26 -0
  34. package/src/components/text-field.js +326 -0
  35. package/src/components/text-field.md +770 -0
  36. package/src/components/text-field.stories.js +513 -0
  37. package/src/index.js +18 -0
  38. package/src/util/types.js +77 -0
package/dist/index.js ADDED
@@ -0,0 +1,1419 @@
1
+ module.exports =
2
+ /******/ (function(modules) { // webpackBootstrap
3
+ /******/ // The module cache
4
+ /******/ var installedModules = {};
5
+ /******/
6
+ /******/ // The require function
7
+ /******/ function __webpack_require__(moduleId) {
8
+ /******/
9
+ /******/ // Check if module is in cache
10
+ /******/ if(installedModules[moduleId]) {
11
+ /******/ return installedModules[moduleId].exports;
12
+ /******/ }
13
+ /******/ // Create a new module (and put it into the cache)
14
+ /******/ var module = installedModules[moduleId] = {
15
+ /******/ i: moduleId,
16
+ /******/ l: false,
17
+ /******/ exports: {}
18
+ /******/ };
19
+ /******/
20
+ /******/ // Execute the module function
21
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22
+ /******/
23
+ /******/ // Flag the module as loaded
24
+ /******/ module.l = true;
25
+ /******/
26
+ /******/ // Return the exports of the module
27
+ /******/ return module.exports;
28
+ /******/ }
29
+ /******/
30
+ /******/
31
+ /******/ // expose the modules object (__webpack_modules__)
32
+ /******/ __webpack_require__.m = modules;
33
+ /******/
34
+ /******/ // expose the module cache
35
+ /******/ __webpack_require__.c = installedModules;
36
+ /******/
37
+ /******/ // define getter function for harmony exports
38
+ /******/ __webpack_require__.d = function(exports, name, getter) {
39
+ /******/ if(!__webpack_require__.o(exports, name)) {
40
+ /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41
+ /******/ }
42
+ /******/ };
43
+ /******/
44
+ /******/ // define __esModule on exports
45
+ /******/ __webpack_require__.r = function(exports) {
46
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48
+ /******/ }
49
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
50
+ /******/ };
51
+ /******/
52
+ /******/ // create a fake namespace object
53
+ /******/ // mode & 1: value is a module id, require it
54
+ /******/ // mode & 2: merge all properties of value into the ns
55
+ /******/ // mode & 4: return value when already ns object
56
+ /******/ // mode & 8|1: behave like require
57
+ /******/ __webpack_require__.t = function(value, mode) {
58
+ /******/ if(mode & 1) value = __webpack_require__(value);
59
+ /******/ if(mode & 8) return value;
60
+ /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61
+ /******/ var ns = Object.create(null);
62
+ /******/ __webpack_require__.r(ns);
63
+ /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64
+ /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65
+ /******/ return ns;
66
+ /******/ };
67
+ /******/
68
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
69
+ /******/ __webpack_require__.n = function(module) {
70
+ /******/ var getter = module && module.__esModule ?
71
+ /******/ function getDefault() { return module['default']; } :
72
+ /******/ function getModuleExports() { return module; };
73
+ /******/ __webpack_require__.d(getter, 'a', getter);
74
+ /******/ return getter;
75
+ /******/ };
76
+ /******/
77
+ /******/ // Object.prototype.hasOwnProperty.call
78
+ /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79
+ /******/
80
+ /******/ // __webpack_public_path__
81
+ /******/ __webpack_require__.p = "";
82
+ /******/
83
+ /******/
84
+ /******/ // Load entry module and return exports
85
+ /******/ return __webpack_require__(__webpack_require__.s = 11);
86
+ /******/ })
87
+ /************************************************************************/
88
+ /******/ ([
89
+ /* 0 */
90
+ /***/ (function(module, exports) {
91
+
92
+ module.exports = require("react");
93
+
94
+ /***/ }),
95
+ /* 1 */
96
+ /***/ (function(module, exports) {
97
+
98
+ module.exports = require("@khanacademy/wonder-blocks-color");
99
+
100
+ /***/ }),
101
+ /* 2 */
102
+ /***/ (function(module, exports) {
103
+
104
+ module.exports = require("@khanacademy/wonder-blocks-core");
105
+
106
+ /***/ }),
107
+ /* 3 */
108
+ /***/ (function(module, exports) {
109
+
110
+ module.exports = require("@khanacademy/wonder-blocks-spacing");
111
+
112
+ /***/ }),
113
+ /* 4 */
114
+ /***/ (function(module, exports) {
115
+
116
+ module.exports = require("@khanacademy/wonder-blocks-typography");
117
+
118
+ /***/ }),
119
+ /* 5 */
120
+ /***/ (function(module, exports) {
121
+
122
+ function _extends() {
123
+ module.exports = _extends = Object.assign || function (target) {
124
+ for (var i = 1; i < arguments.length; i++) {
125
+ var source = arguments[i];
126
+
127
+ for (var key in source) {
128
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
129
+ target[key] = source[key];
130
+ }
131
+ }
132
+ }
133
+
134
+ return target;
135
+ };
136
+
137
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
138
+ return _extends.apply(this, arguments);
139
+ }
140
+
141
+ module.exports = _extends;
142
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
143
+
144
+ /***/ }),
145
+ /* 6 */
146
+ /***/ (function(module, exports) {
147
+
148
+ module.exports = require("aphrodite");
149
+
150
+ /***/ }),
151
+ /* 7 */
152
+ /***/ (function(module, exports) {
153
+
154
+ module.exports = require("@khanacademy/wonder-blocks-layout");
155
+
156
+ /***/ }),
157
+ /* 8 */
158
+ /***/ (function(module, exports) {
159
+
160
+ function _objectWithoutPropertiesLoose(source, excluded) {
161
+ if (source == null) return {};
162
+ var target = {};
163
+ var sourceKeys = Object.keys(source);
164
+ var key, i;
165
+
166
+ for (i = 0; i < sourceKeys.length; i++) {
167
+ key = sourceKeys[i];
168
+ if (excluded.indexOf(key) >= 0) continue;
169
+ target[key] = source[key];
170
+ }
171
+
172
+ return target;
173
+ }
174
+
175
+ module.exports = _objectWithoutPropertiesLoose;
176
+ module.exports["default"] = module.exports, module.exports.__esModule = true;
177
+
178
+ /***/ }),
179
+ /* 9 */
180
+ /***/ (function(module, exports) {
181
+
182
+ module.exports = require("@khanacademy/wonder-blocks-clickable");
183
+
184
+ /***/ }),
185
+ /* 10 */
186
+ /***/ (function(module, exports) {
187
+
188
+ module.exports = require("@khanacademy/wonder-blocks-icon");
189
+
190
+ /***/ }),
191
+ /* 11 */
192
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
193
+
194
+ "use strict";
195
+ // ESM COMPAT FLAG
196
+ __webpack_require__.r(__webpack_exports__);
197
+
198
+ // EXPORTS
199
+ __webpack_require__.d(__webpack_exports__, "Checkbox", function() { return /* reexport */ checkbox_Checkbox; });
200
+ __webpack_require__.d(__webpack_exports__, "Radio", function() { return /* reexport */ radio_Radio; });
201
+ __webpack_require__.d(__webpack_exports__, "Choice", function() { return /* reexport */ choice_Choice; });
202
+ __webpack_require__.d(__webpack_exports__, "CheckboxGroup", function() { return /* reexport */ checkbox_group_CheckboxGroup; });
203
+ __webpack_require__.d(__webpack_exports__, "RadioGroup", function() { return /* reexport */ radio_group_RadioGroup; });
204
+ __webpack_require__.d(__webpack_exports__, "TextField", function() { return /* reexport */ text_field; });
205
+ __webpack_require__.d(__webpack_exports__, "LabeledTextField", function() { return /* reexport */ labeled_text_field; });
206
+
207
+ // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/extends.js
208
+ var helpers_extends = __webpack_require__(5);
209
+ var extends_default = /*#__PURE__*/__webpack_require__.n(helpers_extends);
210
+
211
+ // EXTERNAL MODULE: external "react"
212
+ var external_react_ = __webpack_require__(0);
213
+
214
+ // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js
215
+ var objectWithoutPropertiesLoose = __webpack_require__(8);
216
+ var objectWithoutPropertiesLoose_default = /*#__PURE__*/__webpack_require__.n(objectWithoutPropertiesLoose);
217
+
218
+ // EXTERNAL MODULE: external "aphrodite"
219
+ var external_aphrodite_ = __webpack_require__(6);
220
+
221
+ // EXTERNAL MODULE: external "@khanacademy/wonder-blocks-color"
222
+ var wonder_blocks_color_ = __webpack_require__(1);
223
+ var wonder_blocks_color_default = /*#__PURE__*/__webpack_require__.n(wonder_blocks_color_);
224
+
225
+ // EXTERNAL MODULE: external "@khanacademy/wonder-blocks-core"
226
+ var wonder_blocks_core_ = __webpack_require__(2);
227
+
228
+ // EXTERNAL MODULE: external "@khanacademy/wonder-blocks-clickable"
229
+ var wonder_blocks_clickable_ = __webpack_require__(9);
230
+
231
+ // EXTERNAL MODULE: external "@khanacademy/wonder-blocks-layout"
232
+ var wonder_blocks_layout_ = __webpack_require__(7);
233
+
234
+ // EXTERNAL MODULE: external "@khanacademy/wonder-blocks-spacing"
235
+ var wonder_blocks_spacing_ = __webpack_require__(3);
236
+ var wonder_blocks_spacing_default = /*#__PURE__*/__webpack_require__.n(wonder_blocks_spacing_);
237
+
238
+ // EXTERNAL MODULE: external "@khanacademy/wonder-blocks-typography"
239
+ var wonder_blocks_typography_ = __webpack_require__(4);
240
+
241
+ // EXTERNAL MODULE: external "@khanacademy/wonder-blocks-icon"
242
+ var wonder_blocks_icon_ = __webpack_require__(10);
243
+ var wonder_blocks_icon_default = /*#__PURE__*/__webpack_require__.n(wonder_blocks_icon_);
244
+
245
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/checkbox-core.js
246
+
247
+
248
+ const _excluded = ["checked", "disabled", "error", "groupName", "id", "testId", "hovered", "focused", "pressed", "waiting"];
249
+
250
+
251
+
252
+
253
+
254
+ const {
255
+ blue,
256
+ red,
257
+ white,
258
+ offWhite,
259
+ offBlack16,
260
+ offBlack32,
261
+ offBlack50
262
+ } = wonder_blocks_color_default.a;
263
+ const StyledInput = Object(wonder_blocks_core_["addStyle"])("input");
264
+ const checkboxCheck = {
265
+ small: "M11.263 4.324a1 1 0 1 1 1.474 1.352l-5.5 6a1 1 0 0 1-1.505-.036l-2.5-3a1 1 0 1 1 1.536-1.28L6.536 9.48l4.727-5.157z"
266
+ };
267
+ /**
268
+ * The internal stateless ☑️ Checkbox
269
+ */
270
+
271
+ class checkbox_core_CheckboxCore extends external_react_["Component"] {
272
+ constructor(...args) {
273
+ super(...args);
274
+
275
+ this.handleChange = () => {
276
+ // Empty because change is handled by ClickableBehavior
277
+ return;
278
+ };
279
+ }
280
+
281
+ render() {
282
+ const _this$props = this.props,
283
+ {
284
+ checked,
285
+ disabled,
286
+ error,
287
+ groupName,
288
+ id,
289
+ testId,
290
+ hovered,
291
+ focused,
292
+ pressed
293
+ } = _this$props,
294
+ sharedProps = objectWithoutPropertiesLoose_default()(_this$props, _excluded);
295
+
296
+ const stateStyles = _generateStyles(checked, error);
297
+
298
+ const defaultStyle = [sharedStyles.inputReset, sharedStyles.default, stateStyles.default, !disabled && (pressed ? stateStyles.active : (hovered || focused) && stateStyles.focus), disabled && sharedStyles.disabled];
299
+ const props = {
300
+ "data-test-id": testId
301
+ };
302
+ return /*#__PURE__*/external_react_["createElement"](external_react_["Fragment"], null, /*#__PURE__*/external_react_["createElement"](StyledInput, extends_default()({}, sharedProps, {
303
+ type: "checkbox",
304
+ "aria-invalid": error,
305
+ checked: checked,
306
+ disabled: disabled,
307
+ id: id,
308
+ name: groupName // Need to specify because this is a controlled React form
309
+ // component, but we handle the click via ClickableBehavior
310
+ ,
311
+ onChange: this.handleChange,
312
+ style: defaultStyle
313
+ }, props)), checked && /*#__PURE__*/external_react_["createElement"](wonder_blocks_icon_default.a, {
314
+ color: disabled ? offBlack32 : white,
315
+ icon: checkboxCheck,
316
+ size: "small",
317
+ style: sharedStyles.checkIcon
318
+ }));
319
+ }
320
+
321
+ }
322
+ const size = 16;
323
+ const sharedStyles = external_aphrodite_["StyleSheet"].create({
324
+ // Reset the default styled input element
325
+ inputReset: {
326
+ appearance: "none",
327
+ WebkitAppearance: "none",
328
+ MozAppearance: "none"
329
+ },
330
+ default: {
331
+ height: size,
332
+ width: size,
333
+ minHeight: size,
334
+ minWidth: size,
335
+ margin: 0,
336
+ outline: "none",
337
+ boxSizing: "border-box",
338
+ borderStyle: "solid",
339
+ borderWidth: 1,
340
+ borderRadius: 3
341
+ },
342
+ disabled: {
343
+ cursor: "auto",
344
+ backgroundColor: offWhite,
345
+ borderColor: offBlack16,
346
+ borderWidth: 1
347
+ },
348
+ checkIcon: {
349
+ position: "absolute",
350
+ pointerEvents: "none"
351
+ }
352
+ });
353
+ const fadedBlue = Object(wonder_blocks_color_["mix"])(Object(wonder_blocks_color_["fade"])(blue, 0.16), white);
354
+ const activeBlue = Object(wonder_blocks_color_["mix"])(offBlack32, blue);
355
+ const fadedRed = Object(wonder_blocks_color_["mix"])(Object(wonder_blocks_color_["fade"])(red, 0.08), white);
356
+ const activeRed = Object(wonder_blocks_color_["mix"])(offBlack32, red);
357
+ const colors = {
358
+ default: {
359
+ faded: fadedBlue,
360
+ base: blue,
361
+ active: activeBlue
362
+ },
363
+ error: {
364
+ faded: fadedRed,
365
+ base: red,
366
+ active: activeRed
367
+ }
368
+ };
369
+ const styles = {};
370
+
371
+ const _generateStyles = (checked, error) => {
372
+ // "hash" the parameters
373
+ const styleKey = `${String(checked)}-${String(error)}`;
374
+
375
+ if (styles[styleKey]) {
376
+ return styles[styleKey];
377
+ }
378
+
379
+ const palette = error ? colors.error : colors.default;
380
+ let newStyles = {};
381
+
382
+ if (checked) {
383
+ newStyles = {
384
+ default: {
385
+ backgroundColor: palette.base,
386
+ borderWidth: 0
387
+ },
388
+ focus: {
389
+ boxShadow: `0 0 0 1px ${white}, 0 0 0 3px ${palette.base}`
390
+ },
391
+ active: {
392
+ boxShadow: `0 0 0 1px ${white}, 0 0 0 3px ${palette.active}`,
393
+ background: palette.active
394
+ }
395
+ };
396
+ } else {
397
+ newStyles = {
398
+ default: {
399
+ backgroundColor: error ? fadedRed : white,
400
+ borderColor: error ? red : offBlack50
401
+ },
402
+ focus: {
403
+ backgroundColor: error ? fadedRed : white,
404
+ borderColor: palette.base,
405
+ borderWidth: 2
406
+ },
407
+ active: {
408
+ backgroundColor: palette.faded,
409
+ borderColor: error ? activeRed : blue,
410
+ borderWidth: 2
411
+ }
412
+ };
413
+ }
414
+
415
+ styles[styleKey] = external_aphrodite_["StyleSheet"].create(newStyles);
416
+ return styles[styleKey];
417
+ };
418
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/radio-core.js
419
+
420
+
421
+ const radio_core_excluded = ["checked", "disabled", "error", "groupName", "id", "testId", "hovered", "focused", "pressed", "waiting"];
422
+
423
+
424
+
425
+
426
+ const {
427
+ blue: radio_core_blue,
428
+ red: radio_core_red,
429
+ white: radio_core_white,
430
+ offWhite: radio_core_offWhite,
431
+ offBlack16: radio_core_offBlack16,
432
+ offBlack32: radio_core_offBlack32,
433
+ offBlack50: radio_core_offBlack50
434
+ } = wonder_blocks_color_default.a;
435
+ const radio_core_StyledInput = Object(wonder_blocks_core_["addStyle"])("input");
436
+ /**
437
+ * The internal stateless 🔘 Radio button
438
+ */
439
+
440
+ class radio_core_RadioCore extends external_react_["Component"] {
441
+ constructor(...args) {
442
+ super(...args);
443
+
444
+ this.handleChange = () => {
445
+ // Empty because change is handled by ClickableBehavior
446
+ return;
447
+ };
448
+ }
449
+
450
+ render() {
451
+ const _this$props = this.props,
452
+ {
453
+ checked,
454
+ disabled,
455
+ error,
456
+ groupName,
457
+ id,
458
+ testId,
459
+ hovered,
460
+ focused,
461
+ pressed
462
+ } = _this$props,
463
+ sharedProps = objectWithoutPropertiesLoose_default()(_this$props, radio_core_excluded);
464
+
465
+ const stateStyles = radio_core_generateStyles(checked, error);
466
+
467
+ const defaultStyle = [radio_core_sharedStyles.inputReset, radio_core_sharedStyles.default, stateStyles.default, !disabled && (pressed ? stateStyles.active : (hovered || focused) && stateStyles.focus), disabled && radio_core_sharedStyles.disabled];
468
+ const props = {
469
+ "data-test-id": testId
470
+ };
471
+ return /*#__PURE__*/external_react_["createElement"](external_react_["Fragment"], null, /*#__PURE__*/external_react_["createElement"](radio_core_StyledInput, extends_default()({}, sharedProps, {
472
+ type: "radio",
473
+ "aria-invalid": error,
474
+ checked: checked,
475
+ disabled: disabled,
476
+ id: id,
477
+ name: groupName // Need to specify because this is a controlled React form
478
+ // component, but we handle the click via ClickableBehavior
479
+ ,
480
+ onChange: this.handleChange,
481
+ style: defaultStyle
482
+ }, props)), disabled && checked && /*#__PURE__*/external_react_["createElement"]("span", {
483
+ style: disabledChecked
484
+ }));
485
+ }
486
+
487
+ }
488
+ const radio_core_size = 16; // circle with a different color. Here, we add that center circle. // If the checkbox is disabled and selected, it has a border but also an inner
489
+
490
+ const disabledChecked = {
491
+ position: "absolute",
492
+ top: radio_core_size / 4,
493
+ left: radio_core_size / 4,
494
+ height: radio_core_size / 2,
495
+ width: radio_core_size / 2,
496
+ borderRadius: "50%",
497
+ backgroundColor: radio_core_offBlack32
498
+ };
499
+ const radio_core_sharedStyles = external_aphrodite_["StyleSheet"].create({
500
+ // Reset the default styled input element
501
+ inputReset: {
502
+ appearance: "none",
503
+ WebkitAppearance: "none",
504
+ MozAppearance: "none"
505
+ },
506
+ default: {
507
+ height: radio_core_size,
508
+ width: radio_core_size,
509
+ minHeight: radio_core_size,
510
+ minWidth: radio_core_size,
511
+ margin: 0,
512
+ outline: "none",
513
+ boxSizing: "border-box",
514
+ borderStyle: "solid",
515
+ borderWidth: 1,
516
+ borderRadius: "50%"
517
+ },
518
+ disabled: {
519
+ cursor: "auto",
520
+ backgroundColor: radio_core_offWhite,
521
+ borderColor: radio_core_offBlack16,
522
+ borderWidth: 1
523
+ }
524
+ });
525
+ const radio_core_fadedBlue = Object(wonder_blocks_color_["mix"])(Object(wonder_blocks_color_["fade"])(radio_core_blue, 0.16), radio_core_white);
526
+ const radio_core_activeBlue = Object(wonder_blocks_color_["mix"])(radio_core_offBlack32, radio_core_blue);
527
+ const radio_core_fadedRed = Object(wonder_blocks_color_["mix"])(Object(wonder_blocks_color_["fade"])(radio_core_red, 0.08), radio_core_white);
528
+ const radio_core_activeRed = Object(wonder_blocks_color_["mix"])(radio_core_offBlack32, radio_core_red);
529
+ const radio_core_colors = {
530
+ default: {
531
+ faded: radio_core_fadedBlue,
532
+ base: radio_core_blue,
533
+ active: radio_core_activeBlue
534
+ },
535
+ error: {
536
+ faded: radio_core_fadedRed,
537
+ base: radio_core_red,
538
+ active: radio_core_activeRed
539
+ }
540
+ };
541
+ const radio_core_styles = {};
542
+
543
+ const radio_core_generateStyles = (checked, error) => {
544
+ // "hash" the parameters
545
+ const styleKey = `${String(checked)}-${String(error)}`;
546
+
547
+ if (radio_core_styles[styleKey]) {
548
+ return radio_core_styles[styleKey];
549
+ }
550
+
551
+ const palette = error ? radio_core_colors.error : radio_core_colors.default;
552
+ let newStyles = {};
553
+
554
+ if (checked) {
555
+ newStyles = {
556
+ default: {
557
+ backgroundColor: radio_core_white,
558
+ borderColor: palette.base,
559
+ borderWidth: radio_core_size / 4
560
+ },
561
+ focus: {
562
+ boxShadow: `0 0 0 1px ${radio_core_white}, 0 0 0 3px ${palette.base}`
563
+ },
564
+ active: {
565
+ boxShadow: `0 0 0 1px ${radio_core_white}, 0 0 0 3px ${palette.active}`,
566
+ borderColor: palette.active
567
+ }
568
+ };
569
+ } else {
570
+ newStyles = {
571
+ default: {
572
+ backgroundColor: error ? radio_core_fadedRed : radio_core_white,
573
+ borderColor: error ? radio_core_red : radio_core_offBlack50
574
+ },
575
+ focus: {
576
+ backgroundColor: error ? radio_core_fadedRed : radio_core_white,
577
+ borderColor: palette.base,
578
+ borderWidth: 2
579
+ },
580
+ active: {
581
+ backgroundColor: palette.faded,
582
+ borderColor: error ? radio_core_activeRed : radio_core_blue,
583
+ borderWidth: 2
584
+ }
585
+ };
586
+ }
587
+
588
+ radio_core_styles[styleKey] = external_aphrodite_["StyleSheet"].create(newStyles);
589
+ return radio_core_styles[styleKey];
590
+ };
591
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/choice-internal.js
592
+
593
+
594
+ const choice_internal_excluded = ["label", "description", "onChange", "style", "className", "variant"];
595
+
596
+
597
+
598
+
599
+
600
+
601
+
602
+
603
+
604
+
605
+
606
+ /**
607
+ * This is a potentially labeled 🔘 or ☑️ item. This is an internal component
608
+ * that's wrapped by Checkbox and Radio. Choice is a wrapper for Checkbox and
609
+ * Radio with many of its props auto-populated, to be used with CheckboxGroup
610
+ * and RadioGroup. This design allows for more explicit prop typing. For
611
+ * example, we can make onChange a required prop on Checkbox but not on Choice
612
+ * (because for Choice, that prop would be auto-populated by CheckboxGroup).
613
+ */
614
+ class choice_internal_ChoiceInternal extends external_react_["Component"] {
615
+ constructor(...args) {
616
+ super(...args);
617
+
618
+ this.handleLabelClick = event => {
619
+ // Browsers automatically use the for attribute to select the input,
620
+ // but we use ClickableBehavior to handle this.
621
+ event.preventDefault();
622
+ };
623
+
624
+ this.handleClick = () => {
625
+ const {
626
+ checked,
627
+ onChange,
628
+ variant
629
+ } = this.props; // Radio buttons cannot be unchecked
630
+
631
+ if (variant === "radio" && checked) {
632
+ return;
633
+ }
634
+
635
+ onChange(!checked);
636
+ };
637
+ }
638
+
639
+ getChoiceCoreComponent() {
640
+ if (this.props.variant === "radio") {
641
+ return radio_core_RadioCore;
642
+ } else {
643
+ return checkbox_core_CheckboxCore;
644
+ }
645
+ }
646
+
647
+ getLabel() {
648
+ const {
649
+ disabled,
650
+ id,
651
+ label
652
+ } = this.props;
653
+ return /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelMedium"], {
654
+ style: [choice_internal_styles.label, disabled && choice_internal_styles.disabledLabel]
655
+ }, /*#__PURE__*/external_react_["createElement"]("label", {
656
+ htmlFor: id,
657
+ onClick: this.handleLabelClick
658
+ }, label));
659
+ }
660
+
661
+ getDescription(id) {
662
+ const {
663
+ description
664
+ } = this.props;
665
+ return /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelSmall"], {
666
+ style: choice_internal_styles.description,
667
+ id: id
668
+ }, description);
669
+ }
670
+
671
+ render() {
672
+ const _this$props = this.props,
673
+ {
674
+ label,
675
+ description,
676
+ style,
677
+ className,
678
+ variant
679
+ } = _this$props,
680
+ coreProps = objectWithoutPropertiesLoose_default()(_this$props, choice_internal_excluded);
681
+
682
+ const ChoiceCore = this.getChoiceCoreComponent();
683
+ const ClickableBehavior = Object(wonder_blocks_clickable_["getClickableBehavior"])();
684
+ return /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["UniqueIDProvider"], {
685
+ mockOnFirstRender: true,
686
+ scope: "choice"
687
+ }, ids => {
688
+ const descriptionId = description && ids.get("description");
689
+ return /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
690
+ style: style,
691
+ className: className
692
+ }, /*#__PURE__*/external_react_["createElement"](ClickableBehavior, {
693
+ disabled: coreProps.disabled,
694
+ onClick: this.handleClick,
695
+ role: variant
696
+ }, (state, childrenProps) => {
697
+ return /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], extends_default()({
698
+ style: choice_internal_styles.wrapper
699
+ }, childrenProps, {
700
+ // We are resetting the tabIndex=0 from handlers
701
+ // because the ChoiceCore component will receive
702
+ // focus on basis of it being an input element.
703
+ tabIndex: -1
704
+ }), /*#__PURE__*/external_react_["createElement"](ChoiceCore, extends_default()({}, coreProps, state, {
705
+ "aria-describedby": descriptionId
706
+ })), /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["Strut"], {
707
+ size: wonder_blocks_spacing_default.a.xSmall_8
708
+ }), label && this.getLabel());
709
+ }), description && this.getDescription(descriptionId));
710
+ });
711
+ }
712
+
713
+ }
714
+ choice_internal_ChoiceInternal.defaultProps = {
715
+ checked: false,
716
+ disabled: false,
717
+ error: false
718
+ };
719
+ const choice_internal_styles = external_aphrodite_["StyleSheet"].create({
720
+ wrapper: {
721
+ flexDirection: "row",
722
+ alignItems: "flex-start",
723
+ outline: "none"
724
+ },
725
+ label: {
726
+ userSelect: "none",
727
+ // NOTE: The checkbox/radio button (height 16px) should be center
728
+ // aligned with the first line of the label. However, LabelMedium has a
729
+ // declared line height of 20px, so we need to adjust the top to get the
730
+ // desired alignment.
731
+ marginTop: -2
732
+ },
733
+ disabledLabel: {
734
+ color: wonder_blocks_color_default.a.offBlack32
735
+ },
736
+ description: {
737
+ // 16 for icon + 8 for spacing strut
738
+ marginLeft: wonder_blocks_spacing_default.a.medium_16 + wonder_blocks_spacing_default.a.xSmall_8,
739
+ marginTop: wonder_blocks_spacing_default.a.xxxSmall_4,
740
+ color: wonder_blocks_color_default.a.offBlack64
741
+ }
742
+ });
743
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/checkbox.js
744
+
745
+
746
+ // Keep synced with ChoiceComponentProps in ../util/types.js
747
+
748
+ /**
749
+ * ☑️ A nicely styled checkbox for all your checking needs. Can optionally take
750
+ * label and description props.
751
+ *
752
+ * If you want a whole group of Checkbox[es] that are related, see the Choice
753
+ * and CheckboxGroup components.
754
+ */
755
+ class checkbox_Checkbox extends external_react_["Component"] {
756
+ render() {
757
+ return /*#__PURE__*/external_react_["createElement"](choice_internal_ChoiceInternal, extends_default()({
758
+ variant: "checkbox"
759
+ }, this.props));
760
+ }
761
+
762
+ }
763
+ checkbox_Checkbox.defaultProps = {
764
+ disabled: false,
765
+ error: false
766
+ };
767
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/radio.js
768
+
769
+
770
+ // Keep synced with ChoiceComponentProps in ../util/types.js
771
+
772
+ /**
773
+ * 🔘 A nicely styled radio button for all your non-AMFM radio button needs. Can
774
+ * optionally take label and description props.
775
+ *
776
+ * This component should not really be used by itself because radio buttons are
777
+ * often grouped together. See RadioGroup.
778
+ */
779
+ class radio_Radio extends external_react_["Component"] {
780
+ render() {
781
+ return /*#__PURE__*/external_react_["createElement"](choice_internal_ChoiceInternal, extends_default()({
782
+ variant: "radio"
783
+ }, this.props));
784
+ }
785
+
786
+ }
787
+ radio_Radio.defaultProps = {
788
+ disabled: false,
789
+ error: false
790
+ };
791
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/choice.js
792
+
793
+ const choice_excluded = ["value", "variant"];
794
+
795
+
796
+
797
+
798
+ /**
799
+ * This is a labeled 🔘 or ☑️ item. Choice is meant to be used as children of
800
+ * CheckboxGroup and RadioGroup because many of its props are auto-populated
801
+ * and not shown in the documentation here. See those components for usage
802
+ * examples.
803
+ *
804
+ * If you wish to use just a single field, use Checkbox or Radio with the
805
+ * optional label and description props.
806
+ */
807
+ class choice_Choice extends external_react_["Component"] {
808
+ getChoiceComponent(variant) {
809
+ if (variant === "checkbox") {
810
+ return checkbox_Checkbox;
811
+ } else {
812
+ return radio_Radio;
813
+ }
814
+ }
815
+
816
+ render() {
817
+ // we don't need this going into the ChoiceComponent
818
+ // eslint-disable-next-line no-unused-vars
819
+ const _this$props = this.props,
820
+ {
821
+ variant
822
+ } = _this$props,
823
+ remainingProps = objectWithoutPropertiesLoose_default()(_this$props, choice_excluded);
824
+
825
+ const ChoiceComponent = this.getChoiceComponent(variant);
826
+ return /*#__PURE__*/external_react_["createElement"](ChoiceComponent, remainingProps);
827
+ }
828
+
829
+ }
830
+ choice_Choice.defaultProps = {
831
+ checked: false,
832
+ disabled: false,
833
+ onChange: () => {}
834
+ };
835
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/group-styles.js
836
+
837
+
838
+
839
+ const group_styles_styles = external_aphrodite_["StyleSheet"].create({
840
+ fieldset: {
841
+ border: "none",
842
+ padding: 0,
843
+ margin: 0
844
+ },
845
+ legend: {
846
+ padding: 0
847
+ },
848
+ description: {
849
+ marginTop: wonder_blocks_spacing_default.a.xxxSmall_4,
850
+ color: wonder_blocks_color_default.a.offBlack64
851
+ },
852
+ error: {
853
+ marginTop: wonder_blocks_spacing_default.a.xxxSmall_4,
854
+ color: wonder_blocks_color_default.a.red
855
+ },
856
+ defaultLineGap: {
857
+ marginTop: wonder_blocks_spacing_default.a.xSmall_8
858
+ }
859
+ });
860
+ /* harmony default export */ var group_styles = (group_styles_styles);
861
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/checkbox-group.js
862
+
863
+
864
+
865
+
866
+
867
+
868
+ const StyledFieldset = Object(wonder_blocks_core_["addStyle"])("fieldset");
869
+ const StyledLegend = Object(wonder_blocks_core_["addStyle"])("legend");
870
+ /**
871
+ * A checkbox group allows multiple selection. This component auto-populates
872
+ * many props for its children Choice components. The Choice component is
873
+ * exposed for the user to apply custom styles or to indicate which choices are
874
+ * disabled.
875
+ */
876
+
877
+ class checkbox_group_CheckboxGroup extends external_react_["Component"] {
878
+ handleChange(changedValue, originalCheckedState) {
879
+ const {
880
+ onChange,
881
+ selectedValues
882
+ } = this.props;
883
+
884
+ if (originalCheckedState) {
885
+ const index = selectedValues.indexOf(changedValue);
886
+ const updatedSelection = [].concat(selectedValues.slice(0, index), selectedValues.slice(index + 1));
887
+ onChange(updatedSelection);
888
+ } else {
889
+ onChange([].concat(selectedValues, [changedValue]));
890
+ }
891
+ }
892
+
893
+ render() {
894
+ const {
895
+ children,
896
+ label,
897
+ description,
898
+ errorMessage,
899
+ groupName,
900
+ selectedValues,
901
+ style,
902
+ testId
903
+ } = this.props;
904
+ return /*#__PURE__*/external_react_["createElement"](StyledFieldset, {
905
+ "data-test-id": testId,
906
+ style: group_styles.fieldset
907
+ }, /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
908
+ style: style
909
+ }, typeof label === "string" ? /*#__PURE__*/external_react_["createElement"](StyledLegend, {
910
+ style: group_styles.legend
911
+ }, /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelMedium"], null, label)) : label && label, typeof description === "string" ? /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelSmall"], {
912
+ style: group_styles.description
913
+ }, description) : description && description, errorMessage && /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelSmall"], {
914
+ style: group_styles.error
915
+ }, errorMessage), (label || description || errorMessage) && /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["Strut"], {
916
+ size: wonder_blocks_spacing_default.a.small_12
917
+ }), external_react_["Children"].map(children, (child, index) => {
918
+ const {
919
+ style,
920
+ value
921
+ } = child.props;
922
+ const checked = selectedValues.includes(value);
923
+ return /*#__PURE__*/external_react_["createElement"](external_react_["Fragment"], null, /*#__PURE__*/external_react_["cloneElement"](child, {
924
+ checked: checked,
925
+ error: !!errorMessage,
926
+ groupName: groupName,
927
+ id: `${groupName}-${value}`,
928
+ key: value,
929
+ onChange: () => this.handleChange(value, checked),
930
+ style: [index > 0 && group_styles.defaultLineGap, style],
931
+ variant: "checkbox"
932
+ }));
933
+ })));
934
+ }
935
+
936
+ }
937
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/radio-group.js
938
+
939
+
940
+
941
+
942
+
943
+
944
+ const radio_group_StyledFieldset = Object(wonder_blocks_core_["addStyle"])("fieldset");
945
+ const radio_group_StyledLegend = Object(wonder_blocks_core_["addStyle"])("legend");
946
+ /**
947
+ * A radio group allows only single selection. Like CheckboxGroup, this
948
+ * component auto-populates many props for its children Choice components. The
949
+ * Choice component is exposed for the user to apply custom styles or to
950
+ * indicate which choices are disabled. The use of the groupName prop is
951
+ * important to maintain expected keyboard navigation behavior for
952
+ * accessibility.
953
+ */
954
+
955
+ class radio_group_RadioGroup extends external_react_["Component"] {
956
+ handleChange(changedValue) {
957
+ this.props.onChange(changedValue);
958
+ }
959
+
960
+ render() {
961
+ const {
962
+ children,
963
+ label,
964
+ description,
965
+ errorMessage,
966
+ groupName,
967
+ selectedValue,
968
+ style,
969
+ testId
970
+ } = this.props;
971
+ return /*#__PURE__*/external_react_["createElement"](radio_group_StyledFieldset, {
972
+ "data-test-id": testId,
973
+ style: group_styles.fieldset
974
+ }, /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
975
+ style: style
976
+ }, label && /*#__PURE__*/external_react_["createElement"](radio_group_StyledLegend, {
977
+ style: group_styles.legend
978
+ }, /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelMedium"], null, label)), description && /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelSmall"], {
979
+ style: group_styles.description
980
+ }, description), errorMessage && /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelSmall"], {
981
+ style: group_styles.error
982
+ }, errorMessage), (label || description || errorMessage) && /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["Strut"], {
983
+ size: wonder_blocks_spacing_default.a.small_12
984
+ }), external_react_["Children"].map(children, (child, index) => {
985
+ const {
986
+ style,
987
+ value
988
+ } = child.props;
989
+ const checked = selectedValue === value;
990
+ return /*#__PURE__*/external_react_["createElement"](external_react_["Fragment"], null, /*#__PURE__*/external_react_["cloneElement"](child, {
991
+ checked: checked,
992
+ error: !!errorMessage,
993
+ groupName: groupName,
994
+ id: `${groupName}-${value}`,
995
+ key: value,
996
+ onChange: () => this.handleChange(value),
997
+ style: [index > 0 && group_styles.defaultLineGap, style],
998
+ variant: "radio"
999
+ }));
1000
+ })));
1001
+ }
1002
+
1003
+ }
1004
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/text-field.js
1005
+
1006
+
1007
+ const text_field_excluded = ["id", "type", "value", "disabled", "onKeyDown", "placeholder", "required", "light", "style", "testId", "readOnly", "autoComplete", "forwardedRef", "onFocus", "onBlur", "onValidate", "validate", "onChange"];
1008
+
1009
+
1010
+
1011
+
1012
+
1013
+
1014
+ // TODO(WB-1081): Change class name back to TextField after Styleguidist is gone.
1015
+
1016
+ /**
1017
+ * A TextField is an element used to accept a single line of text from the user.
1018
+ */
1019
+ class text_field_TextFieldInternal extends external_react_["Component"] {
1020
+ constructor(props) {
1021
+ super(props);
1022
+ this.state = {
1023
+ error: null,
1024
+ focused: false
1025
+ };
1026
+
1027
+ this.maybeValidate = newValue => {
1028
+ const {
1029
+ validate,
1030
+ onValidate
1031
+ } = this.props;
1032
+
1033
+ if (validate) {
1034
+ const maybeError = validate(newValue) || null;
1035
+ this.setState({
1036
+ error: maybeError
1037
+ }, () => {
1038
+ if (onValidate) {
1039
+ onValidate(maybeError);
1040
+ }
1041
+ });
1042
+ }
1043
+ };
1044
+
1045
+ this.handleChange = event => {
1046
+ const {
1047
+ onChange
1048
+ } = this.props;
1049
+ const newValue = event.target.value;
1050
+ this.maybeValidate(newValue);
1051
+ onChange(newValue);
1052
+ };
1053
+
1054
+ this.handleFocus = event => {
1055
+ const {
1056
+ onFocus
1057
+ } = this.props;
1058
+ this.setState({
1059
+ focused: true
1060
+ }, () => {
1061
+ if (onFocus) {
1062
+ onFocus(event);
1063
+ }
1064
+ });
1065
+ };
1066
+
1067
+ this.handleBlur = event => {
1068
+ const {
1069
+ onBlur
1070
+ } = this.props;
1071
+ this.setState({
1072
+ focused: false
1073
+ }, () => {
1074
+ if (onBlur) {
1075
+ onBlur(event);
1076
+ }
1077
+ });
1078
+ };
1079
+
1080
+ if (props.validate) {
1081
+ // Ensures error is updated on unmounted server-side renders
1082
+ this.state.error = props.validate(props.value) || null;
1083
+ }
1084
+ }
1085
+
1086
+ componentDidMount() {
1087
+ this.maybeValidate(this.props.value);
1088
+ }
1089
+
1090
+ render() {
1091
+ const _this$props = this.props,
1092
+ {
1093
+ id,
1094
+ type,
1095
+ value,
1096
+ disabled,
1097
+ onKeyDown,
1098
+ placeholder,
1099
+ required,
1100
+ light,
1101
+ style,
1102
+ testId,
1103
+ readOnly,
1104
+ autoComplete,
1105
+ forwardedRef
1106
+ } = _this$props,
1107
+ otherProps = objectWithoutPropertiesLoose_default()(_this$props, text_field_excluded);
1108
+
1109
+ return /*#__PURE__*/external_react_["createElement"]("input", extends_default()({
1110
+ className: Object(external_aphrodite_["css"])([text_field_styles.input, wonder_blocks_typography_["styles"].LabelMedium, text_field_styles.default, // Prioritizes disabled, then focused, then error (if any)
1111
+ disabled ? text_field_styles.disabled : this.state.focused ? [text_field_styles.focused, light && text_field_styles.defaultLight] : this.state.error && [text_field_styles.error, light && text_field_styles.errorLight], style && style]),
1112
+ id: id,
1113
+ type: type,
1114
+ placeholder: placeholder,
1115
+ value: value,
1116
+ disabled: disabled,
1117
+ onChange: this.handleChange,
1118
+ onKeyDown: onKeyDown,
1119
+ onFocus: this.handleFocus,
1120
+ onBlur: this.handleBlur,
1121
+ required: required,
1122
+ "data-test-id": testId,
1123
+ readOnly: readOnly,
1124
+ autoComplete: autoComplete,
1125
+ ref: forwardedRef
1126
+ }, otherProps));
1127
+ }
1128
+
1129
+ }
1130
+
1131
+ text_field_TextFieldInternal.defaultProps = {
1132
+ type: "text",
1133
+ disabled: false,
1134
+ light: false
1135
+ };
1136
+ const text_field_styles = external_aphrodite_["StyleSheet"].create({
1137
+ input: {
1138
+ width: "100%",
1139
+ height: 40,
1140
+ borderRadius: 4,
1141
+ boxSizing: "border-box",
1142
+ paddingLeft: wonder_blocks_spacing_default.a.medium_16,
1143
+ margin: 0,
1144
+ outline: "none",
1145
+ boxShadow: "none"
1146
+ },
1147
+ default: {
1148
+ background: wonder_blocks_color_default.a.white,
1149
+ border: `1px solid ${wonder_blocks_color_default.a.offBlack16}`,
1150
+ color: wonder_blocks_color_default.a.offBlack,
1151
+ "::placeholder": {
1152
+ color: wonder_blocks_color_default.a.offBlack64
1153
+ }
1154
+ },
1155
+ error: {
1156
+ background: `${Object(wonder_blocks_color_["mix"])(Object(wonder_blocks_color_["fade"])(wonder_blocks_color_default.a.red, 0.06), wonder_blocks_color_default.a.white)}`,
1157
+ border: `1px solid ${wonder_blocks_color_default.a.red}`,
1158
+ color: wonder_blocks_color_default.a.offBlack,
1159
+ "::placeholder": {
1160
+ color: wonder_blocks_color_default.a.offBlack64
1161
+ }
1162
+ },
1163
+ disabled: {
1164
+ background: wonder_blocks_color_default.a.offWhite,
1165
+ border: `1px solid ${wonder_blocks_color_default.a.offBlack16}`,
1166
+ color: wonder_blocks_color_default.a.offBlack64,
1167
+ "::placeholder": {
1168
+ color: wonder_blocks_color_default.a.offBlack32
1169
+ }
1170
+ },
1171
+ focused: {
1172
+ background: wonder_blocks_color_default.a.white,
1173
+ border: `1px solid ${wonder_blocks_color_default.a.blue}`,
1174
+ color: wonder_blocks_color_default.a.offBlack,
1175
+ "::placeholder": {
1176
+ color: wonder_blocks_color_default.a.offBlack64
1177
+ }
1178
+ },
1179
+ defaultLight: {
1180
+ boxShadow: `0px 0px 0px 1px ${wonder_blocks_color_default.a.blue}, 0px 0px 0px 2px ${wonder_blocks_color_default.a.white}`
1181
+ },
1182
+ errorLight: {
1183
+ boxShadow: `0px 0px 0px 1px ${wonder_blocks_color_default.a.red}, 0px 0px 0px 2px ${wonder_blocks_color_default.a.white}`
1184
+ }
1185
+ });
1186
+ const TextField = /*#__PURE__*/external_react_["forwardRef"]((props, ref) => /*#__PURE__*/external_react_["createElement"](text_field_TextFieldInternal, extends_default()({}, props, {
1187
+ forwardedRef: ref
1188
+ })));
1189
+ /* harmony default export */ var text_field = (TextField);
1190
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/field-heading.js
1191
+
1192
+
1193
+
1194
+
1195
+
1196
+
1197
+
1198
+
1199
+ /**
1200
+ * A FieldHeading is an element that provides a label, description, and error element
1201
+ * to present better context and hints to any type of form field component.
1202
+ */
1203
+ class field_heading_FieldHeading extends external_react_["Component"] {
1204
+ renderLabel() {
1205
+ const {
1206
+ label,
1207
+ id,
1208
+ testId
1209
+ } = this.props;
1210
+ return /*#__PURE__*/external_react_["createElement"](external_react_["Fragment"], null, typeof label === "string" ? /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelMedium"], {
1211
+ style: field_heading_styles.label,
1212
+ tag: "label",
1213
+ htmlFor: id && `${id}-field`,
1214
+ testId: testId && `${testId}-label`
1215
+ }, label) : label, /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["Strut"], {
1216
+ size: wonder_blocks_spacing_default.a.xxxSmall_4
1217
+ }));
1218
+ }
1219
+
1220
+ maybeRenderDescription() {
1221
+ const {
1222
+ description,
1223
+ testId
1224
+ } = this.props;
1225
+
1226
+ if (!description) {
1227
+ return null;
1228
+ }
1229
+
1230
+ return /*#__PURE__*/external_react_["createElement"](external_react_["Fragment"], null, typeof description === "string" ? /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelSmall"], {
1231
+ style: field_heading_styles.description,
1232
+ testId: testId && `${testId}-description`
1233
+ }, description) : description, /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["Strut"], {
1234
+ size: wonder_blocks_spacing_default.a.xxxSmall_4
1235
+ }));
1236
+ }
1237
+
1238
+ maybeRenderError() {
1239
+ const {
1240
+ error,
1241
+ id,
1242
+ testId
1243
+ } = this.props;
1244
+
1245
+ if (!error) {
1246
+ return null;
1247
+ }
1248
+
1249
+ return /*#__PURE__*/external_react_["createElement"](external_react_["Fragment"], null, /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["Strut"], {
1250
+ size: wonder_blocks_spacing_default.a.small_12
1251
+ }), typeof error === "string" ? /*#__PURE__*/external_react_["createElement"](wonder_blocks_typography_["LabelSmall"], {
1252
+ style: field_heading_styles.error,
1253
+ role: "alert",
1254
+ id: id && `${id}-error`,
1255
+ testId: testId && `${testId}-error`
1256
+ }, error) : error);
1257
+ }
1258
+
1259
+ render() {
1260
+ const {
1261
+ field,
1262
+ style
1263
+ } = this.props;
1264
+ return /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["View"], {
1265
+ style: style
1266
+ }, this.renderLabel(), this.maybeRenderDescription(), /*#__PURE__*/external_react_["createElement"](wonder_blocks_layout_["Strut"], {
1267
+ size: wonder_blocks_spacing_default.a.xSmall_8
1268
+ }), field, this.maybeRenderError());
1269
+ }
1270
+
1271
+ }
1272
+ const field_heading_styles = external_aphrodite_["StyleSheet"].create({
1273
+ label: {
1274
+ color: wonder_blocks_color_default.a.offBlack
1275
+ },
1276
+ description: {
1277
+ color: wonder_blocks_color_default.a.offBlack64
1278
+ },
1279
+ error: {
1280
+ color: wonder_blocks_color_default.a.red
1281
+ }
1282
+ });
1283
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/components/labeled-text-field.js
1284
+
1285
+
1286
+
1287
+
1288
+
1289
+
1290
+ // TODO(WB-1081): Change class name back to LabeledTextField after Styleguidist is gone.
1291
+
1292
+ /**
1293
+ * A LabeledTextField is an element used to accept a single line of text
1294
+ * from the user paired with a label, description, and error field elements.
1295
+ */
1296
+ class labeled_text_field_LabeledTextFieldInternal extends external_react_["Component"] {
1297
+ constructor(props) {
1298
+ super(props);
1299
+
1300
+ this.handleValidate = errorMessage => {
1301
+ const {
1302
+ onValidate
1303
+ } = this.props;
1304
+ this.setState({
1305
+ error: errorMessage
1306
+ }, () => {
1307
+ if (onValidate) {
1308
+ onValidate(errorMessage);
1309
+ }
1310
+ });
1311
+ };
1312
+
1313
+ this.handleFocus = event => {
1314
+ const {
1315
+ onFocus
1316
+ } = this.props;
1317
+ this.setState({
1318
+ focused: true
1319
+ }, () => {
1320
+ if (onFocus) {
1321
+ onFocus(event);
1322
+ }
1323
+ });
1324
+ };
1325
+
1326
+ this.handleBlur = event => {
1327
+ const {
1328
+ onBlur
1329
+ } = this.props;
1330
+ this.setState({
1331
+ focused: false
1332
+ }, () => {
1333
+ if (onBlur) {
1334
+ onBlur(event);
1335
+ }
1336
+ });
1337
+ };
1338
+
1339
+ this.state = {
1340
+ error: null,
1341
+ focused: false
1342
+ };
1343
+ }
1344
+
1345
+ render() {
1346
+ const {
1347
+ id,
1348
+ type,
1349
+ label,
1350
+ description,
1351
+ value,
1352
+ disabled,
1353
+ validate,
1354
+ onChange,
1355
+ onKeyDown,
1356
+ placeholder,
1357
+ light,
1358
+ style,
1359
+ testId,
1360
+ readOnly,
1361
+ autoComplete,
1362
+ forwardedRef
1363
+ } = this.props;
1364
+ return /*#__PURE__*/external_react_["createElement"](wonder_blocks_core_["IDProvider"], {
1365
+ id: id,
1366
+ scope: "labeled-text-field"
1367
+ }, uniqueId => /*#__PURE__*/external_react_["createElement"](field_heading_FieldHeading, {
1368
+ id: uniqueId,
1369
+ testId: testId,
1370
+ style: style,
1371
+ field: /*#__PURE__*/external_react_["createElement"](text_field, {
1372
+ id: `${uniqueId}-field`,
1373
+ "aria-describedby": `${uniqueId}-error`,
1374
+ "aria-invalid": this.state.error ? "true" : "false",
1375
+ testId: testId && `${testId}-field`,
1376
+ type: type,
1377
+ value: value,
1378
+ placeholder: placeholder,
1379
+ disabled: disabled,
1380
+ validate: validate,
1381
+ onValidate: this.handleValidate,
1382
+ onChange: onChange,
1383
+ onKeyDown: onKeyDown,
1384
+ onFocus: this.handleFocus,
1385
+ onBlur: this.handleBlur,
1386
+ light: light,
1387
+ readOnly: readOnly,
1388
+ autoComplete: autoComplete,
1389
+ ref: forwardedRef
1390
+ }),
1391
+ label: label,
1392
+ description: description,
1393
+ error: !this.state.focused && this.state.error || ""
1394
+ }));
1395
+ }
1396
+
1397
+ }
1398
+
1399
+ labeled_text_field_LabeledTextFieldInternal.defaultProps = {
1400
+ type: "text",
1401
+ disabled: false,
1402
+ light: false
1403
+ };
1404
+ const LabeledTextField = /*#__PURE__*/external_react_["forwardRef"]((props, ref) => /*#__PURE__*/external_react_["createElement"](labeled_text_field_LabeledTextFieldInternal, extends_default()({}, props, {
1405
+ forwardedRef: ref
1406
+ })));
1407
+ /* harmony default export */ var labeled_text_field = (LabeledTextField);
1408
+ // CONCATENATED MODULE: ./packages/wonder-blocks-form/src/index.js
1409
+
1410
+
1411
+
1412
+
1413
+
1414
+
1415
+
1416
+
1417
+
1418
+ /***/ })
1419
+ /******/ ]);