@khanacademy/perseus-editor 2.0.1 → 2.0.3
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 +17 -0
- package/dist/article-editor.d.ts +2 -2
- package/dist/article-editor.js.flow +2 -2
- package/dist/components/dropdown-option.d.ts +2 -2
- package/dist/components/dropdown-option.js.flow +2 -2
- package/dist/components/link.d.ts +2 -2
- package/dist/components/link.js.flow +2 -2
- package/dist/diffs/__stories__/perseus-diff-wrapper.d.ts +3 -2
- package/dist/diffs/__stories__/perseus-diff-wrapper.js.flow +3 -2
- package/dist/editor.d.ts +7 -7
- package/dist/editor.js.flow +7 -7
- package/dist/es/index.js +9 -70
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +9 -70
- package/dist/index.js.map +1 -1
- package/dist/section-control-button.d.ts +10 -1
- package/dist/section-control-button.js.flow +13 -1
- package/dist/widgets/label-image/answer-choices.d.ts +1 -1
- package/dist/widgets/label-image/answer-choices.js.flow +1 -1
- package/dist/widgets/label-image/behavior.d.ts +2 -2
- package/dist/widgets/label-image/behavior.js.flow +2 -2
- package/dist/widgets/label-image/marker.d.ts +5 -5
- package/dist/widgets/label-image/marker.js.flow +5 -7
- package/dist/widgets/label-image/question-markers.d.ts +2 -2
- package/dist/widgets/label-image/question-markers.js.flow +2 -4
- package/dist/widgets/label-image/select-image.d.ts +2 -2
- package/dist/widgets/label-image/select-image.js.flow +2 -2
- package/dist/widgets/label-image-editor.d.ts +3 -3
- package/dist/widgets/label-image-editor.js.flow +3 -3
- package/package.json +2 -2
- package/src/__stories__/section-control-button.stories.tsx +3 -3
- package/src/article-editor.tsx +2 -6
- package/src/components/dropdown-option.tsx +2 -10
- package/src/components/link.ts +2 -2
- package/src/diffs/__stories__/perseus-diff-wrapper.tsx +4 -2
- package/src/diffs/__stories__/structured-item-diff.stories.tsx +5 -9
- package/src/diffs/__stories__/tags-diff.stories.tsx +1 -1
- package/src/diffs/__stories__/text-diff.stories.tsx +1 -1
- package/src/diffs/text-diff.tsx +0 -1
- package/src/diffs/widget-diff.tsx +0 -2
- package/src/editor.tsx +8 -11
- package/src/multirenderer-editor.tsx +8 -32
- package/src/widgets/__stories__/label-image-editor.stories.tsx +1 -4
- package/src/widgets/__stories__/radio-editor.stories.tsx +1 -2
- package/src/widgets/categorizer-editor.tsx +0 -1
- package/src/widgets/cs-program-editor.tsx +0 -2
- package/src/widgets/expression-editor.tsx +0 -2
- package/src/widgets/grapher-editor.tsx +0 -1
- package/src/widgets/iframe-editor.tsx +0 -2
- package/src/widgets/input-number-editor.tsx +0 -1
- package/src/widgets/interaction-editor.tsx +0 -1
- package/src/widgets/interactive-graph-editor.tsx +0 -1
- package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +3 -7
- package/src/widgets/label-image/__stories__/behavior.stories.tsx +1 -1
- package/src/widgets/label-image/__stories__/marker.stories.tsx +2 -2
- package/src/widgets/label-image/__stories__/question-markers.stories.tsx +3 -3
- package/src/widgets/label-image/__stories__/select-image.stories.tsx +3 -3
- package/src/widgets/label-image/answer-choices.tsx +5 -5
- package/src/widgets/label-image/behavior.tsx +3 -3
- package/src/widgets/label-image/marker.tsx +5 -6
- package/src/widgets/label-image/question-markers.tsx +2 -2
- package/src/widgets/label-image/select-image.tsx +2 -5
- package/src/widgets/label-image-editor.tsx +3 -3
- package/src/widgets/numeric-input-editor.tsx +0 -20
- package/src/widgets/transformer-editor.tsx +0 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -70,7 +70,7 @@ class ModeDropdown extends React.Component<ModeDropdownProps> {
|
|
|
70
70
|
_handleSelectMode = (event: React.ChangeEvent<HTMLSelectElement>) => {
|
|
71
71
|
if (this.props.onChange) {
|
|
72
72
|
// event.target.value corresponds to the options' values below which
|
|
73
|
-
// are limited to EditorMode, but
|
|
73
|
+
// are limited to EditorMode, but TypeScript doesn't know that so we have
|
|
74
74
|
// to cast through any here.
|
|
75
75
|
const value = event.target.value as EditorMode;
|
|
76
76
|
this.props.onChange(value);
|
|
@@ -141,13 +141,9 @@ type HeaderProps = {
|
|
|
141
141
|
depth: number;
|
|
142
142
|
};
|
|
143
143
|
|
|
144
|
-
const Header: React.
|
|
145
|
-
depth,
|
|
146
|
-
...props
|
|
147
|
-
}): React.ReactElement => {
|
|
144
|
+
const Header = ({depth, ...props}: HeaderProps): React.ReactElement => {
|
|
148
145
|
const headerLevel = Math.min(depth, 5) + 1;
|
|
149
146
|
const HeaderTag = `h${headerLevel}`;
|
|
150
|
-
// @ts-expect-error [FEI-5003] - TS2559 - Type '{ children?: ReactNode; }' has no properties in common with type 'IntrinsicAttributes'.
|
|
151
147
|
return <HeaderTag {...props} />;
|
|
152
148
|
};
|
|
153
149
|
|
|
@@ -268,13 +264,13 @@ type LeafContainerProps = {
|
|
|
268
264
|
path: Path;
|
|
269
265
|
shape: Shape;
|
|
270
266
|
};
|
|
271
|
-
const LeafContainer
|
|
267
|
+
const LeafContainer = ({
|
|
272
268
|
name,
|
|
273
269
|
controls,
|
|
274
270
|
children,
|
|
275
271
|
path,
|
|
276
272
|
shape,
|
|
277
|
-
}): React.ReactElement => {
|
|
273
|
+
}: LeafContainerProps): React.ReactElement => {
|
|
278
274
|
const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
|
|
279
275
|
const previewHeading = hasPreviewHeading && (
|
|
280
276
|
<div className={css(styles.containerHeader)}>
|
|
@@ -314,9 +310,7 @@ type ArrayContainerProps = {
|
|
|
314
310
|
shape: ArrayShape;
|
|
315
311
|
actions: ArrayContainerActions;
|
|
316
312
|
};
|
|
317
|
-
const ArrayContainer: React.
|
|
318
|
-
props,
|
|
319
|
-
): React.ReactElement => {
|
|
313
|
+
const ArrayContainer = (props: ArrayContainerProps): React.ReactElement => {
|
|
320
314
|
const {name, controls, children, path, shape, actions} = props;
|
|
321
315
|
return (
|
|
322
316
|
<div className={css(styles.container)}>
|
|
@@ -347,12 +341,12 @@ type ObjectContainerProps = {
|
|
|
347
341
|
children?: React.ReactNode;
|
|
348
342
|
path: Path;
|
|
349
343
|
};
|
|
350
|
-
const ObjectContainer
|
|
344
|
+
const ObjectContainer = ({
|
|
351
345
|
name,
|
|
352
346
|
controls,
|
|
353
347
|
children,
|
|
354
348
|
path,
|
|
355
|
-
}): React.ReactElement => {
|
|
349
|
+
}: ObjectContainerProps): React.ReactElement => {
|
|
356
350
|
const headingEditor = (
|
|
357
351
|
<div className={css(styles.containerHeader)}>
|
|
358
352
|
{/* @ts-expect-error [FEI-5003] - TS2322 - Type '{ children: string; depth: number; className: string; }' is not assignable to type 'IntrinsicAttributes & HeaderProps & { children?: ReactNode; }'. */}
|
|
@@ -409,7 +403,7 @@ const NodeContent = (props: NodePropTypes) => {
|
|
|
409
403
|
|
|
410
404
|
// All uses of `data` have been cast through any which isn't safe. This was
|
|
411
405
|
// done to avoid introducing new logic which may have resulted in a change
|
|
412
|
-
// of behavior. Also, there doesn't appear to be a way to tell
|
|
406
|
+
// of behavior. Also, there doesn't appear to be a way to tell TypeScript the
|
|
413
407
|
// difference between and `TagsNode` and `ItemArrayNode`, see
|
|
414
408
|
// perseus-all-package/multi-items/item-types.js.
|
|
415
409
|
if (shape.type === "content") {
|
|
@@ -520,12 +514,6 @@ const withStickiness = <
|
|
|
520
514
|
|
|
521
515
|
render(): React.ReactNode {
|
|
522
516
|
return (
|
|
523
|
-
/**
|
|
524
|
-
* $FlowFixMe[incompatible-exact]
|
|
525
|
-
* TODO(somewhatabstract, JIRA-XXXX):
|
|
526
|
-
* Cannot create WrappedComponent element because inexact props
|
|
527
|
-
* [1] is incompatible with exact WithStickiness [2].
|
|
528
|
-
*/
|
|
529
517
|
// @ts-expect-error [FEI-5003] - TS2322 - Type 'Readonly<Config> & { sticky: boolean; children?: ReactNode; }' is not assignable to type 'IntrinsicAttributes & LibraryManagedAttributes<Component, PropsWithChildren<WithStickiness<Config>>>'.
|
|
530
518
|
<WrappedComponent {...this.props} sticky={this.state.sticky} />
|
|
531
519
|
);
|
|
@@ -548,9 +536,6 @@ const ItemNodeContent = withStickiness(
|
|
|
548
536
|
<div className={css(sticky && styles.sticky)}>
|
|
549
537
|
{/* TODO(CP-4852): only pass the props to Editor that it uses. */}
|
|
550
538
|
{
|
|
551
|
-
// $FlowFixMe[incompatible-exact]: {...data} pass too many props
|
|
552
|
-
// $FlowFixMe[incompatible-type]
|
|
553
|
-
// $FlowFixMe[prop-missing]
|
|
554
539
|
// @ts-expect-error [FEI-5003] - TS2769 - No overload matches this call.
|
|
555
540
|
<Editor
|
|
556
541
|
{...data}
|
|
@@ -585,13 +570,6 @@ const HintNodeContent = withStickiness(
|
|
|
585
570
|
<div className={css(styles.row)}>
|
|
586
571
|
<div className={css(styles.columnLeft)}>
|
|
587
572
|
<div className={css(sticky && styles.sticky)}>
|
|
588
|
-
{/**
|
|
589
|
-
* $FlowFixMe[incompatible-exact]
|
|
590
|
-
* TODO(somewhatabstract, JIRA-XXXX):
|
|
591
|
-
* Cannot create WrappedComponent element because
|
|
592
|
-
* inexact props [1] is incompatible with exact
|
|
593
|
-
* WithStickiness [2].
|
|
594
|
-
*/}
|
|
595
573
|
<HintEditor
|
|
596
574
|
{...data}
|
|
597
575
|
className={css(styles.hintEditor)}
|
|
@@ -673,8 +651,6 @@ const ArrayNodeContent = (props: NodePropTypes<ArrayShape, ItemArrayNode>) => {
|
|
|
673
651
|
</SimpleButton>
|
|
674
652
|
</div>
|
|
675
653
|
),
|
|
676
|
-
// $FlowFixMe[unsafe-addition]
|
|
677
|
-
// $FlowFixMe[prop-missing]
|
|
678
654
|
i < data.length - 1 && (
|
|
679
655
|
<div key="moveArrayElementDown" className={css(styles.control)}>
|
|
680
656
|
<SimpleButton
|
|
@@ -85,9 +85,6 @@ class WithState extends React.Component<Empty, State> {
|
|
|
85
85
|
...props,
|
|
86
86
|
})
|
|
87
87
|
}
|
|
88
|
-
// TODO(mdr): We found a new Flow error when upgrading:
|
|
89
|
-
// "widget (null) This type is incompatible with this._widget (LabelImageEditor)"
|
|
90
|
-
// $FlowFixMe[incompatible-type](0.52.0->0.53.0)
|
|
91
88
|
// @ts-expect-error [FEI-5003] - TS2322 - Type 'LabelImageEditor | null' is not assignable to type 'LabelImageEditor'.
|
|
92
89
|
ref={(widget) => (this._widget = widget)}
|
|
93
90
|
/>
|
|
@@ -96,6 +93,6 @@ class WithState extends React.Component<Empty, State> {
|
|
|
96
93
|
}
|
|
97
94
|
}
|
|
98
95
|
|
|
99
|
-
export const Default
|
|
96
|
+
export const Default = (args: StoryArgs): React.ReactElement => {
|
|
100
97
|
return <WithState />;
|
|
101
98
|
};
|
|
@@ -102,7 +102,6 @@ class WithState extends React.Component<Empty, PerseusRadioWidgetOptions> {
|
|
|
102
102
|
...props,
|
|
103
103
|
})
|
|
104
104
|
}
|
|
105
|
-
// $FlowFixMe[incompatible-type] - can be null
|
|
106
105
|
// @ts-expect-error [FEI-5003] - TS2322 - Type 'RadioEditor | null' is not assignable to type 'RadioEditor'.
|
|
107
106
|
ref={(widget) => (this._widget = widget)}
|
|
108
107
|
/>
|
|
@@ -111,6 +110,6 @@ class WithState extends React.Component<Empty, PerseusRadioWidgetOptions> {
|
|
|
111
110
|
}
|
|
112
111
|
}
|
|
113
112
|
|
|
114
|
-
export const Default
|
|
113
|
+
export const Default = (args: StoryArgs): React.ReactElement => {
|
|
115
114
|
return <WithState />;
|
|
116
115
|
};
|
|
@@ -84,7 +84,6 @@ class CategorizerEditor extends React.Component<Props> {
|
|
|
84
84
|
{/* There are a bunch of props that renderer.jsx passes to each widget
|
|
85
85
|
via widget-container.jsx that we aren't passing to Categorizer here.
|
|
86
86
|
See perseus-all-package/types.js#WidgetProps for details. */}
|
|
87
|
-
{/* $FlowFixMe[prop-missing] */}
|
|
88
87
|
{/* @ts-expect-error [FEI-5003] - TS2769 - No overload matches this call. */}
|
|
89
88
|
<Categorizer
|
|
90
89
|
apiOptions={this.props.apiOptions}
|
|
@@ -53,7 +53,6 @@ class PairEditor extends React.Component<any> {
|
|
|
53
53
|
Name:{" "}
|
|
54
54
|
<BlurInput
|
|
55
55
|
value={this.props.name}
|
|
56
|
-
// $FlowFixMe[incompatible-type] single-param call returns a callback
|
|
57
56
|
onChange={this.change("name")}
|
|
58
57
|
/>
|
|
59
58
|
</label>
|
|
@@ -62,7 +61,6 @@ class PairEditor extends React.Component<any> {
|
|
|
62
61
|
Value:{" "}
|
|
63
62
|
<BlurInput
|
|
64
63
|
value={this.props.value}
|
|
65
|
-
// $FlowFixMe[incompatible-type] single-param call returns a callback
|
|
66
64
|
onChange={this.change("value")}
|
|
67
65
|
/>
|
|
68
66
|
</label>
|
|
@@ -223,8 +223,6 @@ class ExpressionEditor extends React.Component<any, any> {
|
|
|
223
223
|
className="math-input-buttons"
|
|
224
224
|
sets={this.props.buttonSets}
|
|
225
225
|
convertDotToTimes={this.props.times}
|
|
226
|
-
// onInsert is typed as `(string | ((input: $FlowFixMe) => void)) => void`
|
|
227
|
-
// $FlowFixMe[incompatible-type]
|
|
228
226
|
onInsert={this.handleTexInsert}
|
|
229
227
|
/>
|
|
230
228
|
)}
|
|
@@ -68,7 +68,6 @@ class GrapherEditor extends React.Component<Props> {
|
|
|
68
68
|
// NOTE(jeremy): This editor doesn't pass in a bunch of
|
|
69
69
|
// standard props that the Renderer provides normally (eg.
|
|
70
70
|
// alignment, findWidgets, etc).
|
|
71
|
-
// $FlowFixMe[prop-missing]
|
|
72
71
|
// @ts-expect-error [FEI-5003] - TS2769 - No overload matches this call.
|
|
73
72
|
<Grapher
|
|
74
73
|
{...graphProps}
|
|
@@ -36,7 +36,6 @@ class PairEditor extends React.Component<PairEditorProps> {
|
|
|
36
36
|
Name:
|
|
37
37
|
<BlurInput
|
|
38
38
|
value={this.props.name}
|
|
39
|
-
// $FlowFixMe[incompatible-type] single-param call returns a callback
|
|
40
39
|
onChange={this.change("name")}
|
|
41
40
|
/>
|
|
42
41
|
</label>
|
|
@@ -44,7 +43,6 @@ class PairEditor extends React.Component<PairEditorProps> {
|
|
|
44
43
|
Value:
|
|
45
44
|
<BlurInput
|
|
46
45
|
value={this.props.value}
|
|
47
|
-
// $FlowFixMe[incompatible-type] single-param call returns a callback
|
|
48
46
|
onChange={this.change("value")}
|
|
49
47
|
/>
|
|
50
48
|
</label>
|
|
@@ -964,7 +964,6 @@ class InteractionEditor extends React.Component<
|
|
|
964
964
|
markings={this.props.graph.markings}
|
|
965
965
|
onChange={this._updateGraphProps}
|
|
966
966
|
/>
|
|
967
|
-
{/* $FlowFixMe[incompatible-type] */}
|
|
968
967
|
{this.props.graph.valid !== true && (
|
|
969
968
|
<div>{this.props.graph.valid}</div>
|
|
970
969
|
)}
|
|
@@ -122,7 +122,6 @@ const InteractiveGraphEditor: any = createReactClass({
|
|
|
122
122
|
// There are a bunch of props that renderer.jsx passes to widgets via
|
|
123
123
|
// getWidgetProps() and widget-container.jsx that the editors don't
|
|
124
124
|
// bother passing.
|
|
125
|
-
// $FlowFixMe[prop-missing]
|
|
126
125
|
// @ts-expect-error [FEI-5003] - TS2769 - No overload matches this call.
|
|
127
126
|
<InteractiveGraph
|
|
128
127
|
{...graphProps}
|
|
@@ -57,16 +57,12 @@ class WithState extends React.Component<
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export const EmptyNonInteractive: React.
|
|
61
|
-
args,
|
|
62
|
-
): React.ReactElement => {
|
|
60
|
+
export const EmptyNonInteractive = (args: StoryArgs): React.ReactElement => {
|
|
63
61
|
const props = {choices: [], onChange: (...args) => {}} as const;
|
|
64
62
|
return <Wrapper {...props} />;
|
|
65
63
|
};
|
|
66
64
|
|
|
67
|
-
export const FilledNonInteractive: React.
|
|
68
|
-
args,
|
|
69
|
-
): React.ReactElement => {
|
|
65
|
+
export const FilledNonInteractive = (args: StoryArgs): React.ReactElement => {
|
|
70
66
|
const props = {
|
|
71
67
|
choices: [
|
|
72
68
|
"Lamborghini",
|
|
@@ -81,6 +77,6 @@ export const FilledNonInteractive: React.FC<StoryArgs> = (
|
|
|
81
77
|
return <Wrapper {...props} />;
|
|
82
78
|
};
|
|
83
79
|
|
|
84
|
-
export const Interactive
|
|
80
|
+
export const Interactive = (args: StoryArgs): React.ReactElement => {
|
|
85
81
|
return <WithState />;
|
|
86
82
|
};
|
|
@@ -13,7 +13,7 @@ export default {
|
|
|
13
13
|
title: "Perseus/Editor/Widgets/Label Image/Behavior",
|
|
14
14
|
} as Story;
|
|
15
15
|
|
|
16
|
-
export const Default
|
|
16
|
+
export const Default = (args: StoryArgs): React.ReactElement => {
|
|
17
17
|
const [state, setState] = React.useState({
|
|
18
18
|
multipleAnswers: false,
|
|
19
19
|
hideChoicesFromInstructions: false,
|
|
@@ -33,7 +33,7 @@ const Wrapper = (props) => (
|
|
|
33
33
|
</div>
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
export const Empty
|
|
36
|
+
export const Empty = (args: StoryArgs): React.ReactElement => {
|
|
37
37
|
const props = {
|
|
38
38
|
answers: [],
|
|
39
39
|
choices: [],
|
|
@@ -50,7 +50,7 @@ export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
|
|
|
50
50
|
return <Wrapper {...props} />;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
export const WithAnswers
|
|
53
|
+
export const WithAnswers = (args: StoryArgs): React.ReactElement => {
|
|
54
54
|
const props = {
|
|
55
55
|
answers: ["BMW", "Ferrari"],
|
|
56
56
|
choices: [
|
|
@@ -70,7 +70,7 @@ class WithState extends React.Component<
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
export const Empty
|
|
73
|
+
export const Empty = (args: StoryArgs): React.ReactElement => {
|
|
74
74
|
const props = {
|
|
75
75
|
choices: [],
|
|
76
76
|
imageUrl: "",
|
|
@@ -82,7 +82,7 @@ export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
|
|
|
82
82
|
return <Wrapper {...props} />;
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
export const Filled
|
|
85
|
+
export const Filled = (args: StoryArgs): React.ReactElement => {
|
|
86
86
|
const props = {
|
|
87
87
|
choices: [],
|
|
88
88
|
imageUrl:
|
|
@@ -102,6 +102,6 @@ export const Filled: React.FC<StoryArgs> = (args): React.ReactElement => {
|
|
|
102
102
|
return <Wrapper {...props} />;
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
-
export const Interactive
|
|
105
|
+
export const Interactive = (args: StoryArgs): React.ReactElement => {
|
|
106
106
|
return <WithState />;
|
|
107
107
|
};
|
|
@@ -36,7 +36,7 @@ const WithState = () => {
|
|
|
36
36
|
);
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export const Empty
|
|
39
|
+
export const Empty = (args: StoryArgs): React.ReactElement => {
|
|
40
40
|
const props = {
|
|
41
41
|
url: "",
|
|
42
42
|
onChange: () => {},
|
|
@@ -45,7 +45,7 @@ export const Empty: React.FC<StoryArgs> = (args): React.ReactElement => {
|
|
|
45
45
|
return <Wrapper {...props} />;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
export const Filled
|
|
48
|
+
export const Filled = (args: StoryArgs): React.ReactElement => {
|
|
49
49
|
const props = {
|
|
50
50
|
url: "https://ka-perseus-images.s3.amazonaws.com/2ee5fc32e35c5178373b39fd304b325b2994c913.png",
|
|
51
51
|
onChange: () => {},
|
|
@@ -54,6 +54,6 @@ export const Filled: React.FC<StoryArgs> = (args): React.ReactElement => {
|
|
|
54
54
|
return <Wrapper {...props} />;
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
export const Interactive
|
|
57
|
+
export const Interactive = (args: StoryArgs): React.ReactElement => {
|
|
58
58
|
return <WithState />;
|
|
59
59
|
};
|
|
@@ -89,7 +89,7 @@ const DraggableGripIcon = () => (
|
|
|
89
89
|
/**
|
|
90
90
|
* A button link to add a new answer.
|
|
91
91
|
*/
|
|
92
|
-
const AddAnswer
|
|
92
|
+
const AddAnswer = ({onClick}: AddAnswerProps): React.ReactElement => (
|
|
93
93
|
<Link
|
|
94
94
|
className={css(styles.addAnswer, editorStyles.addAnswer)}
|
|
95
95
|
onClick={onClick}
|
|
@@ -105,11 +105,11 @@ const AddAnswer: React.FC<AddAnswerProps> = ({onClick}): React.ReactElement => (
|
|
|
105
105
|
*
|
|
106
106
|
* TODO(michaelpolyak): Implement answer reordering, CP-117
|
|
107
107
|
*/
|
|
108
|
-
const Answer
|
|
108
|
+
const Answer = ({
|
|
109
109
|
answer,
|
|
110
110
|
onChange,
|
|
111
111
|
onRemove,
|
|
112
|
-
}): React.ReactElement => (
|
|
112
|
+
}: AnswerProps): React.ReactElement => (
|
|
113
113
|
<li className={css(styles.answer)}>
|
|
114
114
|
<Link onClick={onRemove}>
|
|
115
115
|
<Icon icon={removeIcon} size={24} color="#D92916" />
|
|
@@ -137,10 +137,10 @@ const Answer: React.FC<AnswerProps> = ({
|
|
|
137
137
|
/**
|
|
138
138
|
* The list of choices, handles adding, removing and reording of answers.
|
|
139
139
|
*/
|
|
140
|
-
const AnswerChoices
|
|
140
|
+
const AnswerChoices = ({
|
|
141
141
|
choices,
|
|
142
142
|
onChange,
|
|
143
|
-
}): React.ReactElement => (
|
|
143
|
+
}: AnswerChoicesProps): React.ReactElement => (
|
|
144
144
|
<div>
|
|
145
145
|
<div className={css(styles.title)}>Answer Choices</div>
|
|
146
146
|
|
|
@@ -10,7 +10,7 @@ import Checkbox from "../../components/checkbox";
|
|
|
10
10
|
|
|
11
11
|
const {colors, typography} = globalStyles;
|
|
12
12
|
|
|
13
|
-
type
|
|
13
|
+
type Props = {
|
|
14
14
|
// Whether multiple answer choices may be selected for markers.
|
|
15
15
|
multipleAnswers: boolean;
|
|
16
16
|
// Whether to hide answer choices from user instructions.
|
|
@@ -22,11 +22,11 @@ type BehaviorProps = {
|
|
|
22
22
|
}) => void;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
const Behavior
|
|
25
|
+
const Behavior = ({
|
|
26
26
|
multipleAnswers,
|
|
27
27
|
hideChoicesFromInstructions,
|
|
28
28
|
onChange,
|
|
29
|
-
}): React.ReactElement => (
|
|
29
|
+
}: Props): React.ReactElement => (
|
|
30
30
|
<div>
|
|
31
31
|
<div className={css(styles.title)}>Behavior</div>
|
|
32
32
|
|
|
@@ -17,7 +17,7 @@ import type {MarkerType} from "@khanacademy/perseus";
|
|
|
17
17
|
|
|
18
18
|
const {colors, borderRadius} = globalStyles;
|
|
19
19
|
|
|
20
|
-
type
|
|
20
|
+
type Props = MarkerType & {
|
|
21
21
|
// The list of possible answer choices.
|
|
22
22
|
choices: ReadonlyArray<string>;
|
|
23
23
|
// Callback for when any of the marker props are changed.
|
|
@@ -26,16 +26,16 @@ type MarkerProps = MarkerType & {
|
|
|
26
26
|
onRemove: () => void;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
type
|
|
29
|
+
type State = {
|
|
30
30
|
// Whether answer choices dropdown is shown, controlled by the user clicking
|
|
31
31
|
// on the marker icon.
|
|
32
32
|
showDropdown: boolean;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
export default class Marker extends React.Component<
|
|
35
|
+
export default class Marker extends React.Component<Props, State> {
|
|
36
36
|
_marker: HTMLElement | null | undefined;
|
|
37
37
|
|
|
38
|
-
constructor(props:
|
|
38
|
+
constructor(props: Props) {
|
|
39
39
|
super(props);
|
|
40
40
|
|
|
41
41
|
this.state = {
|
|
@@ -47,7 +47,7 @@ export default class Marker extends React.Component<MarkerProps, MarkerState> {
|
|
|
47
47
|
document.addEventListener("click", this.handleClick, true);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
UNSAFE_componentWillReceiveProps(nextProps:
|
|
50
|
+
UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
|
51
51
|
const {answers} = this.props;
|
|
52
52
|
|
|
53
53
|
// Exclude those answers that are no longer present in choices.
|
|
@@ -162,7 +162,6 @@ export default class Marker extends React.Component<MarkerProps, MarkerState> {
|
|
|
162
162
|
<OptionGroup
|
|
163
163
|
onSelected={this.handleSelectAnswer}
|
|
164
164
|
// TODO(WB-1096): make selectedValues immutable in wonder-blocks
|
|
165
|
-
// $FlowFixMe[incompatible-type]
|
|
166
165
|
// @ts-expect-error [FEI-5003] - TS2769 - No overload matches this call.
|
|
167
166
|
selectedValues={answers}
|
|
168
167
|
>
|
|
@@ -13,7 +13,7 @@ import type {MarkerType} from "@khanacademy/perseus";
|
|
|
13
13
|
|
|
14
14
|
const {colors, typography} = globalStyles;
|
|
15
15
|
|
|
16
|
-
type
|
|
16
|
+
type Props = {
|
|
17
17
|
// The list of possible answers in a specific order.
|
|
18
18
|
choices: ReadonlyArray<string>;
|
|
19
19
|
// The question image properties.
|
|
@@ -26,7 +26,7 @@ type QuestionMarkersProps = {
|
|
|
26
26
|
onChange: (markers: ReadonlyArray<MarkerType>) => void;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export default class QuestionMarkers extends React.Component<
|
|
29
|
+
export default class QuestionMarkers extends React.Component<Props> {
|
|
30
30
|
_markers: Array<Marker | null | undefined> = [];
|
|
31
31
|
|
|
32
32
|
openDropdownForMarkerIndices(indices: ReadonlyArray<number>) {
|
|
@@ -11,17 +11,14 @@ import FormWrappedTextField from "../../components/form-wrapped-text-field";
|
|
|
11
11
|
|
|
12
12
|
const {colors, typography} = globalStyles;
|
|
13
13
|
|
|
14
|
-
type
|
|
14
|
+
type Props = {
|
|
15
15
|
// Callback for when image URL is changed.
|
|
16
16
|
onChange: (url: string) => void;
|
|
17
17
|
// The selected image URL.
|
|
18
18
|
url: string;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const SelectImage: React.
|
|
22
|
-
onChange,
|
|
23
|
-
url,
|
|
24
|
-
}): React.ReactElement => (
|
|
21
|
+
const SelectImage = ({onChange, url}: Props): React.ReactElement => (
|
|
25
22
|
<div>
|
|
26
23
|
<div className={css(styles.title)}>Image</div>
|
|
27
24
|
|
|
@@ -19,7 +19,7 @@ import SelectImage from "./label-image/select-image";
|
|
|
19
19
|
|
|
20
20
|
import type {MarkerType} from "@khanacademy/perseus";
|
|
21
21
|
|
|
22
|
-
type
|
|
22
|
+
type Props = {
|
|
23
23
|
// List of answer choices to label question image with.
|
|
24
24
|
choices: ReadonlyArray<string>;
|
|
25
25
|
// The question image properties.
|
|
@@ -37,7 +37,7 @@ type LabelImageEditorProps = {
|
|
|
37
37
|
onChange: (options: any) => void;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
class LabelImageEditor extends React.Component<
|
|
40
|
+
class LabelImageEditor extends React.Component<Props> {
|
|
41
41
|
_questionMarkers: QuestionMarkers | null | undefined;
|
|
42
42
|
|
|
43
43
|
static defaultProps: {
|
|
@@ -62,7 +62,7 @@ class LabelImageEditor extends React.Component<LabelImageEditorProps> {
|
|
|
62
62
|
|
|
63
63
|
static widgetName = "label-image" as const;
|
|
64
64
|
|
|
65
|
-
componentDidUpdate(prevProps:
|
|
65
|
+
componentDidUpdate(prevProps: Props) {
|
|
66
66
|
const coordsToMarkers: Record<string, any> = {};
|
|
67
67
|
|
|
68
68
|
prevProps.markers.forEach(
|
|
@@ -66,7 +66,6 @@ const NumericInputEditor: any = createReactClass({
|
|
|
66
66
|
size: "normal",
|
|
67
67
|
coefficient: false,
|
|
68
68
|
labelText: "",
|
|
69
|
-
multipleNumberInput: false,
|
|
70
69
|
rightAlign: false,
|
|
71
70
|
};
|
|
72
71
|
},
|
|
@@ -417,16 +416,6 @@ const NumericInputEditor: any = createReactClass({
|
|
|
417
416
|
|
|
418
417
|
return (
|
|
419
418
|
<div className="perseus-input-number-editor">
|
|
420
|
-
<div ref={(e) => (this.multInputOption = e)}>
|
|
421
|
-
<select onChange={this.onMultipleInputChange}>
|
|
422
|
-
<option value="simple-numeric-input">
|
|
423
|
-
Ask for one correct solution
|
|
424
|
-
</option>
|
|
425
|
-
<option value="multiple-numeric-input">
|
|
426
|
-
Ask for all correct solutions
|
|
427
|
-
</option>
|
|
428
|
-
</select>
|
|
429
|
-
</div>
|
|
430
419
|
<div className="ui-title">User input</div>
|
|
431
420
|
<div className="msg-title">
|
|
432
421
|
Message shown to user on attempt
|
|
@@ -480,15 +469,6 @@ const NumericInputEditor: any = createReactClass({
|
|
|
480
469
|
});
|
|
481
470
|
},
|
|
482
471
|
|
|
483
|
-
onMultipleInputChange: function (event) {
|
|
484
|
-
const newOption = event.target.value;
|
|
485
|
-
if (newOption === "multiple-numeric-input") {
|
|
486
|
-
this.props.onChange({multipleNumberInput: true});
|
|
487
|
-
} else {
|
|
488
|
-
this.props.onChange({multipleNumberInput: false});
|
|
489
|
-
}
|
|
490
|
-
},
|
|
491
|
-
|
|
492
472
|
updateAnswer: function (choiceIndex, update) {
|
|
493
473
|
if (!_.isObject(update)) {
|
|
494
474
|
return _.partial(
|
|
@@ -852,7 +852,6 @@ class TransformationsShapeEditor extends React.Component<any> {
|
|
|
852
852
|
|
|
853
853
|
updateCoords = () => {
|
|
854
854
|
this.props.onChange({
|
|
855
|
-
// $FlowFixMe[prop-missing]
|
|
856
855
|
// @ts-expect-error [FEI-5003] - TS2339 - Property 'shape' does not exist on type 'TransformationsShapeEditor'.
|
|
857
856
|
shape: this.shape.toJSON(),
|
|
858
857
|
});
|