@khanacademy/perseus-editor 4.1.5 → 4.1.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.
Files changed (175) hide show
  1. package/dist/es/index.js +1 -1
  2. package/dist/index.js +1 -1
  3. package/package.json +9 -6
  4. package/.babelrc.js +0 -8
  5. package/.eslintrc.js +0 -12
  6. package/CHANGELOG.md +0 -1155
  7. package/src/README.md +0 -7
  8. package/src/__stories__/editor-page.stories.tsx +0 -65
  9. package/src/__stories__/editor.stories.tsx +0 -134
  10. package/src/__stories__/item-editor.stories.tsx +0 -41
  11. package/src/__stories__/tex-error-view.stories.tsx +0 -26
  12. package/src/__testdata__/input-number.testdata.ts +0 -27
  13. package/src/__tests__/editor.test.tsx +0 -142
  14. package/src/__tests__/hint-editor.test.tsx +0 -83
  15. package/src/__tests__/i18n.test.ts +0 -501
  16. package/src/__tests__/integration.test.ts +0 -5
  17. package/src/__tests__/item-extras-editor.test.tsx +0 -85
  18. package/src/__tests__/traversal.test.ts +0 -377
  19. package/src/all-editors.test.ts +0 -16
  20. package/src/all-editors.ts +0 -83
  21. package/src/all-widgets.ts +0 -7
  22. package/src/article-editor.tsx +0 -438
  23. package/src/components/__stories__/blur-input.stories.tsx +0 -22
  24. package/src/components/__stories__/section-control-button.stories.tsx +0 -26
  25. package/src/components/__tests__/blur-input.test.tsx +0 -67
  26. package/src/components/blur-input.tsx +0 -69
  27. package/src/components/checkbox.tsx +0 -194
  28. package/src/components/device-framer.tsx +0 -90
  29. package/src/components/drag-target.tsx +0 -87
  30. package/src/components/dropdown-option.tsx +0 -311
  31. package/src/components/form-wrapped-text-field.tsx +0 -245
  32. package/src/components/graph-points-count-selector.tsx +0 -31
  33. package/src/components/graph-settings.tsx +0 -627
  34. package/src/components/graph-type-selector.tsx +0 -31
  35. package/src/components/hover-behavior.ts +0 -177
  36. package/src/components/json-editor.tsx +0 -121
  37. package/src/components/link.ts +0 -173
  38. package/src/components/section-control-button.tsx +0 -53
  39. package/src/components/segment-count-selector.tsx +0 -27
  40. package/src/components/simple-button.tsx +0 -85
  41. package/src/components/sortable.tsx +0 -187
  42. package/src/components/util.ts +0 -38
  43. package/src/components/viewport-resizer.tsx +0 -72
  44. package/src/components/widget-editor.tsx +0 -222
  45. package/src/components/widget-select.tsx +0 -48
  46. package/src/diffs/__stories__/perseus-diff-wrapper.tsx +0 -11
  47. package/src/diffs/__stories__/structured-item-diff.stories.tsx +0 -855
  48. package/src/diffs/__stories__/tags-diff.stories.tsx +0 -36
  49. package/src/diffs/__stories__/text-diff.stories.tsx +0 -35
  50. package/src/diffs/__tests__/split-diff.test.ts +0 -33
  51. package/src/diffs/__tests__/string-array-diff.test.ts +0 -73
  52. package/src/diffs/__tests__/structured-item-diff.test.ts +0 -433
  53. package/src/diffs/__tests__/widget-diff-performer.test.ts +0 -43
  54. package/src/diffs/article-diff.tsx +0 -69
  55. package/src/diffs/item-diff.tsx +0 -76
  56. package/src/diffs/renderer-diff.tsx +0 -137
  57. package/src/diffs/split-diff.ts +0 -31
  58. package/src/diffs/string-array-diff.ts +0 -74
  59. package/src/diffs/structured-item-diff.tsx +0 -275
  60. package/src/diffs/tags-diff.tsx +0 -49
  61. package/src/diffs/text-diff.tsx +0 -193
  62. package/src/diffs/widget-diff-performer.ts +0 -69
  63. package/src/diffs/widget-diff.tsx +0 -290
  64. package/src/editor-page.tsx +0 -325
  65. package/src/editor.tsx +0 -1099
  66. package/src/hint-editor.tsx +0 -469
  67. package/src/i18n.ts +0 -140
  68. package/src/iframe-content-renderer.tsx +0 -188
  69. package/src/index.ts +0 -30
  70. package/src/item-editor.tsx +0 -158
  71. package/src/item-extras-editor.tsx +0 -230
  72. package/src/katex-mhchem/index.js +0 -73
  73. package/src/katex-mhchem/parser.js +0 -2659
  74. package/src/multirenderer-editor.tsx +0 -1061
  75. package/src/stateful-article-editor.tsx +0 -173
  76. package/src/stateful-editor-page.tsx +0 -88
  77. package/src/styles/perseus-editor.less +0 -1321
  78. package/src/testing-widgets.ts +0 -11
  79. package/src/tex-error-view.tsx +0 -90
  80. package/src/util/points.test.ts +0 -24
  81. package/src/util/points.ts +0 -13
  82. package/src/util/register-all-widgets-and-editors-for-testing.test.ts +0 -17
  83. package/src/util/register-all-widgets-and-editors-for-testing.ts +0 -17
  84. package/src/version.ts +0 -10
  85. package/src/widgets/__stories__/categorizer-editor.stories.tsx +0 -24
  86. package/src/widgets/__stories__/definition-editor.stories.tsx +0 -18
  87. package/src/widgets/__stories__/dropdown-editor.stories.tsx +0 -18
  88. package/src/widgets/__stories__/explanation-editor.stories.tsx +0 -18
  89. package/src/widgets/__stories__/expression-editor.stories.tsx +0 -122
  90. package/src/widgets/__stories__/image-editor.stories.tsx +0 -72
  91. package/src/widgets/__stories__/input-number-editor.stories.tsx +0 -18
  92. package/src/widgets/__stories__/interaction-editor.stories.tsx +0 -37
  93. package/src/widgets/__stories__/label-image-editor.stories.tsx +0 -99
  94. package/src/widgets/__stories__/matcher-editor.stories.tsx +0 -18
  95. package/src/widgets/__stories__/number-line-editor.stories.tsx +0 -18
  96. package/src/widgets/__stories__/numeric-input-editor.stories.tsx +0 -18
  97. package/src/widgets/__stories__/radio-editor.stories.tsx +0 -116
  98. package/src/widgets/__stories__/sorter-editor.stories.tsx +0 -18
  99. package/src/widgets/__tests__/categorizer-editor.test.tsx +0 -51
  100. package/src/widgets/__tests__/definition-editor.test.tsx +0 -41
  101. package/src/widgets/__tests__/dropdown-editor.test.tsx +0 -57
  102. package/src/widgets/__tests__/explanation-editor.test.tsx +0 -59
  103. package/src/widgets/__tests__/expression-editor.test.tsx +0 -403
  104. package/src/widgets/__tests__/input-number-editor.test.tsx +0 -128
  105. package/src/widgets/__tests__/matcher-editor.test.tsx +0 -47
  106. package/src/widgets/__tests__/number-line-editor.test.tsx +0 -144
  107. package/src/widgets/__tests__/numeric-input-editor.test.tsx +0 -177
  108. package/src/widgets/__tests__/radio-editor.test.tsx +0 -118
  109. package/src/widgets/__tests__/sorter-editor.test.tsx +0 -55
  110. package/src/widgets/categorizer-editor.tsx +0 -104
  111. package/src/widgets/cs-program-editor.tsx +0 -256
  112. package/src/widgets/definition-editor.tsx +0 -77
  113. package/src/widgets/deprecated-standin-editor.tsx +0 -29
  114. package/src/widgets/dropdown-editor.tsx +0 -211
  115. package/src/widgets/example-graphie-widget-editor.tsx +0 -70
  116. package/src/widgets/example-graphie-widget.tsx +0 -172
  117. package/src/widgets/example-widget-editor.tsx +0 -62
  118. package/src/widgets/example-widget.tsx +0 -154
  119. package/src/widgets/explanation-editor.tsx +0 -92
  120. package/src/widgets/expression-editor.tsx +0 -557
  121. package/src/widgets/graded-group-editor.tsx +0 -161
  122. package/src/widgets/graded-group-set-editor.tsx +0 -104
  123. package/src/widgets/grapher-editor.tsx +0 -155
  124. package/src/widgets/group-editor.tsx +0 -83
  125. package/src/widgets/iframe-editor.tsx +0 -202
  126. package/src/widgets/image-editor.tsx +0 -367
  127. package/src/widgets/input-number-editor.tsx +0 -288
  128. package/src/widgets/interaction-editor/constraint-editor.tsx +0 -134
  129. package/src/widgets/interaction-editor/function-editor.tsx +0 -108
  130. package/src/widgets/interaction-editor/index.ts +0 -3
  131. package/src/widgets/interaction-editor/interaction-editor.tsx +0 -749
  132. package/src/widgets/interaction-editor/label-editor.tsx +0 -87
  133. package/src/widgets/interaction-editor/line-editor.tsx +0 -125
  134. package/src/widgets/interaction-editor/mathquill-input.tsx +0 -81
  135. package/src/widgets/interaction-editor/movable-line-editor.tsx +0 -121
  136. package/src/widgets/interaction-editor/movable-point-editor.tsx +0 -89
  137. package/src/widgets/interaction-editor/parametric-editor.tsx +0 -117
  138. package/src/widgets/interaction-editor/point-editor.tsx +0 -72
  139. package/src/widgets/interaction-editor/rectangle-editor.tsx +0 -96
  140. package/src/widgets/interactive-graph-editor.tsx +0 -571
  141. package/src/widgets/label-image/__stories__/answer-choices.stories.tsx +0 -82
  142. package/src/widgets/label-image/__stories__/behavior.stories.tsx +0 -31
  143. package/src/widgets/label-image/__stories__/marker.stories.tsx +0 -75
  144. package/src/widgets/label-image/__stories__/question-markers.stories.tsx +0 -107
  145. package/src/widgets/label-image/__stories__/select-image.stories.tsx +0 -59
  146. package/src/widgets/label-image/answer-choices.tsx +0 -231
  147. package/src/widgets/label-image/behavior.tsx +0 -122
  148. package/src/widgets/label-image/marker.tsx +0 -290
  149. package/src/widgets/label-image/question-markers.tsx +0 -176
  150. package/src/widgets/label-image/select-image.tsx +0 -81
  151. package/src/widgets/label-image-editor.tsx +0 -252
  152. package/src/widgets/lights-puzzle-editor.tsx +0 -278
  153. package/src/widgets/matcher-editor.tsx +0 -149
  154. package/src/widgets/matrix-editor.tsx +0 -156
  155. package/src/widgets/measurer-editor.tsx +0 -253
  156. package/src/widgets/molecule-editor.tsx +0 -64
  157. package/src/widgets/number-line-editor.tsx +0 -512
  158. package/src/widgets/numeric-input-editor.tsx +0 -536
  159. package/src/widgets/orderer-editor.tsx +0 -172
  160. package/src/widgets/passage-editor.tsx +0 -117
  161. package/src/widgets/passage-ref-editor.tsx +0 -80
  162. package/src/widgets/passage-ref-target-editor.tsx +0 -49
  163. package/src/widgets/plotter-editor.tsx +0 -542
  164. package/src/widgets/radio/editor.tsx +0 -398
  165. package/src/widgets/reaction-diagram-editor.tsx +0 -131
  166. package/src/widgets/sequence-editor.tsx +0 -205
  167. package/src/widgets/simple-markdown-tester-editor.tsx +0 -86
  168. package/src/widgets/simple-markdown-tester.tsx +0 -92
  169. package/src/widgets/simulator-editor.tsx +0 -146
  170. package/src/widgets/sorter-editor.tsx +0 -103
  171. package/src/widgets/table-editor.tsx +0 -164
  172. package/src/widgets/unit-editor.tsx +0 -299
  173. package/src/widgets/video-editor.tsx +0 -73
  174. package/tsconfig-build.json +0 -22
  175. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,542 +0,0 @@
1
- /* eslint-disable @khanacademy/ts-no-error-suppressions */
2
- /* eslint-disable react/no-unsafe */
3
- import {number as knumber} from "@khanacademy/kmath";
4
- import {
5
- components,
6
- Dependencies,
7
- plotterPlotTypes,
8
- PlotterWidget,
9
- Util,
10
- } from "@khanacademy/perseus";
11
- import * as React from "react";
12
- import ReactDOM from "react-dom";
13
- import _ from "underscore";
14
-
15
- import BlurInput from "../components/blur-input";
16
-
17
- import type {PerseusPlotterWidgetOptions} from "@khanacademy/perseus";
18
-
19
- const {InfoTip, NumberInput, RangeInput, TextListEditor} = components;
20
- const Plotter = PlotterWidget.widget;
21
-
22
- const STARTING = "starting";
23
- const CORRECT = "correct";
24
-
25
- const editingStates = [STARTING, CORRECT];
26
- type EditingState = typeof editingStates[number];
27
-
28
- // Return a copy of array with length n, padded with given value
29
- function padArray(array: any, n, value: any) {
30
- const copy = _.clone(array);
31
- copy.length = n;
32
- for (let i = array.length; i < n; i++) {
33
- copy[i] = value;
34
- }
35
- return copy;
36
- }
37
-
38
- const editorDefaults = {
39
- scaleY: 1,
40
- maxY: 10,
41
- snapsPerLine: 2,
42
- } as const;
43
-
44
- type Props = {
45
- type: PerseusPlotterWidgetOptions["type"];
46
- labels: Array<string>;
47
- categories: ReadonlyArray<string | number>;
48
- scaleY: number;
49
- maxY: number;
50
- snapsPerLine: number;
51
- picSize: number;
52
- picBoxHeight: number;
53
- picUrl: string;
54
- plotDimensions: ReadonlyArray<number>;
55
- labelInterval: number;
56
- starting: ReadonlyArray<number>;
57
- correct: ReadonlyArray<number>;
58
- static: boolean;
59
- onChange: any;
60
- };
61
-
62
- type DefaultProps = {
63
- scaleY: Props["scaleY"];
64
- maxY: Props["maxY"];
65
- snapsPerLine: Props["snapsPerLine"];
66
- correct: Props["correct"];
67
- starting: Props["starting"];
68
- type: Props["type"];
69
- labels: Props["labels"];
70
- categories: Props["categories"];
71
- picSize: Props["picSize"];
72
- picBoxHeight: Props["picBoxHeight"];
73
- plotDimensions: Props["plotDimensions"];
74
- labelInterval: Props["labelInterval"];
75
- picUrl: Props["picUrl"];
76
- };
77
-
78
- type State = {
79
- editing: EditingState;
80
- pic: any;
81
- loadedUrl: string | null;
82
- minX: number | null;
83
- maxX: number | null;
84
- tickStep: number | null;
85
- };
86
-
87
- const formatNumber = (num) => "$" + knumber.round(num, 2) + "$";
88
-
89
- class PlotterEditor extends React.Component<Props, State> {
90
- static widgetName = "plotter" as const;
91
-
92
- static defaultProps: DefaultProps = {
93
- ...editorDefaults,
94
- correct: [1],
95
- starting: [1],
96
-
97
- type: "bar",
98
- labels: ["", ""],
99
- categories: [""],
100
-
101
- picSize: 30,
102
- picBoxHeight: 36,
103
- plotDimensions: [275, 200],
104
- labelInterval: 1,
105
-
106
- // @ts-expect-error - TS2322
107
- get picUrl() {
108
- const staticUrl = Dependencies.getDependencies().staticUrl;
109
- if (staticUrl) {
110
- return staticUrl("/images/badges/earth-small.png");
111
- }
112
-
113
- return null;
114
- },
115
- };
116
-
117
- state: State = {
118
- editing: this.props.static ? STARTING : CORRECT,
119
- pic: null,
120
- loadedUrl: null,
121
- minX: null,
122
- maxX: null,
123
- tickStep: null,
124
- };
125
-
126
- // TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
127
- UNSAFE_componentWillMount() {
128
- this.fetchPic(this.props.picUrl);
129
- }
130
-
131
- UNSAFE_componentWillReceiveProps(nextProps: any) {
132
- this.fetchPic(nextProps.picUrl);
133
-
134
- if (nextProps.static) {
135
- this.setState({
136
- editing: "starting",
137
- });
138
- }
139
- }
140
-
141
- fetchPic: (arg1: string) => any = (url) => {
142
- if (this.state.loadedUrl !== url) {
143
- const pic = new Image();
144
- pic.src = url;
145
- pic.onload = () => {
146
- this.setState({
147
- pic: pic,
148
- loadedUrl: url,
149
- });
150
- };
151
- }
152
- };
153
-
154
- handleChangeTickStep: (arg1: number) => void = (value) => {
155
- this.setState({
156
- tickStep: value,
157
- });
158
- };
159
-
160
- handleChangeRange: (arg1: [number, number]) => void = (newValue) => {
161
- this.setState({
162
- minX: newValue[0],
163
- maxX: newValue[1],
164
- });
165
- };
166
-
167
- changeLabelInterval: (arg1: number) => void = (value) => {
168
- this.props.onChange({
169
- labelInterval: value,
170
- });
171
- };
172
-
173
- handlePlotterChange: (arg1: any) => void = (newProps) => {
174
- const props: Record<string, any> = {};
175
- props[this.state.editing] = newProps.values;
176
- this.props.onChange(props);
177
- };
178
-
179
- changeType: (arg1: any) => void = (type) => {
180
- let categories;
181
- if (type === "histogram") {
182
- // Switching to histogram, add a label (0) to the left
183
- // @ts-expect-error - TS2769
184
- categories = [formatNumber(0)].concat(this.props.categories);
185
- this.props.onChange({type: type, categories: categories});
186
- } else if (this.props.type === "histogram") {
187
- // Switching from histogram, remove a label from the left
188
- categories = this.props.categories.slice(1);
189
- this.props.onChange({type: type, categories: categories});
190
- } else {
191
- this.props.onChange({type: type});
192
- }
193
-
194
- if (categories) {
195
- // eslint-disable-next-line react/no-string-refs
196
- const node = ReactDOM.findDOMNode(this.refs.categories);
197
- // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'value' does not exist on type 'Element | Text'.
198
- node.value = categories.join(", ");
199
- }
200
- };
201
-
202
- changeLabel: (arg1: number, arg2: any) => void = (i, e) => {
203
- const labels = _.clone(this.props.labels);
204
- labels[i] = e.target.value;
205
- this.props.onChange({labels: labels});
206
- };
207
-
208
- changePicUrl: (arg1: string) => void = (value) => {
209
- // We don't need the labels and other data in the plotter, so just
210
- // extract the raw image and use that.
211
- // TODO(emily): Maybe indicate that such a change has happened?
212
- const url = Util.getRealImageUrl(value);
213
-
214
- this.props.onChange({picUrl: url});
215
- };
216
-
217
- changeCategories: (arg1: any) => void = (categories) => {
218
- let n = categories.length;
219
- if (this.props.type === "histogram") {
220
- // Histograms with n labels/categories have n - 1 buckets
221
- n--;
222
- }
223
- const value = this.props.scaleY;
224
-
225
- this.props.onChange({
226
- categories: categories,
227
- correct: padArray(this.props.correct, n, value),
228
- starting: padArray(this.props.starting, n, value),
229
- });
230
- };
231
-
232
- changeScale: (arg1: any) => void = (e) => {
233
- const oldScale = this.props.scaleY;
234
- const newScale = +e.target.value || editorDefaults.scaleY;
235
-
236
- const scale = function (value: any) {
237
- return (value * newScale) / oldScale;
238
- };
239
-
240
- const maxY = scale(this.props.maxY);
241
-
242
- this.props.onChange({
243
- scaleY: newScale,
244
- maxY: maxY,
245
- correct: _.map(this.props.correct, scale),
246
- starting: _.map(this.props.starting, scale),
247
- });
248
-
249
- // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'value' does not exist on type 'Element | Text'.
250
- ReactDOM.findDOMNode(this.refs.maxY).value = maxY; // eslint-disable-line react/no-string-refs
251
- };
252
-
253
- changeMax: (arg1: any) => void = (e) => {
254
- this.props.onChange({
255
- maxY: +e.target.value || editorDefaults.maxY,
256
- });
257
- };
258
-
259
- changeSnaps: (arg1: any) => void = (e) => {
260
- this.props.onChange({
261
- snapsPerLine: +e.target.value || editorDefaults.snapsPerLine,
262
- });
263
- };
264
-
265
- changeEditing: (arg1: EditingState) => void = (editing) => {
266
- this.setState({editing: editing});
267
- };
268
-
269
- setCategoriesFromScale: () => void = () => {
270
- const scale = this.state.tickStep || 1;
271
- const min = this.state.minX || 0;
272
- const max = this.state.maxX || 0;
273
- const length = Math.floor((max - min) / scale) * scale;
274
-
275
- let categories;
276
- if (this.props.type === "histogram" || this.props.type === "dotplot") {
277
- // Ranges for histogram and dotplot labels should start at zero
278
- categories = _.range(0, length + scale, scale);
279
- } else {
280
- categories = _.range(scale, length + scale, scale);
281
- }
282
-
283
- categories = _.map(categories, (num) => num + min);
284
- categories = _.map(categories, formatNumber);
285
-
286
- this.changeCategories(categories);
287
-
288
- // eslint-disable-next-line react/no-string-refs
289
- const node = ReactDOM.findDOMNode(this.refs.categories);
290
-
291
- // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'value' does not exist on type 'Element | Text'.
292
- node.value = categories.join(", ");
293
- };
294
-
295
- serialize: () => any = () => {
296
- const json = _.pick(
297
- this.props,
298
- "correct",
299
- "starting",
300
- "type",
301
- "labels",
302
- "categories",
303
- "scaleY",
304
- "maxY",
305
- "snapsPerLine",
306
- "labelInterval",
307
- );
308
-
309
- if (this.props.type === "pic") {
310
- // @ts-expect-error - TS2339 - Property 'picUrl' does not exist on type 'Pick<Readonly<any> & Readonly<{ children?: ReactNode; }>, "type" | "correct" | "labels" | "categories" | "starting" | "scaleY" | "maxY" | "snapsPerLine" | "labelInterval">'.
311
- json.picUrl = this.props.picUrl;
312
- }
313
-
314
- return json;
315
- };
316
-
317
- render(): React.ReactNode {
318
- const setFromScale = _.contains(
319
- ["line", "histogram", "dotplot"],
320
- this.props.type,
321
- );
322
- const canChangeSnaps = !_.contains(["pic", "dotplot"], this.props.type);
323
- const props = {
324
- trackInteraction: () => {},
325
- ...this.props,
326
- } as const;
327
-
328
- return (
329
- <div className="perseus-widget-plotter-editor">
330
- <div>
331
- Chart type:{" "}
332
- {plotterPlotTypes.map((type) => {
333
- return (
334
- <label key={type}>
335
- <input
336
- type="radio"
337
- name="chart-type"
338
- checked={this.props.type === type}
339
- onChange={_.partial(this.changeType, type)}
340
- />
341
- {type}
342
- </label>
343
- );
344
- }, this)}
345
- </div>
346
- <div>
347
- Labels:{" "}
348
- {["x", "y"].map((axis, i) => {
349
- return (
350
- <label key={axis}>
351
- {axis + ":"}
352
- <input
353
- type="text"
354
- onChange={_.partial(this.changeLabel, i)}
355
- defaultValue={this.props.labels[i]}
356
- />
357
- </label>
358
- );
359
- }, this)}
360
- </div>
361
-
362
- {setFromScale && (
363
- <div className="set-from-scale-box">
364
- <span className="categories-title">
365
- Set Categories From Scale
366
- </span>
367
- <div>
368
- <label>
369
- Tick Step:{" "}
370
- <NumberInput
371
- placeholder={1}
372
- useArrowKeys={true}
373
- value={this.state.tickStep}
374
- onChange={this.handleChangeTickStep}
375
- />
376
- </label>
377
- <InfoTip>
378
- <p>The difference between adjacent ticks.</p>
379
- </InfoTip>
380
- </div>
381
- <div>
382
- <label>
383
- Range:{" "}
384
- <RangeInput
385
- placeholder={[0, 10]}
386
- useArrowKeys={true}
387
- value={[this.state.minX, this.state.maxX]}
388
- onChange={this.handleChangeRange}
389
- />
390
- </label>
391
- </div>
392
- <div>
393
- <button onClick={this.setCategoriesFromScale}>
394
- Set Categories{" "}
395
- </button>
396
- </div>
397
- </div>
398
- )}
399
- <div>
400
- <label>
401
- Label Interval:{" "}
402
- <NumberInput
403
- useArrowKeys={true}
404
- value={this.props.labelInterval}
405
- onChange={this.changeLabelInterval}
406
- />
407
- </label>
408
- <InfoTip>
409
- <p>
410
- Which ticks to display the labels for. For instance,
411
- setting this to "4" will only show every 4th label
412
- (plus the last one)
413
- </p>
414
- </InfoTip>
415
- </div>
416
- {this.props.type === "pic" && (
417
- <div>
418
- <label>
419
- Picture:{" "}
420
- <BlurInput
421
- className="pic-url"
422
- value={this.props.picUrl}
423
- onChange={this.changePicUrl}
424
- />
425
- <InfoTip>
426
- <p>
427
- Use the default picture of Earth, or insert
428
- the URL for a different picture using the
429
- "Add image" function.
430
- </p>
431
- </InfoTip>
432
- </label>
433
- {this.state.pic &&
434
- this.state.pic.width !== this.state.pic.height && (
435
- <p className="warning">
436
- <b>Warning</b>: You are using a picture
437
- which is not square. This means the image
438
- will get distorted. You should probably crop
439
- it to be square.
440
- </p>
441
- )}
442
- </div>
443
- )}
444
- <div>
445
- <label>
446
- Categories:{" "}
447
- <TextListEditor
448
- // eslint-disable-next-line react/no-string-refs
449
- ref="categories"
450
- layout="horizontal"
451
- options={this.props.categories}
452
- onChange={this.changeCategories}
453
- />
454
- </label>
455
- </div>
456
- <div>
457
- <label>
458
- Scale (y):{" "}
459
- <input
460
- type="text"
461
- onChange={this.changeScale}
462
- defaultValue={this.props.scaleY}
463
- />
464
- </label>
465
- </div>
466
- <div>
467
- <label>
468
- Max y:{" "}
469
- <input
470
- type="text"
471
- // eslint-disable-next-line react/no-string-refs
472
- ref="maxY"
473
- onChange={this.changeMax}
474
- defaultValue={this.props.maxY}
475
- />
476
- </label>
477
- </div>
478
- {canChangeSnaps && (
479
- <div>
480
- <label>
481
- Snaps per line:{" "}
482
- <input
483
- type="text"
484
- onChange={this.changeSnaps}
485
- defaultValue={this.props.snapsPerLine}
486
- />
487
- </label>
488
- <InfoTip>
489
- <p>
490
- Creates the specified number of divisions
491
- between the horizontal lines. Fewer snaps
492
- between lines makes the graph easier for the
493
- student to create correctly.
494
- </p>
495
- </InfoTip>
496
- </div>
497
- )}
498
- <div>
499
- Editing values:{" "}
500
- {editingStates.map((editing) => (
501
- <label key={editing}>
502
- <input
503
- type="radio"
504
- disabled={
505
- editing === CORRECT && this.props.static
506
- }
507
- checked={
508
- this.props.static
509
- ? editing === STARTING
510
- : this.state.editing === editing
511
- }
512
- onChange={(e) => this.changeEditing(editing)}
513
- />
514
- {editing}
515
- </label>
516
- ))}
517
- <InfoTip>
518
- <p>
519
- Use this toggle to switch between editing the
520
- correct answer (what the student will be graded on)
521
- and the starting values (what the student will see
522
- plotted when they start the problem). Note: These
523
- cannot be the same.
524
- </p>
525
- <p>
526
- In static mode, the starting values are rendered out
527
- to the displayed widget.
528
- </p>
529
- </InfoTip>
530
- </div>
531
- {/* @ts-expect-error - TS2769 */}
532
- <Plotter
533
- {...props}
534
- starting={this.props[this.state.editing]}
535
- onChange={this.handlePlotterChange}
536
- />
537
- </div>
538
- );
539
- }
540
- }
541
-
542
- export default PlotterEditor;