@khanacademy/perseus-editor 2.15.3 → 2.15.5

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 (61) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/editor-page.d.ts +4 -10
  3. package/dist/editor.d.ts +2 -2
  4. package/dist/es/index.js +362 -360
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.js +426 -425
  7. package/dist/index.js.map +1 -1
  8. package/dist/widgets/interaction-editor/function-editor.d.ts +26 -0
  9. package/dist/widgets/interaction-editor/index.d.ts +2 -0
  10. package/dist/widgets/interaction-editor/label-editor.d.ts +22 -0
  11. package/dist/widgets/interaction-editor/line-editor.d.ts +30 -0
  12. package/dist/widgets/interaction-editor/movable-line-editor.d.ts +32 -0
  13. package/dist/widgets/interaction-editor/movable-point-editor.d.ts +28 -0
  14. package/dist/widgets/interaction-editor/parametric-editor.d.ts +28 -0
  15. package/dist/widgets/interaction-editor/point-editor.d.ts +20 -0
  16. package/dist/widgets/interaction-editor/rectangle-editor.d.ts +24 -0
  17. package/dist/widgets/interactive-graph-editor.d.ts +92 -92
  18. package/package.json +2 -2
  19. package/src/__stories__/editor-page.stories.tsx +65 -0
  20. package/src/__stories__/editor.stories.tsx +2 -4
  21. package/src/editor-page.tsx +5 -11
  22. package/src/editor.tsx +2 -2
  23. package/src/widgets/__stories__/categorizer-editor.stories.tsx +24 -0
  24. package/src/widgets/__stories__/definition-editor.stories.tsx +18 -0
  25. package/src/widgets/__stories__/dropdown-editor.stories.tsx +18 -0
  26. package/src/widgets/__stories__/explanation-editor.stories.tsx +18 -0
  27. package/src/widgets/__stories__/input-number-editor.stories.tsx +18 -0
  28. package/src/widgets/__stories__/interaction-editor.stories.tsx +24 -0
  29. package/src/widgets/__stories__/matcher-editor.stories.tsx +18 -0
  30. package/src/widgets/__stories__/number-line-editor.stories.tsx +18 -0
  31. package/src/widgets/__stories__/numeric-input-editor.stories.tsx +18 -0
  32. package/src/widgets/__stories__/radio-editor.stories.tsx +3 -3
  33. package/src/widgets/__stories__/sorter-editor.stories.tsx +18 -0
  34. package/src/widgets/__tests__/categorizer-editor.test.tsx +51 -0
  35. package/src/widgets/__tests__/definition-editor.test.tsx +41 -0
  36. package/src/widgets/__tests__/dropdown-editor.test.tsx +57 -0
  37. package/src/widgets/__tests__/explanation-editor.test.tsx +59 -0
  38. package/src/widgets/__tests__/input-number-editor.test.tsx +128 -0
  39. package/src/widgets/__tests__/matcher-editor.test.tsx +47 -0
  40. package/src/widgets/__tests__/number-line-editor.test.tsx +144 -0
  41. package/src/widgets/__tests__/numeric-input-editor.test.tsx +177 -0
  42. package/src/widgets/__tests__/radio-editor.test.tsx +118 -0
  43. package/src/widgets/__tests__/sorter-editor.test.tsx +55 -0
  44. package/src/widgets/dropdown-editor.tsx +1 -0
  45. package/src/widgets/input-number-editor.tsx +2 -0
  46. package/src/widgets/interaction-editor/function-editor.tsx +111 -0
  47. package/src/widgets/interaction-editor/index.ts +3 -0
  48. package/src/widgets/{interaction-editor.tsx → interaction-editor/interaction-editor.tsx} +14 -768
  49. package/src/widgets/interaction-editor/label-editor.tsx +91 -0
  50. package/src/widgets/interaction-editor/line-editor.tsx +129 -0
  51. package/src/widgets/interaction-editor/movable-line-editor.tsx +125 -0
  52. package/src/widgets/interaction-editor/movable-point-editor.tsx +92 -0
  53. package/src/widgets/interaction-editor/parametric-editor.tsx +122 -0
  54. package/src/widgets/interaction-editor/point-editor.tsx +79 -0
  55. package/src/widgets/interaction-editor/rectangle-editor.tsx +105 -0
  56. package/src/widgets/number-line-editor.tsx +16 -5
  57. package/src/widgets/numeric-input-editor.tsx +2 -0
  58. package/tsconfig-build.tsbuildinfo +1 -1
  59. package/dist/widgets/{interaction → interaction-editor}/constraint-editor.d.ts +0 -0
  60. package/dist/widgets/{interaction-editor.d.ts → interaction-editor/interaction-editor.d.ts} +1 -1
  61. /package/src/widgets/{interaction → interaction-editor}/constraint-editor.tsx +0 -0
@@ -0,0 +1,91 @@
1
+ import {
2
+ components,
3
+ Changeable,
4
+ Dependencies,
5
+ EditorJsonify,
6
+ KhanColors,
7
+ ColorPicker,
8
+ } from "@khanacademy/perseus";
9
+ import PropTypes from "prop-types";
10
+ import * as React from "react";
11
+ import _ from "underscore";
12
+
13
+ const {MathInput, TextInput} = components;
14
+ const {getDependencies} = Dependencies;
15
+
16
+ type LabelEditorProps = any;
17
+
18
+ //
19
+ // Editor for labels
20
+ //
21
+ // TODO(eater): Factor this out maybe?
22
+ // TODO(eater): Add text direction
23
+ //
24
+ class LabelEditor extends React.Component<LabelEditorProps> {
25
+ static propTypes = {
26
+ ...Changeable.propTypes,
27
+ color: PropTypes.string,
28
+ coordX: PropTypes.string,
29
+ coordY: PropTypes.string,
30
+ label: PropTypes.string,
31
+ };
32
+
33
+ static defaultProps = {
34
+ coordX: "0",
35
+ coordY: "0",
36
+ color: KhanColors.BLACK,
37
+ label: "\\phi",
38
+ };
39
+
40
+ change: (arg1: any, arg2?: any, arg3?: any) => any = (...args) => {
41
+ return Changeable.change.apply(this, args);
42
+ };
43
+
44
+ serialize = () => {
45
+ return EditorJsonify.serialize.call(this);
46
+ };
47
+
48
+ render(): React.ReactNode {
49
+ const {TeX} = getDependencies();
50
+ const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
51
+
52
+ return (
53
+ <div className="graph-settings">
54
+ <div className="perseus-widget-row">
55
+ <TextInput
56
+ value={this.props.label}
57
+ onChange={this.change("label")}
58
+ style={{
59
+ width: "100%",
60
+ }}
61
+ />
62
+ </div>
63
+ <div className="perseus-widget-row">
64
+ Location: <TeX>\Large(</TeX>
65
+ <MathInput
66
+ buttonsVisible="never"
67
+ value={this.props.coordX}
68
+ onChange={this.change("coordX")}
69
+ analytics={analyticsStub}
70
+ />
71
+ <TeX>,</TeX>{" "}
72
+ <MathInput
73
+ buttonsVisible="never"
74
+ value={this.props.coordY}
75
+ onChange={this.change("coordY")}
76
+ analytics={analyticsStub}
77
+ />
78
+ <TeX>\Large)</TeX>
79
+ </div>
80
+ <div className="perseus-widget-row">
81
+ <ColorPicker
82
+ value={this.props.color}
83
+ onChange={this.change("color")}
84
+ />
85
+ </div>
86
+ </div>
87
+ );
88
+ }
89
+ }
90
+
91
+ export default LabelEditor;
@@ -0,0 +1,129 @@
1
+ import {
2
+ components,
3
+ Changeable,
4
+ Dependencies,
5
+ EditorJsonify,
6
+ KhanColors,
7
+ ArrowPicker,
8
+ ColorPicker,
9
+ DashPicker,
10
+ } from "@khanacademy/perseus";
11
+ import PropTypes from "prop-types";
12
+ import * as React from "react";
13
+ import _ from "underscore";
14
+
15
+ const {MathInput, NumberInput} = components;
16
+ const {getDependencies} = Dependencies;
17
+
18
+ type LineEditorProps = any;
19
+
20
+ //
21
+ // Editor for non-interactive line segments
22
+ //
23
+ // TODO(eater): Factor this out
24
+ //
25
+ class LineEditor extends React.Component<LineEditorProps> {
26
+ static propTypes = {
27
+ ...Changeable.propTypes,
28
+ startX: PropTypes.string,
29
+ startY: PropTypes.string,
30
+ endX: PropTypes.string,
31
+ endY: PropTypes.string,
32
+ color: PropTypes.string,
33
+ strokeDasharray: PropTypes.string,
34
+ arrows: PropTypes.string,
35
+ strokeWidth: PropTypes.number,
36
+ };
37
+
38
+ static defaultProps = {
39
+ startX: "-5",
40
+ startY: "5",
41
+ endX: "5",
42
+ endY: "5",
43
+ color: KhanColors.BLACK,
44
+ strokeDasharray: "",
45
+ arrows: "",
46
+ strokeWidth: 2,
47
+ };
48
+
49
+ change: (arg1: any, arg2?: any, arg3?: any) => any = (...args) => {
50
+ return Changeable.change.apply(this, args);
51
+ };
52
+
53
+ serialize = () => {
54
+ return EditorJsonify.serialize.call(this);
55
+ };
56
+
57
+ render(): React.ReactNode {
58
+ const {TeX} = getDependencies();
59
+ const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
60
+
61
+ return (
62
+ <div className="graph-settings">
63
+ <div className="perseus-widget-row">
64
+ Start: <TeX>\Large(</TeX>
65
+ <MathInput
66
+ buttonsVisible="never"
67
+ value={this.props.startX}
68
+ onChange={this.change("startX")}
69
+ analytics={analyticsStub}
70
+ />
71
+ <TeX>,</TeX>{" "}
72
+ <MathInput
73
+ buttonsVisible="never"
74
+ value={this.props.startY}
75
+ onChange={this.change("startY")}
76
+ analytics={analyticsStub}
77
+ />
78
+ <TeX>\Large)</TeX>
79
+ </div>
80
+ <div className="perseus-widget-row">
81
+ End: <TeX>\Large(</TeX>
82
+ <MathInput
83
+ buttonsVisible="never"
84
+ value={this.props.endX}
85
+ onChange={this.change("endX")}
86
+ analytics={analyticsStub}
87
+ />
88
+ <TeX>,</TeX>{" "}
89
+ <MathInput
90
+ buttonsVisible="never"
91
+ value={this.props.endY}
92
+ onChange={this.change("endY")}
93
+ analytics={analyticsStub}
94
+ />
95
+ <TeX>\Large)</TeX>
96
+ </div>
97
+ <div className="perseus-widget-row">
98
+ <ColorPicker
99
+ value={this.props.color}
100
+ onChange={this.change("color")}
101
+ />
102
+ </div>
103
+ <div className="perseus-widget-row">
104
+ <DashPicker
105
+ value={this.props.strokeDasharray}
106
+ onChange={this.change("strokeDasharray")}
107
+ />
108
+ &nbsp; &nbsp;
109
+ <ArrowPicker
110
+ value={this.props.arrows}
111
+ onChange={this.change("arrows")}
112
+ />
113
+ </div>
114
+ <div className="perseus-widget-row">
115
+ <div className="perseus-widget-left-col">
116
+ Width:{" "}
117
+ <NumberInput
118
+ value={this.props.strokeWidth}
119
+ placeholder={2}
120
+ onChange={this.change("strokeWidth")}
121
+ />
122
+ </div>
123
+ </div>
124
+ </div>
125
+ );
126
+ }
127
+ }
128
+
129
+ export default LineEditor;
@@ -0,0 +1,125 @@
1
+ import {
2
+ components,
3
+ Changeable,
4
+ Dependencies,
5
+ EditorJsonify,
6
+ } from "@khanacademy/perseus";
7
+ import PropTypes from "prop-types";
8
+ import * as React from "react";
9
+ import _ from "underscore";
10
+
11
+ import ConstraintEditor from "./constraint-editor";
12
+
13
+ const {MathInput, NumberInput} = components;
14
+ const {getDependencies} = Dependencies;
15
+
16
+ type MovableLineEditorProps = any;
17
+
18
+ //
19
+ // Editor for interactive movable line segments
20
+ //
21
+ // TODO(eater): Factor this out
22
+ // TODO(eater): Rethink how constraints are represented
23
+ //
24
+ class MovableLineEditor extends React.Component<MovableLineEditorProps> {
25
+ static propTypes = {
26
+ ...Changeable.propTypes,
27
+ startX: PropTypes.string,
28
+ startY: PropTypes.string,
29
+ endX: PropTypes.string,
30
+ endY: PropTypes.string,
31
+ constraint: PropTypes.string,
32
+ snap: PropTypes.number,
33
+ constraintFn: PropTypes.string,
34
+ };
35
+
36
+ static defaultProps = {
37
+ startX: "-5",
38
+ startY: "5",
39
+ endX: "5",
40
+ endY: "5",
41
+ constraint: "none",
42
+ snap: 0.5,
43
+ constraintFn: "0",
44
+ constraintXMin: "-10",
45
+ constraintXMax: "10",
46
+ constraintYMin: "-10",
47
+ constraintYMax: "10",
48
+ };
49
+
50
+ change = (...args) => {
51
+ return Changeable.change.apply(this, args);
52
+ };
53
+
54
+ serialize = () => {
55
+ return EditorJsonify.serialize.call(this);
56
+ };
57
+
58
+ render(): React.ReactNode {
59
+ const {TeX} = getDependencies();
60
+ const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
61
+
62
+ return (
63
+ <div className="graph-settings">
64
+ Initial position:
65
+ <div className="perseus-widget-row">
66
+ Start: <TeX>\Large(</TeX>
67
+ <MathInput
68
+ buttonsVisible="never"
69
+ value={this.props.startX}
70
+ onChange={this.change("startX")}
71
+ analytics={analyticsStub}
72
+ />
73
+ <TeX>,</TeX>{" "}
74
+ <MathInput
75
+ buttonsVisible="never"
76
+ value={this.props.startY}
77
+ onChange={this.change("startY")}
78
+ analytics={analyticsStub}
79
+ />
80
+ <TeX>\Large)</TeX>
81
+ </div>
82
+ <div className="perseus-widget-row">
83
+ End: <TeX>\Large(</TeX>
84
+ <MathInput
85
+ buttonsVisible="never"
86
+ value={this.props.endX}
87
+ onChange={this.change("endX")}
88
+ analytics={analyticsStub}
89
+ />
90
+ <TeX>,</TeX>{" "}
91
+ <MathInput
92
+ buttonsVisible="never"
93
+ value={this.props.endY}
94
+ onChange={this.change("endY")}
95
+ analytics={analyticsStub}
96
+ />
97
+ <TeX>\Large)</TeX>
98
+ </div>
99
+ <div className="perseus-widget-row">
100
+ Start updates <TeX>(x_n, y_n)</TeX> for <TeX>n =</TeX>
101
+ <NumberInput
102
+ value={this.props.startSubscript}
103
+ placeholder={0}
104
+ onChange={this.change("startSubscript")}
105
+ />
106
+ </div>
107
+ <div className="perseus-widget-row">
108
+ End updates <TeX>(x_m, y_m)</TeX> for <TeX>m =</TeX>
109
+ <NumberInput
110
+ value={this.props.endSubscript}
111
+ placeholder={0}
112
+ onChange={this.change("endSubscript")}
113
+ />
114
+ </div>
115
+ <div className="perseus-widget-row">
116
+ All constraints are applied to the start point.
117
+ </div>
118
+ {/* @ts-expect-error - TS2769 - No overload matches this call. */}
119
+ <ConstraintEditor {...this.props} />
120
+ </div>
121
+ );
122
+ }
123
+ }
124
+
125
+ export default MovableLineEditor;
@@ -0,0 +1,92 @@
1
+ import {
2
+ components,
3
+ Changeable,
4
+ Dependencies,
5
+ EditorJsonify,
6
+ } from "@khanacademy/perseus";
7
+ import PropTypes from "prop-types";
8
+ import * as React from "react";
9
+ import _ from "underscore";
10
+
11
+ import ConstraintEditor from "./constraint-editor";
12
+
13
+ const {MathInput, NumberInput} = components;
14
+ const {getDependencies} = Dependencies;
15
+
16
+ type MovablePointEditorProps = any;
17
+
18
+ //
19
+ // Editor for interactive movable points
20
+ //
21
+ // TODO(eater): Factor this out
22
+ // TODO(eater): Rethink how constraints are represented
23
+ //
24
+ class MovablePointEditor extends React.Component<MovablePointEditorProps> {
25
+ static propTypes = {
26
+ ...Changeable.propTypes,
27
+ startX: PropTypes.string,
28
+ startY: PropTypes.string,
29
+ constraint: PropTypes.string,
30
+ snap: PropTypes.number,
31
+ constraintFn: PropTypes.string,
32
+ };
33
+
34
+ static defaultProps = {
35
+ startX: "0",
36
+ startY: "0",
37
+ constraint: "none",
38
+ snap: 0.5,
39
+ constraintFn: "0",
40
+ constraintXMin: "-10",
41
+ constraintXMax: "10",
42
+ constraintYMin: "-10",
43
+ constraintYMax: "10",
44
+ };
45
+
46
+ change = (...args) => {
47
+ return Changeable.change.apply(this, args);
48
+ };
49
+
50
+ serialize = () => {
51
+ return EditorJsonify.serialize.call(this);
52
+ };
53
+
54
+ render(): React.ReactNode {
55
+ const {TeX} = getDependencies();
56
+ const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
57
+
58
+ return (
59
+ <div className="graph-settings">
60
+ <div className="perseus-widget-row">
61
+ Start: <TeX>\Large(</TeX>
62
+ <MathInput
63
+ buttonsVisible="never"
64
+ value={this.props.startX}
65
+ onChange={this.change("startX")}
66
+ analytics={analyticsStub}
67
+ />
68
+ <TeX>,</TeX>{" "}
69
+ <MathInput
70
+ buttonsVisible="never"
71
+ value={this.props.startY}
72
+ onChange={this.change("startY")}
73
+ analytics={analyticsStub}
74
+ />
75
+ <TeX>\Large)</TeX>
76
+ </div>
77
+ <div className="perseus-widget-row">
78
+ Update <TeX>(x_n, y_n)</TeX> for <TeX>n =</TeX>{" "}
79
+ <NumberInput
80
+ value={this.props.varSubscript}
81
+ placeholder={0}
82
+ onChange={this.change("varSubscript")}
83
+ />
84
+ </div>
85
+ {/* @ts-expect-error - TS2769 - No overload matches this call. */}
86
+ <ConstraintEditor {...this.props} />
87
+ </div>
88
+ );
89
+ }
90
+ }
91
+
92
+ export default MovablePointEditor;
@@ -0,0 +1,122 @@
1
+ import {
2
+ components,
3
+ Changeable,
4
+ Dependencies,
5
+ EditorJsonify,
6
+ KhanColors,
7
+ ColorPicker,
8
+ DashPicker,
9
+ } from "@khanacademy/perseus";
10
+ import PropTypes from "prop-types";
11
+ import * as React from "react";
12
+ import _ from "underscore";
13
+
14
+ const {MathInput, NumberInput} = components;
15
+ const {getDependencies} = Dependencies;
16
+
17
+ type ParametricEditorProps = any;
18
+
19
+ //
20
+ // Editor for parametric plots
21
+ //
22
+ // TODO(eater): Factor this out
23
+ //
24
+ class ParametricEditor extends React.Component<ParametricEditorProps> {
25
+ static propTypes = {
26
+ ...Changeable.propTypes,
27
+ x: PropTypes.string,
28
+ y: PropTypes.string,
29
+ rangeMin: PropTypes.string,
30
+ rangeMax: PropTypes.string,
31
+ color: PropTypes.string,
32
+ strokeDashArray: PropTypes.string,
33
+ strokeWidth: PropTypes.number,
34
+ };
35
+
36
+ static defaultProps = {
37
+ x: "cos(t)",
38
+ y: "sin(t)",
39
+ rangeMin: "0",
40
+ rangeMax: "2\\pi",
41
+ color: KhanColors.BLUE,
42
+ strokeDasharray: "",
43
+ strokeWidth: 2,
44
+ };
45
+
46
+ change: (arg1: any, arg2?: any, arg3?: any) => any = (...args) => {
47
+ return Changeable.change.apply(this, args);
48
+ };
49
+
50
+ serialize = () => {
51
+ return EditorJsonify.serialize.call(this);
52
+ };
53
+
54
+ render(): React.ReactNode {
55
+ const {TeX} = getDependencies();
56
+ const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
57
+
58
+ return (
59
+ <div className="graph-settings">
60
+ <div className="perseus-widget-row">
61
+ <TeX>X(t) =</TeX>{" "}
62
+ <MathInput
63
+ buttonsVisible="never"
64
+ value={this.props.x}
65
+ onChange={this.change("x")}
66
+ analytics={analyticsStub}
67
+ />
68
+ </div>
69
+ <div className="perseus-widget-row">
70
+ <TeX>Y(t) =</TeX>{" "}
71
+ <MathInput
72
+ buttonsVisible="never"
73
+ value={this.props.y}
74
+ onChange={this.change("y")}
75
+ analytics={analyticsStub}
76
+ />
77
+ </div>
78
+ <div className="perseus-widget-row">
79
+ Range: <TeX>\Large(</TeX>
80
+ <MathInput
81
+ buttonsVisible="never"
82
+ value={this.props.rangeMin}
83
+ onChange={this.change("rangeMin")}
84
+ analytics={analyticsStub}
85
+ />
86
+ <TeX>,</TeX>{" "}
87
+ <MathInput
88
+ buttonsVisible="never"
89
+ value={this.props.rangeMax}
90
+ onChange={this.change("rangeMax")}
91
+ analytics={analyticsStub}
92
+ />
93
+ <TeX>\Large)</TeX>
94
+ </div>
95
+ <div className="perseus-widget-row">
96
+ <ColorPicker
97
+ value={this.props.color}
98
+ onChange={this.change("color")}
99
+ />
100
+ </div>
101
+ <div className="perseus-widget-row">
102
+ <DashPicker
103
+ value={this.props.strokeDasharray}
104
+ onChange={this.change("strokeDasharray")}
105
+ />
106
+ </div>
107
+ <div className="perseus-widget-row">
108
+ <div className="perseus-widget-left-col">
109
+ Width:{" "}
110
+ <NumberInput
111
+ value={this.props.strokeWidth}
112
+ placeholder={2}
113
+ onChange={this.change("strokeWidth")}
114
+ />
115
+ </div>
116
+ </div>
117
+ </div>
118
+ );
119
+ }
120
+ }
121
+
122
+ export default ParametricEditor;
@@ -0,0 +1,79 @@
1
+ import {
2
+ components,
3
+ Changeable,
4
+ Dependencies,
5
+ EditorJsonify,
6
+ KhanColors,
7
+ ColorPicker,
8
+ } from "@khanacademy/perseus";
9
+ import PropTypes from "prop-types";
10
+ import * as React from "react";
11
+ import _ from "underscore";
12
+
13
+ const {MathInput} = components;
14
+ const {getDependencies} = Dependencies;
15
+
16
+ type PointEditorProps = any;
17
+
18
+ //
19
+ // Editor for non-interactive points
20
+ //
21
+ // TODO(eater): Factor this out
22
+ //
23
+ class PointEditor extends React.Component<PointEditorProps> {
24
+ static propTypes = {
25
+ ...Changeable.propTypes,
26
+ coordX: PropTypes.string,
27
+ coordY: PropTypes.string,
28
+ color: PropTypes.string,
29
+ };
30
+
31
+ static defaultProps = {
32
+ coordX: "0",
33
+ coordY: "0",
34
+ color: KhanColors.BLACK,
35
+ };
36
+
37
+ change: (arg1: any, arg2?: any, arg3?: any) => any = (...args) => {
38
+ return Changeable.change.apply(this, args);
39
+ };
40
+
41
+ serialize = () => {
42
+ return EditorJsonify.serialize.call(this);
43
+ };
44
+
45
+ render(): React.ReactNode {
46
+ const {TeX} = getDependencies();
47
+ const analyticsStub = {onAnalyticsEvent: () => Promise.resolve()};
48
+
49
+ return (
50
+ <div className="graph-settings">
51
+ <div className="perseus-widget-row">
52
+ Coordinate: <TeX>\Large(</TeX>
53
+ <MathInput
54
+ buttonsVisible="never"
55
+ value={this.props.coordX}
56
+ onChange={this.change("coordX")}
57
+ analytics={analyticsStub}
58
+ />
59
+ <TeX>,</TeX>{" "}
60
+ <MathInput
61
+ buttonsVisible="never"
62
+ value={this.props.coordY}
63
+ onChange={this.change("coordY")}
64
+ analytics={analyticsStub}
65
+ />
66
+ <TeX>\Large)</TeX>
67
+ </div>
68
+ <div className="perseus-widget-row">
69
+ <ColorPicker
70
+ value={this.props.color}
71
+ onChange={this.change("color")}
72
+ />
73
+ </div>
74
+ </div>
75
+ );
76
+ }
77
+ }
78
+
79
+ export default PointEditor;