@khanacademy/wonder-blocks-form 2.4.8 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/es/index.js +11 -11
- package/dist/index.js +71 -75
- package/docs.md +5 -1
- package/package.json +2 -2
- package/src/__docs__/_overview_.stories.mdx +15 -0
- package/src/components/__docs__/checkbox-group.stories.js +0 -1
- package/src/components/__docs__/labeled-text-field.argtypes.js +2 -2
- package/src/components/__docs__/labeled-text-field.stories.js +25 -0
- package/src/components/__docs__/radio.stories.js +3 -2
- package/src/components/__tests__/checkbox-group.test.js +118 -67
- package/src/components/__tests__/field-heading.test.js +40 -0
- package/src/components/__tests__/radio-group.test.js +131 -58
- package/src/components/checkbox-group.js +5 -13
- package/src/components/checkbox.js +2 -2
- package/src/components/choice-internal.js +5 -3
- package/src/components/choice.js +2 -2
- package/src/components/field-heading.js +27 -43
- package/src/components/labeled-text-field.js +2 -3
- package/src/components/radio-group.js +2 -2
- package/src/components/radio.js +2 -2
- package/src/index.js +0 -2
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +0 -6126
- package/src/__tests__/generated-snapshot.test.js +0 -654
- package/src/components/checkbox-group.md +0 -200
- package/src/components/checkbox.md +0 -134
- package/src/components/field-heading.md +0 -43
- package/src/components/labeled-text-field.md +0 -535
- package/src/components/radio-group.md +0 -129
- package/src/components/radio.md +0 -26
- package/src/components/text-field.md +0 -770
|
@@ -1,535 +0,0 @@
|
|
|
1
|
-
LabeledTextField derives from TextField and allows the handling of single lines of text with convenient label, description, and error messages.
|
|
2
|
-
|
|
3
|
-
Text
|
|
4
|
-
|
|
5
|
-
```js
|
|
6
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
7
|
-
|
|
8
|
-
class LabeledTextFieldExample extends React.Component {
|
|
9
|
-
constructor(props) {
|
|
10
|
-
super(props);
|
|
11
|
-
this.state = {
|
|
12
|
-
value: "Khan",
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
handleKeyDown(event) {
|
|
17
|
-
if (event.key === "Enter") {
|
|
18
|
-
event.currentTarget.blur();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
render() {
|
|
23
|
-
return (
|
|
24
|
-
<LabeledTextField
|
|
25
|
-
label="Name"
|
|
26
|
-
description="Please enter your name"
|
|
27
|
-
value={this.state.value}
|
|
28
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
29
|
-
placeholder="Name"
|
|
30
|
-
onKeyDown={this.handleKeyDown}
|
|
31
|
-
/>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
<LabeledTextFieldExample />
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Number
|
|
40
|
-
|
|
41
|
-
```js
|
|
42
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
43
|
-
|
|
44
|
-
class LabeledTextFieldExample extends React.Component {
|
|
45
|
-
constructor(props) {
|
|
46
|
-
super(props);
|
|
47
|
-
this.state = {
|
|
48
|
-
value: "18",
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
handleKeyDown(event) {
|
|
53
|
-
if (event.key === "Enter") {
|
|
54
|
-
event.currentTarget.blur();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
render() {
|
|
59
|
-
return (
|
|
60
|
-
<LabeledTextField
|
|
61
|
-
label="Age"
|
|
62
|
-
type="number"
|
|
63
|
-
description="Please enter your age"
|
|
64
|
-
value={this.state.value}
|
|
65
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
66
|
-
placeholder="Age"
|
|
67
|
-
onKeyDown={this.handleKeyDown}
|
|
68
|
-
/>
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
<LabeledTextFieldExample />
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Password
|
|
77
|
-
|
|
78
|
-
```js
|
|
79
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
80
|
-
|
|
81
|
-
class LabeledTextFieldExample extends React.Component {
|
|
82
|
-
constructor(props) {
|
|
83
|
-
super(props);
|
|
84
|
-
this.state = {
|
|
85
|
-
value: "Password123",
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
validate(value) {
|
|
90
|
-
if (value.length < 8) {
|
|
91
|
-
return "Password must be at least 8 characters long";
|
|
92
|
-
}
|
|
93
|
-
if (!/\d/.test(value)) {
|
|
94
|
-
return "Password must contain a numeric value";
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
handleKeyDown(event) {
|
|
99
|
-
if (event.key === "Enter") {
|
|
100
|
-
event.currentTarget.blur();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
render() {
|
|
105
|
-
return (
|
|
106
|
-
<LabeledTextField
|
|
107
|
-
label="Password"
|
|
108
|
-
type="password"
|
|
109
|
-
description="Please enter a secure password"
|
|
110
|
-
value={this.state.value}
|
|
111
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
112
|
-
placeholder="Password"
|
|
113
|
-
validate={this.validate}
|
|
114
|
-
onKeyDown={this.handleKeyDown}
|
|
115
|
-
/>
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
<LabeledTextFieldExample />
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Email
|
|
124
|
-
|
|
125
|
-
```js
|
|
126
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
127
|
-
|
|
128
|
-
class LabeledTextFieldExample extends React.Component {
|
|
129
|
-
constructor(props) {
|
|
130
|
-
super(props);
|
|
131
|
-
this.state = {
|
|
132
|
-
value: "khan@khan.org",
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
validate(value) {
|
|
137
|
-
const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/;
|
|
138
|
-
if (!emailRegex.test(value)) {
|
|
139
|
-
return "Please enter a valid email";
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
handleKeyDown(event) {
|
|
144
|
-
if (event.key === "Enter") {
|
|
145
|
-
event.currentTarget.blur();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
render() {
|
|
150
|
-
return (
|
|
151
|
-
<LabeledTextField
|
|
152
|
-
label="Email"
|
|
153
|
-
type="email"
|
|
154
|
-
description="Please provide your personal email"
|
|
155
|
-
value={this.state.value}
|
|
156
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
157
|
-
placeholder="Email"
|
|
158
|
-
validate={this.validate}
|
|
159
|
-
onKeyDown={this.handleKeyDown}
|
|
160
|
-
/>
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
<LabeledTextFieldExample />
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Telephone
|
|
169
|
-
|
|
170
|
-
```js
|
|
171
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
172
|
-
|
|
173
|
-
class LabeledTextFieldExample extends React.Component {
|
|
174
|
-
constructor(props) {
|
|
175
|
-
super(props);
|
|
176
|
-
this.state = {
|
|
177
|
-
value: "123-456-7890",
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
validate(value) {
|
|
182
|
-
const telRegex = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
|
|
183
|
-
if (!telRegex.test(value)) {
|
|
184
|
-
return "Invalid US telephone number";
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
handleKeyDown(event) {
|
|
189
|
-
if (event.key === "Enter") {
|
|
190
|
-
event.currentTarget.blur();
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
render() {
|
|
195
|
-
return (
|
|
196
|
-
<LabeledTextField
|
|
197
|
-
label="Telephone"
|
|
198
|
-
type="tel"
|
|
199
|
-
description="Please provide your personal phone number"
|
|
200
|
-
value={this.state.value}
|
|
201
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
202
|
-
placeholder="Telephone"
|
|
203
|
-
validate={this.validate}
|
|
204
|
-
onKeyDown={this.handleKeyDown}
|
|
205
|
-
/>
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
<LabeledTextFieldExample />
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
The field can have an error
|
|
214
|
-
|
|
215
|
-
```js
|
|
216
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
217
|
-
|
|
218
|
-
class LabeledTextFieldExample extends React.Component {
|
|
219
|
-
constructor(props) {
|
|
220
|
-
super(props);
|
|
221
|
-
this.state = {
|
|
222
|
-
value: "khan",
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
validate(value) {
|
|
227
|
-
const emailRegex = /^[^@\s]+@[^@\s.]+\.[^@.\s]+$/;
|
|
228
|
-
if (!emailRegex.test(value)) {
|
|
229
|
-
return "Please enter a valid email";
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
handleKeyDown(event) {
|
|
234
|
-
if (event.key === "Enter") {
|
|
235
|
-
event.currentTarget.blur();
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
render() {
|
|
240
|
-
return (
|
|
241
|
-
<LabeledTextField
|
|
242
|
-
label="Email"
|
|
243
|
-
type="email"
|
|
244
|
-
description="Please enter your personal email"
|
|
245
|
-
value={this.state.value}
|
|
246
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
247
|
-
placeholder="Email"
|
|
248
|
-
validate={this.validate}
|
|
249
|
-
onKeyDown={this.handleKeyDown}
|
|
250
|
-
/>
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
<LabeledTextFieldExample />
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
The field can be disabled
|
|
259
|
-
|
|
260
|
-
```js
|
|
261
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
262
|
-
|
|
263
|
-
<LabeledTextField
|
|
264
|
-
label="Name"
|
|
265
|
-
description="Please enter your name"
|
|
266
|
-
value=""
|
|
267
|
-
onChange={() => {}}
|
|
268
|
-
placeholder="Name"
|
|
269
|
-
disabled={true}
|
|
270
|
-
/>
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
The field can be in light mode to fit a dark background
|
|
274
|
-
|
|
275
|
-
```js
|
|
276
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
277
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
278
|
-
import {LabelMedium, LabelSmall} from "@khanacademy/wonder-blocks-typography";
|
|
279
|
-
import Color from "@khanacademy/wonder-blocks-color";
|
|
280
|
-
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
281
|
-
import {StyleSheet} from "aphrodite";
|
|
282
|
-
|
|
283
|
-
class LabeledTextFieldExample extends React.Component {
|
|
284
|
-
constructor(props) {
|
|
285
|
-
super(props);
|
|
286
|
-
this.state = {
|
|
287
|
-
value: "",
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
handleKeyDown(event) {
|
|
292
|
-
if (event.key === "Enter") {
|
|
293
|
-
event.currentTarget.blur();
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
render() {
|
|
298
|
-
return (
|
|
299
|
-
<View style={styles.darkBackground}>
|
|
300
|
-
<LabeledTextField
|
|
301
|
-
label={
|
|
302
|
-
<LabelMedium style={styles.whiteColor}>Name</LabelMedium>
|
|
303
|
-
}
|
|
304
|
-
description={
|
|
305
|
-
<LabelSmall style={styles.offWhiteColor}>
|
|
306
|
-
Please enter your name
|
|
307
|
-
</LabelSmall>
|
|
308
|
-
}
|
|
309
|
-
value={this.state.value}
|
|
310
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
311
|
-
placeholder="Name"
|
|
312
|
-
light={true}
|
|
313
|
-
onKeyDown={this.handleKeyDown}
|
|
314
|
-
/>
|
|
315
|
-
</View>
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const styles = StyleSheet.create({
|
|
321
|
-
darkBackground: {
|
|
322
|
-
background: Color.darkBlue,
|
|
323
|
-
padding: `${Spacing.medium_16}px`,
|
|
324
|
-
},
|
|
325
|
-
whiteColor: {
|
|
326
|
-
color: Color.white,
|
|
327
|
-
},
|
|
328
|
-
offWhiteColor: {
|
|
329
|
-
color: Color.white64,
|
|
330
|
-
},
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
<LabeledTextFieldExample />
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
The field container can have a style
|
|
337
|
-
|
|
338
|
-
```js
|
|
339
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
340
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
341
|
-
import {Strut} from "@khanacademy/wonder-blocks-layout";
|
|
342
|
-
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
343
|
-
import {StyleSheet} from "aphrodite";
|
|
344
|
-
|
|
345
|
-
class LabeledTextFieldExample extends React.Component {
|
|
346
|
-
constructor(props) {
|
|
347
|
-
super(props);
|
|
348
|
-
this.state = {
|
|
349
|
-
firstName: "",
|
|
350
|
-
lastName: "",
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
handleKeyDown(event) {
|
|
355
|
-
if (event.key === "Enter") {
|
|
356
|
-
event.currentTarget.blur();
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
render() {
|
|
361
|
-
return (
|
|
362
|
-
<View style={styles.row}>
|
|
363
|
-
<LabeledTextField
|
|
364
|
-
label="First name"
|
|
365
|
-
description="Please enter your first name"
|
|
366
|
-
placeholder="Khan"
|
|
367
|
-
value={this.state.firstName}
|
|
368
|
-
onChange={(newValue) => this.setState({firstName: newValue})}
|
|
369
|
-
placeholder="Khan"
|
|
370
|
-
style={styles.grow}
|
|
371
|
-
onKeyDown={this.handleKeyDown}
|
|
372
|
-
/>
|
|
373
|
-
<Strut size={Spacing.xLarge_32} />
|
|
374
|
-
<LabeledTextField
|
|
375
|
-
label="Last name"
|
|
376
|
-
description="Please enter your last name"
|
|
377
|
-
placeholder="Academy"
|
|
378
|
-
value={this.state.lastName}
|
|
379
|
-
onChange={(newValue) => this.setState({lastName: newValue})}
|
|
380
|
-
placeholder="Academy"
|
|
381
|
-
style={styles.grow}
|
|
382
|
-
onKeyDown={this.handleKeyDown}
|
|
383
|
-
/>
|
|
384
|
-
</View>
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const styles = StyleSheet.create({
|
|
390
|
-
row: {
|
|
391
|
-
flexDirection: "row",
|
|
392
|
-
},
|
|
393
|
-
grow: {
|
|
394
|
-
flexGrow: 1,
|
|
395
|
-
},
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
<LabeledTextFieldExample />
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
The field forwards its ref to the input
|
|
402
|
-
|
|
403
|
-
```js
|
|
404
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
405
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
406
|
-
import Button from "@khanacademy/wonder-blocks-button";
|
|
407
|
-
import {Strut} from "@khanacademy/wonder-blocks-layout";
|
|
408
|
-
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
409
|
-
import {StyleSheet} from "aphrodite";
|
|
410
|
-
|
|
411
|
-
class LabeledTextFieldExample extends React.Component {
|
|
412
|
-
constructor(props) {
|
|
413
|
-
super(props);
|
|
414
|
-
this.state = {
|
|
415
|
-
value: "Khan",
|
|
416
|
-
};
|
|
417
|
-
this.inputRef = React.createRef();
|
|
418
|
-
this.handleSubmit = this.handleSubmit.bind(this);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
handleKeyDown(event) {
|
|
422
|
-
if (event.key === "Enter") {
|
|
423
|
-
event.currentTarget.blur();
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
handleSubmit() {
|
|
428
|
-
if (this.inputRef.current) {
|
|
429
|
-
this.inputRef.current.focus();
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
render() {
|
|
434
|
-
return (
|
|
435
|
-
<View>
|
|
436
|
-
<LabeledTextField
|
|
437
|
-
label="Name"
|
|
438
|
-
description="Please enter your name"
|
|
439
|
-
value={this.state.value}
|
|
440
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
441
|
-
placeholder="Name"
|
|
442
|
-
onKeyDown={this.handleKeyDown}
|
|
443
|
-
ref={this.inputRef}
|
|
444
|
-
/>
|
|
445
|
-
<Strut size={Spacing.medium_16} />
|
|
446
|
-
<Button style={styles.button} onClick={this.handleSubmit}>
|
|
447
|
-
Focus Input
|
|
448
|
-
</Button>
|
|
449
|
-
</View>
|
|
450
|
-
);
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
const styles = StyleSheet.create({
|
|
455
|
-
button: {
|
|
456
|
-
maxWidth: 150,
|
|
457
|
-
},
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
<LabeledTextFieldExample />
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
The field can be read-only
|
|
464
|
-
|
|
465
|
-
```js
|
|
466
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
467
|
-
|
|
468
|
-
class LabeledTextFieldExample extends React.Component {
|
|
469
|
-
constructor(props) {
|
|
470
|
-
super(props);
|
|
471
|
-
this.state = {
|
|
472
|
-
value: "Khan",
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
handleKeyDown(event) {
|
|
477
|
-
if (event.key === "Enter") {
|
|
478
|
-
event.currentTarget.blur();
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
render() {
|
|
483
|
-
return (
|
|
484
|
-
<LabeledTextField
|
|
485
|
-
label="Name"
|
|
486
|
-
description="Please enter your name"
|
|
487
|
-
value={this.state.value}
|
|
488
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
489
|
-
placeholder="Name"
|
|
490
|
-
onKeyDown={this.handleKeyDown}
|
|
491
|
-
readOnly={true}
|
|
492
|
-
/>
|
|
493
|
-
);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
<LabeledTextFieldExample />
|
|
498
|
-
```
|
|
499
|
-
|
|
500
|
-
The field can have specific autocomplete
|
|
501
|
-
|
|
502
|
-
```js
|
|
503
|
-
import {LabeledTextField} from "@khanacademy/wonder-blocks-form";
|
|
504
|
-
|
|
505
|
-
class LabeledTextFieldExample extends React.Component {
|
|
506
|
-
constructor(props) {
|
|
507
|
-
super(props);
|
|
508
|
-
this.state = {
|
|
509
|
-
value: "",
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
handleKeyDown(event) {
|
|
514
|
-
if (event.key === "Enter") {
|
|
515
|
-
event.currentTarget.blur();
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
render() {
|
|
520
|
-
return (
|
|
521
|
-
<LabeledTextField
|
|
522
|
-
label="Name"
|
|
523
|
-
description="Please enter your name"
|
|
524
|
-
value={this.state.value}
|
|
525
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
526
|
-
placeholder="Name"
|
|
527
|
-
onKeyDown={this.handleKeyDown}
|
|
528
|
-
autoComplete="name"
|
|
529
|
-
/>
|
|
530
|
-
);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
<LabeledTextFieldExample />
|
|
535
|
-
```
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
This example has a disabled item. Selecting the last item results in an error
|
|
2
|
-
state for the entire group.
|
|
3
|
-
|
|
4
|
-
Try out the keyboard navigation! Use up/left and down/right to navigate among
|
|
5
|
-
the choices, and use tab to navigate between this radio group and the rest of
|
|
6
|
-
the page.
|
|
7
|
-
|
|
8
|
-
```js
|
|
9
|
-
import {Choice, RadioGroup} from "@khanacademy/wonder-blocks-form";
|
|
10
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
11
|
-
import {StyleSheet} from "aphrodite";
|
|
12
|
-
|
|
13
|
-
const styles = StyleSheet.create({
|
|
14
|
-
wrapper: {
|
|
15
|
-
width: 300,
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
class RadioGroupPokemonExample extends React.Component {
|
|
20
|
-
constructor() {
|
|
21
|
-
super();
|
|
22
|
-
this.state = {
|
|
23
|
-
selectedValue: null,
|
|
24
|
-
};
|
|
25
|
-
this.handleChange = this.handleChange.bind(this);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
handleChange(change) {
|
|
29
|
-
console.log(`${change} was selected!`);
|
|
30
|
-
const error = this.checkForError(change);
|
|
31
|
-
this.setState({
|
|
32
|
-
selectedValue: change,
|
|
33
|
-
error: error,
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
checkForError(input) {
|
|
38
|
-
if (input === "infiltrator") {
|
|
39
|
-
return "Superman isn't a Pokemon!";
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
render() {
|
|
44
|
-
return <RadioGroup
|
|
45
|
-
label="Choose a starter!"
|
|
46
|
-
description="Your first Pokemon"
|
|
47
|
-
errorMessage={this.state.error}
|
|
48
|
-
groupName="Pokemon"
|
|
49
|
-
onChange={this.handleChange}
|
|
50
|
-
selectedValue={this.state.selectedValue}
|
|
51
|
-
>
|
|
52
|
-
<Choice label="Bulbasaur" value="bulb" />
|
|
53
|
-
<Choice label="Charmander" value="char" description="Oops, we ran out of Charmanders" disabled />
|
|
54
|
-
<Choice label="Squirtle" value="squirt" />
|
|
55
|
-
<Choice label="Pikachu" value="pika" />
|
|
56
|
-
<Choice label="Superman" value="infiltrator" />
|
|
57
|
-
</RadioGroup>
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
<View style={styles.wrapper}>
|
|
61
|
-
<RadioGroupPokemonExample />
|
|
62
|
-
</View>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
This example shows how to use custom styling to change the appearance of the
|
|
66
|
-
radio group to look more like a multiple choice question.
|
|
67
|
-
|
|
68
|
-
```js
|
|
69
|
-
import {Choice, RadioGroup} from "@khanacademy/wonder-blocks-form";
|
|
70
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
71
|
-
import Color from "@khanacademy/wonder-blocks-color";
|
|
72
|
-
import {LabelLarge} from "@khanacademy/wonder-blocks-typography";
|
|
73
|
-
import {StyleSheet} from "aphrodite";
|
|
74
|
-
|
|
75
|
-
const styles = StyleSheet.create({
|
|
76
|
-
wrapper: {
|
|
77
|
-
width: 650,
|
|
78
|
-
},
|
|
79
|
-
choice: {
|
|
80
|
-
margin: 0,
|
|
81
|
-
height: 48,
|
|
82
|
-
borderTop: "solid 1px #CCC",
|
|
83
|
-
justifyContent: "center",
|
|
84
|
-
":last-child": {
|
|
85
|
-
borderBottom: "solid 1px #CCC",
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
prompt: {
|
|
89
|
-
marginBottom: 16,
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
class ClassSelectorExample extends React.Component {
|
|
94
|
-
constructor() {
|
|
95
|
-
super();
|
|
96
|
-
this.state = {
|
|
97
|
-
selectedValue: null,
|
|
98
|
-
};
|
|
99
|
-
this.handleChange = this.handleChange.bind(this);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
handleChange(change) {
|
|
103
|
-
console.log(`${change} was selected!`);
|
|
104
|
-
this.setState({
|
|
105
|
-
selectedValue: change,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
render() {
|
|
110
|
-
return <RadioGroup
|
|
111
|
-
groupName="science-classes"
|
|
112
|
-
onChange={this.handleChange}
|
|
113
|
-
selectedValue={this.state.selectedValue}
|
|
114
|
-
>
|
|
115
|
-
<Choice label="A" value="1" style={styles.choice} />
|
|
116
|
-
<Choice label="B" value="2" style={styles.choice} />
|
|
117
|
-
<Choice label="AB" value="3" style={styles.choice} />
|
|
118
|
-
<Choice label="O" value="4" style={styles.choice} />
|
|
119
|
-
</RadioGroup>
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
<View>
|
|
124
|
-
<LabelLarge style={styles.prompt}>
|
|
125
|
-
Select your blood type
|
|
126
|
-
</LabelLarge>
|
|
127
|
-
<ClassSelectorExample />
|
|
128
|
-
</View>
|
|
129
|
-
```
|
package/src/components/radio.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
The radio button has various styles for clickable states. Here are sets of default radio buttons, radio buttons in an error state, and disabled radio buttons.
|
|
2
|
-
```js
|
|
3
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
4
|
-
import {Radio} from "@khanacademy/wonder-blocks-form";
|
|
5
|
-
import {StyleSheet} from "aphrodite";
|
|
6
|
-
|
|
7
|
-
const styles = StyleSheet.create({
|
|
8
|
-
row: {
|
|
9
|
-
flexDirection: "row",
|
|
10
|
-
},
|
|
11
|
-
marginRight: {
|
|
12
|
-
marginRight: 16,
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
const handleChange = (checked) => console.log(`clicked on radio, will be checked=${checked.toString()}`);
|
|
17
|
-
|
|
18
|
-
<View style={styles.row}>
|
|
19
|
-
<Radio error={false} checked={false} style={styles.marginRight} onChange={handleChange} />
|
|
20
|
-
<Radio error={false} checked={true} style={styles.marginRight} onChange={handleChange} />
|
|
21
|
-
<Radio error={true} checked={false} style={styles.marginRight} onChange={handleChange} />
|
|
22
|
-
<Radio error={true} checked={true} style={styles.marginRight} onChange={handleChange} />
|
|
23
|
-
<Radio disabled={true} checked={false} style={styles.marginRight} onChange={handleChange} />
|
|
24
|
-
<Radio disabled={true} checked={true} style={styles.marginRight} onChange={handleChange} />
|
|
25
|
-
</View>
|
|
26
|
-
```
|