@khanacademy/perseus-editor 2.15.4 → 2.15.6
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/es/index.js +432 -580
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +500 -658
- package/dist/index.js.map +1 -1
- package/dist/widgets/interaction-editor/function-editor.d.ts +25 -0
- package/dist/widgets/interaction-editor/index.d.ts +2 -0
- package/dist/widgets/interaction-editor/interaction-editor.d.ts +37 -0
- package/dist/widgets/interaction-editor/label-editor.d.ts +21 -0
- package/dist/widgets/interaction-editor/line-editor.d.ts +29 -0
- package/dist/widgets/interaction-editor/mathquill-input.d.ts +12 -0
- package/dist/widgets/interaction-editor/movable-line-editor.d.ts +29 -0
- package/dist/widgets/interaction-editor/movable-point-editor.d.ts +24 -0
- package/dist/widgets/interaction-editor/parametric-editor.d.ts +27 -0
- package/dist/widgets/interaction-editor/point-editor.d.ts +19 -0
- package/dist/widgets/interaction-editor/rectangle-editor.d.ts +23 -0
- package/package.json +3 -2
- package/src/widgets/__stories__/interaction-editor.stories.tsx +37 -0
- package/src/widgets/{interaction → interaction-editor}/constraint-editor.tsx +9 -21
- package/src/widgets/interaction-editor/function-editor.tsx +108 -0
- package/src/widgets/interaction-editor/index.ts +3 -0
- package/src/widgets/{interaction-editor.tsx → interaction-editor/interaction-editor.tsx} +40 -787
- package/src/widgets/interaction-editor/label-editor.tsx +87 -0
- package/src/widgets/interaction-editor/line-editor.tsx +125 -0
- package/src/widgets/interaction-editor/mathquill-input.tsx +81 -0
- package/src/widgets/interaction-editor/movable-line-editor.tsx +121 -0
- package/src/widgets/interaction-editor/movable-point-editor.tsx +89 -0
- package/src/widgets/interaction-editor/parametric-editor.tsx +117 -0
- package/src/widgets/interaction-editor/point-editor.tsx +72 -0
- package/src/widgets/interaction-editor/rectangle-editor.tsx +96 -0
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/widgets/interaction-editor.d.ts +0 -28
- /package/dist/widgets/{interaction → interaction-editor}/constraint-editor.d.ts +0 -0
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
2
|
-
/* eslint-disable @babel/no-invalid-this, react/no-unsafe
|
|
2
|
+
/* eslint-disable @babel/no-invalid-this, react/no-unsafe */
|
|
3
3
|
import {
|
|
4
|
-
components,
|
|
5
4
|
Changeable,
|
|
6
5
|
Dependencies,
|
|
7
6
|
EditorJsonify,
|
|
8
|
-
KhanColors,
|
|
9
7
|
Util,
|
|
10
|
-
ArrowPicker,
|
|
11
|
-
ColorPicker,
|
|
12
|
-
DashPicker,
|
|
13
8
|
ElementContainer,
|
|
14
9
|
} from "@khanacademy/perseus";
|
|
15
|
-
import PropTypes from "prop-types";
|
|
16
10
|
import * as React from "react";
|
|
17
11
|
import _ from "underscore";
|
|
18
12
|
|
|
19
|
-
import GraphSettings from "
|
|
13
|
+
import GraphSettings from "../../components/graph-settings";
|
|
20
14
|
|
|
21
|
-
import
|
|
15
|
+
import FunctionEditor from "./function-editor";
|
|
16
|
+
import LabelEditor from "./label-editor";
|
|
17
|
+
import LineEditor from "./line-editor";
|
|
18
|
+
import MovableLineEditor from "./movable-line-editor";
|
|
19
|
+
import MovablePointEditor from "./movable-point-editor";
|
|
20
|
+
import ParametricEditor from "./parametric-editor";
|
|
21
|
+
import PointEditor from "./point-editor";
|
|
22
|
+
import RectangleEditor from "./rectangle-editor";
|
|
22
23
|
|
|
23
|
-
const {MathInput, NumberInput, TextInput} = components;
|
|
24
24
|
const {getDependencies} = Dependencies;
|
|
25
25
|
const {unescapeMathMode} = Util;
|
|
26
26
|
|
|
@@ -39,785 +39,38 @@ const defaultInteractionProps = {
|
|
|
39
39
|
elements: [],
|
|
40
40
|
} as const;
|
|
41
41
|
|
|
42
|
-
type
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<div className="graph-settings">
|
|
69
|
-
<div className="perseus-widget-row">
|
|
70
|
-
Coordinate: <TeX>\Large(</TeX>
|
|
71
|
-
<MathInput
|
|
72
|
-
buttonsVisible="never"
|
|
73
|
-
value={this.props.coordX}
|
|
74
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
75
|
-
onChange={this.change("coordX")}
|
|
76
|
-
analytics={analyticsStub}
|
|
77
|
-
/>
|
|
78
|
-
<TeX>,</TeX>{" "}
|
|
79
|
-
<MathInput
|
|
80
|
-
buttonsVisible="never"
|
|
81
|
-
value={this.props.coordY}
|
|
82
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
83
|
-
onChange={this.change("coordY")}
|
|
84
|
-
analytics={analyticsStub}
|
|
85
|
-
/>
|
|
86
|
-
<TeX>\Large)</TeX>
|
|
87
|
-
</div>
|
|
88
|
-
<div className="perseus-widget-row">
|
|
89
|
-
<ColorPicker
|
|
90
|
-
value={this.props.color}
|
|
91
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
92
|
-
onChange={this.change("color")}
|
|
93
|
-
/>
|
|
94
|
-
</div>
|
|
95
|
-
</div>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
100
|
-
return Changeable.change.apply(this, args);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
serialize = () => {
|
|
104
|
-
return EditorJsonify.serialize.call(this);
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
type LineEditorProps = any;
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
// Editor for non-interactive line segments
|
|
112
|
-
//
|
|
113
|
-
// TODO(eater): Factor this out
|
|
114
|
-
//
|
|
115
|
-
class LineEditor extends React.Component<LineEditorProps> {
|
|
116
|
-
static propTypes = {
|
|
117
|
-
...Changeable.propTypes,
|
|
118
|
-
startX: PropTypes.string,
|
|
119
|
-
startY: PropTypes.string,
|
|
120
|
-
endX: PropTypes.string,
|
|
121
|
-
endY: PropTypes.string,
|
|
122
|
-
color: PropTypes.string,
|
|
123
|
-
strokeDasharray: PropTypes.string,
|
|
124
|
-
arrows: PropTypes.string,
|
|
125
|
-
strokeWidth: PropTypes.number,
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
static defaultProps = {
|
|
129
|
-
startX: "-5",
|
|
130
|
-
startY: "5",
|
|
131
|
-
endX: "5",
|
|
132
|
-
endY: "5",
|
|
133
|
-
color: KhanColors.BLACK,
|
|
134
|
-
strokeDasharray: "",
|
|
135
|
-
arrows: "",
|
|
136
|
-
strokeWidth: 2,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
render(): React.ReactNode {
|
|
140
|
-
const {TeX} = getDependencies();
|
|
141
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
142
|
-
|
|
143
|
-
return (
|
|
144
|
-
<div className="graph-settings">
|
|
145
|
-
<div className="perseus-widget-row">
|
|
146
|
-
Start: <TeX>\Large(</TeX>
|
|
147
|
-
<MathInput
|
|
148
|
-
buttonsVisible="never"
|
|
149
|
-
value={this.props.startX}
|
|
150
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
151
|
-
onChange={this.change("startX")}
|
|
152
|
-
analytics={analyticsStub}
|
|
153
|
-
/>
|
|
154
|
-
<TeX>,</TeX>{" "}
|
|
155
|
-
<MathInput
|
|
156
|
-
buttonsVisible="never"
|
|
157
|
-
value={this.props.startY}
|
|
158
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
159
|
-
onChange={this.change("startY")}
|
|
160
|
-
analytics={analyticsStub}
|
|
161
|
-
/>
|
|
162
|
-
<TeX>\Large)</TeX>
|
|
163
|
-
</div>
|
|
164
|
-
<div className="perseus-widget-row">
|
|
165
|
-
End: <TeX>\Large(</TeX>
|
|
166
|
-
<MathInput
|
|
167
|
-
buttonsVisible="never"
|
|
168
|
-
value={this.props.endX}
|
|
169
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
170
|
-
onChange={this.change("endX")}
|
|
171
|
-
analytics={analyticsStub}
|
|
172
|
-
/>
|
|
173
|
-
<TeX>,</TeX>{" "}
|
|
174
|
-
<MathInput
|
|
175
|
-
buttonsVisible="never"
|
|
176
|
-
value={this.props.endY}
|
|
177
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
178
|
-
onChange={this.change("endY")}
|
|
179
|
-
analytics={analyticsStub}
|
|
180
|
-
/>
|
|
181
|
-
<TeX>\Large)</TeX>
|
|
182
|
-
</div>
|
|
183
|
-
<div className="perseus-widget-row">
|
|
184
|
-
<ColorPicker
|
|
185
|
-
value={this.props.color}
|
|
186
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
187
|
-
onChange={this.change("color")}
|
|
188
|
-
/>
|
|
189
|
-
</div>
|
|
190
|
-
<div className="perseus-widget-row">
|
|
191
|
-
<DashPicker
|
|
192
|
-
value={this.props.strokeDasharray}
|
|
193
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
194
|
-
onChange={this.change("strokeDasharray")}
|
|
195
|
-
/>
|
|
196
|
-
|
|
197
|
-
<ArrowPicker
|
|
198
|
-
value={this.props.arrows}
|
|
199
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
200
|
-
onChange={this.change("arrows")}
|
|
201
|
-
/>
|
|
202
|
-
</div>
|
|
203
|
-
<div className="perseus-widget-row">
|
|
204
|
-
<div className="perseus-widget-left-col">
|
|
205
|
-
Width:{" "}
|
|
206
|
-
<NumberInput
|
|
207
|
-
value={this.props.strokeWidth}
|
|
208
|
-
placeholder={2}
|
|
209
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
210
|
-
onChange={this.change("strokeWidth")}
|
|
211
|
-
/>
|
|
212
|
-
</div>
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
219
|
-
return Changeable.change.apply(this, args);
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
serialize = () => {
|
|
223
|
-
return EditorJsonify.serialize.call(this);
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
type MovablePointEditorProps = any;
|
|
228
|
-
|
|
229
|
-
//
|
|
230
|
-
// Editor for interactive movable points
|
|
231
|
-
//
|
|
232
|
-
// TODO(eater): Factor this out
|
|
233
|
-
// TODO(eater): Rethink how constraints are represented
|
|
234
|
-
//
|
|
235
|
-
class MovablePointEditor extends React.Component<MovablePointEditorProps> {
|
|
236
|
-
static propTypes = {
|
|
237
|
-
...Changeable.propTypes,
|
|
238
|
-
startX: PropTypes.string,
|
|
239
|
-
startY: PropTypes.string,
|
|
240
|
-
constraint: PropTypes.string,
|
|
241
|
-
snap: PropTypes.number,
|
|
242
|
-
constraintFn: PropTypes.string,
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
static defaultProps = {
|
|
246
|
-
startX: "0",
|
|
247
|
-
startY: "0",
|
|
248
|
-
constraint: "none",
|
|
249
|
-
snap: 0.5,
|
|
250
|
-
constraintFn: "0",
|
|
251
|
-
constraintXMin: "-10",
|
|
252
|
-
constraintXMax: "10",
|
|
253
|
-
constraintYMin: "-10",
|
|
254
|
-
constraintYMax: "10",
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
render(): React.ReactNode {
|
|
258
|
-
const {TeX} = getDependencies();
|
|
259
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
260
|
-
|
|
261
|
-
return (
|
|
262
|
-
<div className="graph-settings">
|
|
263
|
-
<div className="perseus-widget-row">
|
|
264
|
-
Start: <TeX>\Large(</TeX>
|
|
265
|
-
<MathInput
|
|
266
|
-
buttonsVisible="never"
|
|
267
|
-
value={this.props.startX}
|
|
268
|
-
onChange={this.change("startX")}
|
|
269
|
-
analytics={analyticsStub}
|
|
270
|
-
/>
|
|
271
|
-
<TeX>,</TeX>{" "}
|
|
272
|
-
<MathInput
|
|
273
|
-
buttonsVisible="never"
|
|
274
|
-
value={this.props.startY}
|
|
275
|
-
onChange={this.change("startY")}
|
|
276
|
-
analytics={analyticsStub}
|
|
277
|
-
/>
|
|
278
|
-
<TeX>\Large)</TeX>
|
|
279
|
-
</div>
|
|
280
|
-
<div className="perseus-widget-row">
|
|
281
|
-
Update <TeX>(x_n, y_n)</TeX> for <TeX>n =</TeX>{" "}
|
|
282
|
-
<NumberInput
|
|
283
|
-
value={this.props.varSubscript}
|
|
284
|
-
placeholder={0}
|
|
285
|
-
onChange={this.change("varSubscript")}
|
|
286
|
-
/>
|
|
287
|
-
</div>
|
|
288
|
-
{/* @ts-expect-error - TS2769 - No overload matches this call. */}
|
|
289
|
-
<ConstraintEditor {...this.props} />
|
|
290
|
-
</div>
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
change = (...args) => {
|
|
295
|
-
return Changeable.change.apply(this, args);
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
serialize = () => {
|
|
299
|
-
return EditorJsonify.serialize.call(this);
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
type MovableLineEditorProps = any;
|
|
304
|
-
|
|
305
|
-
//
|
|
306
|
-
// Editor for interactive movable line segments
|
|
307
|
-
//
|
|
308
|
-
// TODO(eater): Factor this out
|
|
309
|
-
// TODO(eater): Rethink how constraints are represented
|
|
310
|
-
//
|
|
311
|
-
class MovableLineEditor extends React.Component<MovableLineEditorProps> {
|
|
312
|
-
static propTypes = {
|
|
313
|
-
...Changeable.propTypes,
|
|
314
|
-
startX: PropTypes.string,
|
|
315
|
-
startY: PropTypes.string,
|
|
316
|
-
endX: PropTypes.string,
|
|
317
|
-
endY: PropTypes.string,
|
|
318
|
-
constraint: PropTypes.string,
|
|
319
|
-
snap: PropTypes.number,
|
|
320
|
-
constraintFn: PropTypes.string,
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
static defaultProps = {
|
|
324
|
-
startX: "-5",
|
|
325
|
-
startY: "5",
|
|
326
|
-
endX: "5",
|
|
327
|
-
endY: "5",
|
|
328
|
-
constraint: "none",
|
|
329
|
-
snap: 0.5,
|
|
330
|
-
constraintFn: "0",
|
|
331
|
-
constraintXMin: "-10",
|
|
332
|
-
constraintXMax: "10",
|
|
333
|
-
constraintYMin: "-10",
|
|
334
|
-
constraintYMax: "10",
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
render(): React.ReactNode {
|
|
338
|
-
const {TeX} = getDependencies();
|
|
339
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
340
|
-
|
|
341
|
-
return (
|
|
342
|
-
<div className="graph-settings">
|
|
343
|
-
Initial position:
|
|
344
|
-
<div className="perseus-widget-row">
|
|
345
|
-
Start: <TeX>\Large(</TeX>
|
|
346
|
-
<MathInput
|
|
347
|
-
buttonsVisible="never"
|
|
348
|
-
value={this.props.startX}
|
|
349
|
-
onChange={this.change("startX")}
|
|
350
|
-
analytics={analyticsStub}
|
|
351
|
-
/>
|
|
352
|
-
<TeX>,</TeX>{" "}
|
|
353
|
-
<MathInput
|
|
354
|
-
buttonsVisible="never"
|
|
355
|
-
value={this.props.startY}
|
|
356
|
-
onChange={this.change("startY")}
|
|
357
|
-
analytics={analyticsStub}
|
|
358
|
-
/>
|
|
359
|
-
<TeX>\Large)</TeX>
|
|
360
|
-
</div>
|
|
361
|
-
<div className="perseus-widget-row">
|
|
362
|
-
End: <TeX>\Large(</TeX>
|
|
363
|
-
<MathInput
|
|
364
|
-
buttonsVisible="never"
|
|
365
|
-
value={this.props.endX}
|
|
366
|
-
onChange={this.change("endX")}
|
|
367
|
-
analytics={analyticsStub}
|
|
368
|
-
/>
|
|
369
|
-
<TeX>,</TeX>{" "}
|
|
370
|
-
<MathInput
|
|
371
|
-
buttonsVisible="never"
|
|
372
|
-
value={this.props.endY}
|
|
373
|
-
onChange={this.change("endY")}
|
|
374
|
-
analytics={analyticsStub}
|
|
375
|
-
/>
|
|
376
|
-
<TeX>\Large)</TeX>
|
|
377
|
-
</div>
|
|
378
|
-
<div className="perseus-widget-row">
|
|
379
|
-
Start updates <TeX>(x_n, y_n)</TeX> for <TeX>n =</TeX>
|
|
380
|
-
<NumberInput
|
|
381
|
-
value={this.props.startSubscript}
|
|
382
|
-
placeholder={0}
|
|
383
|
-
onChange={this.change("startSubscript")}
|
|
384
|
-
/>
|
|
385
|
-
</div>
|
|
386
|
-
<div className="perseus-widget-row">
|
|
387
|
-
End updates <TeX>(x_m, y_m)</TeX> for <TeX>m =</TeX>
|
|
388
|
-
<NumberInput
|
|
389
|
-
value={this.props.endSubscript}
|
|
390
|
-
placeholder={0}
|
|
391
|
-
onChange={this.change("endSubscript")}
|
|
392
|
-
/>
|
|
393
|
-
</div>
|
|
394
|
-
<div className="perseus-widget-row">
|
|
395
|
-
All constraints are applied to the start point.
|
|
396
|
-
</div>
|
|
397
|
-
{/* @ts-expect-error - TS2769 - No overload matches this call. */}
|
|
398
|
-
<ConstraintEditor {...this.props} />
|
|
399
|
-
</div>
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
change = (...args) => {
|
|
404
|
-
return Changeable.change.apply(this, args);
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
serialize = () => {
|
|
408
|
-
return EditorJsonify.serialize.call(this);
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
type FunctionEditorProps = any;
|
|
413
|
-
|
|
414
|
-
//
|
|
415
|
-
// Editor for function plots
|
|
416
|
-
//
|
|
417
|
-
// TODO(eater): Factor this out
|
|
418
|
-
//
|
|
419
|
-
class FunctionEditor extends React.Component<FunctionEditorProps> {
|
|
420
|
-
static propTypes = {
|
|
421
|
-
...Changeable.propTypes,
|
|
422
|
-
value: PropTypes.string,
|
|
423
|
-
rangeMin: PropTypes.string,
|
|
424
|
-
rangeMax: PropTypes.string,
|
|
425
|
-
color: PropTypes.string,
|
|
426
|
-
strokeDashArray: PropTypes.string,
|
|
427
|
-
strokeWidth: PropTypes.number,
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
static defaultProps = {
|
|
431
|
-
value: "x",
|
|
432
|
-
rangeMin: "-10",
|
|
433
|
-
rangeMax: "10",
|
|
434
|
-
color: KhanColors.BLUE,
|
|
435
|
-
strokeDasharray: "",
|
|
436
|
-
strokeWidth: 2,
|
|
437
|
-
};
|
|
438
|
-
|
|
439
|
-
render(): React.ReactNode {
|
|
440
|
-
const {TeX} = getDependencies();
|
|
441
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
442
|
-
|
|
443
|
-
return (
|
|
444
|
-
<div className="graph-settings">
|
|
445
|
-
<div className="perseus-widget-row">
|
|
446
|
-
<TeX>{this.props.funcName + "(x)="}</TeX>{" "}
|
|
447
|
-
<MathInput
|
|
448
|
-
buttonsVisible="never"
|
|
449
|
-
value={this.props.value}
|
|
450
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
451
|
-
onChange={this.change("value")}
|
|
452
|
-
analytics={analyticsStub}
|
|
453
|
-
/>
|
|
454
|
-
</div>
|
|
455
|
-
<div className="perseus-widget-row">
|
|
456
|
-
Range: <TeX>\Large(</TeX>
|
|
457
|
-
<MathInput
|
|
458
|
-
buttonsVisible="never"
|
|
459
|
-
value={this.props.rangeMin}
|
|
460
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
461
|
-
onChange={this.change("rangeMin")}
|
|
462
|
-
analytics={analyticsStub}
|
|
463
|
-
/>
|
|
464
|
-
<TeX>,</TeX>{" "}
|
|
465
|
-
<MathInput
|
|
466
|
-
buttonsVisible="never"
|
|
467
|
-
value={this.props.rangeMax}
|
|
468
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
469
|
-
onChange={this.change("rangeMax")}
|
|
470
|
-
analytics={analyticsStub}
|
|
471
|
-
/>
|
|
472
|
-
<TeX>\Large)</TeX>
|
|
473
|
-
</div>
|
|
474
|
-
<div className="perseus-widget-row">
|
|
475
|
-
<ColorPicker
|
|
476
|
-
value={this.props.color}
|
|
477
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
478
|
-
onChange={this.change("color")}
|
|
479
|
-
/>
|
|
480
|
-
</div>
|
|
481
|
-
<div className="perseus-widget-row">
|
|
482
|
-
<DashPicker
|
|
483
|
-
value={this.props.strokeDasharray}
|
|
484
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
485
|
-
onChange={this.change("strokeDasharray")}
|
|
486
|
-
/>
|
|
487
|
-
</div>
|
|
488
|
-
<div className="perseus-widget-row">
|
|
489
|
-
<div className="perseus-widget-left-col">
|
|
490
|
-
Width:{" "}
|
|
491
|
-
<NumberInput
|
|
492
|
-
value={this.props.strokeWidth}
|
|
493
|
-
placeholder={2}
|
|
494
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
495
|
-
onChange={this.change("strokeWidth")}
|
|
496
|
-
/>
|
|
497
|
-
</div>
|
|
498
|
-
</div>
|
|
499
|
-
</div>
|
|
500
|
-
);
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
504
|
-
return Changeable.change.apply(this, args);
|
|
505
|
-
};
|
|
506
|
-
|
|
507
|
-
serialize = () => {
|
|
508
|
-
return EditorJsonify.serialize.call(this);
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
type ParametricEditorProps = any;
|
|
513
|
-
|
|
514
|
-
//
|
|
515
|
-
// Editor for parametric plots
|
|
516
|
-
//
|
|
517
|
-
// TODO(eater): Factor this out
|
|
518
|
-
//
|
|
519
|
-
class ParametricEditor extends React.Component<ParametricEditorProps> {
|
|
520
|
-
static propTypes = {
|
|
521
|
-
...Changeable.propTypes,
|
|
522
|
-
x: PropTypes.string,
|
|
523
|
-
y: PropTypes.string,
|
|
524
|
-
rangeMin: PropTypes.string,
|
|
525
|
-
rangeMax: PropTypes.string,
|
|
526
|
-
color: PropTypes.string,
|
|
527
|
-
strokeDashArray: PropTypes.string,
|
|
528
|
-
strokeWidth: PropTypes.number,
|
|
529
|
-
};
|
|
530
|
-
|
|
531
|
-
static defaultProps = {
|
|
532
|
-
x: "cos(t)",
|
|
533
|
-
y: "sin(t)",
|
|
534
|
-
rangeMin: "0",
|
|
535
|
-
rangeMax: "2\\pi",
|
|
536
|
-
color: KhanColors.BLUE,
|
|
537
|
-
strokeDasharray: "",
|
|
538
|
-
strokeWidth: 2,
|
|
539
|
-
};
|
|
540
|
-
|
|
541
|
-
render(): React.ReactNode {
|
|
542
|
-
const {TeX} = getDependencies();
|
|
543
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
544
|
-
|
|
545
|
-
return (
|
|
546
|
-
<div className="graph-settings">
|
|
547
|
-
<div className="perseus-widget-row">
|
|
548
|
-
<TeX>X(t) =</TeX>{" "}
|
|
549
|
-
<MathInput
|
|
550
|
-
buttonsVisible="never"
|
|
551
|
-
value={this.props.x}
|
|
552
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
553
|
-
onChange={this.change("x")}
|
|
554
|
-
analytics={analyticsStub}
|
|
555
|
-
/>
|
|
556
|
-
</div>
|
|
557
|
-
<div className="perseus-widget-row">
|
|
558
|
-
<TeX>Y(t) =</TeX>{" "}
|
|
559
|
-
<MathInput
|
|
560
|
-
buttonsVisible="never"
|
|
561
|
-
value={this.props.y}
|
|
562
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
563
|
-
onChange={this.change("y")}
|
|
564
|
-
analytics={analyticsStub}
|
|
565
|
-
/>
|
|
566
|
-
</div>
|
|
567
|
-
<div className="perseus-widget-row">
|
|
568
|
-
Range: <TeX>\Large(</TeX>
|
|
569
|
-
<MathInput
|
|
570
|
-
buttonsVisible="never"
|
|
571
|
-
value={this.props.rangeMin}
|
|
572
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
573
|
-
onChange={this.change("rangeMin")}
|
|
574
|
-
analytics={analyticsStub}
|
|
575
|
-
/>
|
|
576
|
-
<TeX>,</TeX>{" "}
|
|
577
|
-
<MathInput
|
|
578
|
-
buttonsVisible="never"
|
|
579
|
-
value={this.props.rangeMax}
|
|
580
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
581
|
-
onChange={this.change("rangeMax")}
|
|
582
|
-
analytics={analyticsStub}
|
|
583
|
-
/>
|
|
584
|
-
<TeX>\Large)</TeX>
|
|
585
|
-
</div>
|
|
586
|
-
<div className="perseus-widget-row">
|
|
587
|
-
<ColorPicker
|
|
588
|
-
value={this.props.color}
|
|
589
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
590
|
-
onChange={this.change("color")}
|
|
591
|
-
/>
|
|
592
|
-
</div>
|
|
593
|
-
<div className="perseus-widget-row">
|
|
594
|
-
<DashPicker
|
|
595
|
-
value={this.props.strokeDasharray}
|
|
596
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
597
|
-
onChange={this.change("strokeDasharray")}
|
|
598
|
-
/>
|
|
599
|
-
</div>
|
|
600
|
-
<div className="perseus-widget-row">
|
|
601
|
-
<div className="perseus-widget-left-col">
|
|
602
|
-
Width:{" "}
|
|
603
|
-
<NumberInput
|
|
604
|
-
value={this.props.strokeWidth}
|
|
605
|
-
placeholder={2}
|
|
606
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
607
|
-
onChange={this.change("strokeWidth")}
|
|
608
|
-
/>
|
|
609
|
-
</div>
|
|
610
|
-
</div>
|
|
611
|
-
</div>
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
616
|
-
return Changeable.change.apply(this, args);
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
serialize = () => {
|
|
620
|
-
return EditorJsonify.serialize.call(this);
|
|
621
|
-
};
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
type LabelEditorProps = any;
|
|
625
|
-
|
|
626
|
-
//
|
|
627
|
-
// Editor for labels
|
|
628
|
-
//
|
|
629
|
-
// TODO(eater): Factor this out maybe?
|
|
630
|
-
// TODO(eater): Add text direction
|
|
631
|
-
//
|
|
632
|
-
class LabelEditor extends React.Component<LabelEditorProps> {
|
|
633
|
-
static propTypes = {
|
|
634
|
-
...Changeable.propTypes,
|
|
635
|
-
color: PropTypes.string,
|
|
636
|
-
coordX: PropTypes.string,
|
|
637
|
-
coordY: PropTypes.string,
|
|
638
|
-
label: PropTypes.string,
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
static defaultProps = {
|
|
642
|
-
coordX: "0",
|
|
643
|
-
coordY: "0",
|
|
644
|
-
color: KhanColors.BLACK,
|
|
645
|
-
label: "\\phi",
|
|
646
|
-
};
|
|
647
|
-
|
|
648
|
-
render(): React.ReactNode {
|
|
649
|
-
const {TeX} = getDependencies();
|
|
650
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
651
|
-
|
|
652
|
-
return (
|
|
653
|
-
<div className="graph-settings">
|
|
654
|
-
<div className="perseus-widget-row">
|
|
655
|
-
<TextInput
|
|
656
|
-
value={this.props.label}
|
|
657
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
658
|
-
onChange={this.change("label")}
|
|
659
|
-
style={{
|
|
660
|
-
width: "100%",
|
|
661
|
-
}}
|
|
662
|
-
/>
|
|
663
|
-
</div>
|
|
664
|
-
<div className="perseus-widget-row">
|
|
665
|
-
Location: <TeX>\Large(</TeX>
|
|
666
|
-
<MathInput
|
|
667
|
-
buttonsVisible="never"
|
|
668
|
-
value={this.props.coordX}
|
|
669
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
670
|
-
onChange={this.change("coordX")}
|
|
671
|
-
analytics={analyticsStub}
|
|
672
|
-
/>
|
|
673
|
-
<TeX>,</TeX>{" "}
|
|
674
|
-
<MathInput
|
|
675
|
-
buttonsVisible="never"
|
|
676
|
-
value={this.props.coordY}
|
|
677
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
678
|
-
onChange={this.change("coordY")}
|
|
679
|
-
analytics={analyticsStub}
|
|
680
|
-
/>
|
|
681
|
-
<TeX>\Large)</TeX>
|
|
682
|
-
</div>
|
|
683
|
-
<div className="perseus-widget-row">
|
|
684
|
-
<ColorPicker
|
|
685
|
-
value={this.props.color}
|
|
686
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
687
|
-
onChange={this.change("color")}
|
|
688
|
-
/>
|
|
689
|
-
</div>
|
|
690
|
-
</div>
|
|
691
|
-
);
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
695
|
-
return Changeable.change.apply(this, args);
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
serialize = () => {
|
|
699
|
-
return EditorJsonify.serialize.call(this);
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
type RectangleEditorProps = any;
|
|
704
|
-
|
|
705
|
-
//
|
|
706
|
-
// Editor for rectangles
|
|
707
|
-
//
|
|
708
|
-
// TODO(eater): Factor this out maybe?
|
|
709
|
-
//
|
|
710
|
-
class RectangleEditor extends React.Component<RectangleEditorProps> {
|
|
711
|
-
static propTypes = {
|
|
712
|
-
...Changeable.propTypes,
|
|
713
|
-
color: PropTypes.string,
|
|
714
|
-
coordX: PropTypes.string,
|
|
715
|
-
coordY: PropTypes.string,
|
|
716
|
-
height: PropTypes.string,
|
|
717
|
-
width: PropTypes.string,
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
static defaultProps = {
|
|
721
|
-
coordX: "-5",
|
|
722
|
-
coordY: "5",
|
|
723
|
-
width: "2",
|
|
724
|
-
height: "3",
|
|
725
|
-
color: KhanColors.LIGHT_BLUE,
|
|
726
|
-
};
|
|
727
|
-
|
|
728
|
-
render(): React.ReactNode {
|
|
729
|
-
const {TeX} = getDependencies();
|
|
730
|
-
const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
|
|
731
|
-
|
|
732
|
-
return (
|
|
733
|
-
<div className="graph-settings">
|
|
734
|
-
<div className="perseus-widget-row">
|
|
735
|
-
Bottom left: <TeX>\Large(</TeX>
|
|
736
|
-
<MathInput
|
|
737
|
-
buttonsVisible="never"
|
|
738
|
-
value={this.props.coordX}
|
|
739
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
740
|
-
onChange={this.change("coordX")}
|
|
741
|
-
analytics={analyticsStub}
|
|
742
|
-
/>
|
|
743
|
-
<TeX>,</TeX>{" "}
|
|
744
|
-
<MathInput
|
|
745
|
-
buttonsVisible="never"
|
|
746
|
-
value={this.props.coordY}
|
|
747
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
748
|
-
onChange={this.change("coordY")}
|
|
749
|
-
analytics={analyticsStub}
|
|
750
|
-
/>
|
|
751
|
-
<TeX>\Large)</TeX>
|
|
752
|
-
</div>
|
|
753
|
-
<div className="perseus-widget-row">
|
|
754
|
-
Width:{" "}
|
|
755
|
-
<MathInput
|
|
756
|
-
buttonsVisible="never"
|
|
757
|
-
value={this.props.width}
|
|
758
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
759
|
-
onChange={this.change("width")}
|
|
760
|
-
analytics={analyticsStub}
|
|
761
|
-
/>
|
|
762
|
-
</div>
|
|
763
|
-
<div className="perseus-widget-row">
|
|
764
|
-
Height:{" "}
|
|
765
|
-
<MathInput
|
|
766
|
-
buttonsVisible="never"
|
|
767
|
-
value={this.props.height}
|
|
768
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
769
|
-
onChange={this.change("height")}
|
|
770
|
-
analytics={analyticsStub}
|
|
771
|
-
/>
|
|
772
|
-
</div>
|
|
773
|
-
<div className="perseus-widget-row">
|
|
774
|
-
<ColorPicker
|
|
775
|
-
value={this.props.color}
|
|
776
|
-
lightColors={true}
|
|
777
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
778
|
-
onChange={this.change("color")}
|
|
779
|
-
/>
|
|
780
|
-
</div>
|
|
781
|
-
<div className="perseus-widget-row">
|
|
782
|
-
You want a border? Sorry, draw your own.
|
|
783
|
-
</div>
|
|
784
|
-
</div>
|
|
785
|
-
);
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
|
|
789
|
-
return Changeable.change.apply(this, args);
|
|
790
|
-
};
|
|
791
|
-
|
|
792
|
-
serialize = () => {
|
|
793
|
-
return EditorJsonify.serialize.call(this);
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
|
|
797
|
-
type InteractionEditorProps = any;
|
|
798
|
-
type InteractionEditorState = any;
|
|
799
|
-
|
|
800
|
-
class InteractionEditor extends React.Component<
|
|
801
|
-
InteractionEditorProps,
|
|
802
|
-
InteractionEditorState
|
|
803
|
-
> {
|
|
804
|
-
// TODO(eater): Make more better
|
|
805
|
-
static propTypes = {
|
|
806
|
-
...Changeable.propTypes,
|
|
807
|
-
// eslint-disable-next-line react/forbid-prop-types
|
|
808
|
-
elements: PropTypes.arrayOf(PropTypes.object),
|
|
809
|
-
graph: PropTypes.objectOf(PropTypes.any),
|
|
810
|
-
};
|
|
811
|
-
|
|
42
|
+
type Graph = {
|
|
43
|
+
box: ReadonlyArray<number>;
|
|
44
|
+
labels: ReadonlyArray<string>;
|
|
45
|
+
range: ReadonlyArray<ReadonlyArray<number>>;
|
|
46
|
+
tickStep: ReadonlyArray<number>;
|
|
47
|
+
gridStep: ReadonlyArray<number>;
|
|
48
|
+
markings: string;
|
|
49
|
+
valid?: boolean;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type Props = Changeable.ChangeableProps & {
|
|
53
|
+
elements: ReadonlyArray<any>;
|
|
54
|
+
graph: Graph;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
type DefaultProps = {
|
|
58
|
+
elements: Props["elements"];
|
|
59
|
+
graph: Props["graph"];
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
type State = any;
|
|
63
|
+
|
|
64
|
+
class InteractionEditor extends React.Component<Props, State> {
|
|
812
65
|
static widgetName = "interaction" as const;
|
|
813
|
-
static defaultProps:
|
|
66
|
+
static defaultProps: DefaultProps = defaultInteractionProps;
|
|
814
67
|
|
|
815
|
-
state:
|
|
68
|
+
state: State = {
|
|
816
69
|
usedVarSubscripts: this._getAllVarSubscripts(this.props.elements),
|
|
817
70
|
usedFunctionNames: this._getAllFunctionNames(this.props.elements),
|
|
818
71
|
};
|
|
819
72
|
|
|
820
|
-
UNSAFE_componentWillReceiveProps(nextProps:
|
|
73
|
+
UNSAFE_componentWillReceiveProps(nextProps: Props) {
|
|
821
74
|
this.setState({
|
|
822
75
|
usedVarSubscripts: this._getAllVarSubscripts(nextProps.elements),
|
|
823
76
|
usedFunctionNames: this._getAllFunctionNames(nextProps.elements),
|
|
@@ -956,6 +209,10 @@ class InteractionEditor extends React.Component<
|
|
|
956
209
|
return Changeable.change.apply(this, args);
|
|
957
210
|
};
|
|
958
211
|
|
|
212
|
+
serialize: () => any = () => {
|
|
213
|
+
return EditorJsonify.serialize.call(this);
|
|
214
|
+
};
|
|
215
|
+
|
|
959
216
|
render(): React.ReactNode {
|
|
960
217
|
const {TeX} = getDependencies();
|
|
961
218
|
|
|
@@ -1487,10 +744,6 @@ class InteractionEditor extends React.Component<
|
|
|
1487
744
|
);
|
|
1488
745
|
/* eslint-enable max-len */
|
|
1489
746
|
}
|
|
1490
|
-
|
|
1491
|
-
serialize: () => any = () => {
|
|
1492
|
-
return EditorJsonify.serialize.call(this);
|
|
1493
|
-
};
|
|
1494
747
|
}
|
|
1495
748
|
|
|
1496
749
|
export default InteractionEditor;
|