@khanacademy/perseus-editor 2.7.6 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ export declare const libVersion = "__lib_version__";
@@ -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: (arg1: number) => void;
28
- updateForm: (arg1: number, arg2: any) => void;
29
- handleReorder: (arg1: any) => void;
30
- handleButtonSet: (arg1: string) => void;
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.7.6",
6
+ "version": "2.8.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -22,9 +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.1",
26
- "@khanacademy/kmath": "^0.1.2",
27
- "@khanacademy/perseus": "^11.6.0"
25
+ "@khanacademy/kas": "^0.3.2",
26
+ "@khanacademy/kmath": "^0.1.3",
27
+ "@khanacademy/perseus": "^12.0.0",
28
+ "@khanacademy/perseus-core": "1.1.1"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@khanacademy/wonder-blocks-button": "^4.1.3",
@@ -40,7 +41,7 @@
40
41
  "create-react-class": "^15.6.3",
41
42
  "jquery": "^2.1.1",
42
43
  "katex": "^0.11.1",
43
- "perseus-build-settings": "^0.2.0",
44
+ "perseus-build-settings": "^0.2.1",
44
45
  "prop-types": "^15.6.1",
45
46
  "react": "16.14.0",
46
47
  "react-dom": "16.14.0",
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export {libVersion} from "./version";
2
+
1
3
  export {default as ArticleEditor} from "./article-editor";
2
4
  export {default as DeviceFramer} from "./components/device-framer";
3
5
  export {default as ViewportResizer} from "./components/viewport-resizer";
package/src/version.ts ADDED
@@ -0,0 +1,10 @@
1
+ // This file is processed by a Rollup plugin (replace) to inject the production
2
+ // version number during the release build.
3
+ // In dev, you'll never see the version number.
4
+
5
+ import {addLibraryVersionToPerseusDebug} from "@khanacademy/perseus-core";
6
+
7
+ const libName = "@khanacademy/perseus-editor";
8
+ export const libVersion = "__lib_version__";
9
+
10
+ addLibraryVersionToPerseusDebug(libName, libVersion);
@@ -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: any) => {
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.key] = true;
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((obj, index) => {
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: obj.form,
112
- simplify: obj.simplify,
113
- value: obj.value,
125
+ form: ans.form,
126
+ simplify: ans.simplify,
127
+ value: ans.value,
114
128
 
115
- onChange: (props) => this.updateForm(index, props),
129
+ onChange: (props) => this.updateForm(key, props),
116
130
  trackInteraction: () => {},
117
131
 
118
- widgetId: this.props.widgetId + "-" + index,
132
+ widgetId: this.props.widgetId + "-" + ans.key,
119
133
  } as const;
120
134
 
121
- return lens(obj)
135
+ return lens(ans)
122
136
  .merge([], {
123
137
  draggable: true,
124
- onChange: (props) => this.updateForm(index, props),
125
- onDelete: () => this.handleRemoveForm(index),
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, index) => <AnswerOption key={index} {...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 = this.props.buttonSets.includes(name) || isFirst;
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: (arg1: number) => void = (i) => {
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: (arg1: number, arg2: any) => void = (i, props) => {
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: (arg1: any) => void = (components) => {
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: (arg1: string) => void = (changingName) => {
379
- const buttonSetNames = Object.keys(TexButtons.buttonSets);
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: string | undefined;
398
- let remove: string | undefined;
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">
@@ -17,5 +17,6 @@
17
17
  {"path": "../kas/tsconfig-build.json"},
18
18
  {"path": "../kmath/tsconfig-build.json"},
19
19
  {"path": "../perseus/tsconfig-build.json"},
20
+ {"path": "../perseus-core/tsconfig-build.json"},
20
21
  ]
21
22
  }