@khanacademy/perseus-editor 2.7.7 → 2.8.1
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 +27 -0
- package/dist/es/index.js +116 -75
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +117 -75
- package/dist/index.js.map +1 -1
- package/dist/widgets/expression-editor.d.ts +4 -4
- package/package.json +5 -5
- package/src/widgets/expression-editor.tsx +43 -20
- package/src/widgets/interaction/constraint-editor.tsx +8 -6
- package/src/widgets/interaction-editor.tsx +33 -25
- package/tsconfig-build.tsbuildinfo +1 -1
|
@@ -24,10 +24,10 @@ declare class ExpressionEditor extends React.Component<Props, State> {
|
|
|
24
24
|
getSaveWarnings: () => any;
|
|
25
25
|
_newEmptyAnswerForm: () => any;
|
|
26
26
|
newAnswer: () => void;
|
|
27
|
-
handleRemoveForm: (
|
|
28
|
-
updateForm: (
|
|
29
|
-
handleReorder: (
|
|
30
|
-
handleButtonSet: (
|
|
27
|
+
handleRemoveForm: (answerKey: number) => void;
|
|
28
|
+
updateForm: (i: number, props: any) => void;
|
|
29
|
+
handleReorder: (components: any) => void;
|
|
30
|
+
handleButtonSet: (changingName: string) => void;
|
|
31
31
|
handleToggleDiv: () => void;
|
|
32
32
|
handleTexInsert: (arg1: string) => void;
|
|
33
33
|
handleFunctions: (arg1: React.ChangeEvent<HTMLInputElement>) => void;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Perseus editors",
|
|
4
4
|
"author": "Khan Academy",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.8.1",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"test": "bash -c 'yarn --silent --cwd \"../..\" test ${@:0} $($([[ ${@: -1} = -* ]] || [[ ${@: -1} = bash ]]) && echo $PWD)'"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@khanacademy/kas": "^0.3.
|
|
26
|
-
"@khanacademy/kmath": "^0.1.
|
|
27
|
-
"@khanacademy/perseus": "^
|
|
28
|
-
"@khanacademy/perseus-core": "1.1.
|
|
25
|
+
"@khanacademy/kas": "^0.3.3",
|
|
26
|
+
"@khanacademy/kmath": "^0.1.4",
|
|
27
|
+
"@khanacademy/perseus": "^12.0.1",
|
|
28
|
+
"@khanacademy/perseus-core": "1.1.2"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@khanacademy/wonder-blocks-button": "^4.1.3",
|
|
@@ -26,6 +26,10 @@ type Props = {
|
|
|
26
26
|
} & Omit<PerseusExpressionWidgetOptions, "buttonsVisible"> &
|
|
27
27
|
Changeable.ChangeableProps;
|
|
28
28
|
|
|
29
|
+
// types for iterables
|
|
30
|
+
type AnswerForm = PerseusExpressionWidgetOptions["answerForms"][number];
|
|
31
|
+
type LegacyButtonSet = PerseusExpressionWidgetOptions["buttonSets"][number];
|
|
32
|
+
|
|
29
33
|
type DefaultProps = {
|
|
30
34
|
answerForms: Props["answerForms"];
|
|
31
35
|
times: Props["times"];
|
|
@@ -33,14 +37,22 @@ type DefaultProps = {
|
|
|
33
37
|
functions: Props["functions"];
|
|
34
38
|
};
|
|
35
39
|
|
|
40
|
+
const parseAnswerKey = ({key}: AnswerForm): number => {
|
|
41
|
+
const parsedKey = Number.parseInt(key ?? "");
|
|
42
|
+
if (Number.isNaN(parsedKey)) {
|
|
43
|
+
throw new Error(`Invalid answer key: ${key}`);
|
|
44
|
+
}
|
|
45
|
+
return parsedKey;
|
|
46
|
+
};
|
|
47
|
+
|
|
36
48
|
// Pick a key that isn't currently used by an answer in answerForms
|
|
37
|
-
const _makeNewKey = (answerForms:
|
|
49
|
+
const _makeNewKey = (answerForms: ReadonlyArray<AnswerForm>) => {
|
|
38
50
|
// first note all the currently used keys in an array, used like a map :3
|
|
39
51
|
// note that this automatically updates the array's length property to
|
|
40
52
|
// be one past the largest key.
|
|
41
53
|
const usedKeys: Array<boolean> = [];
|
|
42
54
|
answerForms.forEach((ans) => {
|
|
43
|
-
usedKeys[ans
|
|
55
|
+
usedKeys[parseAnswerKey(ans)] = true;
|
|
44
56
|
});
|
|
45
57
|
|
|
46
58
|
// then scan through the array to find the first unused (undefined) key
|
|
@@ -98,7 +110,9 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
98
110
|
|
|
99
111
|
render(): React.ReactNode {
|
|
100
112
|
const answerOptions = this.props.answerForms
|
|
101
|
-
.map((
|
|
113
|
+
.map((ans: AnswerForm) => {
|
|
114
|
+
const key = parseAnswerKey(ans);
|
|
115
|
+
|
|
102
116
|
const expressionProps = {
|
|
103
117
|
// note we're using
|
|
104
118
|
// *this.props*.{times,functions,buttonSets} since each
|
|
@@ -108,26 +122,30 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
108
122
|
buttonSets: this.props.buttonSets,
|
|
109
123
|
|
|
110
124
|
buttonsVisible: "focused",
|
|
111
|
-
form:
|
|
112
|
-
simplify:
|
|
113
|
-
value:
|
|
125
|
+
form: ans.form,
|
|
126
|
+
simplify: ans.simplify,
|
|
127
|
+
value: ans.value,
|
|
114
128
|
|
|
115
|
-
onChange: (props) => this.updateForm(
|
|
129
|
+
onChange: (props) => this.updateForm(key, props),
|
|
116
130
|
trackInteraction: () => {},
|
|
117
131
|
|
|
118
|
-
widgetId: this.props.widgetId + "-" +
|
|
132
|
+
widgetId: this.props.widgetId + "-" + ans.key,
|
|
119
133
|
} as const;
|
|
120
134
|
|
|
121
|
-
return lens(
|
|
135
|
+
return lens(ans)
|
|
122
136
|
.merge([], {
|
|
123
137
|
draggable: true,
|
|
124
|
-
onChange: (props) =>
|
|
125
|
-
|
|
138
|
+
onChange: (props) =>
|
|
139
|
+
this.updateForm(
|
|
140
|
+
Number.parseInt(ans.key ?? ""),
|
|
141
|
+
props,
|
|
142
|
+
),
|
|
143
|
+
onDelete: () => this.handleRemoveForm(key),
|
|
126
144
|
expressionProps: expressionProps,
|
|
127
145
|
})
|
|
128
146
|
.freeze();
|
|
129
147
|
})
|
|
130
|
-
.map((obj
|
|
148
|
+
.map((obj) => <AnswerOption key={obj.key} {...obj} />);
|
|
131
149
|
|
|
132
150
|
const sortable = (
|
|
133
151
|
<SortableArea
|
|
@@ -143,7 +161,10 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
143
161
|
// The first one gets special cased to always be checked, disabled,
|
|
144
162
|
// and float left.
|
|
145
163
|
const isFirst = name === "basic";
|
|
146
|
-
const checked =
|
|
164
|
+
const checked =
|
|
165
|
+
this.props.buttonSets.includes(
|
|
166
|
+
name as PerseusExpressionWidgetOptions["buttonSets"][number],
|
|
167
|
+
) || isFirst;
|
|
147
168
|
const className = isFirst
|
|
148
169
|
? "button-set-label-float"
|
|
149
170
|
: "button-set-label";
|
|
@@ -342,7 +363,7 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
342
363
|
this.change({answerForms});
|
|
343
364
|
};
|
|
344
365
|
|
|
345
|
-
handleRemoveForm: (
|
|
366
|
+
handleRemoveForm: (answerKey: number) => void = (i) => {
|
|
346
367
|
const answerForms = this.props.answerForms.slice();
|
|
347
368
|
answerForms.splice(i, 1);
|
|
348
369
|
this.change({answerForms});
|
|
@@ -350,7 +371,7 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
350
371
|
|
|
351
372
|
// called when the options (including the expression itself) to an answer
|
|
352
373
|
// form change
|
|
353
|
-
updateForm: (
|
|
374
|
+
updateForm: (i: number, props: any) => void = (i, props) => {
|
|
354
375
|
const answerForms = lens(this.props.answerForms)
|
|
355
376
|
.merge([i], props)
|
|
356
377
|
.freeze();
|
|
@@ -358,7 +379,7 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
358
379
|
this.change({answerForms});
|
|
359
380
|
};
|
|
360
381
|
|
|
361
|
-
handleReorder: (
|
|
382
|
+
handleReorder: (components: any) => void = (components) => {
|
|
362
383
|
const answerForms = components.map((component) => {
|
|
363
384
|
const form = _(component.props).pick(
|
|
364
385
|
"considered",
|
|
@@ -375,8 +396,10 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
375
396
|
};
|
|
376
397
|
|
|
377
398
|
// called when the selected buttonset changes
|
|
378
|
-
handleButtonSet: (
|
|
379
|
-
const buttonSetNames = Object.keys(
|
|
399
|
+
handleButtonSet: (changingName: string) => void = (changingName) => {
|
|
400
|
+
const buttonSetNames = Object.keys(
|
|
401
|
+
TexButtons.buttonSets,
|
|
402
|
+
) as LegacyButtonSet[];
|
|
380
403
|
|
|
381
404
|
// Filter to preserve order - using .union and .difference would always
|
|
382
405
|
// move the last added button set to the end.
|
|
@@ -394,8 +417,8 @@ class ExpressionEditor extends React.Component<Props, State> {
|
|
|
394
417
|
// "basic+div". Toggle between the two of them.
|
|
395
418
|
// If someone can think of a more elegant formulation of this (there
|
|
396
419
|
// must be one!) feel free to change it.
|
|
397
|
-
let keep:
|
|
398
|
-
let remove:
|
|
420
|
+
let keep: LegacyButtonSet | undefined;
|
|
421
|
+
let remove: LegacyButtonSet | undefined;
|
|
399
422
|
if (this.props.buttonSets.includes("basic+div")) {
|
|
400
423
|
keep = "basic";
|
|
401
424
|
remove = "basic+div";
|
|
@@ -45,6 +45,8 @@ class ConstraintEditor extends React.Component<Props> {
|
|
|
45
45
|
render(): React.ReactNode {
|
|
46
46
|
const {TeX} = Dependencies.getDependencies();
|
|
47
47
|
|
|
48
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
49
|
+
|
|
48
50
|
return (
|
|
49
51
|
<div>
|
|
50
52
|
<div className="perseus-widget-row">
|
|
@@ -76,10 +78,10 @@ class ConstraintEditor extends React.Component<Props> {
|
|
|
76
78
|
<div className="perseus-widget-row">
|
|
77
79
|
<TeX>x=</TeX>{" "}
|
|
78
80
|
<MathInput
|
|
79
|
-
buttonSets={[]}
|
|
80
81
|
buttonsVisible="never"
|
|
81
82
|
value={this.props.constraintFn}
|
|
82
83
|
onChange={this.change("constraintFn")}
|
|
84
|
+
analytics={analyticsStub}
|
|
83
85
|
/>
|
|
84
86
|
</div>
|
|
85
87
|
</div>
|
|
@@ -89,10 +91,10 @@ class ConstraintEditor extends React.Component<Props> {
|
|
|
89
91
|
<div className="perseus-widget-row">
|
|
90
92
|
<TeX>y=</TeX>{" "}
|
|
91
93
|
<MathInput
|
|
92
|
-
buttonSets={[]}
|
|
93
94
|
buttonsVisible="never"
|
|
94
95
|
value={this.props.constraintFn}
|
|
95
96
|
onChange={this.change("constraintFn")}
|
|
97
|
+
analytics={analyticsStub}
|
|
96
98
|
/>
|
|
97
99
|
</div>
|
|
98
100
|
</div>
|
|
@@ -102,17 +104,17 @@ class ConstraintEditor extends React.Component<Props> {
|
|
|
102
104
|
<div className="perseus-widget-row">
|
|
103
105
|
<TeX>x \in \Large[</TeX>{" "}
|
|
104
106
|
<MathInput
|
|
105
|
-
buttonSets={[]}
|
|
106
107
|
buttonsVisible="never"
|
|
107
108
|
value={this.props.constraintXMin}
|
|
108
109
|
onChange={this.change("constraintXMin")}
|
|
110
|
+
analytics={analyticsStub}
|
|
109
111
|
/>
|
|
110
112
|
<TeX>, </TeX>{" "}
|
|
111
113
|
<MathInput
|
|
112
|
-
buttonSets={[]}
|
|
113
114
|
buttonsVisible="never"
|
|
114
115
|
value={this.props.constraintXMax}
|
|
115
116
|
onChange={this.change("constraintXMax")}
|
|
117
|
+
analytics={analyticsStub}
|
|
116
118
|
/>{" "}
|
|
117
119
|
<TeX>\Large]</TeX>
|
|
118
120
|
</div>
|
|
@@ -121,17 +123,17 @@ class ConstraintEditor extends React.Component<Props> {
|
|
|
121
123
|
<div className="perseus-widget-row">
|
|
122
124
|
<TeX>y \in \Large[</TeX>{" "}
|
|
123
125
|
<MathInput
|
|
124
|
-
buttonSets={[]}
|
|
125
126
|
buttonsVisible="never"
|
|
126
127
|
value={this.props.constraintYMin}
|
|
127
128
|
onChange={this.change("constraintYMin")}
|
|
129
|
+
analytics={analyticsStub}
|
|
128
130
|
/>
|
|
129
131
|
<TeX>, </TeX>{" "}
|
|
130
132
|
<MathInput
|
|
131
|
-
buttonSets={[]}
|
|
132
133
|
buttonsVisible="never"
|
|
133
134
|
value={this.props.constraintYMax}
|
|
134
135
|
onChange={this.change("constraintYMax")}
|
|
136
|
+
analytics={analyticsStub}
|
|
135
137
|
/>{" "}
|
|
136
138
|
<TeX>\Large]</TeX>
|
|
137
139
|
</div>
|
|
@@ -62,25 +62,26 @@ class PointEditor extends React.Component<PointEditorProps> {
|
|
|
62
62
|
|
|
63
63
|
render(): React.ReactNode {
|
|
64
64
|
const {TeX} = getDependencies();
|
|
65
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
65
66
|
|
|
66
67
|
return (
|
|
67
68
|
<div className="graph-settings">
|
|
68
69
|
<div className="perseus-widget-row">
|
|
69
70
|
Coordinate: <TeX>\Large(</TeX>
|
|
70
71
|
<MathInput
|
|
71
|
-
buttonSets={[]}
|
|
72
72
|
buttonsVisible="never"
|
|
73
73
|
value={this.props.coordX}
|
|
74
74
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
75
75
|
onChange={this.change("coordX")}
|
|
76
|
+
analytics={analyticsStub}
|
|
76
77
|
/>
|
|
77
78
|
<TeX>,</TeX>{" "}
|
|
78
79
|
<MathInput
|
|
79
|
-
buttonSets={[]}
|
|
80
80
|
buttonsVisible="never"
|
|
81
81
|
value={this.props.coordY}
|
|
82
82
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
83
83
|
onChange={this.change("coordY")}
|
|
84
|
+
analytics={analyticsStub}
|
|
84
85
|
/>
|
|
85
86
|
<TeX>\Large)</TeX>
|
|
86
87
|
</div>
|
|
@@ -137,44 +138,45 @@ class LineEditor extends React.Component<LineEditorProps> {
|
|
|
137
138
|
|
|
138
139
|
render(): React.ReactNode {
|
|
139
140
|
const {TeX} = getDependencies();
|
|
141
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
140
142
|
|
|
141
143
|
return (
|
|
142
144
|
<div className="graph-settings">
|
|
143
145
|
<div className="perseus-widget-row">
|
|
144
146
|
Start: <TeX>\Large(</TeX>
|
|
145
147
|
<MathInput
|
|
146
|
-
buttonSets={[]}
|
|
147
148
|
buttonsVisible="never"
|
|
148
149
|
value={this.props.startX}
|
|
149
150
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
150
151
|
onChange={this.change("startX")}
|
|
152
|
+
analytics={analyticsStub}
|
|
151
153
|
/>
|
|
152
154
|
<TeX>,</TeX>{" "}
|
|
153
155
|
<MathInput
|
|
154
|
-
buttonSets={[]}
|
|
155
156
|
buttonsVisible="never"
|
|
156
157
|
value={this.props.startY}
|
|
157
158
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
158
159
|
onChange={this.change("startY")}
|
|
160
|
+
analytics={analyticsStub}
|
|
159
161
|
/>
|
|
160
162
|
<TeX>\Large)</TeX>
|
|
161
163
|
</div>
|
|
162
164
|
<div className="perseus-widget-row">
|
|
163
165
|
End: <TeX>\Large(</TeX>
|
|
164
166
|
<MathInput
|
|
165
|
-
buttonSets={[]}
|
|
166
167
|
buttonsVisible="never"
|
|
167
168
|
value={this.props.endX}
|
|
168
169
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
169
170
|
onChange={this.change("endX")}
|
|
171
|
+
analytics={analyticsStub}
|
|
170
172
|
/>
|
|
171
173
|
<TeX>,</TeX>{" "}
|
|
172
174
|
<MathInput
|
|
173
|
-
buttonSets={[]}
|
|
174
175
|
buttonsVisible="never"
|
|
175
176
|
value={this.props.endY}
|
|
176
177
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
177
178
|
onChange={this.change("endY")}
|
|
179
|
+
analytics={analyticsStub}
|
|
178
180
|
/>
|
|
179
181
|
<TeX>\Large)</TeX>
|
|
180
182
|
</div>
|
|
@@ -254,23 +256,24 @@ class MovablePointEditor extends React.Component<MovablePointEditorProps> {
|
|
|
254
256
|
|
|
255
257
|
render(): React.ReactNode {
|
|
256
258
|
const {TeX} = getDependencies();
|
|
259
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
257
260
|
|
|
258
261
|
return (
|
|
259
262
|
<div className="graph-settings">
|
|
260
263
|
<div className="perseus-widget-row">
|
|
261
264
|
Start: <TeX>\Large(</TeX>
|
|
262
265
|
<MathInput
|
|
263
|
-
buttonSets={[]}
|
|
264
266
|
buttonsVisible="never"
|
|
265
267
|
value={this.props.startX}
|
|
266
268
|
onChange={this.change("startX")}
|
|
269
|
+
analytics={analyticsStub}
|
|
267
270
|
/>
|
|
268
271
|
<TeX>,</TeX>{" "}
|
|
269
272
|
<MathInput
|
|
270
|
-
buttonSets={[]}
|
|
271
273
|
buttonsVisible="never"
|
|
272
274
|
value={this.props.startY}
|
|
273
275
|
onChange={this.change("startY")}
|
|
276
|
+
analytics={analyticsStub}
|
|
274
277
|
/>
|
|
275
278
|
<TeX>\Large)</TeX>
|
|
276
279
|
</div>
|
|
@@ -333,6 +336,7 @@ class MovableLineEditor extends React.Component<MovableLineEditorProps> {
|
|
|
333
336
|
|
|
334
337
|
render(): React.ReactNode {
|
|
335
338
|
const {TeX} = getDependencies();
|
|
339
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
336
340
|
|
|
337
341
|
return (
|
|
338
342
|
<div className="graph-settings">
|
|
@@ -340,34 +344,34 @@ class MovableLineEditor extends React.Component<MovableLineEditorProps> {
|
|
|
340
344
|
<div className="perseus-widget-row">
|
|
341
345
|
Start: <TeX>\Large(</TeX>
|
|
342
346
|
<MathInput
|
|
343
|
-
buttonSets={[]}
|
|
344
347
|
buttonsVisible="never"
|
|
345
348
|
value={this.props.startX}
|
|
346
349
|
onChange={this.change("startX")}
|
|
350
|
+
analytics={analyticsStub}
|
|
347
351
|
/>
|
|
348
352
|
<TeX>,</TeX>{" "}
|
|
349
353
|
<MathInput
|
|
350
|
-
buttonSets={[]}
|
|
351
354
|
buttonsVisible="never"
|
|
352
355
|
value={this.props.startY}
|
|
353
356
|
onChange={this.change("startY")}
|
|
357
|
+
analytics={analyticsStub}
|
|
354
358
|
/>
|
|
355
359
|
<TeX>\Large)</TeX>
|
|
356
360
|
</div>
|
|
357
361
|
<div className="perseus-widget-row">
|
|
358
362
|
End: <TeX>\Large(</TeX>
|
|
359
363
|
<MathInput
|
|
360
|
-
buttonSets={[]}
|
|
361
364
|
buttonsVisible="never"
|
|
362
365
|
value={this.props.endX}
|
|
363
366
|
onChange={this.change("endX")}
|
|
367
|
+
analytics={analyticsStub}
|
|
364
368
|
/>
|
|
365
369
|
<TeX>,</TeX>{" "}
|
|
366
370
|
<MathInput
|
|
367
|
-
buttonSets={[]}
|
|
368
371
|
buttonsVisible="never"
|
|
369
372
|
value={this.props.endY}
|
|
370
373
|
onChange={this.change("endY")}
|
|
374
|
+
analytics={analyticsStub}
|
|
371
375
|
/>
|
|
372
376
|
<TeX>\Large)</TeX>
|
|
373
377
|
</div>
|
|
@@ -434,35 +438,36 @@ class FunctionEditor extends React.Component<FunctionEditorProps> {
|
|
|
434
438
|
|
|
435
439
|
render(): React.ReactNode {
|
|
436
440
|
const {TeX} = getDependencies();
|
|
441
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
437
442
|
|
|
438
443
|
return (
|
|
439
444
|
<div className="graph-settings">
|
|
440
445
|
<div className="perseus-widget-row">
|
|
441
446
|
<TeX>{this.props.funcName + "(x)="}</TeX>{" "}
|
|
442
447
|
<MathInput
|
|
443
|
-
buttonSets={[]}
|
|
444
448
|
buttonsVisible="never"
|
|
445
449
|
value={this.props.value}
|
|
446
450
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
447
451
|
onChange={this.change("value")}
|
|
452
|
+
analytics={analyticsStub}
|
|
448
453
|
/>
|
|
449
454
|
</div>
|
|
450
455
|
<div className="perseus-widget-row">
|
|
451
456
|
Range: <TeX>\Large(</TeX>
|
|
452
457
|
<MathInput
|
|
453
|
-
buttonSets={[]}
|
|
454
458
|
buttonsVisible="never"
|
|
455
459
|
value={this.props.rangeMin}
|
|
456
460
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
457
461
|
onChange={this.change("rangeMin")}
|
|
462
|
+
analytics={analyticsStub}
|
|
458
463
|
/>
|
|
459
464
|
<TeX>,</TeX>{" "}
|
|
460
465
|
<MathInput
|
|
461
|
-
buttonSets={[]}
|
|
462
466
|
buttonsVisible="never"
|
|
463
467
|
value={this.props.rangeMax}
|
|
464
468
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
465
469
|
onChange={this.change("rangeMax")}
|
|
470
|
+
analytics={analyticsStub}
|
|
466
471
|
/>
|
|
467
472
|
<TeX>\Large)</TeX>
|
|
468
473
|
</div>
|
|
@@ -535,45 +540,46 @@ class ParametricEditor extends React.Component<ParametricEditorProps> {
|
|
|
535
540
|
|
|
536
541
|
render(): React.ReactNode {
|
|
537
542
|
const {TeX} = getDependencies();
|
|
543
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
538
544
|
|
|
539
545
|
return (
|
|
540
546
|
<div className="graph-settings">
|
|
541
547
|
<div className="perseus-widget-row">
|
|
542
548
|
<TeX>X(t) =</TeX>{" "}
|
|
543
549
|
<MathInput
|
|
544
|
-
buttonSets={[]}
|
|
545
550
|
buttonsVisible="never"
|
|
546
551
|
value={this.props.x}
|
|
547
552
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
548
553
|
onChange={this.change("x")}
|
|
554
|
+
analytics={analyticsStub}
|
|
549
555
|
/>
|
|
550
556
|
</div>
|
|
551
557
|
<div className="perseus-widget-row">
|
|
552
558
|
<TeX>Y(t) =</TeX>{" "}
|
|
553
559
|
<MathInput
|
|
554
|
-
buttonSets={[]}
|
|
555
560
|
buttonsVisible="never"
|
|
556
561
|
value={this.props.y}
|
|
557
562
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
558
563
|
onChange={this.change("y")}
|
|
564
|
+
analytics={analyticsStub}
|
|
559
565
|
/>
|
|
560
566
|
</div>
|
|
561
567
|
<div className="perseus-widget-row">
|
|
562
568
|
Range: <TeX>\Large(</TeX>
|
|
563
569
|
<MathInput
|
|
564
|
-
buttonSets={[]}
|
|
565
570
|
buttonsVisible="never"
|
|
566
571
|
value={this.props.rangeMin}
|
|
567
572
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
568
573
|
onChange={this.change("rangeMin")}
|
|
574
|
+
analytics={analyticsStub}
|
|
569
575
|
/>
|
|
570
576
|
<TeX>,</TeX>{" "}
|
|
571
577
|
<MathInput
|
|
572
|
-
buttonSets={[]}
|
|
573
578
|
buttonsVisible="never"
|
|
574
579
|
value={this.props.rangeMax}
|
|
575
580
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
576
581
|
onChange={this.change("rangeMax")}
|
|
582
|
+
analytics={analyticsStub}
|
|
577
583
|
/>
|
|
578
584
|
<TeX>\Large)</TeX>
|
|
579
585
|
</div>
|
|
@@ -641,6 +647,7 @@ class LabelEditor extends React.Component<LabelEditorProps> {
|
|
|
641
647
|
|
|
642
648
|
render(): React.ReactNode {
|
|
643
649
|
const {TeX} = getDependencies();
|
|
650
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
644
651
|
|
|
645
652
|
return (
|
|
646
653
|
<div className="graph-settings">
|
|
@@ -657,19 +664,19 @@ class LabelEditor extends React.Component<LabelEditorProps> {
|
|
|
657
664
|
<div className="perseus-widget-row">
|
|
658
665
|
Location: <TeX>\Large(</TeX>
|
|
659
666
|
<MathInput
|
|
660
|
-
buttonSets={[]}
|
|
661
667
|
buttonsVisible="never"
|
|
662
668
|
value={this.props.coordX}
|
|
663
669
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
664
670
|
onChange={this.change("coordX")}
|
|
671
|
+
analytics={analyticsStub}
|
|
665
672
|
/>
|
|
666
673
|
<TeX>,</TeX>{" "}
|
|
667
674
|
<MathInput
|
|
668
|
-
buttonSets={[]}
|
|
669
675
|
buttonsVisible="never"
|
|
670
676
|
value={this.props.coordY}
|
|
671
677
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
672
678
|
onChange={this.change("coordY")}
|
|
679
|
+
analytics={analyticsStub}
|
|
673
680
|
/>
|
|
674
681
|
<TeX>\Large)</TeX>
|
|
675
682
|
</div>
|
|
@@ -720,46 +727,47 @@ class RectangleEditor extends React.Component<RectangleEditorProps> {
|
|
|
720
727
|
|
|
721
728
|
render(): React.ReactNode {
|
|
722
729
|
const {TeX} = getDependencies();
|
|
730
|
+
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
723
731
|
|
|
724
732
|
return (
|
|
725
733
|
<div className="graph-settings">
|
|
726
734
|
<div className="perseus-widget-row">
|
|
727
735
|
Bottom left: <TeX>\Large(</TeX>
|
|
728
736
|
<MathInput
|
|
729
|
-
buttonSets={[]}
|
|
730
737
|
buttonsVisible="never"
|
|
731
738
|
value={this.props.coordX}
|
|
732
739
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
733
740
|
onChange={this.change("coordX")}
|
|
741
|
+
analytics={analyticsStub}
|
|
734
742
|
/>
|
|
735
743
|
<TeX>,</TeX>{" "}
|
|
736
744
|
<MathInput
|
|
737
|
-
buttonSets={[]}
|
|
738
745
|
buttonsVisible="never"
|
|
739
746
|
value={this.props.coordY}
|
|
740
747
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
741
748
|
onChange={this.change("coordY")}
|
|
749
|
+
analytics={analyticsStub}
|
|
742
750
|
/>
|
|
743
751
|
<TeX>\Large)</TeX>
|
|
744
752
|
</div>
|
|
745
753
|
<div className="perseus-widget-row">
|
|
746
754
|
Width:{" "}
|
|
747
755
|
<MathInput
|
|
748
|
-
buttonSets={[]}
|
|
749
756
|
buttonsVisible="never"
|
|
750
757
|
value={this.props.width}
|
|
751
758
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
752
759
|
onChange={this.change("width")}
|
|
760
|
+
analytics={analyticsStub}
|
|
753
761
|
/>
|
|
754
762
|
</div>
|
|
755
763
|
<div className="perseus-widget-row">
|
|
756
764
|
Height:{" "}
|
|
757
765
|
<MathInput
|
|
758
|
-
buttonSets={[]}
|
|
759
766
|
buttonsVisible="never"
|
|
760
767
|
value={this.props.height}
|
|
761
768
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
762
769
|
onChange={this.change("height")}
|
|
770
|
+
analytics={analyticsStub}
|
|
763
771
|
/>
|
|
764
772
|
</div>
|
|
765
773
|
<div className="perseus-widget-row">
|