@khanacademy/wonder-blocks-form 3.1.11 → 3.1.13

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 (66) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/dist/components/checkbox-core.d.ts +16 -0
  3. package/dist/components/checkbox-core.js.flow +26 -0
  4. package/dist/components/checkbox-group.d.ts +84 -0
  5. package/dist/components/checkbox-group.js.flow +103 -0
  6. package/dist/components/checkbox.d.ts +83 -0
  7. package/dist/components/checkbox.js.flow +106 -0
  8. package/dist/components/choice-internal.d.ts +63 -0
  9. package/dist/components/choice-internal.js.flow +100 -0
  10. package/dist/components/choice.d.ts +127 -0
  11. package/dist/components/choice.js.flow +161 -0
  12. package/dist/components/field-heading.d.ts +50 -0
  13. package/dist/components/field-heading.js.flow +64 -0
  14. package/dist/components/group-styles.d.ts +3 -0
  15. package/dist/components/group-styles.js.flow +10 -0
  16. package/dist/components/labeled-text-field.d.ts +169 -0
  17. package/dist/components/labeled-text-field.js.flow +211 -0
  18. package/dist/components/radio-core.d.ts +15 -0
  19. package/dist/components/radio-core.js.flow +26 -0
  20. package/dist/components/radio-group.d.ts +85 -0
  21. package/dist/components/radio-group.js.flow +104 -0
  22. package/dist/components/radio.d.ts +68 -0
  23. package/dist/components/radio.js.flow +92 -0
  24. package/dist/components/text-field.d.ts +146 -0
  25. package/dist/components/text-field.js.flow +186 -0
  26. package/dist/es/index.js +258 -224
  27. package/dist/index.d.ts +7 -0
  28. package/dist/index.js +281 -249
  29. package/dist/index.js.flow +21 -2
  30. package/dist/util/types.d.ts +62 -0
  31. package/dist/util/types.js.flow +138 -0
  32. package/package.json +10 -10
  33. package/src/__tests__/{custom-snapshot.test.js → custom-snapshot.test.tsx} +8 -9
  34. package/src/components/__tests__/{checkbox-group.test.js → checkbox-group.test.tsx} +5 -5
  35. package/src/components/__tests__/{field-heading.test.js → field-heading.test.tsx} +0 -1
  36. package/src/components/__tests__/{labeled-text-field.test.js → labeled-text-field.test.tsx} +4 -5
  37. package/src/components/__tests__/{radio-group.test.js → radio-group.test.tsx} +8 -8
  38. package/src/components/__tests__/{text-field.test.js → text-field.test.tsx} +22 -18
  39. package/src/components/{checkbox-core.js → checkbox-core.tsx} +12 -15
  40. package/src/components/{checkbox-group.js → checkbox-group.tsx} +20 -23
  41. package/src/components/{checkbox.js → checkbox.tsx} +18 -32
  42. package/src/components/{choice-internal.js → choice-internal.tsx} +25 -39
  43. package/src/components/{choice.js → choice.tsx} +24 -37
  44. package/src/components/{field-heading.js → field-heading.tsx} +16 -23
  45. package/src/components/{group-styles.js → group-styles.ts} +0 -1
  46. package/src/components/{labeled-text-field.js → labeled-text-field.tsx} +54 -69
  47. package/src/components/{radio-core.js → radio-core.tsx} +13 -16
  48. package/src/components/{radio-group.js → radio-group.tsx} +20 -23
  49. package/src/components/{radio.js → radio.tsx} +18 -32
  50. package/src/components/{text-field.js → text-field.tsx} +53 -64
  51. package/src/{index.js → index.ts} +0 -1
  52. package/src/util/{types.js → types.ts} +32 -35
  53. package/tsconfig.json +19 -0
  54. package/tsconfig.tsbuildinfo +1 -0
  55. package/src/__docs__/_overview_.stories.mdx +0 -15
  56. package/src/components/__docs__/checkbox-accessibility.stories.mdx +0 -147
  57. package/src/components/__docs__/checkbox-group.stories.js +0 -300
  58. package/src/components/__docs__/checkbox.stories.js +0 -167
  59. package/src/components/__docs__/choice.stories.js +0 -86
  60. package/src/components/__docs__/labeled-text-field.argtypes.js +0 -248
  61. package/src/components/__docs__/labeled-text-field.stories.js +0 -709
  62. package/src/components/__docs__/radio-group.stories.js +0 -217
  63. package/src/components/__docs__/radio.stories.js +0 -161
  64. package/src/components/__docs__/text-field.argtypes.js +0 -206
  65. package/src/components/__docs__/text-field.stories.js +0 -780
  66. /package/src/__tests__/__snapshots__/{custom-snapshot.test.js.snap → custom-snapshot.test.tsx.snap} +0 -0
@@ -1,780 +0,0 @@
1
- // @flow
2
- import * as React from "react";
3
- import {StyleSheet} from "aphrodite";
4
-
5
- import {View, Text as _Text} from "@khanacademy/wonder-blocks-core";
6
- import Color from "@khanacademy/wonder-blocks-color";
7
- import {Strut} from "@khanacademy/wonder-blocks-layout";
8
- import Spacing from "@khanacademy/wonder-blocks-spacing";
9
- import {TextField} from "@khanacademy/wonder-blocks-form";
10
- import Button from "@khanacademy/wonder-blocks-button";
11
-
12
- import type {StoryComponentType} from "@storybook/react";
13
-
14
- import ComponentInfo from "../../../../../.storybook/components/component-info";
15
- import {name, version} from "../../../package.json";
16
- import TextFieldArgTypes from "./text-field.argtypes";
17
-
18
- export default {
19
- title: "Form / TextField",
20
- component: TextField,
21
- parameters: {
22
- componentSubtitle: ((
23
- <ComponentInfo name={name} version={version} />
24
- ): any),
25
- },
26
- argTypes: TextFieldArgTypes,
27
- };
28
-
29
- export const Default: StoryComponentType = (args) => {
30
- return <TextField {...args} />;
31
- };
32
-
33
- Default.args = {
34
- id: "some-id",
35
- type: "text",
36
- value: "",
37
- disabled: false,
38
- placeholder: "",
39
- required: false,
40
- light: false,
41
- testId: "",
42
- readOnly: false,
43
- autoComplete: "off",
44
- validate: () => {},
45
- onValidate: () => {},
46
- onChange: () => {},
47
- onKeyDown: () => {},
48
- onFocus: () => {},
49
- onBlur: () => {},
50
- };
51
-
52
- export const Text: StoryComponentType = () => {
53
- const [value, setValue] = React.useState("");
54
-
55
- const handleChange = (newValue: string) => {
56
- setValue(newValue);
57
- };
58
-
59
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
60
- if (event.key === "Enter") {
61
- event.currentTarget.blur();
62
- }
63
- };
64
-
65
- return (
66
- <TextField
67
- id="tf-1"
68
- type="text"
69
- value={value}
70
- placeholder="Text"
71
- onChange={handleChange}
72
- onKeyDown={handleKeyDown}
73
- />
74
- );
75
- };
76
-
77
- Text.parameters = {
78
- docs: {
79
- storyDescription:
80
- "An input field with type `text` takes all kinds of characters.",
81
- },
82
- };
83
-
84
- export const Required: StoryComponentType = () => {
85
- const [value, setValue] = React.useState("");
86
-
87
- const handleChange = (newValue: string) => {
88
- setValue(newValue);
89
- };
90
-
91
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
92
- if (event.key === "Enter") {
93
- event.currentTarget.blur();
94
- }
95
- };
96
-
97
- return (
98
- <TextField
99
- id="tf-2"
100
- type="text"
101
- value={value}
102
- onChange={handleChange}
103
- onKeyDown={handleKeyDown}
104
- required={true}
105
- />
106
- );
107
- };
108
-
109
- Required.parameters = {
110
- docs: {
111
- storyDescription: `A required field will have error styling if the
112
- field is left blank. To observe this, type something into the
113
- field, backspace all the way, and then shift focus out of the field.`,
114
- },
115
- chromatic: {
116
- // Disabling snapshot because it doesn't show the error style
117
- // until after the user interacts with this field.
118
- disableSnapshot: true,
119
- },
120
- };
121
-
122
- export const Number: StoryComponentType = () => {
123
- const [value, setValue] = React.useState("12345");
124
-
125
- const handleChange = (newValue: string) => {
126
- setValue(newValue);
127
- };
128
-
129
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
130
- if (event.key === "Enter") {
131
- event.currentTarget.blur();
132
- }
133
- };
134
-
135
- return (
136
- <TextField
137
- id="tf-3"
138
- type="number"
139
- value={value}
140
- placeholder="Number"
141
- onChange={handleChange}
142
- onKeyDown={handleKeyDown}
143
- />
144
- );
145
- };
146
-
147
- Number.parameters = {
148
- docs: {
149
- storyDescription:
150
- "An input field with type `number` will only take numeric characters as input.",
151
- },
152
- };
153
-
154
- export const Password: StoryComponentType = () => {
155
- const [value, setValue] = React.useState("Password123");
156
- const [errorMessage, setErrorMessage] = React.useState();
157
- const [focused, setFocused] = React.useState(false);
158
-
159
- const handleChange = (newValue: string) => {
160
- setValue(newValue);
161
- };
162
-
163
- const validate = (value: string) => {
164
- if (value.length < 8) {
165
- return "Password must be at least 8 characters long";
166
- }
167
- if (!/\d/.test(value)) {
168
- return "Password must contain a numeric value";
169
- }
170
- };
171
-
172
- const handleValidate = (errorMessage: ?string) => {
173
- setErrorMessage(errorMessage);
174
- };
175
-
176
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
177
- if (event.key === "Enter") {
178
- event.currentTarget.blur();
179
- }
180
- };
181
-
182
- const handleFocus = () => {
183
- setFocused(true);
184
- };
185
-
186
- const handleBlur = () => {
187
- setFocused(false);
188
- };
189
-
190
- return (
191
- <View>
192
- <TextField
193
- id="tf-4"
194
- type="password"
195
- value={value}
196
- placeholder="Password"
197
- validate={validate}
198
- onValidate={handleValidate}
199
- onChange={handleChange}
200
- onKeyDown={handleKeyDown}
201
- onFocus={handleFocus}
202
- onBlur={handleBlur}
203
- />
204
- {!focused && errorMessage && (
205
- <View>
206
- <Strut size={Spacing.xSmall_8} />
207
- <_Text style={styles.errorMessage}>{errorMessage}</_Text>
208
- </View>
209
- )}
210
- </View>
211
- );
212
- };
213
-
214
- Password.parameters = {
215
- docs: {
216
- storyDescription: `An input field with type \`password\` will
217
- obscure the input value. It also often contains validation.
218
- In this example, the password must be over 8 characters long and
219
- must contain a numeric value.`,
220
- },
221
- };
222
-
223
- export const Email: StoryComponentType = () => {
224
- const [value, setValue] = React.useState("khan@khanacademy.org");
225
- const [errorMessage, setErrorMessage] = React.useState();
226
- const [focused, setFocused] = React.useState(false);
227
-
228
- const handleChange = (newValue: string) => {
229
- setValue(newValue);
230
- };
231
-
232
- const validate = (value: string) => {
233
- const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/;
234
- if (!emailRegex.test(value)) {
235
- return "Please enter a valid email";
236
- }
237
- };
238
-
239
- const handleValidate = (errorMessage: ?string) => {
240
- setErrorMessage(errorMessage);
241
- };
242
-
243
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
244
- if (event.key === "Enter") {
245
- event.currentTarget.blur();
246
- }
247
- };
248
-
249
- const handleFocus = () => {
250
- setFocused(true);
251
- };
252
-
253
- const handleBlur = () => {
254
- setFocused(false);
255
- };
256
-
257
- return (
258
- <View>
259
- <TextField
260
- id="tf-5"
261
- type="email"
262
- value={value}
263
- placeholder="Email"
264
- validate={validate}
265
- onValidate={handleValidate}
266
- onChange={handleChange}
267
- onKeyDown={handleKeyDown}
268
- onFocus={handleFocus}
269
- onBlur={handleBlur}
270
- />
271
- {!focused && errorMessage && (
272
- <View>
273
- <Strut size={Spacing.xSmall_8} />
274
- <_Text style={styles.errorMessage}>{errorMessage}</_Text>
275
- </View>
276
- )}
277
- </View>
278
- );
279
- };
280
-
281
- Email.parameters = {
282
- docs: {
283
- storyDescription: `An input field with type \`email\` will automatically
284
- validate an input on submit to ensure it's either formatted properly
285
- or blank. \`TextField\` will run validation on blur if the
286
- \`validate\` prop is passed in, as in this example.`,
287
- },
288
- };
289
-
290
- export const Telephone: StoryComponentType = () => {
291
- const [value, setValue] = React.useState("123-456-7890");
292
- const [errorMessage, setErrorMessage] = React.useState();
293
- const [focused, setFocused] = React.useState(false);
294
-
295
- const handleChange = (newValue: string) => {
296
- setValue(newValue);
297
- };
298
-
299
- const validate = (value: string) => {
300
- const telRegex = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
301
- if (!telRegex.test(value)) {
302
- return "Invalid US telephone number";
303
- }
304
- };
305
-
306
- const handleValidate = (errorMessage: ?string) => {
307
- setErrorMessage(errorMessage);
308
- };
309
-
310
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
311
- if (event.key === "Enter") {
312
- event.currentTarget.blur();
313
- }
314
- };
315
-
316
- const handleFocus = () => {
317
- setFocused(true);
318
- };
319
-
320
- const handleBlur = () => {
321
- setFocused(false);
322
- };
323
-
324
- return (
325
- <View>
326
- <TextField
327
- id="tf-6"
328
- type="tel"
329
- value={value}
330
- placeholder="Telephone"
331
- validate={validate}
332
- onValidate={handleValidate}
333
- onChange={handleChange}
334
- onKeyDown={handleKeyDown}
335
- onFocus={handleFocus}
336
- onBlur={handleBlur}
337
- />
338
- {!focused && errorMessage && (
339
- <View>
340
- <Strut size={Spacing.xSmall_8} />
341
- <_Text style={styles.errorMessage}>{errorMessage}</_Text>
342
- </View>
343
- )}
344
- </View>
345
- );
346
- };
347
-
348
- Telephone.parameters = {
349
- docs: {
350
- storyDescription: `An input field with type \`tel\` will NOT
351
- validate an input on submit by default as telephone numbers
352
- can vary considerably. \`TextField\` will run validation on blur
353
- if the \`validate\` prop is passed in, as in this example.`,
354
- },
355
- };
356
-
357
- export const Error: StoryComponentType = () => {
358
- const [value, setValue] = React.useState("khan");
359
- const [errorMessage, setErrorMessage] = React.useState();
360
- const [focused, setFocused] = React.useState(false);
361
-
362
- const handleChange = (newValue: string) => {
363
- setValue(newValue);
364
- };
365
-
366
- const validate = (value: string) => {
367
- const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/;
368
- if (!emailRegex.test(value)) {
369
- return "Please enter a valid email";
370
- }
371
- };
372
-
373
- const handleValidate = (errorMessage: ?string) => {
374
- setErrorMessage(errorMessage);
375
- };
376
-
377
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
378
- if (event.key === "Enter") {
379
- event.currentTarget.blur();
380
- }
381
- };
382
-
383
- const handleFocus = () => {
384
- setFocused(true);
385
- };
386
-
387
- const handleBlur = () => {
388
- setFocused(false);
389
- };
390
-
391
- return (
392
- <View>
393
- <TextField
394
- id="tf-7"
395
- type="email"
396
- value={value}
397
- placeholder="Email"
398
- validate={validate}
399
- onValidate={handleValidate}
400
- onChange={handleChange}
401
- onKeyDown={handleKeyDown}
402
- onFocus={handleFocus}
403
- onBlur={handleBlur}
404
- />
405
- {!focused && errorMessage && (
406
- <View>
407
- <Strut size={Spacing.xSmall_8} />
408
- <_Text style={styles.errorMessage}>{errorMessage}</_Text>
409
- </View>
410
- )}
411
- </View>
412
- );
413
- };
414
-
415
- Error.parameters = {
416
- docs: {
417
- storyDescription: `If an input value fails validation,
418
- \`TextField\` will have error styling.`,
419
- },
420
- };
421
-
422
- export const Light: StoryComponentType = () => {
423
- const [value, setValue] = React.useState("khan@khanacademy.org");
424
- const [errorMessage, setErrorMessage] = React.useState();
425
- const [focused, setFocused] = React.useState(false);
426
-
427
- const handleChange = (newValue: string) => {
428
- setValue(newValue);
429
- };
430
-
431
- const validate = (value: string) => {
432
- const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/;
433
- if (!emailRegex.test(value)) {
434
- return "Please enter a valid email";
435
- }
436
- };
437
-
438
- const handleValidate = (errorMessage: ?string) => {
439
- setErrorMessage(errorMessage);
440
- };
441
-
442
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
443
- if (event.key === "Enter") {
444
- event.currentTarget.blur();
445
- }
446
- };
447
-
448
- const handleFocus = () => {
449
- setFocused(true);
450
- };
451
-
452
- const handleBlur = () => {
453
- setFocused(false);
454
- };
455
-
456
- return (
457
- <View style={styles.darkBackground}>
458
- <TextField
459
- id="tf-9"
460
- type="email"
461
- value={value}
462
- placeholder="Email"
463
- light={true}
464
- validate={validate}
465
- onValidate={handleValidate}
466
- onChange={handleChange}
467
- onKeyDown={handleKeyDown}
468
- onFocus={handleFocus}
469
- onBlur={handleBlur}
470
- />
471
- {!focused && errorMessage && (
472
- <View>
473
- <Strut size={Spacing.xSmall_8} />
474
- <_Text style={styles.errorMessageLight}>
475
- {errorMessage}
476
- </_Text>
477
- </View>
478
- )}
479
- </View>
480
- );
481
- };
482
-
483
- Light.parameters = {
484
- docs: {
485
- storyDescription: `If the \`light\` prop is set to true,
486
- \`TextField\` will have light styling. This is intended to be used
487
- on a dark background. There is also a specific light styling for the
488
- error state, as seen in the \`ErrorLight\` story.`,
489
- },
490
- };
491
-
492
- export const ErrorLight: StoryComponentType = () => {
493
- const [value, setValue] = React.useState("khan");
494
- const [errorMessage, setErrorMessage] = React.useState();
495
- const [focused, setFocused] = React.useState(false);
496
-
497
- const handleChange = (newValue: string) => {
498
- setValue(newValue);
499
- };
500
-
501
- const validate = (value: string) => {
502
- const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/;
503
- if (!emailRegex.test(value)) {
504
- return "Please enter a valid email";
505
- }
506
- };
507
-
508
- const handleValidate = (errorMessage: ?string) => {
509
- setErrorMessage(errorMessage);
510
- };
511
-
512
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
513
- if (event.key === "Enter") {
514
- event.currentTarget.blur();
515
- }
516
- };
517
-
518
- const handleFocus = () => {
519
- setFocused(true);
520
- };
521
-
522
- const handleBlur = () => {
523
- setFocused(false);
524
- };
525
-
526
- return (
527
- <View style={styles.darkBackground}>
528
- <TextField
529
- id="tf-7"
530
- type="email"
531
- value={value}
532
- placeholder="Email"
533
- light={true}
534
- validate={validate}
535
- onValidate={handleValidate}
536
- onChange={handleChange}
537
- onKeyDown={handleKeyDown}
538
- onFocus={handleFocus}
539
- onBlur={handleBlur}
540
- />
541
- {!focused && errorMessage && (
542
- <View>
543
- <Strut size={Spacing.xSmall_8} />
544
- <_Text style={styles.errorMessage}>{errorMessage}</_Text>
545
- </View>
546
- )}
547
- </View>
548
- );
549
- };
550
-
551
- ErrorLight.parameters = {
552
- docs: {
553
- storyDescription: `If an input value fails validation and the
554
- \`light\` prop is true, \`TextField\` will have light error styling.`,
555
- },
556
- };
557
-
558
- export const Disabled: StoryComponentType = () => (
559
- <TextField
560
- id="tf-8"
561
- value=""
562
- placeholder="This field is disabled."
563
- onChange={() => {}}
564
- disabled={true}
565
- />
566
- );
567
-
568
- Disabled.parameters = {
569
- docs: {
570
- storyDescription: `If the \`disabled\` prop is set to true,
571
- \`TextField\` will have disabled styling and will not be interactable.`,
572
- },
573
- };
574
-
575
- export const CustomStyle: StoryComponentType = () => {
576
- const [value, setValue] = React.useState("");
577
-
578
- const handleChange = (newValue: string) => {
579
- setValue(newValue);
580
- };
581
-
582
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
583
- if (event.key === "Enter") {
584
- event.currentTarget.blur();
585
- }
586
- };
587
-
588
- return (
589
- <TextField
590
- id="tf-10"
591
- style={styles.customField}
592
- type="text"
593
- value={value}
594
- placeholder="Text"
595
- onChange={handleChange}
596
- onKeyDown={handleKeyDown}
597
- />
598
- );
599
- };
600
-
601
- CustomStyle.parameters = {
602
- docs: {
603
- storyDescription: `\`TextField\` can take in custom styles that
604
- override the default styles. This example has custom styles for the
605
- \`backgroundColor\`, \`color\`, \`border\`, \`maxWidth\`, and
606
- placeholder \`color\` properties.`,
607
- },
608
- };
609
-
610
- export const Ref: StoryComponentType = () => {
611
- const [value, setValue] = React.useState("");
612
- const inputRef: RefObject<typeof HTMLInputElement> = React.createRef();
613
-
614
- const handleChange = (newValue: string) => {
615
- setValue(newValue);
616
- };
617
-
618
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
619
- if (event.key === "Enter") {
620
- event.currentTarget.blur();
621
- }
622
- };
623
-
624
- const handleSubmit = () => {
625
- if (inputRef.current) {
626
- inputRef.current.focus();
627
- }
628
- };
629
-
630
- return (
631
- <View>
632
- <TextField
633
- id="tf-11"
634
- type="text"
635
- value={value}
636
- placeholder="Text"
637
- onChange={handleChange}
638
- onKeyDown={handleKeyDown}
639
- ref={inputRef}
640
- />
641
- <Strut size={Spacing.medium_16} />
642
- <Button style={styles.button} onClick={handleSubmit}>
643
- Focus Input
644
- </Button>
645
- </View>
646
- );
647
- };
648
-
649
- Ref.parameters = {
650
- docs: {
651
- storyDescription: `If you need to save a reference to the input
652
- field, you can do so by using the \`ref\` prop. In this example,
653
- we want the input field to receive focus when the button is
654
- pressed. We can do this by creating a React ref of type
655
- \`HTMLInputElement\` and passing it into \`TextField\`'s \`ref\` prop.
656
- Now we can use the ref variable in the \`handleSubmit\` function to
657
- shift focus to the field.`,
658
- chromatic: {
659
- // Disabling snapshot because this is testing interaction,
660
- // not visuals.
661
- disableSnapshot: true,
662
- },
663
- },
664
- };
665
-
666
- export const ReadOnly: StoryComponentType = () => {
667
- const [value, setValue] = React.useState("Khan");
668
-
669
- const handleChange = (newValue: string) => {
670
- setValue(newValue);
671
- };
672
-
673
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
674
- if (event.key === "Enter") {
675
- event.currentTarget.blur();
676
- }
677
- };
678
-
679
- return (
680
- <TextField
681
- id="tf-12"
682
- type="text"
683
- value={value}
684
- placeholder="Text"
685
- onChange={handleChange}
686
- onKeyDown={handleKeyDown}
687
- readOnly={true}
688
- />
689
- );
690
- };
691
-
692
- ReadOnly.parameters = {
693
- docs: {
694
- storyDescription: `An input field with the prop \`readOnly\` set
695
- to true is not interactable. It looks the same as if it were not
696
- read only, and it can still receive focus, but the interaction
697
- point will not appear and the input will not change.`,
698
- chromatic: {
699
- // Disabling snapshot because this is testing interaction,
700
- // not visuals.
701
- disableSnapshot: true,
702
- },
703
- },
704
- };
705
-
706
- export const AutoComplete: StoryComponentType = () => {
707
- const [value, setValue] = React.useState("");
708
-
709
- const handleChange = (newValue: string) => {
710
- setValue(newValue);
711
- };
712
-
713
- const handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
714
- if (event.key === "Enter") {
715
- event.currentTarget.blur();
716
- }
717
- };
718
-
719
- return (
720
- <form>
721
- <TextField
722
- id="tf-13"
723
- type="text"
724
- value={value}
725
- placeholder="Name"
726
- onChange={handleChange}
727
- onKeyDown={handleKeyDown}
728
- style={styles.fieldWithButton}
729
- autoComplete="name"
730
- />
731
- <Button type="submit">Submit</Button>
732
- </form>
733
- );
734
- };
735
-
736
- AutoComplete.parameters = {
737
- docs: {
738
- storyDescription: `If \`TextField\`'s \`autocomplete\` prop is set,
739
- the browser can predict values for the input. When the user starts
740
- to type in the field, a list of options will show up based on
741
- values that may have been submitted at a previous time.
742
- In this example, the text field provides options after you
743
- input a value, press the submit button, and refresh the page.`,
744
- chromatic: {
745
- // Disabling snapshot because this is testing interaction,
746
- // not visuals.
747
- disableSnapshot: true,
748
- },
749
- },
750
- };
751
-
752
- const styles = StyleSheet.create({
753
- errorMessage: {
754
- color: Color.red,
755
- paddingLeft: Spacing.xxxSmall_4,
756
- },
757
- errorMessageLight: {
758
- color: Color.white,
759
- paddingLeft: Spacing.xxxSmall_4,
760
- },
761
- darkBackground: {
762
- backgroundColor: Color.darkBlue,
763
- padding: Spacing.medium_16,
764
- },
765
- customField: {
766
- backgroundColor: Color.darkBlue,
767
- color: Color.white,
768
- border: "none",
769
- maxWidth: 250,
770
- "::placeholder": {
771
- color: Color.white64,
772
- },
773
- },
774
- button: {
775
- maxWidth: 150,
776
- },
777
- fieldWithButton: {
778
- marginBottom: Spacing.medium_16,
779
- },
780
- });