@khanacademy/perseus 0.4.3 → 1.1.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/.eslintrc.js +6 -1
- package/CHANGELOG.md +45 -0
- package/dist/es/index.css +15 -8
- package/dist/es/index.js +1214 -1404
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +15 -8
- package/dist/index.js +1217 -1411
- package/dist/index.js.map +1 -1
- package/dist/strings.js +0 -4
- package/package.json +9 -8
- package/src/components/number-input.jsx +2 -2
- package/src/components/simple-keypad-input.jsx +18 -21
- package/src/index.js +1 -1
- package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +426 -135
- package/src/multi-items/__tests__/multi-renderer_test.js +9 -9
- package/src/perseus-api.jsx +10 -36
- package/src/perseus-types.js +18 -145
- package/src/styles/constants.js +0 -2
- package/src/styles/perseus-renderer.less +8 -2
- package/src/styles/variables.less +0 -2
- package/src/styles/widgets/passage.less +9 -5
- package/src/types.js +18 -35
- package/src/util/answer-types.js +2 -3
- package/src/util/math.js +3 -10
- package/src/util.js +0 -6
- package/src/version.js +1 -1
- package/src/widgets/__stories__/numeric-input.stories.jsx +43 -2
- package/src/widgets/__testdata__/base-radio_testdata.js +22 -0
- package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +4 -4
- package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +291 -130
- package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +3293 -1415
- package/src/widgets/__tests__/group_test.jsx +4 -4
- package/src/widgets/__tests__/numeric-input_test.jsx +12 -8
- package/src/widgets/__tests__/passage_test.jsx +81 -0
- package/src/widgets/__tests__/radio/base-radio_test.jsx +291 -41
- package/src/widgets/__tests__/radio/choice-icon_test.jsx +67 -0
- package/src/widgets/__tests__/radio/choice_test.jsx +302 -0
- package/src/widgets/__tests__/radio/focus-ring_test.jsx +23 -0
- package/src/widgets/__tests__/radio/option-status_test.jsx +65 -0
- package/src/widgets/__tests__/radio_test.jsx +39 -15
- package/src/widgets/definition.jsx +1 -1
- package/src/widgets/group.jsx +84 -102
- package/src/widgets/input-number.jsx +6 -1
- package/src/widgets/numeric-input.jsx +87 -80
- package/src/widgets/passage/__tests__/passage-markdown_test.jsx +0 -9
- package/src/widgets/passage/get-line-height-for-node.js +4 -5
- package/src/widgets/passage/passage-markdown.jsx +176 -120
- package/src/widgets/passage.jsx +48 -46
- package/src/widgets/radio/__stories__/base-radio.stories.jsx +164 -17
- package/src/widgets/radio/__stories__/choice-icon.stories.jsx +202 -111
- package/src/widgets/radio/__stories__/choice-none-above.stories.jsx +21 -6
- package/src/widgets/radio/__stories__/choice.stories.jsx +138 -0
- package/src/widgets/radio/__stories__/focus-ring.stories.jsx +29 -23
- package/src/widgets/radio/__stories__/option-status.stories.jsx +93 -99
- package/src/widgets/radio/base-radio.jsx +485 -556
- package/src/widgets/radio/choice-a11y-text.js +62 -0
- package/src/widgets/radio/choice-icon/choice-icon.jsx +87 -0
- package/src/widgets/radio/choice-icon/cross-out-line.jsx +55 -0
- package/src/widgets/radio/choice-icon/library-choice-icon.jsx +214 -0
- package/src/widgets/radio/choice-icon/sat-choice-icon.jsx +120 -0
- package/src/widgets/radio/choice-icon/shared-styles.js +17 -0
- package/src/widgets/radio/choice-none-above.jsx +49 -40
- package/src/widgets/radio/choice.jsx +319 -347
- package/src/widgets/radio/choice.jsx.fixture.js +0 -18
- package/src/widgets/radio/focus-ring.jsx +29 -22
- package/src/widgets/radio/option-status.jsx +58 -36
- package/src/widgets/radio/widget.jsx +181 -136
- package/src/widgets/radio.jsx +16 -17
- package/src/widgets/radio/__stories__/cross-out-button.stories.jsx +0 -64
- package/src/widgets/radio/choice-icon.jsx +0 -469
- package/src/widgets/radio/cross-out-button.jsx +0 -134
|
@@ -1,157 +1,248 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
|
-
import ChoiceIcon from "../choice-icon.jsx";
|
|
5
|
-
|
|
6
|
-
type StoryArgs = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
import ChoiceIcon from "../choice-icon/choice-icon.jsx";
|
|
5
|
+
|
|
6
|
+
type StoryArgs = {|
|
|
7
|
+
pos: number,
|
|
8
|
+
checked: boolean,
|
|
9
|
+
crossedOut: boolean,
|
|
10
|
+
focused: boolean,
|
|
11
|
+
hovered: boolean,
|
|
12
|
+
pressed: boolean,
|
|
13
|
+
correct: boolean,
|
|
14
|
+
showCorrectness: boolean,
|
|
15
|
+
product: "sat" | "library",
|
|
16
|
+
multipleSelect: boolean,
|
|
17
|
+
reviewMode: boolean,
|
|
18
|
+
previouslyAnswered: boolean,
|
|
19
|
+
transparentBackground: boolean,
|
|
20
|
+
primaryProductColor?: string,
|
|
10
21
|
|};
|
|
11
22
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}: Story);
|
|
15
|
-
|
|
16
|
-
const defaultObject = {
|
|
17
|
-
crossedOut: false,
|
|
23
|
+
const defaultProps = {
|
|
24
|
+
pos: 0,
|
|
18
25
|
checked: false,
|
|
19
|
-
|
|
26
|
+
crossedOut: false,
|
|
27
|
+
focused: false,
|
|
28
|
+
hovered: false,
|
|
20
29
|
pressed: false,
|
|
21
|
-
|
|
30
|
+
correct: false,
|
|
31
|
+
showCorrectness: false,
|
|
22
32
|
product: "library",
|
|
23
|
-
|
|
33
|
+
multipleSelect: false,
|
|
24
34
|
reviewMode: false,
|
|
25
|
-
showCorrectness: false,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
// Note: the SAT icon is different from the general library
|
|
29
|
-
// icon displayed on KA. Therefore props like pressed,
|
|
30
|
-
// previouslyAnswered and focused do not apply here.
|
|
31
|
-
// That said, the props of the component still want them as they are
|
|
32
|
-
// currently defined, so we give them values anyway.
|
|
33
|
-
const satObject = {
|
|
34
|
-
crossedOut: false,
|
|
35
|
-
pressed: false,
|
|
36
|
-
checked: false,
|
|
37
|
-
focused: false,
|
|
38
|
-
correct: true,
|
|
39
35
|
previouslyAnswered: false,
|
|
40
|
-
|
|
41
|
-
reviewMode: false,
|
|
42
|
-
showCorrectness: false,
|
|
36
|
+
transparentBackground: false,
|
|
43
37
|
};
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
const defaultSATProps = {
|
|
40
|
+
...defaultProps,
|
|
41
|
+
product: "sat",
|
|
47
42
|
};
|
|
48
43
|
|
|
49
|
-
export
|
|
50
|
-
|
|
44
|
+
export default {
|
|
45
|
+
title: "Perseus/Widgets/Radio/Choice Icon",
|
|
46
|
+
argTypes: {
|
|
47
|
+
pos: {
|
|
48
|
+
control: {type: "number", min: 0, max: 25, step: 1},
|
|
49
|
+
},
|
|
50
|
+
product: {
|
|
51
|
+
options: ["library", "sat"],
|
|
52
|
+
control: {type: "radio"},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
args: defaultProps,
|
|
51
56
|
};
|
|
52
57
|
|
|
53
|
-
export const
|
|
54
|
-
return
|
|
55
|
-
<ChoiceIcon {...satObject} pos={2} checked={true} crossedOut={false} />
|
|
56
|
-
);
|
|
58
|
+
export const Interactive = (args: StoryArgs): React.Node => {
|
|
59
|
+
return <ChoiceIcon {...args} />;
|
|
57
60
|
};
|
|
58
61
|
|
|
59
|
-
export const
|
|
62
|
+
export const Default = (args: StoryArgs): React.Node => {
|
|
60
63
|
return (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
<>
|
|
65
|
+
<p>Library</p>
|
|
66
|
+
<ChoiceIcon {...defaultProps} />
|
|
67
|
+
<ChoiceIcon {...defaultProps} multipleSelect={true} />
|
|
68
|
+
<p>SAT</p>
|
|
69
|
+
<ChoiceIcon {...defaultSATProps} />
|
|
70
|
+
<ChoiceIcon {...defaultSATProps} multipleSelect={true} />
|
|
71
|
+
</>
|
|
68
72
|
);
|
|
69
73
|
};
|
|
70
74
|
|
|
71
|
-
export const
|
|
72
|
-
args: StoryArgs,
|
|
73
|
-
): React.Node => {
|
|
75
|
+
export const Focused = (args: StoryArgs): React.Node => {
|
|
74
76
|
return (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
<>
|
|
78
|
+
<p>Library</p>
|
|
79
|
+
<ChoiceIcon {...defaultProps} focused={true} />
|
|
80
|
+
<ChoiceIcon
|
|
81
|
+
{...defaultProps}
|
|
82
|
+
focused={true}
|
|
83
|
+
multipleSelect={true}
|
|
84
|
+
/>
|
|
85
|
+
<p>SAT</p>
|
|
86
|
+
<ChoiceIcon {...defaultSATProps} focused={true} />
|
|
87
|
+
<ChoiceIcon
|
|
88
|
+
{...defaultSATProps}
|
|
89
|
+
focused={true}
|
|
90
|
+
multipleSelect={true}
|
|
91
|
+
/>
|
|
92
|
+
</>
|
|
82
93
|
);
|
|
83
94
|
};
|
|
84
95
|
|
|
85
|
-
export const Position0 = (args: StoryArgs): React.Node => {
|
|
86
|
-
return <ChoiceIcon {...defaultObject} pos={0} reviewMode={false} />;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
export const Position1 = (args: StoryArgs): React.Node => {
|
|
90
|
-
return <ChoiceIcon {...defaultObject} pos={1} reviewMode={false} />;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export const Position2 = (args: StoryArgs): React.Node => {
|
|
94
|
-
return <ChoiceIcon {...defaultObject} pos={2} reviewMode={false} />;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
96
|
export const Checked = (args: StoryArgs): React.Node => {
|
|
98
97
|
return (
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
98
|
+
<>
|
|
99
|
+
<p>Library</p>
|
|
100
|
+
<ChoiceIcon {...defaultProps} checked={true} />
|
|
101
|
+
<ChoiceIcon
|
|
102
|
+
{...defaultProps}
|
|
103
|
+
checked={true}
|
|
104
|
+
multipleSelect={true}
|
|
105
|
+
/>
|
|
106
|
+
<p>SAT</p>
|
|
107
|
+
<ChoiceIcon {...defaultSATProps} checked={true} />
|
|
108
|
+
<ChoiceIcon
|
|
109
|
+
{...defaultSATProps}
|
|
110
|
+
checked={true}
|
|
111
|
+
multipleSelect={true}
|
|
112
|
+
/>
|
|
113
|
+
</>
|
|
105
114
|
);
|
|
106
115
|
};
|
|
107
116
|
|
|
108
|
-
export const
|
|
117
|
+
export const CrossedOut = (args: StoryArgs): React.Node => {
|
|
109
118
|
return (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
<>
|
|
120
|
+
<p>Library</p>
|
|
121
|
+
<ChoiceIcon {...defaultProps} crossedOut={true} />
|
|
122
|
+
<ChoiceIcon
|
|
123
|
+
{...defaultProps}
|
|
124
|
+
crossedOut={true}
|
|
125
|
+
multipleSelect={true}
|
|
126
|
+
/>
|
|
127
|
+
<p>SAT</p>
|
|
128
|
+
<ChoiceIcon {...defaultSATProps} crossedOut={true} />
|
|
129
|
+
<ChoiceIcon
|
|
130
|
+
{...defaultSATProps}
|
|
131
|
+
crossedOut={true}
|
|
132
|
+
multipleSelect={true}
|
|
133
|
+
/>
|
|
134
|
+
</>
|
|
117
135
|
);
|
|
118
136
|
};
|
|
119
137
|
|
|
120
|
-
export const
|
|
138
|
+
export const Correct = (args: StoryArgs): React.Node => {
|
|
121
139
|
return (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
140
|
+
<>
|
|
141
|
+
<p>Library</p>
|
|
142
|
+
<ChoiceIcon
|
|
143
|
+
{...defaultProps}
|
|
144
|
+
checked={true}
|
|
145
|
+
correct={true}
|
|
146
|
+
showCorrectness={true}
|
|
147
|
+
reviewMode={true}
|
|
148
|
+
/>
|
|
149
|
+
<ChoiceIcon
|
|
150
|
+
{...defaultProps}
|
|
151
|
+
checked={true}
|
|
152
|
+
correct={true}
|
|
153
|
+
showCorrectness={true}
|
|
154
|
+
reviewMode={true}
|
|
155
|
+
multipleSelect={true}
|
|
156
|
+
/>
|
|
157
|
+
<p>SAT</p>
|
|
158
|
+
<ChoiceIcon
|
|
159
|
+
{...defaultSATProps}
|
|
160
|
+
checked={true}
|
|
161
|
+
correct={true}
|
|
162
|
+
showCorrectness={true}
|
|
163
|
+
reviewMode={true}
|
|
164
|
+
/>
|
|
165
|
+
<ChoiceIcon
|
|
166
|
+
{...defaultSATProps}
|
|
167
|
+
checked={true}
|
|
168
|
+
correct={true}
|
|
169
|
+
showCorrectness={true}
|
|
170
|
+
reviewMode={true}
|
|
171
|
+
multipleSelect={true}
|
|
172
|
+
/>
|
|
173
|
+
</>
|
|
129
174
|
);
|
|
130
175
|
};
|
|
131
176
|
|
|
132
|
-
export const
|
|
177
|
+
export const Incorrect = (args: StoryArgs): React.Node => {
|
|
133
178
|
return (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
179
|
+
<>
|
|
180
|
+
<p>Library</p>
|
|
181
|
+
<ChoiceIcon
|
|
182
|
+
{...defaultProps}
|
|
183
|
+
checked={true}
|
|
184
|
+
correct={false}
|
|
185
|
+
showCorrectness={true}
|
|
186
|
+
reviewMode={true}
|
|
187
|
+
/>
|
|
188
|
+
<ChoiceIcon
|
|
189
|
+
{...defaultProps}
|
|
190
|
+
checked={true}
|
|
191
|
+
correct={false}
|
|
192
|
+
showCorrectness={true}
|
|
193
|
+
reviewMode={true}
|
|
194
|
+
multipleSelect={true}
|
|
195
|
+
/>
|
|
196
|
+
<p>SAT</p>
|
|
197
|
+
<ChoiceIcon
|
|
198
|
+
{...defaultSATProps}
|
|
199
|
+
checked={true}
|
|
200
|
+
correct={false}
|
|
201
|
+
showCorrectness={true}
|
|
202
|
+
reviewMode={true}
|
|
203
|
+
/>
|
|
204
|
+
<ChoiceIcon
|
|
205
|
+
{...defaultSATProps}
|
|
206
|
+
checked={true}
|
|
207
|
+
correct={false}
|
|
208
|
+
showCorrectness={true}
|
|
209
|
+
reviewMode={true}
|
|
210
|
+
multipleSelect={true}
|
|
211
|
+
/>
|
|
212
|
+
</>
|
|
141
213
|
);
|
|
142
214
|
};
|
|
143
215
|
|
|
144
|
-
export const
|
|
145
|
-
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
export const CrossedOutPressed = (args: StoryArgs): React.Node => {
|
|
216
|
+
export const AllPositions = (args: StoryArgs): React.Node => {
|
|
217
|
+
const allLetters = Array(26).fill();
|
|
149
218
|
return (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
219
|
+
<>
|
|
220
|
+
<p>Library</p>
|
|
221
|
+
{allLetters.map((_, i: number) => (
|
|
222
|
+
<ChoiceIcon {...defaultProps} pos={i} key={"choice" + i} />
|
|
223
|
+
))}
|
|
224
|
+
<br />
|
|
225
|
+
{allLetters.map((_, i: number) => (
|
|
226
|
+
<ChoiceIcon
|
|
227
|
+
{...defaultProps}
|
|
228
|
+
pos={i}
|
|
229
|
+
multipleSelect={true}
|
|
230
|
+
key={"choice" + i}
|
|
231
|
+
/>
|
|
232
|
+
))}
|
|
233
|
+
<p>SAT</p>
|
|
234
|
+
{allLetters.map((_, i: number) => (
|
|
235
|
+
<ChoiceIcon {...defaultSATProps} pos={i} key={"choice" + i} />
|
|
236
|
+
))}
|
|
237
|
+
<br />
|
|
238
|
+
{allLetters.map((_, i: number) => (
|
|
239
|
+
<ChoiceIcon
|
|
240
|
+
{...defaultSATProps}
|
|
241
|
+
pos={i}
|
|
242
|
+
multipleSelect={true}
|
|
243
|
+
key={"choice" + i}
|
|
244
|
+
/>
|
|
245
|
+
))}
|
|
246
|
+
</>
|
|
156
247
|
);
|
|
157
248
|
};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// @flow
|
|
2
|
+
import {action} from "@storybook/addon-actions";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
|
|
4
5
|
import ChoiceNoneAbove from "../choice-none-above.jsx";
|
|
5
6
|
|
|
6
7
|
type StoryArgs = {|
|
|
7
|
-
// Eventually this?
|
|
8
|
-
// ...React.ElementConfig<ChoiceNoneAbove>,
|
|
9
|
-
className: string,
|
|
10
8
|
content: React.Node,
|
|
11
9
|
showContent?: boolean,
|
|
12
10
|
|};
|
|
@@ -17,10 +15,27 @@ type ChoiceNoneAboveStory = {|
|
|
|
17
15
|
|};
|
|
18
16
|
|
|
19
17
|
export default ({
|
|
20
|
-
title: "Perseus/Widgets/Radio/None of the Above",
|
|
21
|
-
args: {
|
|
18
|
+
title: "Perseus/Widgets/Radio/Choice None of the Above",
|
|
19
|
+
args: {showContent: false, content: "This is a possible choice"},
|
|
22
20
|
}: ChoiceNoneAboveStory);
|
|
23
21
|
|
|
22
|
+
const ChoiceDefaults = {
|
|
23
|
+
checked: false,
|
|
24
|
+
rationale: "This is a good rational",
|
|
25
|
+
correct: true,
|
|
26
|
+
disabled: false,
|
|
27
|
+
pos: 0,
|
|
28
|
+
reviewMode: false,
|
|
29
|
+
showRationale: false,
|
|
30
|
+
showCorrectness: false,
|
|
31
|
+
multipleSelect: false,
|
|
32
|
+
crossedOut: false,
|
|
33
|
+
previouslyAnswered: false,
|
|
34
|
+
apiOptions: {},
|
|
35
|
+
onChange: action("changed"),
|
|
36
|
+
};
|
|
37
|
+
|
|
24
38
|
export const Example = (args: StoryArgs): React.Node => {
|
|
25
|
-
|
|
39
|
+
const combineProps = {...ChoiceDefaults, ...args};
|
|
40
|
+
return <ChoiceNoneAbove {...combineProps} />;
|
|
26
41
|
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import {action} from "@storybook/addon-actions";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import Choice from "../choice.jsx";
|
|
6
|
+
|
|
7
|
+
type StoryArgs = {|
|
|
8
|
+
checked: boolean,
|
|
9
|
+
rationale: React.Node,
|
|
10
|
+
content: React.Node,
|
|
11
|
+
correct: boolean,
|
|
12
|
+
disabled: boolean,
|
|
13
|
+
pos: number,
|
|
14
|
+
reviewMode: boolean,
|
|
15
|
+
showRationale: boolean,
|
|
16
|
+
showCorrectness: boolean,
|
|
17
|
+
multipleSelect: boolean,
|
|
18
|
+
crossedOut: boolean,
|
|
19
|
+
previouslyAnswered: boolean,
|
|
20
|
+
onChange: (newValues: {checked: boolean, crossedOut: boolean}) => void,
|
|
21
|
+
|};
|
|
22
|
+
|
|
23
|
+
type Story = {|
|
|
24
|
+
title: string,
|
|
25
|
+
args: StoryArgs,
|
|
26
|
+
|};
|
|
27
|
+
|
|
28
|
+
const defaultProps = {
|
|
29
|
+
checked: false,
|
|
30
|
+
rationale: "This is a good rationale",
|
|
31
|
+
content: "This is a possible choice",
|
|
32
|
+
correct: true,
|
|
33
|
+
disabled: false,
|
|
34
|
+
pos: 0,
|
|
35
|
+
reviewMode: false,
|
|
36
|
+
showRationale: false,
|
|
37
|
+
showCorrectness: false,
|
|
38
|
+
multipleSelect: false,
|
|
39
|
+
crossedOut: false,
|
|
40
|
+
previouslyAnswered: false,
|
|
41
|
+
onChange: action("changed"),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default ({
|
|
45
|
+
title: "Perseus/Widgets/Radio/Choice",
|
|
46
|
+
args: defaultProps,
|
|
47
|
+
}: Story);
|
|
48
|
+
|
|
49
|
+
export const Interactive = (args: StoryArgs): React.Node => {
|
|
50
|
+
return <Choice {...args} />;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const Checked = (args: StoryArgs): React.Node => {
|
|
54
|
+
const sharedProps = {
|
|
55
|
+
...defaultProps,
|
|
56
|
+
checked: true,
|
|
57
|
+
showCorrectness: true,
|
|
58
|
+
};
|
|
59
|
+
const correctProps = {
|
|
60
|
+
...sharedProps,
|
|
61
|
+
correct: true,
|
|
62
|
+
content: "This choice is correct",
|
|
63
|
+
};
|
|
64
|
+
const incorrectProps = {
|
|
65
|
+
...sharedProps,
|
|
66
|
+
correct: false,
|
|
67
|
+
content: "This choice is incorrect",
|
|
68
|
+
};
|
|
69
|
+
return (
|
|
70
|
+
<>
|
|
71
|
+
<Choice {...correctProps} />
|
|
72
|
+
<Choice {...incorrectProps} />
|
|
73
|
+
</>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const ReviewMode = (args: StoryArgs): React.Node => {
|
|
78
|
+
const sharedProps = {
|
|
79
|
+
...defaultProps,
|
|
80
|
+
showCorrectness: true,
|
|
81
|
+
reviewMode: true,
|
|
82
|
+
multipleSelect: true,
|
|
83
|
+
};
|
|
84
|
+
return (
|
|
85
|
+
<>
|
|
86
|
+
<Choice
|
|
87
|
+
{...sharedProps}
|
|
88
|
+
correct={true}
|
|
89
|
+
checked={true}
|
|
90
|
+
content="This choice was correct and checked"
|
|
91
|
+
/>
|
|
92
|
+
<Choice
|
|
93
|
+
{...sharedProps}
|
|
94
|
+
correct={true}
|
|
95
|
+
content="This choice was also correct and not checked"
|
|
96
|
+
/>
|
|
97
|
+
<Choice
|
|
98
|
+
{...sharedProps}
|
|
99
|
+
correct={false}
|
|
100
|
+
checked={true}
|
|
101
|
+
content="This choice was incorrect and checked"
|
|
102
|
+
/>
|
|
103
|
+
<Choice
|
|
104
|
+
{...sharedProps}
|
|
105
|
+
correct={false}
|
|
106
|
+
content="This choice was also incorrect and not checked"
|
|
107
|
+
/>
|
|
108
|
+
</>
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export const Rationale = (args: StoryArgs): React.Node => {
|
|
113
|
+
const sharedProps = {
|
|
114
|
+
...defaultProps,
|
|
115
|
+
checked: true,
|
|
116
|
+
showCorrectness: true,
|
|
117
|
+
showRationale: true,
|
|
118
|
+
reviewMode: true,
|
|
119
|
+
};
|
|
120
|
+
const correctProps = {
|
|
121
|
+
...sharedProps,
|
|
122
|
+
correct: true,
|
|
123
|
+
content: "This choice is correct",
|
|
124
|
+
rationale: "It was correct because of the way it is",
|
|
125
|
+
};
|
|
126
|
+
const incorrectProps = {
|
|
127
|
+
...sharedProps,
|
|
128
|
+
correct: false,
|
|
129
|
+
content: "This choice is incorrect",
|
|
130
|
+
rationale: "It was incorrect because of the way it is",
|
|
131
|
+
};
|
|
132
|
+
return (
|
|
133
|
+
<>
|
|
134
|
+
<Choice {...correctProps} />
|
|
135
|
+
<Choice {...incorrectProps} />
|
|
136
|
+
</>
|
|
137
|
+
);
|
|
138
|
+
};
|
|
@@ -1,38 +1,44 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
|
+
import * as styleConstants from "../../../styles/constants.js";
|
|
4
5
|
import FocusRing from "../focus-ring.jsx";
|
|
5
6
|
|
|
6
|
-
type StoryArgs = {
|
|
7
|
+
type StoryArgs = {|
|
|
8
|
+
children: React.Node,
|
|
9
|
+
color: string,
|
|
10
|
+
visible: boolean,
|
|
11
|
+
multipleSelect: boolean,
|
|
12
|
+
|};
|
|
7
13
|
|
|
8
14
|
type Story = {|
|
|
9
15
|
title: string,
|
|
16
|
+
args: StoryArgs,
|
|
10
17
|
|};
|
|
11
18
|
|
|
12
19
|
export default ({
|
|
13
20
|
title: "Perseus/Widgets/Radio/Focus Ring",
|
|
21
|
+
args: {
|
|
22
|
+
children: "",
|
|
23
|
+
color: styleConstants.kaGreen,
|
|
24
|
+
visible: true,
|
|
25
|
+
multipleSelect: false,
|
|
26
|
+
},
|
|
14
27
|
}: Story);
|
|
15
28
|
|
|
16
|
-
export const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const SingleSpanChild = (args: StoryArgs): React.Node => {
|
|
33
|
-
return (
|
|
34
|
-
<FocusRing>
|
|
35
|
-
<span>test</span>
|
|
36
|
-
</FocusRing>
|
|
37
|
-
);
|
|
29
|
+
export const Interactive = (args: StoryArgs): React.Node => {
|
|
30
|
+
// faux choice is just for demonstration
|
|
31
|
+
const fauxChoiceStyles = {
|
|
32
|
+
height: "20px",
|
|
33
|
+
width: "20px",
|
|
34
|
+
background: args.color,
|
|
35
|
+
borderRadius: args.multipleSelect ? "3px" : "50%",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const customArgs = {
|
|
39
|
+
...args,
|
|
40
|
+
children: args.children || <div style={fauxChoiceStyles} />,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
return <FocusRing {...customArgs} />;
|
|
38
44
|
};
|