@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,256 +0,0 @@
1
- /* eslint-disable no-useless-escape */
2
- /**
3
- * This editor is for embedding Khan Academy CS programs.
4
- */
5
-
6
- import {
7
- components,
8
- Changeable,
9
- Dependencies,
10
- EditorJsonify,
11
- Errors,
12
- Log,
13
- } from "@khanacademy/perseus";
14
- import $ from "jquery";
15
- import PropTypes from "prop-types";
16
- import * as React from "react";
17
- import _ from "underscore";
18
-
19
- import BlurInput from "../components/blur-input";
20
-
21
- const {InfoTip, PropCheckBox} = components;
22
-
23
- const DEFAULT_WIDTH = 400;
24
- const DEFAULT_HEIGHT = 400;
25
-
26
- /**
27
- * This is used for editing a name/value pair.
28
- */
29
- class PairEditor extends React.Component<any> {
30
- static propTypes = {
31
- ...Changeable.propTypes,
32
- name: PropTypes.string,
33
- value: PropTypes.string,
34
- };
35
-
36
- static defaultProps = {
37
- name: "",
38
- value: "",
39
- };
40
-
41
- change = (...args) => {
42
- return Changeable.change.apply(this, args);
43
- };
44
-
45
- serialize = () => {
46
- return EditorJsonify.serialize.call(this);
47
- };
48
-
49
- render(): React.ReactNode {
50
- return (
51
- <fieldset className="pair-editor">
52
- <label>
53
- Name:{" "}
54
- <BlurInput
55
- value={this.props.name}
56
- onChange={this.change("name")}
57
- />
58
- </label>
59
- <label>
60
- {" "}
61
- Value:{" "}
62
- <BlurInput
63
- value={this.props.value}
64
- onChange={this.change("value")}
65
- />
66
- </label>
67
- </fieldset>
68
- );
69
- }
70
- }
71
-
72
- /**
73
- * This is used for editing a set of name/value pairs.
74
- */
75
- class PairsEditor extends React.Component<any> {
76
- static propTypes = {
77
- ...Changeable.propTypes,
78
- pairs: PropTypes.arrayOf(
79
- PropTypes.shape({
80
- name: PropTypes.string,
81
- value: PropTypes.string,
82
- }),
83
- ).isRequired,
84
- };
85
-
86
- change = (...args) => {
87
- return Changeable.change.apply(this, args);
88
- };
89
-
90
- handlePairChange = (pairIndex, pair: any) => {
91
- // If they're both non empty, add a new one
92
- const pairs = this.props.pairs.slice();
93
- pairs[pairIndex] = pair;
94
-
95
- const lastPair = pairs[pairs.length - 1];
96
- if (lastPair.name && lastPair.value) {
97
- pairs.push({name: "", value: ""});
98
- }
99
- this.change("pairs", pairs);
100
- };
101
-
102
- serialize = () => {
103
- return EditorJsonify.serialize.call(this);
104
- };
105
-
106
- render(): React.ReactNode {
107
- const editors = _.map(this.props.pairs, (pair, i) => {
108
- return (
109
- <PairEditor
110
- key={i}
111
- name={pair.name}
112
- value={pair.value}
113
- // eslint-disable-next-line react/jsx-no-bind
114
- onChange={this.handlePairChange.bind(this, i)}
115
- />
116
- );
117
- });
118
- return <div>{editors}</div>;
119
- }
120
- }
121
-
122
- const KA_PROGRAM_URL = /khanacademy\.org\/computer-programming\/[^\/]+\/(\d+)/;
123
-
124
- /**
125
- * Given a program URL from the site, extract its program ID.
126
- * If the input does not match the known URL patterns, it is assumed to be
127
- * a program ID.
128
- */
129
- function isolateProgramID(programUrl: string) {
130
- const match = KA_PROGRAM_URL.exec(programUrl);
131
- if (match) {
132
- programUrl = match[1];
133
- }
134
-
135
- return programUrl;
136
- }
137
-
138
- /**
139
- * This is the main editor for this widget, to specify all the options.
140
- */
141
- class CSProgramEditor extends React.Component<any> {
142
- static propTypes = {
143
- ...Changeable.propTypes,
144
- };
145
-
146
- static widgetName = "cs-program" as const;
147
-
148
- static defaultProps: any = {
149
- programID: "",
150
- programType: null,
151
- settings: [{name: "", value: ""}],
152
- showEditor: false,
153
- showButtons: false,
154
- width: DEFAULT_WIDTH,
155
- height: DEFAULT_HEIGHT,
156
- };
157
-
158
- change: (...args: ReadonlyArray<unknown>) => any = (...args) => {
159
- // @ts-expect-error - TS2345 - Argument of type 'readonly unknown[]' is not assignable to parameter of type 'any[]'.
160
- return Changeable.change.apply(this, args);
161
- };
162
-
163
- _handleSettingsChange: (arg1: any) => void = (settings) => {
164
- this.change({settings: settings.pairs});
165
- };
166
-
167
- _handleProgramIDChange: (arg1: string) => void = (programID) => {
168
- programID = isolateProgramID(programID);
169
- const {isDevServer, InitialRequestUrl} = Dependencies.getDependencies();
170
-
171
- const host = isDevServer
172
- ? InitialRequestUrl.origin
173
- : "https://www.khanacademy.org";
174
- const baseUrl = `${host}/api/internal/scratchpads/${programID}`;
175
-
176
- $.getJSON(baseUrl)
177
- .done((programInfo) => {
178
- const programType = programInfo.userAuthoredContentType;
179
- this.change({
180
- width: programInfo.width,
181
- height: programInfo.height,
182
- programID: programID,
183
- programType: programType,
184
- });
185
- })
186
- .fail((jqxhr, textStatus, error) => {
187
- Log.error(
188
- "Error retrieving scratchpad info for program ID ",
189
- Errors.TransientService,
190
- {
191
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'Error | null | undefined'.
192
- cause: error,
193
- loggedMetadata: {
194
- textStatus,
195
- programID,
196
- },
197
- },
198
- );
199
- this.change({
200
- width: DEFAULT_WIDTH,
201
- height: DEFAULT_HEIGHT,
202
- programID: programID,
203
- programType: null,
204
- });
205
- });
206
- };
207
-
208
- serialize: () => any = () => {
209
- return EditorJsonify.serialize.call(this);
210
- };
211
-
212
- render(): React.ReactNode {
213
- return (
214
- <div>
215
- <label>
216
- Url or Program ID:{" "}
217
- <BlurInput
218
- value={this.props.programID}
219
- onChange={this._handleProgramIDChange}
220
- />
221
- </label>
222
- <br />
223
- <PropCheckBox
224
- label="Show Editor"
225
- showEditor={this.props.showEditor}
226
- onChange={this.props.onChange}
227
- />
228
- <InfoTip>
229
- If you show the editor, you should use the "full-width"
230
- alignment to make room for the width of the editor.
231
- </InfoTip>
232
- <br />
233
- <PropCheckBox
234
- label="Show Buttons"
235
- showButtons={this.props.showButtons}
236
- onChange={this.props.onChange}
237
- />
238
- <br />
239
- <label>
240
- Settings:
241
- <PairsEditor
242
- name="settings"
243
- pairs={this.props.settings}
244
- onChange={this._handleSettingsChange}
245
- />
246
- <InfoTip>
247
- Settings that you add here are available to the program
248
- as an object returned by <code>Program.settings()</code>
249
- </InfoTip>
250
- </label>
251
- </div>
252
- );
253
- }
254
- }
255
-
256
- export default CSProgramEditor;
@@ -1,77 +0,0 @@
1
- /* eslint-disable @khanacademy/ts-no-error-suppressions */
2
- import {components, Changeable, EditorJsonify} from "@khanacademy/perseus";
3
- import PropTypes from "prop-types";
4
- import * as React from "react";
5
- import _ from "underscore";
6
-
7
- import Editor from "../editor";
8
-
9
- const {TextInput} = components;
10
-
11
- type Props = any;
12
-
13
- class DefinitionEditor extends React.Component<Props> {
14
- static propTypes = {
15
- ...Changeable.propTypes,
16
- togglePrompt: PropTypes.string,
17
- definition: PropTypes.string,
18
- apiOptions: PropTypes.any,
19
- };
20
-
21
- static widgetName = "definition" as const;
22
-
23
- static defaultProps: Props = {
24
- togglePrompt: "",
25
- definition: "",
26
- };
27
-
28
- change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
29
- return Changeable.change.apply(this, args);
30
- };
31
-
32
- serialize: () => any = () => {
33
- return EditorJsonify.serialize.call(this);
34
- };
35
-
36
- render(): React.ReactNode {
37
- return (
38
- <div className="perseus-widget-definition-editor">
39
- <a
40
- href="https://docs.google.com/document/d/1udaPef4imOfTMhmLDlWq4SM0mxL0r3YHFZE-5J1uGfo"
41
- target="_blank"
42
- >
43
- Definition style guide
44
- </a>
45
- <div className="perseus-widget-row">
46
- <label>
47
- Word to be defined:{" "}
48
- <TextInput
49
- value={this.props.togglePrompt}
50
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
51
- onChange={this.change("togglePrompt")}
52
- placeholder="define me"
53
- />
54
- </label>
55
- </div>
56
- <div className="perseus-widget-row">
57
- <Editor
58
- apiOptions={this.props.apiOptions}
59
- content={this.props.definition}
60
- widgetEnabled={false}
61
- placeholder="definition goes here"
62
- onChange={(props) => {
63
- const newProps: Record<string, any> = {};
64
- if (_.has(props, "content")) {
65
- newProps.definition = props.content;
66
- }
67
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
68
- this.change(newProps);
69
- }}
70
- />
71
- </div>
72
- </div>
73
- );
74
- }
75
- }
76
-
77
- export default DefinitionEditor;
@@ -1,29 +0,0 @@
1
- import {EditorJsonify} from "@khanacademy/perseus";
2
- import * as React from "react";
3
-
4
- type Props = {
5
- // Callback for when a widget prop is changed.
6
- onChange: (options: any) => void;
7
- };
8
-
9
- class DeprecatedStandinEditor extends React.Component<Props> {
10
- static widgetName = "deprecated-standin" as const;
11
-
12
- serialize(): any {
13
- return EditorJsonify.serialize.call(this);
14
- }
15
-
16
- render(): React.ReactNode {
17
- return (
18
- <div>
19
- <p>This widget has been deprecated and removed</p>
20
- <p>
21
- Learners will see a message and they will not be graded on
22
- this part. Please replace this widget with a supported one.
23
- </p>
24
- </div>
25
- );
26
- }
27
- }
28
-
29
- export default DeprecatedStandinEditor;
@@ -1,211 +0,0 @@
1
- /* eslint-disable @khanacademy/ts-no-error-suppressions */
2
- import {components, icons, EditorJsonify} from "@khanacademy/perseus";
3
- import PropTypes from "prop-types";
4
- import * as React from "react";
5
- import ReactDOM from "react-dom";
6
- import _ from "underscore";
7
-
8
- const {InfoTip, InlineIcon} = components;
9
- const {iconPlus, iconTrash} = icons;
10
-
11
- type Props = any;
12
-
13
- class DropdownEditor extends React.Component<Props> {
14
- static propTypes = {
15
- choices: PropTypes.arrayOf(
16
- PropTypes.shape({
17
- content: PropTypes.string,
18
- correct: PropTypes.bool,
19
- }),
20
- ),
21
- placeholder: PropTypes.string,
22
- };
23
-
24
- static widgetName = "dropdown" as const;
25
-
26
- static defaultProps: Props = {
27
- placeholder: "",
28
- choices: [
29
- {
30
- content: "",
31
- correct: false,
32
- },
33
- ],
34
- };
35
-
36
- onPlaceholderChange: (arg1: React.ChangeEvent<HTMLInputElement>) => void = (
37
- e,
38
- ) => {
39
- const placeholder = e.target.value;
40
- this.props.onChange({placeholder: placeholder});
41
- };
42
-
43
- onCorrectChange: (
44
- arg1: number,
45
- arg2: React.ChangeEvent<HTMLInputElement>,
46
- ) => void = (choiceIndex) => {
47
- const choices = _.map(this.props.choices, function (choice, i) {
48
- return _.extend({}, choice, {
49
- correct: i === choiceIndex,
50
- });
51
- });
52
- this.props.onChange({choices: choices});
53
- };
54
-
55
- onContentChange: (
56
- arg1: number,
57
- arg2: React.ChangeEvent<HTMLInputElement>,
58
- ) => void = (choiceIndex, e) => {
59
- const choices = this.props.choices.slice();
60
- const choice = _.clone(choices[choiceIndex]);
61
- choice.content = e.target.value;
62
- choices[choiceIndex] = choice;
63
- this.props.onChange({choices: choices});
64
- };
65
-
66
- addChoice: (arg1: React.MouseEvent) => void = (e) => {
67
- e.preventDefault();
68
-
69
- const choices = this.props.choices;
70
- const blankChoice = {content: "", correct: false} as const;
71
- this.props.onChange(
72
- {
73
- choices: choices.concat([blankChoice]),
74
- },
75
- this.focus.bind(this, choices.length),
76
- );
77
- };
78
-
79
- removeChoice: (arg1: number, arg2: React.MouseEvent) => void = (
80
- choiceIndex,
81
- e,
82
- ) => {
83
- e.preventDefault();
84
- const choices = _(this.props.choices).clone();
85
- choices.splice(choiceIndex, 1);
86
- this.props.onChange({
87
- choices: choices,
88
- });
89
- };
90
-
91
- focus: (arg1: number) => boolean = (i) => {
92
- // @ts-expect-error - TS2531 - Object is possibly 'null'. | TS2339 - Property 'focus' does not exist on type 'Element | Text'.
93
- ReactDOM.findDOMNode(this.refs["editor" + i]).focus(); // eslint-disable-line react/no-string-refs
94
- return true;
95
- };
96
-
97
- serialize: () => any = () => {
98
- return EditorJsonify.serialize.call(this);
99
- };
100
-
101
- render(): React.ReactNode {
102
- const dropdownGroupName = _.uniqueId("perseus_dropdown_");
103
- return (
104
- <div className="perseus-widget-dropdown">
105
- <div className="dropdown-info">
106
- Dropdown
107
- <InfoTip>
108
- <p>
109
- The drop down is useful for making inequalities in a
110
- custom format. We normally use the symbols {"<"},{" "}
111
- {">"}, ≤, ≥ (in that order) which you can copy into
112
- the choices. When possible, use the "multiple
113
- choice" answer type instead.
114
- </p>
115
- </InfoTip>
116
- </div>
117
- <div className="dropdown-placeholder">
118
- <input
119
- type="text"
120
- placeholder="Placeholder value"
121
- value={this.props.placeholder}
122
- onChange={this.onPlaceholderChange}
123
- />
124
- <InfoTip>
125
- <p>
126
- This value will appear as the drop down default. It
127
- should give the user some indication of the values
128
- available in the drop down itself, e.g.,
129
- Yes/No/Maybe.
130
- </p>
131
- </InfoTip>
132
- </div>
133
- <div className="clearfix" />
134
- <ul className="dropdown-choices">
135
- {this.props.choices.map(function (choice, i) {
136
- const checkedClass = choice.correct
137
- ? "correct"
138
- : "incorrect";
139
-
140
- return (
141
- <li key={"" + i}>
142
- <div>
143
- <input
144
- ref={"radio" + i}
145
- type="radio"
146
- name={dropdownGroupName}
147
- // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'boolean | undefined'.
148
- checked={
149
- choice.correct ? "checked" : ""
150
- }
151
- // eslint-disable-next-line react/jsx-no-bind
152
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
153
- onChange={this.onCorrectChange.bind(
154
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
155
- this,
156
- i,
157
- )}
158
- value={i}
159
- />
160
- <input
161
- type="text"
162
- ref={"editor" + i}
163
- // eslint-disable-next-line react/jsx-no-bind
164
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
165
- onChange={this.onContentChange.bind(
166
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
167
- this,
168
- i,
169
- )}
170
- className={checkedClass}
171
- value={choice.content}
172
- />
173
- {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
174
- <a
175
- href="#"
176
- className="simple-button orange"
177
- aria-label="Delete choice"
178
- // eslint-disable-next-line react/jsx-no-bind
179
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
180
- onClick={this.removeChoice.bind(
181
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
182
- this,
183
- i,
184
- )}
185
- >
186
- <span className="remove-choice">
187
- <InlineIcon {...iconTrash} />
188
- </span>
189
- </a>
190
- </div>
191
- </li>
192
- );
193
- }, this)}
194
- </ul>
195
-
196
- <div className="add-choice-container">
197
- {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
198
- <a
199
- href="#"
200
- className="simple-button orange"
201
- onClick={this.addChoice}
202
- >
203
- <InlineIcon {...iconPlus} /> Add a choice{" "}
204
- </a>
205
- </div>
206
- </div>
207
- );
208
- }
209
- }
210
-
211
- export default DropdownEditor;
@@ -1,70 +0,0 @@
1
- import {Changeable, EditorJsonify} from "@khanacademy/perseus";
2
- import * as React from "react";
3
-
4
- import ExampleGraphie from "./example-graphie-widget";
5
-
6
- const ExampleGraphieWidget = ExampleGraphie.widget;
7
-
8
- type Props = any;
9
-
10
- /**
11
- * This is the widget's editor. This is what shows up on the left side
12
- * of the screen in the demo page. Only the question writer sees this.
13
- */
14
- class ExampleGraphieWidgetEditor extends React.Component<Props> {
15
- static propTypes = {
16
- ...Changeable.propTypes,
17
- };
18
-
19
- static widgetName = "example-graphie-widget" as const;
20
-
21
- static defaultProps: Props = {
22
- correct: [4, 4],
23
- graph: {
24
- box: [340, 340],
25
- labels: ["x", "y"],
26
- range: [
27
- [-10, 10],
28
- [-10, 10],
29
- ],
30
- step: [1, 1],
31
- gridStep: [1, 1],
32
- valid: true,
33
- backgroundImage: null,
34
- markings: "grid",
35
- showProtractor: false,
36
- },
37
- };
38
-
39
- change: (arg1: any, arg2: any, arg3: any) => any = (...args) => {
40
- return Changeable.change.apply(this, args);
41
- };
42
-
43
- handleChange: (arg1: any) => void = (newProps) => {
44
- if (newProps.coord) {
45
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
46
- this.change({
47
- correct: newProps.coord,
48
- });
49
- }
50
- };
51
-
52
- serialize: () => any = () => {
53
- return EditorJsonify.serialize.call(this);
54
- };
55
-
56
- render(): React.ReactNode {
57
- return (
58
- <div>
59
- <ExampleGraphieWidget
60
- graph={this.props.graph}
61
- coord={this.props.correct}
62
- onChange={this.handleChange}
63
- apiOptions={this.props.apiOptions}
64
- />
65
- </div>
66
- );
67
- }
68
- }
69
-
70
- export default ExampleGraphieWidgetEditor;