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