@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,200 +0,0 @@
|
|
|
1
|
-
This example has two items with descriptions, and it sets an error state to the
|
|
2
|
-
entire group if more than three items are selected.
|
|
3
|
-
|
|
4
|
-
Try out the keyboard navigation! Use tab and shift+tab to navigate among the
|
|
5
|
-
choices, and use space to select/de-select each option.
|
|
6
|
-
|
|
7
|
-
```js
|
|
8
|
-
import {StyleSheet} from "aphrodite";
|
|
9
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
10
|
-
import {CheckboxGroup, Choice} from "@khanacademy/wonder-blocks-form";
|
|
11
|
-
|
|
12
|
-
const styles = StyleSheet.create({
|
|
13
|
-
wrapper: {
|
|
14
|
-
width: 300,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
class CheckboxGroupPizzaExample extends React.Component {
|
|
19
|
-
constructor() {
|
|
20
|
-
super();
|
|
21
|
-
this.state = {
|
|
22
|
-
selectedValues: ["pineapple"],
|
|
23
|
-
};
|
|
24
|
-
this.handleChange = this.handleChange.bind(this);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
handleChange(change) {
|
|
28
|
-
console.log(`${change} was selected!`);
|
|
29
|
-
const error = this.checkForError(change);
|
|
30
|
-
this.setState({
|
|
31
|
-
selectedValues: change,
|
|
32
|
-
error: error,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
checkForError(input) {
|
|
37
|
-
if (input.length > 3) {
|
|
38
|
-
return "You have selected too many toppings";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
render() {
|
|
43
|
-
return <CheckboxGroup
|
|
44
|
-
label="Pizza order"
|
|
45
|
-
description="You may choose at most three toppings"
|
|
46
|
-
errorMessage={this.state.error}
|
|
47
|
-
groupName="Toppings"
|
|
48
|
-
onChange={this.handleChange}
|
|
49
|
-
selectedValues={this.state.selectedValues}
|
|
50
|
-
>
|
|
51
|
-
<Choice label="Pepperoni" value="pepperoni" />
|
|
52
|
-
<Choice label="Sausage" value="sausage" description="Imported from Italy" />
|
|
53
|
-
<Choice label="Extra cheese" value="cheese" />
|
|
54
|
-
<Choice label="Green pepper" value="pepper" />
|
|
55
|
-
<Choice label="Mushroom" value="mushroom" />
|
|
56
|
-
<Choice label="Pineapple" value="pineapple" description="Does in fact belong on pizzas" />
|
|
57
|
-
</CheckboxGroup>
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
<View style={styles.wrapper}>
|
|
61
|
-
<CheckboxGroupPizzaExample />
|
|
62
|
-
</View>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
This example shows how one can add custom styles to the checkbox group and to
|
|
66
|
-
each component to achieve desired custom layouts. This context is inspired by
|
|
67
|
-
the class selector modal. The label is created separately because we are
|
|
68
|
-
reflowing all the elements in the group to row.
|
|
69
|
-
|
|
70
|
-
```js
|
|
71
|
-
import {StyleSheet} from "aphrodite";
|
|
72
|
-
import Color from "@khanacademy/wonder-blocks-color";
|
|
73
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
74
|
-
import {CheckboxGroup, Choice} from "@khanacademy/wonder-blocks-form";
|
|
75
|
-
import {LabelLarge} from "@khanacademy/wonder-blocks-typography";
|
|
76
|
-
|
|
77
|
-
const styles = StyleSheet.create({
|
|
78
|
-
wrapper: {
|
|
79
|
-
width: 650,
|
|
80
|
-
},
|
|
81
|
-
group: {
|
|
82
|
-
flexDirection: "row",
|
|
83
|
-
flexWrap: "wrap",
|
|
84
|
-
},
|
|
85
|
-
choice: {
|
|
86
|
-
marginTop: 8,
|
|
87
|
-
width: 200,
|
|
88
|
-
},
|
|
89
|
-
title: {
|
|
90
|
-
paddingBottom: 8,
|
|
91
|
-
borderBottom: `1px solid ${Color.offBlack64}`,
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
class ClassSelectorExample extends React.Component {
|
|
96
|
-
constructor() {
|
|
97
|
-
super();
|
|
98
|
-
this.state = {
|
|
99
|
-
selectedValues: [],
|
|
100
|
-
};
|
|
101
|
-
this.handleChange = this.handleChange.bind(this);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
handleChange(change) {
|
|
105
|
-
console.log(`${change} was selected!`);
|
|
106
|
-
this.setState({
|
|
107
|
-
selectedValues: change,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
render() {
|
|
112
|
-
return <CheckboxGroup
|
|
113
|
-
groupName="science-classes"
|
|
114
|
-
onChange={this.handleChange}
|
|
115
|
-
selectedValues={this.state.selectedValues}
|
|
116
|
-
style={styles.group}
|
|
117
|
-
>
|
|
118
|
-
<Choice label="Biology" value="1" style={styles.choice} />
|
|
119
|
-
<Choice label="AP®︎ Biology" value="2" style={styles.choice} />
|
|
120
|
-
<Choice label="High school biology" value="3" style={styles.choice} />
|
|
121
|
-
<Choice label="Cosmology and astronomy" value="4" style={styles.choice} />
|
|
122
|
-
<Choice label="Electrical engineering" value="5" style={styles.choice} />
|
|
123
|
-
<Choice label="Health and medicine" value="6" style={styles.choice} />
|
|
124
|
-
</CheckboxGroup>
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
<View style={styles.wrapper}>
|
|
128
|
-
<LabelLarge style={styles.title}>Science</LabelLarge>
|
|
129
|
-
<ClassSelectorExample />
|
|
130
|
-
</View>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
This example shows how to use custom styling to change the appearance of the
|
|
134
|
-
checkbox group to look more like a multiple choice question. You may also provide
|
|
135
|
-
custom typography to the label and description.
|
|
136
|
-
|
|
137
|
-
```js
|
|
138
|
-
import {CheckboxGroup, Choice} from "@khanacademy/wonder-blocks-form";
|
|
139
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
140
|
-
import Color from "@khanacademy/wonder-blocks-color";
|
|
141
|
-
import {LabelLarge, LabelXSmall} from "@khanacademy/wonder-blocks-typography";
|
|
142
|
-
import {StyleSheet} from "aphrodite";
|
|
143
|
-
|
|
144
|
-
const styles = StyleSheet.create({
|
|
145
|
-
choice: {
|
|
146
|
-
margin: 0,
|
|
147
|
-
height: 48,
|
|
148
|
-
borderTop: "solid 1px #CCC",
|
|
149
|
-
justifyContent: "center",
|
|
150
|
-
":last-child": {
|
|
151
|
-
borderBottom: "solid 1px #CCC",
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
description: {
|
|
155
|
-
marginTop: 5,
|
|
156
|
-
color: Color.offBlack64,
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
class ClassSelectorExample extends React.Component {
|
|
161
|
-
constructor() {
|
|
162
|
-
super();
|
|
163
|
-
this.state = {
|
|
164
|
-
selectedValues: [],
|
|
165
|
-
};
|
|
166
|
-
this.handleChange = this.handleChange.bind(this);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
handleChange(change) {
|
|
170
|
-
console.log(`${change} was selected!`);
|
|
171
|
-
this.setState({
|
|
172
|
-
selectedValues: change,
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
render() {
|
|
177
|
-
return <CheckboxGroup
|
|
178
|
-
label={<LabelLarge>Select all prime numbers</LabelLarge>}
|
|
179
|
-
description={
|
|
180
|
-
<LabelXSmall style={styles.description}>
|
|
181
|
-
Hint: There is at least one prime number
|
|
182
|
-
</LabelXSmall>
|
|
183
|
-
}
|
|
184
|
-
groupName="science-classes"
|
|
185
|
-
onChange={this.handleChange}
|
|
186
|
-
selectedValues={this.state.selectedValues}
|
|
187
|
-
>
|
|
188
|
-
<Choice label="1" value="1" style={styles.choice} />
|
|
189
|
-
<Choice label="2" value="2" style={styles.choice} />
|
|
190
|
-
<Choice label="3" value="3" style={styles.choice} />
|
|
191
|
-
<Choice label="4" value="4" style={styles.choice} />
|
|
192
|
-
<Choice label="5" value="5" style={styles.choice} />
|
|
193
|
-
</CheckboxGroup>
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
<View>
|
|
198
|
-
<ClassSelectorExample />
|
|
199
|
-
</View>
|
|
200
|
-
```
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
The checkbox has various styles for clickable states. Here are sets of default checkboxes, checkboxes in an error state, and disabled checkboxes.
|
|
2
|
-
```js
|
|
3
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
4
|
-
import {Checkbox} 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 checkbox, will be checked=${checked.toString()}`);
|
|
17
|
-
|
|
18
|
-
<View style={styles.row}>
|
|
19
|
-
<Checkbox error={false} checked={false} style={styles.marginRight} onChange={handleChange} />
|
|
20
|
-
<Checkbox error={false} checked={true} style={styles.marginRight} onChange={handleChange} />
|
|
21
|
-
<Checkbox error={true} checked={false} style={styles.marginRight} onChange={handleChange} />
|
|
22
|
-
<Checkbox error={true} checked={true} style={styles.marginRight} onChange={handleChange} />
|
|
23
|
-
<Checkbox disabled={true} checked={false} style={styles.marginRight} onChange={handleChange} />
|
|
24
|
-
<Checkbox disabled={true} checked={true} style={styles.marginRight} onChange={handleChange} />
|
|
25
|
-
</View>
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
The checkbox can have a optional label and description. This allows it to be
|
|
29
|
-
used as a settings-like item. The user of this component is responsible for
|
|
30
|
-
keeping track of checked state and providing an onChange callback.
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
34
|
-
import {Checkbox} from "@khanacademy/wonder-blocks-form";
|
|
35
|
-
import {LabelMedium, LabelSmall} from "@khanacademy/wonder-blocks-typography";
|
|
36
|
-
import {StyleSheet} from "aphrodite";
|
|
37
|
-
|
|
38
|
-
class Settings extends React.Component {
|
|
39
|
-
constructor() {
|
|
40
|
-
super();
|
|
41
|
-
this.state = {
|
|
42
|
-
assignment: false,
|
|
43
|
-
};
|
|
44
|
-
this.handleChange = this.handleChange.bind(this);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
handleChange(checked) {
|
|
48
|
-
this.setState({
|
|
49
|
-
assignment: checked,
|
|
50
|
-
});
|
|
51
|
-
// Potentially do something here with this updated state information.
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
render() {
|
|
55
|
-
const handleChanged = (checked) => console.log(`clicked on checkbox with checked=${checked.toString()}`);
|
|
56
|
-
const headingText = "Functions";
|
|
57
|
-
|
|
58
|
-
return <View>
|
|
59
|
-
<Checkbox
|
|
60
|
-
label="Receive assignment reminders for Algebra"
|
|
61
|
-
description="You will receive a reminder 24 hours before each deadline"
|
|
62
|
-
checked={this.state.assignment}
|
|
63
|
-
id="assignment"
|
|
64
|
-
onChange={this.handleChange}
|
|
65
|
-
testId="algebra-assignment-test"
|
|
66
|
-
variant="checkbox"
|
|
67
|
-
/>
|
|
68
|
-
</View>;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
<Settings />
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Sometimes one may wish to use a checkbox in a different context (label may not
|
|
76
|
-
be right next to the checkbox), like in this example content item. Use a
|
|
77
|
-
`<label htmlFor={id}>` element where the id matches the `id` prop of the
|
|
78
|
-
Checkbox. This is for accessibility purposes, and doing this also automatically
|
|
79
|
-
makes the label a click target for the checkbox.
|
|
80
|
-
```js
|
|
81
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
82
|
-
import {Checkbox} from "@khanacademy/wonder-blocks-form";
|
|
83
|
-
import {LabelMedium, LabelSmall} from "@khanacademy/wonder-blocks-typography";
|
|
84
|
-
import {StyleSheet} from "aphrodite";
|
|
85
|
-
|
|
86
|
-
const styles = StyleSheet.create({
|
|
87
|
-
wrapper: {
|
|
88
|
-
flexDirection: "row",
|
|
89
|
-
alignItems: "center",
|
|
90
|
-
justifyContent: "space-evenly",
|
|
91
|
-
},
|
|
92
|
-
topic: {
|
|
93
|
-
maxWidth: 600,
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
class ContentItem extends React.Component {
|
|
98
|
-
constructor() {
|
|
99
|
-
super();
|
|
100
|
-
this.state = {
|
|
101
|
-
checked: false,
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
handleChange(checked) {
|
|
106
|
-
this.setState({
|
|
107
|
-
checked: checked,
|
|
108
|
-
});
|
|
109
|
-
// Potentially do something here with this updated state information.
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
render() {
|
|
113
|
-
const handleChanged = (checked) => console.log(`clicked on checkbox with checked=${checked.toString()}`);
|
|
114
|
-
const headingText = "Functions";
|
|
115
|
-
const descriptionText = `A great cook knows how to take basic ingredients and
|
|
116
|
-
prepare a delicious meal. In this topic, you will become function-chefs! You
|
|
117
|
-
will learn how to combine functions with arithmetic operations and how to
|
|
118
|
-
compose functions.`;
|
|
119
|
-
return <View style={styles.wrapper}>
|
|
120
|
-
<View style={styles.topic}>
|
|
121
|
-
<label htmlFor="topic-123"><LabelMedium>{headingText}</LabelMedium></label>
|
|
122
|
-
<LabelSmall>{descriptionText}</LabelSmall>
|
|
123
|
-
</View>
|
|
124
|
-
<Checkbox
|
|
125
|
-
checked={this.state.checked}
|
|
126
|
-
id="topic-123"
|
|
127
|
-
onChange={(checked) => this.handleChange(checked)}
|
|
128
|
-
/>
|
|
129
|
-
</View>;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
<ContentItem />
|
|
134
|
-
```
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
```js
|
|
2
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
3
|
-
import {TextField} from "@khanacademy/wonder-blocks-form";
|
|
4
|
-
|
|
5
|
-
class FieldHeadingExample extends React.Component {
|
|
6
|
-
constructor(props) {
|
|
7
|
-
super(props);
|
|
8
|
-
this.state = {
|
|
9
|
-
value: "",
|
|
10
|
-
};
|
|
11
|
-
this.handleKeyDown = this.handleKeyDown.bind(this);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
handleKeyDown(event) {
|
|
15
|
-
if (event.key === "Enter") {
|
|
16
|
-
event.currentTarget.blur();
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
render() {
|
|
21
|
-
return (
|
|
22
|
-
<FieldHeading
|
|
23
|
-
field={
|
|
24
|
-
<TextField
|
|
25
|
-
id="tf-1"
|
|
26
|
-
type="text"
|
|
27
|
-
value={this.state.value}
|
|
28
|
-
placeholder="Username"
|
|
29
|
-
onChange={(newValue) => this.setState({value: newValue})}
|
|
30
|
-
onKeyDown={this.handleKeyDown}
|
|
31
|
-
/>
|
|
32
|
-
}
|
|
33
|
-
label="Username"
|
|
34
|
-
description="Please enter your username."
|
|
35
|
-
error="That username is already taken."
|
|
36
|
-
/>
|
|
37
|
-
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
<FieldHeadingExample />
|
|
43
|
-
```
|