@khanacademy/perseus-editor 4.1.5 → 4.1.7
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/dist/es/index.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +9 -6
- package/.babelrc.js +0 -8
- package/.eslintrc.js +0 -12
- package/CHANGELOG.md +0 -1155
- package/src/README.md +0 -7
- package/src/__stories__/editor-page.stories.tsx +0 -65
- package/src/__stories__/editor.stories.tsx +0 -134
- package/src/__stories__/item-editor.stories.tsx +0 -41
- package/src/__stories__/tex-error-view.stories.tsx +0 -26
- package/src/__testdata__/input-number.testdata.ts +0 -27
- package/src/__tests__/editor.test.tsx +0 -142
- package/src/__tests__/hint-editor.test.tsx +0 -83
- package/src/__tests__/i18n.test.ts +0 -501
- package/src/__tests__/integration.test.ts +0 -5
- package/src/__tests__/item-extras-editor.test.tsx +0 -85
- package/src/__tests__/traversal.test.ts +0 -377
- package/src/all-editors.test.ts +0 -16
- package/src/all-editors.ts +0 -83
- package/src/all-widgets.ts +0 -7
- package/src/article-editor.tsx +0 -438
- package/src/components/__stories__/blur-input.stories.tsx +0 -22
- package/src/components/__stories__/section-control-button.stories.tsx +0 -26
- package/src/components/__tests__/blur-input.test.tsx +0 -67
- package/src/components/blur-input.tsx +0 -69
- package/src/components/checkbox.tsx +0 -194
- package/src/components/device-framer.tsx +0 -90
- package/src/components/drag-target.tsx +0 -87
- package/src/components/dropdown-option.tsx +0 -311
- package/src/components/form-wrapped-text-field.tsx +0 -245
- package/src/components/graph-points-count-selector.tsx +0 -31
- package/src/components/graph-settings.tsx +0 -627
- package/src/components/graph-type-selector.tsx +0 -31
- package/src/components/hover-behavior.ts +0 -177
- package/src/components/json-editor.tsx +0 -121
- package/src/components/link.ts +0 -173
- package/src/components/section-control-button.tsx +0 -53
- package/src/components/segment-count-selector.tsx +0 -27
- package/src/components/simple-button.tsx +0 -85
- package/src/components/sortable.tsx +0 -187
- package/src/components/util.ts +0 -38
- package/src/components/viewport-resizer.tsx +0 -72
- package/src/components/widget-editor.tsx +0 -222
- package/src/components/widget-select.tsx +0 -48
- package/src/diffs/__stories__/perseus-diff-wrapper.tsx +0 -11
- package/src/diffs/__stories__/structured-item-diff.stories.tsx +0 -855
- package/src/diffs/__stories__/tags-diff.stories.tsx +0 -36
- package/src/diffs/__stories__/text-diff.stories.tsx +0 -35
- package/src/diffs/__tests__/split-diff.test.ts +0 -33
- package/src/diffs/__tests__/string-array-diff.test.ts +0 -73
- package/src/diffs/__tests__/structured-item-diff.test.ts +0 -433
- package/src/diffs/__tests__/widget-diff-performer.test.ts +0 -43
- package/src/diffs/article-diff.tsx +0 -69
- package/src/diffs/item-diff.tsx +0 -76
- package/src/diffs/renderer-diff.tsx +0 -137
- package/src/diffs/split-diff.ts +0 -31
- package/src/diffs/string-array-diff.ts +0 -74
- package/src/diffs/structured-item-diff.tsx +0 -275
- package/src/diffs/tags-diff.tsx +0 -49
- package/src/diffs/text-diff.tsx +0 -193
- package/src/diffs/widget-diff-performer.ts +0 -69
- package/src/diffs/widget-diff.tsx +0 -290
- package/src/editor-page.tsx +0 -325
- package/src/editor.tsx +0 -1099
- package/src/hint-editor.tsx +0 -469
- package/src/i18n.ts +0 -140
- package/src/iframe-content-renderer.tsx +0 -188
- package/src/index.ts +0 -30
- package/src/item-editor.tsx +0 -158
- package/src/item-extras-editor.tsx +0 -230
- package/src/katex-mhchem/index.js +0 -73
- package/src/katex-mhchem/parser.js +0 -2659
- package/src/multirenderer-editor.tsx +0 -1061
- package/src/stateful-article-editor.tsx +0 -173
- package/src/stateful-editor-page.tsx +0 -88
- package/src/styles/perseus-editor.less +0 -1321
- package/src/testing-widgets.ts +0 -11
- package/src/tex-error-view.tsx +0 -90
- package/src/util/points.test.ts +0 -24
- package/src/util/points.ts +0 -13
- package/src/util/register-all-widgets-and-editors-for-testing.test.ts +0 -17
- package/src/util/register-all-widgets-and-editors-for-testing.ts +0 -17
- package/src/version.ts +0 -10
- package/src/widgets/__stories__/categorizer-editor.stories.tsx +0 -24
- package/src/widgets/__stories__/definition-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/dropdown-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/explanation-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/expression-editor.stories.tsx +0 -122
- package/src/widgets/__stories__/image-editor.stories.tsx +0 -72
- package/src/widgets/__stories__/input-number-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/interaction-editor.stories.tsx +0 -37
- package/src/widgets/__stories__/label-image-editor.stories.tsx +0 -99
- package/src/widgets/__stories__/matcher-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/number-line-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/numeric-input-editor.stories.tsx +0 -18
- package/src/widgets/__stories__/radio-editor.stories.tsx +0 -116
- package/src/widgets/__stories__/sorter-editor.stories.tsx +0 -18
- package/src/widgets/__tests__/categorizer-editor.test.tsx +0 -51
- package/src/widgets/__tests__/definition-editor.test.tsx +0 -41
- package/src/widgets/__tests__/dropdown-editor.test.tsx +0 -57
- package/src/widgets/__tests__/explanation-editor.test.tsx +0 -59
- package/src/widgets/__tests__/expression-editor.test.tsx +0 -403
- package/src/widgets/__tests__/input-number-editor.test.tsx +0 -128
- package/src/widgets/__tests__/matcher-editor.test.tsx +0 -47
- package/src/widgets/__tests__/number-line-editor.test.tsx +0 -144
- package/src/widgets/__tests__/numeric-input-editor.test.tsx +0 -177
- package/src/widgets/__tests__/radio-editor.test.tsx +0 -118
- package/src/widgets/__tests__/sorter-editor.test.tsx +0 -55
- package/src/widgets/categorizer-editor.tsx +0 -104
- package/src/widgets/cs-program-editor.tsx +0 -256
- package/src/widgets/definition-editor.tsx +0 -77
- package/src/widgets/deprecated-standin-editor.tsx +0 -29
- package/src/widgets/dropdown-editor.tsx +0 -211
- package/src/widgets/example-graphie-widget-editor.tsx +0 -70
- package/src/widgets/example-graphie-widget.tsx +0 -172
- package/src/widgets/example-widget-editor.tsx +0 -62
- package/src/widgets/example-widget.tsx +0 -154
- package/src/widgets/explanation-editor.tsx +0 -92
- package/src/widgets/expression-editor.tsx +0 -557
- package/src/widgets/graded-group-editor.tsx +0 -161
- package/src/widgets/graded-group-set-editor.tsx +0 -104
- package/src/widgets/grapher-editor.tsx +0 -155
- package/src/widgets/group-editor.tsx +0 -83
- package/src/widgets/iframe-editor.tsx +0 -202
- package/src/widgets/image-editor.tsx +0 -367
- package/src/widgets/input-number-editor.tsx +0 -288
- package/src/widgets/interaction-editor/constraint-editor.tsx +0 -134
- package/src/widgets/interaction-editor/function-editor.tsx +0 -108
- package/src/widgets/interaction-editor/index.ts +0 -3
- package/src/widgets/interaction-editor/interaction-editor.tsx +0 -749
- package/src/widgets/interaction-editor/label-editor.tsx +0 -87
- package/src/widgets/interaction-editor/line-editor.tsx +0 -125
- package/src/widgets/interaction-editor/mathquill-input.tsx +0 -81
- package/src/widgets/interaction-editor/movable-line-editor.tsx +0 -121
- package/src/widgets/interaction-editor/movable-point-editor.tsx +0 -89
- package/src/widgets/interaction-editor/parametric-editor.tsx +0 -117
- package/src/widgets/interaction-editor/point-editor.tsx +0 -72
- package/src/widgets/interaction-editor/rectangle-editor.tsx +0 -96
- package/src/widgets/interactive-graph-editor.tsx +0 -571
- package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -82
- package/src/widgets/label-image/__stories__/behavior.stories.tsx +0 -31
- package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -75
- package/src/widgets/label-image/__stories__/question-markers.stories.tsx +0 -107
- package/src/widgets/label-image/__stories__/select-image.stories.tsx +0 -59
- package/src/widgets/label-image/answer-choices.tsx +0 -231
- package/src/widgets/label-image/behavior.tsx +0 -122
- package/src/widgets/label-image/marker.tsx +0 -290
- package/src/widgets/label-image/question-markers.tsx +0 -176
- package/src/widgets/label-image/select-image.tsx +0 -81
- package/src/widgets/label-image-editor.tsx +0 -252
- package/src/widgets/lights-puzzle-editor.tsx +0 -278
- package/src/widgets/matcher-editor.tsx +0 -149
- package/src/widgets/matrix-editor.tsx +0 -156
- package/src/widgets/measurer-editor.tsx +0 -253
- package/src/widgets/molecule-editor.tsx +0 -64
- package/src/widgets/number-line-editor.tsx +0 -512
- package/src/widgets/numeric-input-editor.tsx +0 -536
- package/src/widgets/orderer-editor.tsx +0 -172
- package/src/widgets/passage-editor.tsx +0 -117
- package/src/widgets/passage-ref-editor.tsx +0 -80
- package/src/widgets/passage-ref-target-editor.tsx +0 -49
- package/src/widgets/plotter-editor.tsx +0 -542
- package/src/widgets/radio/editor.tsx +0 -398
- package/src/widgets/reaction-diagram-editor.tsx +0 -131
- package/src/widgets/sequence-editor.tsx +0 -205
- package/src/widgets/simple-markdown-tester-editor.tsx +0 -86
- package/src/widgets/simple-markdown-tester.tsx +0 -92
- package/src/widgets/simulator-editor.tsx +0 -146
- package/src/widgets/sorter-editor.tsx +0 -103
- package/src/widgets/table-editor.tsx +0 -164
- package/src/widgets/unit-editor.tsx +0 -299
- package/src/widgets/video-editor.tsx +0 -73
- package/tsconfig-build.json +0 -22
- package/tsconfig-build.tsbuildinfo +0 -1
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Changeable,
|
|
3
|
-
Dependencies,
|
|
4
|
-
EditorJsonify,
|
|
5
|
-
KhanColors,
|
|
6
|
-
ColorPicker,
|
|
7
|
-
} from "@khanacademy/perseus";
|
|
8
|
-
import * as React from "react";
|
|
9
|
-
import _ from "underscore";
|
|
10
|
-
|
|
11
|
-
import MathquillInput from "./mathquill-input";
|
|
12
|
-
|
|
13
|
-
const {getDependencies} = Dependencies;
|
|
14
|
-
|
|
15
|
-
type Props = Changeable.ChangeableProps & {
|
|
16
|
-
color: string;
|
|
17
|
-
coordX: string;
|
|
18
|
-
coordY: string;
|
|
19
|
-
height: string;
|
|
20
|
-
width: string;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
type DefaultProps = {
|
|
24
|
-
color: Props["color"];
|
|
25
|
-
coordX: Props["coordX"];
|
|
26
|
-
coordY: Props["coordY"];
|
|
27
|
-
height: Props["height"];
|
|
28
|
-
width: Props["width"];
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Editor for rectangles
|
|
32
|
-
class RectangleEditor extends React.Component<Props> {
|
|
33
|
-
static defaultProps: DefaultProps = {
|
|
34
|
-
coordX: "-5",
|
|
35
|
-
coordY: "5",
|
|
36
|
-
width: "2",
|
|
37
|
-
height: "3",
|
|
38
|
-
color: KhanColors.LIGHT_BLUE,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
change: (arg1: any, arg2?: any, arg3?: any) => any = (...args) => {
|
|
42
|
-
return Changeable.change.apply(this, args);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
serialize = () => {
|
|
46
|
-
return EditorJsonify.serialize.call(this);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
render(): React.ReactNode {
|
|
50
|
-
const {TeX} = getDependencies();
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<div className="graph-settings">
|
|
54
|
-
<div className="perseus-widget-row">
|
|
55
|
-
Bottom left: <TeX>\Large(</TeX>
|
|
56
|
-
<MathquillInput
|
|
57
|
-
value={this.props.coordX}
|
|
58
|
-
onChange={this.change("coordX")}
|
|
59
|
-
/>
|
|
60
|
-
<TeX>,</TeX>{" "}
|
|
61
|
-
<MathquillInput
|
|
62
|
-
value={this.props.coordY}
|
|
63
|
-
onChange={this.change("coordY")}
|
|
64
|
-
/>
|
|
65
|
-
<TeX>\Large)</TeX>
|
|
66
|
-
</div>
|
|
67
|
-
<div className="perseus-widget-row">
|
|
68
|
-
Width:{" "}
|
|
69
|
-
<MathquillInput
|
|
70
|
-
value={this.props.width}
|
|
71
|
-
onChange={this.change("width")}
|
|
72
|
-
/>
|
|
73
|
-
</div>
|
|
74
|
-
<div className="perseus-widget-row">
|
|
75
|
-
Height:{" "}
|
|
76
|
-
<MathquillInput
|
|
77
|
-
value={this.props.height}
|
|
78
|
-
onChange={this.change("height")}
|
|
79
|
-
/>
|
|
80
|
-
</div>
|
|
81
|
-
<div className="perseus-widget-row">
|
|
82
|
-
<ColorPicker
|
|
83
|
-
value={this.props.color}
|
|
84
|
-
lightColors={true}
|
|
85
|
-
onChange={this.change("color")}
|
|
86
|
-
/>
|
|
87
|
-
</div>
|
|
88
|
-
<div className="perseus-widget-row">
|
|
89
|
-
You want a border? Sorry, draw your own.
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export default RectangleEditor;
|
|
@@ -1,571 +0,0 @@
|
|
|
1
|
-
/* eslint-disable react/no-unsafe */
|
|
2
|
-
/* eslint-disable react/sort-comp */
|
|
3
|
-
import {
|
|
4
|
-
components,
|
|
5
|
-
interactiveSizes,
|
|
6
|
-
InteractiveGraphWidget,
|
|
7
|
-
SizingUtils,
|
|
8
|
-
Util,
|
|
9
|
-
} from "@khanacademy/perseus";
|
|
10
|
-
import {View} from "@khanacademy/wonder-blocks-core";
|
|
11
|
-
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
12
|
-
import * as Typography from "@khanacademy/wonder-blocks-typography";
|
|
13
|
-
import * as React from "react";
|
|
14
|
-
import _ from "underscore";
|
|
15
|
-
|
|
16
|
-
import GraphPointsCountSelector from "../components/graph-points-count-selector";
|
|
17
|
-
import GraphSettings from "../components/graph-settings";
|
|
18
|
-
import GraphTypeSelector from "../components/graph-type-selector";
|
|
19
|
-
import SegmentCountSelector from "../components/segment-count-selector";
|
|
20
|
-
import {parsePointCount} from "../util/points";
|
|
21
|
-
|
|
22
|
-
import type {
|
|
23
|
-
PerseusImageBackground,
|
|
24
|
-
PerseusInteractiveGraphWidgetOptions,
|
|
25
|
-
APIOptionsWithDefaults,
|
|
26
|
-
} from "@khanacademy/perseus";
|
|
27
|
-
import type {PropsFor, StyleType} from "@khanacademy/wonder-blocks-core";
|
|
28
|
-
|
|
29
|
-
const {InfoTip} = components;
|
|
30
|
-
const {containerSizeClass, getInteractiveBoxFromSizeClass} = SizingUtils;
|
|
31
|
-
const DeprecationMixin = Util.DeprecationMixin;
|
|
32
|
-
const InteractiveGraph = InteractiveGraphWidget.widget;
|
|
33
|
-
|
|
34
|
-
type InteractiveGraphProps = PropsFor<typeof InteractiveGraph>;
|
|
35
|
-
|
|
36
|
-
const defaultBackgroundImage = {
|
|
37
|
-
url: null,
|
|
38
|
-
} as const;
|
|
39
|
-
|
|
40
|
-
const deprecatedProps = {
|
|
41
|
-
showGraph: function (props) {
|
|
42
|
-
return {markings: props.showGraph ? "graph" : "none"};
|
|
43
|
-
},
|
|
44
|
-
} as const;
|
|
45
|
-
|
|
46
|
-
type Range = [number, number]; // [min, max]
|
|
47
|
-
|
|
48
|
-
// Renders the given children in a View laid out horizontally.
|
|
49
|
-
const Row = (props: {style?: StyleType; children: React.ReactNode}) => {
|
|
50
|
-
const {children, style} = props;
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<View
|
|
54
|
-
style={{
|
|
55
|
-
...style,
|
|
56
|
-
flexDirection: "row",
|
|
57
|
-
marginTop: Spacing.xSmall_8,
|
|
58
|
-
}}
|
|
59
|
-
>
|
|
60
|
-
{children}
|
|
61
|
-
</View>
|
|
62
|
-
);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const FieldLabel = (props: {children: string}) => {
|
|
66
|
-
return (
|
|
67
|
-
<Typography.LabelSmall style={{marginRight: Spacing.xSmall_8}}>
|
|
68
|
-
{props.children}
|
|
69
|
-
</Typography.LabelSmall>
|
|
70
|
-
);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
type Props = {
|
|
74
|
-
apiOptions: APIOptionsWithDefaults;
|
|
75
|
-
|
|
76
|
-
labels: ReadonlyArray<string>;
|
|
77
|
-
range: [Range, Range]; // x, y
|
|
78
|
-
step: [number, number]; // x, y
|
|
79
|
-
gridStep: [number, number]; // x, y
|
|
80
|
-
snapStep: [number, number]; // x, y
|
|
81
|
-
box: [number, number]; // x, y
|
|
82
|
-
|
|
83
|
-
valid: boolean;
|
|
84
|
-
backgroundImage: PerseusImageBackground;
|
|
85
|
-
markings: string; // TODO(jeremy)
|
|
86
|
-
showProtractor: boolean;
|
|
87
|
-
showRuler: boolean;
|
|
88
|
-
showTooltips: boolean;
|
|
89
|
-
rulerLabel: string;
|
|
90
|
-
rulerTicks: number;
|
|
91
|
-
correct: any; // TODO(jeremy)
|
|
92
|
-
|
|
93
|
-
graph: InteractiveGraphProps["graph"];
|
|
94
|
-
onChange: (props: Partial<Props>) => void;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
type DefaultProps = {
|
|
98
|
-
labels: Props["labels"];
|
|
99
|
-
range: Props["range"];
|
|
100
|
-
step: Props["step"];
|
|
101
|
-
valid: Props["valid"];
|
|
102
|
-
backgroundImage: Props["backgroundImage"];
|
|
103
|
-
markings: Props["markings"];
|
|
104
|
-
showProtractor: Props["showProtractor"];
|
|
105
|
-
showRuler: Props["showRuler"];
|
|
106
|
-
showTooltips: Props["showTooltips"];
|
|
107
|
-
rulerLabel: Props["rulerLabel"];
|
|
108
|
-
rulerTicks: Props["rulerTicks"];
|
|
109
|
-
correct: Props["correct"];
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
class InteractiveGraphEditor extends React.Component<Props> {
|
|
113
|
-
displayName = "InteractiveGraphEditor";
|
|
114
|
-
className = "perseus-widget-interactive-graph";
|
|
115
|
-
|
|
116
|
-
static widgetName = "interactive-graph";
|
|
117
|
-
|
|
118
|
-
static defaultProps: DefaultProps = {
|
|
119
|
-
...InteractiveGraph.defaultProps,
|
|
120
|
-
valid: true,
|
|
121
|
-
backgroundImage: defaultBackgroundImage,
|
|
122
|
-
showTooltips: false,
|
|
123
|
-
correct: {
|
|
124
|
-
type: InteractiveGraph.defaultProps.graph.type,
|
|
125
|
-
coords: null,
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// TODO(jack): Use versioning instead of DeprecationMixin
|
|
130
|
-
deprecatedProps = deprecatedProps;
|
|
131
|
-
|
|
132
|
-
// TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
|
|
133
|
-
UNSAFE_componentWillMount() {
|
|
134
|
-
DeprecationMixin.UNSAFE_componentWillMount.call(this);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
render() {
|
|
138
|
-
let graph;
|
|
139
|
-
let equationString;
|
|
140
|
-
|
|
141
|
-
const gridStep =
|
|
142
|
-
this.props.gridStep ||
|
|
143
|
-
Util.getGridStep(
|
|
144
|
-
this.props.range,
|
|
145
|
-
this.props.step,
|
|
146
|
-
interactiveSizes.defaultBoxSize,
|
|
147
|
-
);
|
|
148
|
-
const snapStep =
|
|
149
|
-
this.props.snapStep || Util.snapStepFromGridStep(gridStep);
|
|
150
|
-
|
|
151
|
-
const sizeClass = containerSizeClass.SMALL;
|
|
152
|
-
if (this.props.valid === true) {
|
|
153
|
-
// TODO(aria): send these down all at once
|
|
154
|
-
const graphProps = {
|
|
155
|
-
ref: "graph",
|
|
156
|
-
box: this.props.box,
|
|
157
|
-
range: this.props.range,
|
|
158
|
-
labels: this.props.labels,
|
|
159
|
-
step: this.props.step,
|
|
160
|
-
gridStep: gridStep,
|
|
161
|
-
snapStep: snapStep,
|
|
162
|
-
graph: this.props.correct,
|
|
163
|
-
backgroundImage: this.props.backgroundImage,
|
|
164
|
-
markings: this.props.markings,
|
|
165
|
-
showProtractor: this.props.showProtractor,
|
|
166
|
-
showRuler: this.props.showRuler,
|
|
167
|
-
rulerLabel: this.props.rulerLabel,
|
|
168
|
-
rulerTicks: this.props.rulerTicks,
|
|
169
|
-
trackInteraction: function () {},
|
|
170
|
-
onChange: (newProps: InteractiveGraphProps) => {
|
|
171
|
-
let correct = this.props.correct;
|
|
172
|
-
// @ts-expect-error - TS2532 - Object is possibly 'undefined'.
|
|
173
|
-
if (correct.type === newProps.graph.type) {
|
|
174
|
-
correct = _.extend({}, correct, newProps.graph);
|
|
175
|
-
} else {
|
|
176
|
-
// Clear options from previous graph
|
|
177
|
-
correct = newProps.graph;
|
|
178
|
-
}
|
|
179
|
-
this.props.onChange({correct: correct});
|
|
180
|
-
},
|
|
181
|
-
} as const;
|
|
182
|
-
graph = (
|
|
183
|
-
// There are a bunch of props that renderer.jsx passes to widgets via
|
|
184
|
-
// getWidgetProps() and widget-container.jsx that the editors don't
|
|
185
|
-
// bother passing.
|
|
186
|
-
// @ts-expect-error - TS2769 - No overload matches this call.
|
|
187
|
-
<InteractiveGraph
|
|
188
|
-
{...graphProps}
|
|
189
|
-
containerSizeClass={sizeClass}
|
|
190
|
-
apiOptions={{
|
|
191
|
-
...this.props.apiOptions,
|
|
192
|
-
isMobile: false,
|
|
193
|
-
}}
|
|
194
|
-
/>
|
|
195
|
-
);
|
|
196
|
-
// TODO(kevinb): Update getEquationString to only accept the data it actually
|
|
197
|
-
// needs to compute the equation string.
|
|
198
|
-
// @ts-expect-error - TS2345 - Argument of type '{ readonly ref: "graph"; readonly box: any; readonly range: any; readonly labels: any; readonly step: any; readonly gridStep: any; readonly snapStep: any; readonly graph: any; readonly backgroundImage: any; ... 6 more ...; readonly onChange: (newProps: Pick<...> & ... 1 more ... & InexactPartial<...>) => void; }' is not assignable to parameter of type 'Props'.
|
|
199
|
-
equationString = InteractiveGraph.getEquationString(graphProps);
|
|
200
|
-
} else {
|
|
201
|
-
graph = <div className="perseus-error">{this.props.valid}</div>;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return (
|
|
205
|
-
<View>
|
|
206
|
-
<Row>
|
|
207
|
-
<FieldLabel>Type of Graph:</FieldLabel>
|
|
208
|
-
<GraphTypeSelector
|
|
209
|
-
graphType={
|
|
210
|
-
this.props.graph?.type ??
|
|
211
|
-
InteractiveGraph.defaultProps.graph.type
|
|
212
|
-
}
|
|
213
|
-
onChange={(
|
|
214
|
-
type: Required<InteractiveGraphProps>["graph"]["type"],
|
|
215
|
-
) => {
|
|
216
|
-
this.props.onChange({
|
|
217
|
-
graph: {type},
|
|
218
|
-
correct: {type},
|
|
219
|
-
});
|
|
220
|
-
}}
|
|
221
|
-
/>
|
|
222
|
-
</Row>
|
|
223
|
-
{this.props.correct?.type === "point" && (
|
|
224
|
-
<Row>
|
|
225
|
-
<FieldLabel>Number of Points:</FieldLabel>
|
|
226
|
-
<GraphPointsCountSelector
|
|
227
|
-
numPoints={this.props.correct?.numPoints}
|
|
228
|
-
onChange={(points) => {
|
|
229
|
-
this.props.onChange({
|
|
230
|
-
correct: {
|
|
231
|
-
type: "point",
|
|
232
|
-
numPoints: points,
|
|
233
|
-
},
|
|
234
|
-
});
|
|
235
|
-
}}
|
|
236
|
-
/>
|
|
237
|
-
</Row>
|
|
238
|
-
)}
|
|
239
|
-
{this.props.correct?.type === "polygon" && (
|
|
240
|
-
<>
|
|
241
|
-
<Row>
|
|
242
|
-
<FieldLabel>Number of sides:</FieldLabel>
|
|
243
|
-
<select
|
|
244
|
-
key="polygon-select"
|
|
245
|
-
value={this.props.correct?.numSides || 3}
|
|
246
|
-
onChange={(e) => {
|
|
247
|
-
const graph = {
|
|
248
|
-
...this.props.correct,
|
|
249
|
-
numSides: parsePointCount(
|
|
250
|
-
e.target.value,
|
|
251
|
-
),
|
|
252
|
-
coords: null,
|
|
253
|
-
// reset the snap for UNLIMITED, which
|
|
254
|
-
// only supports "grid"
|
|
255
|
-
// From: D6578
|
|
256
|
-
snapTo: "grid",
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
this.props.onChange({correct: graph});
|
|
260
|
-
}}
|
|
261
|
-
>
|
|
262
|
-
{_.map(_.range(3, 13), function (n) {
|
|
263
|
-
return (
|
|
264
|
-
<option key={n} value={n}>
|
|
265
|
-
{`${n} sides`}
|
|
266
|
-
</option>
|
|
267
|
-
);
|
|
268
|
-
})}
|
|
269
|
-
<option value={"unlimited"}>
|
|
270
|
-
unlimited sides
|
|
271
|
-
</option>
|
|
272
|
-
</select>
|
|
273
|
-
</Row>
|
|
274
|
-
<Row>
|
|
275
|
-
<FieldLabel>Snap to:</FieldLabel>
|
|
276
|
-
<select
|
|
277
|
-
key="polygon-snap"
|
|
278
|
-
value={this.props.correct?.snapTo}
|
|
279
|
-
onChange={(e) => {
|
|
280
|
-
const graph = {
|
|
281
|
-
...this.props.correct,
|
|
282
|
-
snapTo: e.target.value,
|
|
283
|
-
coords: null,
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
this.props.onChange({correct: graph});
|
|
287
|
-
}}
|
|
288
|
-
>
|
|
289
|
-
<option value="grid">grid</option>
|
|
290
|
-
{this.props.correct?.numSides !==
|
|
291
|
-
"unlimited" && (
|
|
292
|
-
<React.Fragment>
|
|
293
|
-
<option value="angles">
|
|
294
|
-
interior angles
|
|
295
|
-
</option>
|
|
296
|
-
<option value="sides">
|
|
297
|
-
side measures
|
|
298
|
-
</option>
|
|
299
|
-
</React.Fragment>
|
|
300
|
-
)}
|
|
301
|
-
</select>
|
|
302
|
-
<InfoTip>
|
|
303
|
-
<p>
|
|
304
|
-
These options affect the movement of the
|
|
305
|
-
vertex points. The grid option will guide
|
|
306
|
-
the points to the nearest half step along
|
|
307
|
-
the grid.
|
|
308
|
-
</p>
|
|
309
|
-
<p>
|
|
310
|
-
The interior angle and side measure options
|
|
311
|
-
guide the points to the nearest whole angle
|
|
312
|
-
or side
|
|
313
|
-
</p>{" "}
|
|
314
|
-
measure respectively.
|
|
315
|
-
</InfoTip>
|
|
316
|
-
</Row>
|
|
317
|
-
<Row>
|
|
318
|
-
<Typography.LabelSmall tag="label">
|
|
319
|
-
Show angle measures:{" "}
|
|
320
|
-
<input
|
|
321
|
-
type="checkbox"
|
|
322
|
-
checked={this.props.correct?.showAngles}
|
|
323
|
-
onChange={() => {
|
|
324
|
-
this.props.onChange({
|
|
325
|
-
correct: {
|
|
326
|
-
...this.props.correct,
|
|
327
|
-
showAngles:
|
|
328
|
-
!this.props.correct
|
|
329
|
-
.showAngles,
|
|
330
|
-
},
|
|
331
|
-
});
|
|
332
|
-
}}
|
|
333
|
-
/>
|
|
334
|
-
</Typography.LabelSmall>
|
|
335
|
-
<InfoTip>
|
|
336
|
-
<p>Displays the interior angle measures.</p>
|
|
337
|
-
</InfoTip>
|
|
338
|
-
</Row>
|
|
339
|
-
<Row>
|
|
340
|
-
<Typography.LabelSmall tag="label">
|
|
341
|
-
Show side measures:{" "}
|
|
342
|
-
<input
|
|
343
|
-
type="checkbox"
|
|
344
|
-
checked={this.props.correct?.showSides}
|
|
345
|
-
onChange={() => {
|
|
346
|
-
this.props.onChange({
|
|
347
|
-
correct: {
|
|
348
|
-
...this.props.correct,
|
|
349
|
-
showSides:
|
|
350
|
-
!this.props.correct
|
|
351
|
-
.showSides,
|
|
352
|
-
},
|
|
353
|
-
});
|
|
354
|
-
}}
|
|
355
|
-
/>
|
|
356
|
-
</Typography.LabelSmall>
|
|
357
|
-
<InfoTip>
|
|
358
|
-
<p>Displays the side lengths.</p>
|
|
359
|
-
</InfoTip>
|
|
360
|
-
</Row>
|
|
361
|
-
</>
|
|
362
|
-
)}
|
|
363
|
-
{this.props.correct?.type === "segment" && (
|
|
364
|
-
<Row>
|
|
365
|
-
<FieldLabel>Number of segments: </FieldLabel>
|
|
366
|
-
<SegmentCountSelector
|
|
367
|
-
numSegments={this.props.correct?.numSegments}
|
|
368
|
-
onChange={(sides) => {
|
|
369
|
-
this.props.onChange({
|
|
370
|
-
correct: {
|
|
371
|
-
type: "segment",
|
|
372
|
-
numSegments: sides,
|
|
373
|
-
coords: null,
|
|
374
|
-
},
|
|
375
|
-
});
|
|
376
|
-
}}
|
|
377
|
-
/>
|
|
378
|
-
</Row>
|
|
379
|
-
)}
|
|
380
|
-
|
|
381
|
-
<Row>
|
|
382
|
-
<FieldLabel>Correct answer:</FieldLabel>
|
|
383
|
-
<Typography.BodyMonospace
|
|
384
|
-
style={{
|
|
385
|
-
fontSize: 12,
|
|
386
|
-
backgroundColor: "#eee",
|
|
387
|
-
paddingInline: Spacing.xxSmall_6,
|
|
388
|
-
borderColor: "#ccc",
|
|
389
|
-
borderStyle: "solid",
|
|
390
|
-
borderWidth: 1,
|
|
391
|
-
}}
|
|
392
|
-
>
|
|
393
|
-
{equationString}
|
|
394
|
-
</Typography.BodyMonospace>
|
|
395
|
-
<InfoTip>
|
|
396
|
-
<p>
|
|
397
|
-
Graph the correct answer in the graph below and
|
|
398
|
-
ensure the equation or point coordinates displayed
|
|
399
|
-
represent the correct answer.
|
|
400
|
-
</p>
|
|
401
|
-
</InfoTip>
|
|
402
|
-
</Row>
|
|
403
|
-
<GraphSettings
|
|
404
|
-
box={getInteractiveBoxFromSizeClass(sizeClass)}
|
|
405
|
-
range={this.props.range}
|
|
406
|
-
labels={this.props.labels}
|
|
407
|
-
step={this.props.step}
|
|
408
|
-
gridStep={gridStep}
|
|
409
|
-
snapStep={snapStep}
|
|
410
|
-
valid={this.props.valid}
|
|
411
|
-
backgroundImage={this.props.backgroundImage}
|
|
412
|
-
markings={this.props.markings}
|
|
413
|
-
showProtractor={this.props.showProtractor}
|
|
414
|
-
showRuler={this.props.showRuler}
|
|
415
|
-
showTooltips={this.props.showTooltips}
|
|
416
|
-
rulerLabel={this.props.rulerLabel}
|
|
417
|
-
rulerTicks={this.props.rulerTicks}
|
|
418
|
-
onChange={this.props.onChange}
|
|
419
|
-
/>
|
|
420
|
-
{this.props.correct.type === "polygon" && (
|
|
421
|
-
<div className="type-settings">
|
|
422
|
-
<label>
|
|
423
|
-
{" "}
|
|
424
|
-
Student answer must{" "}
|
|
425
|
-
<select
|
|
426
|
-
value={this.props.correct.match}
|
|
427
|
-
onChange={this.changeMatchType}
|
|
428
|
-
>
|
|
429
|
-
<option value="exact">match exactly</option>
|
|
430
|
-
<option value="congruent">be congruent</option>
|
|
431
|
-
<option value="approx">
|
|
432
|
-
be approximately congruent
|
|
433
|
-
</option>
|
|
434
|
-
<option value="similar">be similar</option>
|
|
435
|
-
</select>
|
|
436
|
-
</label>
|
|
437
|
-
<InfoTip>
|
|
438
|
-
<ul>
|
|
439
|
-
<li>
|
|
440
|
-
<p>
|
|
441
|
-
<b>Match Exactly:</b> Match exactly in
|
|
442
|
-
size, orientation, and location on the
|
|
443
|
-
grid even if it is not shown in the
|
|
444
|
-
background.
|
|
445
|
-
</p>
|
|
446
|
-
</li>
|
|
447
|
-
<li>
|
|
448
|
-
<p>
|
|
449
|
-
<b>Be Congruent:</b> Be congruent in
|
|
450
|
-
size and shape, but can be located
|
|
451
|
-
anywhere on the grid.
|
|
452
|
-
</p>
|
|
453
|
-
</li>
|
|
454
|
-
<li>
|
|
455
|
-
<p>
|
|
456
|
-
<b>Be Approximately Congruent:</b> Be
|
|
457
|
-
exactly similar, and congruent in size
|
|
458
|
-
and shape to within 0.1 units, but can
|
|
459
|
-
be located anywhere on the grid.{" "}
|
|
460
|
-
<em>
|
|
461
|
-
Use this with snapping to angle
|
|
462
|
-
measure.
|
|
463
|
-
</em>
|
|
464
|
-
</p>
|
|
465
|
-
</li>
|
|
466
|
-
<li>
|
|
467
|
-
<p>
|
|
468
|
-
<b>Be Similar:</b> Be similar with
|
|
469
|
-
matching interior angles, and side
|
|
470
|
-
measures that are matching or a multiple
|
|
471
|
-
of the correct side measures. The figure
|
|
472
|
-
can be located anywhere on the grid.
|
|
473
|
-
</p>
|
|
474
|
-
</li>
|
|
475
|
-
</ul>
|
|
476
|
-
</InfoTip>
|
|
477
|
-
</div>
|
|
478
|
-
)}
|
|
479
|
-
{this.props.correct.type === "angle" && (
|
|
480
|
-
<div className="type-settings">
|
|
481
|
-
<div>
|
|
482
|
-
<label>
|
|
483
|
-
{" "}
|
|
484
|
-
Student answer must{" "}
|
|
485
|
-
<select
|
|
486
|
-
value={this.props.correct.match}
|
|
487
|
-
onChange={this.changeMatchType}
|
|
488
|
-
>
|
|
489
|
-
<option value="exact">match exactly</option>
|
|
490
|
-
<option value="congruent">
|
|
491
|
-
be congruent
|
|
492
|
-
</option>
|
|
493
|
-
</select>
|
|
494
|
-
</label>
|
|
495
|
-
<InfoTip>
|
|
496
|
-
<p>
|
|
497
|
-
Congruency requires only that the angle
|
|
498
|
-
measures are the same. An exact match
|
|
499
|
-
implies congruency, but also requires that
|
|
500
|
-
the angles have the same orientation and
|
|
501
|
-
that the vertices are in the same position.
|
|
502
|
-
</p>
|
|
503
|
-
</InfoTip>
|
|
504
|
-
</div>
|
|
505
|
-
</div>
|
|
506
|
-
)}
|
|
507
|
-
{graph}
|
|
508
|
-
</View>
|
|
509
|
-
);
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
changeMatchType(e) {
|
|
513
|
-
const correct = _.extend({}, this.props.correct, {
|
|
514
|
-
match: e.target.value,
|
|
515
|
-
});
|
|
516
|
-
this.props.onChange({correct: correct});
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
serialize(): PerseusInteractiveGraphWidgetOptions {
|
|
520
|
-
const json = _.pick(
|
|
521
|
-
this.props,
|
|
522
|
-
"step",
|
|
523
|
-
"backgroundImage",
|
|
524
|
-
"markings",
|
|
525
|
-
"labels",
|
|
526
|
-
"showProtractor",
|
|
527
|
-
"showRuler",
|
|
528
|
-
"showTooltips",
|
|
529
|
-
"rulerLabel",
|
|
530
|
-
"rulerTicks",
|
|
531
|
-
"range",
|
|
532
|
-
"gridStep",
|
|
533
|
-
"snapStep",
|
|
534
|
-
);
|
|
535
|
-
|
|
536
|
-
// eslint-disable-next-line react/no-string-refs
|
|
537
|
-
const graph = this.refs.graph;
|
|
538
|
-
if (graph) {
|
|
539
|
-
// @ts-expect-error TS2339 Property 'getUserInput' does not exist on type 'ReactInstance'. Property 'getUserInput' does not exist on type 'Component<any, {}, any>'.
|
|
540
|
-
const correct = graph && graph.getUserInput();
|
|
541
|
-
_.extend(json, {
|
|
542
|
-
graph: {type: correct.type},
|
|
543
|
-
correct: correct,
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
_.each(
|
|
547
|
-
[
|
|
548
|
-
"allowReflexAngles",
|
|
549
|
-
"angleOffsetDeg",
|
|
550
|
-
"numPoints",
|
|
551
|
-
"numSides",
|
|
552
|
-
"numSegments",
|
|
553
|
-
"showAngles",
|
|
554
|
-
"showSides",
|
|
555
|
-
"snapTo",
|
|
556
|
-
"snapDegrees",
|
|
557
|
-
],
|
|
558
|
-
function (key) {
|
|
559
|
-
if (_.has(correct, key)) {
|
|
560
|
-
// @ts-expect-error - TS2339 - Property 'graph' does not exist on type 'Pick<any, "step" | "range" | "backgroundImage" | "snapStep" | "labels" | "showTooltips" | "markings" | "gridStep" | "showProtractor" | "showRuler" | "rulerLabel" | "rulerTicks">'.
|
|
561
|
-
json.graph[key] = correct[key];
|
|
562
|
-
}
|
|
563
|
-
},
|
|
564
|
-
);
|
|
565
|
-
}
|
|
566
|
-
// @ts-expect-error TS2739 Type 'Pick<Readonly<Props> & Readonly<{ children?: ReactNode; }>, "step" | "gridStep" | "snapStep" | "backgroundImage" | "markings" | "labels" | ... 5 more ... | "range">' is missing the following properties from type 'PerseusInteractiveGraphWidgetOptions': graph, correct
|
|
567
|
-
return json;
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
export default InteractiveGraphEditor;
|