@khanacademy/perseus-editor 13.1.0 → 14.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/all-editors.d.ts +1 -4
- package/dist/components/hover-behavior.d.ts +2 -2
- package/dist/components/widget-editor.d.ts +1 -1
- package/dist/es/index.js +187 -624
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +745 -1210
- package/dist/index.js.map +1 -1
- package/dist/widgets/expression-editor.d.ts +1 -1
- package/dist/widgets/graded-group-editor.d.ts +1 -1
- package/dist/widgets/grapher-editor.d.ts +1 -1
- package/dist/widgets/group-editor.d.ts +1 -1
- package/dist/widgets/iframe-editor.d.ts +1 -1
- package/dist/widgets/image-editor.d.ts +2 -2
- package/dist/widgets/input-number-editor.d.ts +1 -1
- package/dist/widgets/interactive-graph-editor.d.ts +30 -38
- package/dist/widgets/matcher-editor.d.ts +1 -1
- package/dist/widgets/matrix-editor.d.ts +1 -1
- package/dist/widgets/measurer-editor.d.ts +1 -1
- package/dist/widgets/numeric-input-editor.d.ts +1 -1
- package/dist/widgets/orderer-editor.d.ts +1 -1
- package/dist/widgets/phet-simulation-editor.d.ts +2 -1
- package/dist/widgets/radio/editor.d.ts +1 -1
- package/dist/widgets/table-editor.d.ts +1 -1
- package/package.json +2 -2
- package/dist/all-widgets.d.ts +0 -22
- package/dist/testing-widgets.d.ts +0 -22
- package/dist/widgets/example-graphie-widget-editor.d.ts +0 -18
- package/dist/widgets/example-graphie-widget.d.ts +0 -61
- package/dist/widgets/example-widget-editor.d.ts +0 -20
- package/dist/widgets/example-widget.d.ts +0 -89
- package/dist/widgets/simple-markdown-tester-editor.d.ts +0 -21
- package/dist/widgets/simple-markdown-tester.d.ts +0 -54
package/dist/index.js
CHANGED
|
@@ -19,12 +19,12 @@ var caretRight = require('@phosphor-icons/core/bold/caret-right-bold.svg');
|
|
|
19
19
|
var classNames = require('classnames');
|
|
20
20
|
var wonderBlocksForm = require('@khanacademy/wonder-blocks-form');
|
|
21
21
|
var ReactDOM = require('react-dom');
|
|
22
|
-
var kmath = require('@khanacademy/kmath');
|
|
23
22
|
var KAS = require('@khanacademy/kas');
|
|
24
23
|
var Button = require('@khanacademy/wonder-blocks-button');
|
|
25
24
|
var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
|
|
26
25
|
var wonderStuffCore = require('@khanacademy/wonder-stuff-core');
|
|
27
26
|
var mathInput = require('@khanacademy/math-input');
|
|
27
|
+
var kmath = require('@khanacademy/kmath');
|
|
28
28
|
var wonderBlocksDropdown = require('@khanacademy/wonder-blocks-dropdown');
|
|
29
29
|
var wonderBlocksAccordion = require('@khanacademy/wonder-blocks-accordion');
|
|
30
30
|
var IconButton = require('@khanacademy/wonder-blocks-icon-button');
|
|
@@ -91,7 +91,7 @@ var arrowCounterClockwise__default = /*#__PURE__*/_interopDefaultLegacy(arrowCou
|
|
|
91
91
|
|
|
92
92
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
93
93
|
const libName = "@khanacademy/perseus-editor";
|
|
94
|
-
const libVersion = "
|
|
94
|
+
const libVersion = "14.0.1";
|
|
95
95
|
perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
96
96
|
|
|
97
97
|
function _extends() {
|
|
@@ -188,16 +188,6 @@ const JsonEditor = createReactClass__default["default"]({
|
|
|
188
188
|
this.setState(this.getInitialState());
|
|
189
189
|
}
|
|
190
190
|
},
|
|
191
|
-
render: function () {
|
|
192
|
-
const classes = "perseus-json-editor " + (this.state.valid ? "valid" : "invalid");
|
|
193
|
-
return /*#__PURE__*/React__namespace.createElement("textarea", {
|
|
194
|
-
className: classes,
|
|
195
|
-
value: this.state.currentValue,
|
|
196
|
-
onChange: this.handleChange,
|
|
197
|
-
onKeyDown: this.handleKeyDown,
|
|
198
|
-
onBlur: this.handleBlur
|
|
199
|
-
});
|
|
200
|
-
},
|
|
201
191
|
handleKeyDown: function (e) {
|
|
202
192
|
// This handler allows the tab character to be entered by pressing
|
|
203
193
|
// tab, instead of jumping to the next (non-existant) field
|
|
@@ -264,6 +254,16 @@ const JsonEditor = createReactClass__default["default"]({
|
|
|
264
254
|
valid: true
|
|
265
255
|
});
|
|
266
256
|
}
|
|
257
|
+
},
|
|
258
|
+
render: function () {
|
|
259
|
+
const classes = "perseus-json-editor " + (this.state.valid ? "valid" : "invalid");
|
|
260
|
+
return /*#__PURE__*/React__namespace.createElement("textarea", {
|
|
261
|
+
className: classes,
|
|
262
|
+
value: this.state.currentValue,
|
|
263
|
+
onChange: this.handleChange,
|
|
264
|
+
onKeyDown: this.handleKeyDown,
|
|
265
|
+
onBlur: this.handleBlur
|
|
266
|
+
});
|
|
267
267
|
}
|
|
268
268
|
});
|
|
269
269
|
|
|
@@ -25549,7 +25549,7 @@ const styles$N = aphrodite.StyleSheet.create({
|
|
|
25549
25549
|
}
|
|
25550
25550
|
});
|
|
25551
25551
|
|
|
25552
|
-
/* eslint-disable react/no-unsafe
|
|
25552
|
+
/* eslint-disable react/no-unsafe */
|
|
25553
25553
|
|
|
25554
25554
|
/* Renders an EditorPage (or an ArticleEditor) as a non-controlled component.
|
|
25555
25555
|
*
|
|
@@ -25568,10 +25568,6 @@ const StatefulEditorPage = createReactClass__default["default"]({
|
|
|
25568
25568
|
componentClass: EditorPage
|
|
25569
25569
|
};
|
|
25570
25570
|
},
|
|
25571
|
-
render: function () {
|
|
25572
|
-
const Component = this.props.componentClass;
|
|
25573
|
-
return /*#__PURE__*/React__namespace.createElement(Component, this.state);
|
|
25574
|
-
},
|
|
25575
25571
|
getInitialState: function () {
|
|
25576
25572
|
return ___default["default"]({}).extend(___default["default"].omit(this.props, "componentClass"), {
|
|
25577
25573
|
onChange: this.handleChange,
|
|
@@ -25581,9 +25577,6 @@ const StatefulEditorPage = createReactClass__default["default"]({
|
|
|
25581
25577
|
componentDidMount: function () {
|
|
25582
25578
|
this._isMounted = true;
|
|
25583
25579
|
},
|
|
25584
|
-
componentWillUnmount: function () {
|
|
25585
|
-
this._isMounted = false;
|
|
25586
|
-
},
|
|
25587
25580
|
// getInitialState isn't called if the react component is re-rendered
|
|
25588
25581
|
// in-place on the dom, in which case this is called instead, so we
|
|
25589
25582
|
// need to update the state here.
|
|
@@ -25591,6 +25584,9 @@ const StatefulEditorPage = createReactClass__default["default"]({
|
|
|
25591
25584
|
UNSAFE_componentWillReceiveProps: function (nextProps) {
|
|
25592
25585
|
this.setState(___default["default"](nextProps).pick("apiOptions", "imageUploader", "developerMode", "problemNum", "previewDevice", "frameSource"));
|
|
25593
25586
|
},
|
|
25587
|
+
componentWillUnmount: function () {
|
|
25588
|
+
this._isMounted = false;
|
|
25589
|
+
},
|
|
25594
25590
|
getSaveWarnings: function () {
|
|
25595
25591
|
// eslint-disable-next-line react/no-string-refs
|
|
25596
25592
|
return this.refs.editor.getSaveWarnings();
|
|
@@ -25607,6 +25603,10 @@ const StatefulEditorPage = createReactClass__default["default"]({
|
|
|
25607
25603
|
scorePreview: function () {
|
|
25608
25604
|
// eslint-disable-next-line react/no-string-refs
|
|
25609
25605
|
return this.refs.editor.scorePreview();
|
|
25606
|
+
},
|
|
25607
|
+
render: function () {
|
|
25608
|
+
const Component = this.props.componentClass;
|
|
25609
|
+
return /*#__PURE__*/React__namespace.createElement(Component, this.state);
|
|
25610
25610
|
}
|
|
25611
25611
|
});
|
|
25612
25612
|
|
|
@@ -25955,7 +25955,7 @@ class CSProgramEditor extends React__namespace.Component {
|
|
|
25955
25955
|
|
|
25956
25956
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
25957
25957
|
const {
|
|
25958
|
-
TextInput: TextInput$
|
|
25958
|
+
TextInput: TextInput$7
|
|
25959
25959
|
} = perseus.components;
|
|
25960
25960
|
class DefinitionEditor extends React__namespace.Component {
|
|
25961
25961
|
static propTypes = {
|
|
@@ -25989,7 +25989,7 @@ class DefinitionEditor extends React__namespace.Component {
|
|
|
25989
25989
|
target: "_blank"
|
|
25990
25990
|
}, "Definition style guide"), /*#__PURE__*/React__namespace.createElement("div", {
|
|
25991
25991
|
className: "perseus-widget-row"
|
|
25992
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Word to be defined:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
25992
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Word to be defined:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$7, {
|
|
25993
25993
|
value: this.props.togglePrompt
|
|
25994
25994
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
25995
25995
|
,
|
|
@@ -26170,236 +26170,9 @@ class DropdownEditor extends React__namespace.Component {
|
|
|
26170
26170
|
}
|
|
26171
26171
|
}
|
|
26172
26172
|
|
|
26173
|
-
/* eslint-disable @typescript-eslint/no-unused-vars, react/forbid-prop-types, react/sort-comp */
|
|
26174
|
-
const {
|
|
26175
|
-
Graphie
|
|
26176
|
-
} = perseus.components;
|
|
26177
|
-
|
|
26178
|
-
// @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
|
|
26179
|
-
const MovablePoint = Graphie.MovablePoint;
|
|
26180
|
-
/**
|
|
26181
|
-
* This is the widget's renderer. It shows up in the right column
|
|
26182
|
-
* in the demo, and is what is visible to users, and where
|
|
26183
|
-
* users enter their answers.
|
|
26184
|
-
*/
|
|
26185
|
-
class ExampleGraphieWidget$1 extends React__namespace.Component {
|
|
26186
|
-
static defaultProps = {
|
|
26187
|
-
// We want to allow our coord to be null to test if the
|
|
26188
|
-
// user has interacted with this widget yet when grading it
|
|
26189
|
-
coord: null,
|
|
26190
|
-
graph: {
|
|
26191
|
-
box: [400, 400],
|
|
26192
|
-
labels: ["x", "y"],
|
|
26193
|
-
range: [[-10, 10], [-10, 10]],
|
|
26194
|
-
step: [1, 1],
|
|
26195
|
-
gridStep: [1, 1],
|
|
26196
|
-
valid: true,
|
|
26197
|
-
backgroundImage: null,
|
|
26198
|
-
markings: "grid",
|
|
26199
|
-
showProtractor: false
|
|
26200
|
-
}
|
|
26201
|
-
};
|
|
26202
|
-
|
|
26203
|
-
/**
|
|
26204
|
-
* This is the widget's grading function
|
|
26205
|
-
*/
|
|
26206
|
-
static validate(state, rubric) {
|
|
26207
|
-
if (state.coord == null) {
|
|
26208
|
-
return {
|
|
26209
|
-
type: "invalid",
|
|
26210
|
-
message: null
|
|
26211
|
-
};
|
|
26212
|
-
}
|
|
26213
|
-
if (kmath.point.equal(state.coord, rubric.correct)) {
|
|
26214
|
-
return {
|
|
26215
|
-
type: "points",
|
|
26216
|
-
earned: 1,
|
|
26217
|
-
total: 1,
|
|
26218
|
-
message: null
|
|
26219
|
-
};
|
|
26220
|
-
}
|
|
26221
|
-
return {
|
|
26222
|
-
type: "points",
|
|
26223
|
-
earned: 0,
|
|
26224
|
-
total: 1,
|
|
26225
|
-
message: null
|
|
26226
|
-
};
|
|
26227
|
-
}
|
|
26228
|
-
getUserInput = () => {
|
|
26229
|
-
return perseus.WidgetJsonifyDeprecated.getUserInput.call(this);
|
|
26230
|
-
};
|
|
26231
|
-
render() {
|
|
26232
|
-
return /*#__PURE__*/React__namespace.createElement(Graphie
|
|
26233
|
-
// eslint-disable-next-line react/no-string-refs
|
|
26234
|
-
, {
|
|
26235
|
-
ref: "graphie",
|
|
26236
|
-
box: this.props.graph.box,
|
|
26237
|
-
range: this.props.graph.range,
|
|
26238
|
-
options: this.props.graph,
|
|
26239
|
-
setup: this.setupGraphie,
|
|
26240
|
-
setDrawingAreaAvailable: this.props.apiOptions?.setDrawingAreaAvailable
|
|
26241
|
-
}, /*#__PURE__*/React__namespace.createElement(MovablePoint, {
|
|
26242
|
-
pointSize: 5,
|
|
26243
|
-
coord: this.props.coord || [0, 0],
|
|
26244
|
-
constraints: [MovablePoint.constraints.snap(), MovablePoint.constraints.bound()],
|
|
26245
|
-
onMove: this.movePoint
|
|
26246
|
-
}));
|
|
26247
|
-
}
|
|
26248
|
-
change = (() => {
|
|
26249
|
-
var _this = this;
|
|
26250
|
-
return function () {
|
|
26251
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
26252
|
-
args[_key] = arguments[_key];
|
|
26253
|
-
}
|
|
26254
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
26255
|
-
};
|
|
26256
|
-
})();
|
|
26257
|
-
movePoint = newCoord => {
|
|
26258
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
26259
|
-
this.change({
|
|
26260
|
-
coord: newCoord
|
|
26261
|
-
});
|
|
26262
|
-
};
|
|
26263
|
-
_getGridConfig = options => {
|
|
26264
|
-
return ___default["default"].map(options.step, function (step, i) {
|
|
26265
|
-
return perseus.Util.gridDimensionConfig(step, options.range[i], options.box[i], options.gridStep[i]);
|
|
26266
|
-
});
|
|
26267
|
-
};
|
|
26268
|
-
setupGraphie = (graphie, options) => {
|
|
26269
|
-
const gridConfig = this._getGridConfig(options);
|
|
26270
|
-
graphie.graphInit({
|
|
26271
|
-
range: options.range,
|
|
26272
|
-
scale: ___default["default"].pluck(gridConfig, "scale"),
|
|
26273
|
-
axisArrows: "<->",
|
|
26274
|
-
labelFormat: function (s) {
|
|
26275
|
-
return "\\small{" + s + "}";
|
|
26276
|
-
},
|
|
26277
|
-
gridStep: options.gridStep,
|
|
26278
|
-
tickStep: ___default["default"].pluck(gridConfig, "tickStep"),
|
|
26279
|
-
labelStep: 1,
|
|
26280
|
-
unityLabels: ___default["default"].pluck(gridConfig, "unityLabel")
|
|
26281
|
-
});
|
|
26282
|
-
graphie.label([0, options.range[1][1]], options.labels[1], "above");
|
|
26283
|
-
};
|
|
26284
|
-
simpleValidate = rubric => {
|
|
26285
|
-
return ExampleGraphieWidget$1.validate(this.getUserInput(), rubric);
|
|
26286
|
-
};
|
|
26287
|
-
}
|
|
26288
|
-
|
|
26289
|
-
/**
|
|
26290
|
-
* For this widget to work, we must export it.
|
|
26291
|
-
* We also must import this file in src/all-widgets.js
|
|
26292
|
-
*/
|
|
26293
|
-
var ExampleGraphieWidget$2 = {
|
|
26294
|
-
name: "example-graphie-widget",
|
|
26295
|
-
displayName: "Example Graphie Widget",
|
|
26296
|
-
hidden: true,
|
|
26297
|
-
// Hides this widget from the Perseus.Editor widget select
|
|
26298
|
-
widget: ExampleGraphieWidget$1
|
|
26299
|
-
};
|
|
26300
|
-
|
|
26301
|
-
const ExampleGraphieWidget = ExampleGraphieWidget$2.widget;
|
|
26302
|
-
/**
|
|
26303
|
-
* This is the widget's editor. This is what shows up on the left side
|
|
26304
|
-
* of the screen in the demo page. Only the question writer sees this.
|
|
26305
|
-
*/
|
|
26306
|
-
class ExampleGraphieWidgetEditor extends React__namespace.Component {
|
|
26307
|
-
static propTypes = {
|
|
26308
|
-
...perseus.Changeable.propTypes
|
|
26309
|
-
};
|
|
26310
|
-
static widgetName = "example-graphie-widget";
|
|
26311
|
-
static defaultProps = {
|
|
26312
|
-
correct: [4, 4],
|
|
26313
|
-
graph: {
|
|
26314
|
-
box: [340, 340],
|
|
26315
|
-
labels: ["x", "y"],
|
|
26316
|
-
range: [[-10, 10], [-10, 10]],
|
|
26317
|
-
step: [1, 1],
|
|
26318
|
-
gridStep: [1, 1],
|
|
26319
|
-
valid: true,
|
|
26320
|
-
backgroundImage: null,
|
|
26321
|
-
markings: "grid",
|
|
26322
|
-
showProtractor: false
|
|
26323
|
-
}
|
|
26324
|
-
};
|
|
26325
|
-
change = (() => {
|
|
26326
|
-
var _this = this;
|
|
26327
|
-
return function () {
|
|
26328
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
26329
|
-
args[_key] = arguments[_key];
|
|
26330
|
-
}
|
|
26331
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
26332
|
-
};
|
|
26333
|
-
})();
|
|
26334
|
-
handleChange = newProps => {
|
|
26335
|
-
if (newProps.coord) {
|
|
26336
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
26337
|
-
this.change({
|
|
26338
|
-
correct: newProps.coord
|
|
26339
|
-
});
|
|
26340
|
-
}
|
|
26341
|
-
};
|
|
26342
|
-
serialize = () => {
|
|
26343
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
26344
|
-
};
|
|
26345
|
-
render() {
|
|
26346
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(ExampleGraphieWidget, {
|
|
26347
|
-
graph: this.props.graph,
|
|
26348
|
-
coord: this.props.correct,
|
|
26349
|
-
onChange: this.handleChange,
|
|
26350
|
-
apiOptions: this.props.apiOptions
|
|
26351
|
-
}));
|
|
26352
|
-
}
|
|
26353
|
-
}
|
|
26354
|
-
|
|
26355
|
-
/* eslint-disable react/sort-comp */
|
|
26356
|
-
/**
|
|
26357
|
-
* This is the widget's editor. This is what shows up on the left side
|
|
26358
|
-
* of the screen in the demo. Only the question writer sees this.
|
|
26359
|
-
*/
|
|
26360
|
-
class ExampleWidgetEditor extends React__namespace.Component {
|
|
26361
|
-
static propTypes = {
|
|
26362
|
-
...perseus.Changeable.propTypes
|
|
26363
|
-
};
|
|
26364
|
-
static widgetName = "example-widget";
|
|
26365
|
-
static defaultProps = {
|
|
26366
|
-
correct: ""
|
|
26367
|
-
};
|
|
26368
|
-
input = /*#__PURE__*/React__namespace.createRef();
|
|
26369
|
-
handleAnswerChange = event => {
|
|
26370
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
26371
|
-
this.change({
|
|
26372
|
-
correct: event.target.value
|
|
26373
|
-
});
|
|
26374
|
-
};
|
|
26375
|
-
render() {
|
|
26376
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Correct answer:", /*#__PURE__*/React__namespace.createElement("input", {
|
|
26377
|
-
value: this.props.correct,
|
|
26378
|
-
onChange: this.handleAnswerChange,
|
|
26379
|
-
ref: this.input
|
|
26380
|
-
})));
|
|
26381
|
-
}
|
|
26382
|
-
change = (() => {
|
|
26383
|
-
var _this = this;
|
|
26384
|
-
return function () {
|
|
26385
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
26386
|
-
args[_key] = arguments[_key];
|
|
26387
|
-
}
|
|
26388
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
26389
|
-
};
|
|
26390
|
-
})();
|
|
26391
|
-
focus = () => {
|
|
26392
|
-
this.input.current?.focus();
|
|
26393
|
-
return true;
|
|
26394
|
-
};
|
|
26395
|
-
serialize = () => {
|
|
26396
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
26397
|
-
};
|
|
26398
|
-
}
|
|
26399
|
-
|
|
26400
26173
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
26401
26174
|
const {
|
|
26402
|
-
TextInput: TextInput$
|
|
26175
|
+
TextInput: TextInput$6
|
|
26403
26176
|
} = perseus.components;
|
|
26404
26177
|
const defaultExplanationProps = {
|
|
26405
26178
|
showPrompt: "Explain",
|
|
@@ -26436,14 +26209,14 @@ class ExplanationEditor extends React__namespace.Component {
|
|
|
26436
26209
|
className: "perseus-widget-explanation-editor"
|
|
26437
26210
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
26438
26211
|
className: "perseus-widget-row"
|
|
26439
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Prompt to show explanation:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
26212
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Prompt to show explanation:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$6, {
|
|
26440
26213
|
value: this.props.showPrompt
|
|
26441
26214
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
26442
26215
|
,
|
|
26443
26216
|
onChange: this.change("showPrompt")
|
|
26444
26217
|
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26445
26218
|
className: "perseus-widget-row"
|
|
26446
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Prompt to hide explanation:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
26219
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Prompt to hide explanation:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$6, {
|
|
26447
26220
|
value: this.props.hidePrompt
|
|
26448
26221
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
26449
26222
|
,
|
|
@@ -26718,101 +26491,6 @@ class ExpressionEditor extends React__namespace.Component {
|
|
|
26718
26491
|
}
|
|
26719
26492
|
return perseus.Changeable.change.apply(this, args);
|
|
26720
26493
|
}
|
|
26721
|
-
render() {
|
|
26722
|
-
const answerOptions = this.props.answerForms.map(ans => {
|
|
26723
|
-
const key = parseAnswerKey(ans);
|
|
26724
|
-
const expressionProps = {
|
|
26725
|
-
// note we're using
|
|
26726
|
-
// *this.props*.{times,functions,buttonSets} since each
|
|
26727
|
-
// answer area has the same settings for those
|
|
26728
|
-
times: this.props.times,
|
|
26729
|
-
functions: this.props.functions,
|
|
26730
|
-
buttonSets: this.props.buttonSets,
|
|
26731
|
-
buttonsVisible: "focused",
|
|
26732
|
-
form: ans.form,
|
|
26733
|
-
simplify: ans.simplify,
|
|
26734
|
-
value: ans.value,
|
|
26735
|
-
onChange: props => this.updateForm(key, props),
|
|
26736
|
-
trackInteraction: () => {},
|
|
26737
|
-
widgetId: this.props.widgetId + "-" + ans.key
|
|
26738
|
-
};
|
|
26739
|
-
return lens(ans).merge([], {
|
|
26740
|
-
key,
|
|
26741
|
-
draggable: true,
|
|
26742
|
-
onChange: props => this.updateForm(Number.parseInt(ans.key ?? ""), props),
|
|
26743
|
-
onDelete: () => this.handleRemoveForm(key),
|
|
26744
|
-
expressionProps: expressionProps
|
|
26745
|
-
}).freeze();
|
|
26746
|
-
}).map(obj => /*#__PURE__*/React__namespace.createElement(AnswerOption, _extends({
|
|
26747
|
-
key: obj.key
|
|
26748
|
-
}, obj)));
|
|
26749
|
-
const sortable = /*#__PURE__*/React__namespace.createElement(SortableArea, {
|
|
26750
|
-
components: answerOptions,
|
|
26751
|
-
onReorder: this.handleReorder
|
|
26752
|
-
});
|
|
26753
|
-
|
|
26754
|
-
// checkboxes to choose which sets of input buttons are shown
|
|
26755
|
-
const buttonSetChoices = buttonSetsList.map(name => {
|
|
26756
|
-
// The first one gets special cased to always be checked, disabled,
|
|
26757
|
-
// and float left.
|
|
26758
|
-
const isBasic = name === "basic";
|
|
26759
|
-
const checked = this.props.buttonSets.includes(name) || isBasic;
|
|
26760
|
-
return /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
26761
|
-
key: name,
|
|
26762
|
-
label: name,
|
|
26763
|
-
checked: checked,
|
|
26764
|
-
disabled: isBasic,
|
|
26765
|
-
onChange: () => this.handleButtonSet(name)
|
|
26766
|
-
});
|
|
26767
|
-
});
|
|
26768
|
-
buttonSetChoices.unshift( /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
26769
|
-
key: "show \xF7 button",
|
|
26770
|
-
label: "show \xF7 button",
|
|
26771
|
-
checked: this.props.buttonSets.includes("basic+div"),
|
|
26772
|
-
onChange: this.handleToggleDiv
|
|
26773
|
-
}));
|
|
26774
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingSmall, null, "Global Options"), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26775
|
-
className: aphrodite.css(styles$L.paddedY)
|
|
26776
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
26777
|
-
label: "Visible label",
|
|
26778
|
-
value: this.props.visibleLabel || "",
|
|
26779
|
-
onChange: this.change("visibleLabel")
|
|
26780
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26781
|
-
className: aphrodite.css(styles$L.paddedY)
|
|
26782
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
26783
|
-
label: "Aria label",
|
|
26784
|
-
value: this.props.ariaLabel || "",
|
|
26785
|
-
onChange: this.change("ariaLabel")
|
|
26786
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writting accessible labels, please see", " ", /*#__PURE__*/React__namespace.createElement("a", {
|
|
26787
|
-
href: "https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",
|
|
26788
|
-
target: "_blank"
|
|
26789
|
-
}, "this article.")))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26790
|
-
className: aphrodite.css(styles$L.paddedY)
|
|
26791
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
26792
|
-
label: "Function variables",
|
|
26793
|
-
value: this.state.functionsInternal,
|
|
26794
|
-
onChange: this.handleFunctions
|
|
26795
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26796
|
-
className: aphrodite.css(styles$L.paddedY)
|
|
26797
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
26798
|
-
label: "Use \xD7 instead of \u22C5 for multiplication",
|
|
26799
|
-
checked: this.props.times,
|
|
26800
|
-
onChange: value => {
|
|
26801
|
-
this.props.onChange({
|
|
26802
|
-
times: value
|
|
26803
|
-
});
|
|
26804
|
-
}
|
|
26805
|
-
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26806
|
-
className: aphrodite.css(styles$L.paddedY)
|
|
26807
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingXSmall, null, "Button Sets"), buttonSetChoices), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingSmall, null, "Answers"), /*#__PURE__*/React__namespace.createElement("p", {
|
|
26808
|
-
style: {
|
|
26809
|
-
margin: "4px 0"
|
|
26810
|
-
}
|
|
26811
|
-
}, "student responses area matched against these from top to bottom"), sortable, /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
26812
|
-
size: "small",
|
|
26813
|
-
onClick: this.newAnswer
|
|
26814
|
-
}, "Add new answer")));
|
|
26815
|
-
}
|
|
26816
26494
|
serialize = () => {
|
|
26817
26495
|
const formSerializables = ["value", "form", "simplify", "considered",
|
|
26818
26496
|
// it's a little weird to serialize the react key, but saves some
|
|
@@ -26953,6 +26631,101 @@ class ExpressionEditor extends React__namespace.Component {
|
|
|
26953
26631
|
newProps.functions = value.split(/[ ,]+/).filter(wonderStuffCore.isTruthy);
|
|
26954
26632
|
this.props.onChange(newProps);
|
|
26955
26633
|
};
|
|
26634
|
+
render() {
|
|
26635
|
+
const answerOptions = this.props.answerForms.map(ans => {
|
|
26636
|
+
const key = parseAnswerKey(ans);
|
|
26637
|
+
const expressionProps = {
|
|
26638
|
+
// note we're using
|
|
26639
|
+
// *this.props*.{times,functions,buttonSets} since each
|
|
26640
|
+
// answer area has the same settings for those
|
|
26641
|
+
times: this.props.times,
|
|
26642
|
+
functions: this.props.functions,
|
|
26643
|
+
buttonSets: this.props.buttonSets,
|
|
26644
|
+
buttonsVisible: "focused",
|
|
26645
|
+
form: ans.form,
|
|
26646
|
+
simplify: ans.simplify,
|
|
26647
|
+
value: ans.value,
|
|
26648
|
+
onChange: props => this.updateForm(key, props),
|
|
26649
|
+
trackInteraction: () => {},
|
|
26650
|
+
widgetId: this.props.widgetId + "-" + ans.key
|
|
26651
|
+
};
|
|
26652
|
+
return lens(ans).merge([], {
|
|
26653
|
+
key,
|
|
26654
|
+
draggable: true,
|
|
26655
|
+
onChange: props => this.updateForm(Number.parseInt(ans.key ?? ""), props),
|
|
26656
|
+
onDelete: () => this.handleRemoveForm(key),
|
|
26657
|
+
expressionProps: expressionProps
|
|
26658
|
+
}).freeze();
|
|
26659
|
+
}).map(obj => /*#__PURE__*/React__namespace.createElement(AnswerOption, _extends({
|
|
26660
|
+
key: obj.key
|
|
26661
|
+
}, obj)));
|
|
26662
|
+
const sortable = /*#__PURE__*/React__namespace.createElement(SortableArea, {
|
|
26663
|
+
components: answerOptions,
|
|
26664
|
+
onReorder: this.handleReorder
|
|
26665
|
+
});
|
|
26666
|
+
|
|
26667
|
+
// checkboxes to choose which sets of input buttons are shown
|
|
26668
|
+
const buttonSetChoices = buttonSetsList.map(name => {
|
|
26669
|
+
// The first one gets special cased to always be checked, disabled,
|
|
26670
|
+
// and float left.
|
|
26671
|
+
const isBasic = name === "basic";
|
|
26672
|
+
const checked = this.props.buttonSets.includes(name) || isBasic;
|
|
26673
|
+
return /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
26674
|
+
key: name,
|
|
26675
|
+
label: name,
|
|
26676
|
+
checked: checked,
|
|
26677
|
+
disabled: isBasic,
|
|
26678
|
+
onChange: () => this.handleButtonSet(name)
|
|
26679
|
+
});
|
|
26680
|
+
});
|
|
26681
|
+
buttonSetChoices.unshift( /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
26682
|
+
key: "show \xF7 button",
|
|
26683
|
+
label: "show \xF7 button",
|
|
26684
|
+
checked: this.props.buttonSets.includes("basic+div"),
|
|
26685
|
+
onChange: this.handleToggleDiv
|
|
26686
|
+
}));
|
|
26687
|
+
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingSmall, null, "Global Options"), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26688
|
+
className: aphrodite.css(styles$L.paddedY)
|
|
26689
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
26690
|
+
label: "Visible label",
|
|
26691
|
+
value: this.props.visibleLabel || "",
|
|
26692
|
+
onChange: this.change("visibleLabel")
|
|
26693
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26694
|
+
className: aphrodite.css(styles$L.paddedY)
|
|
26695
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
26696
|
+
label: "Aria label",
|
|
26697
|
+
value: this.props.ariaLabel || "",
|
|
26698
|
+
onChange: this.change("ariaLabel")
|
|
26699
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writting accessible labels, please see", " ", /*#__PURE__*/React__namespace.createElement("a", {
|
|
26700
|
+
href: "https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",
|
|
26701
|
+
target: "_blank"
|
|
26702
|
+
}, "this article.")))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26703
|
+
className: aphrodite.css(styles$L.paddedY)
|
|
26704
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
26705
|
+
label: "Function variables",
|
|
26706
|
+
value: this.state.functionsInternal,
|
|
26707
|
+
onChange: this.handleFunctions
|
|
26708
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26709
|
+
className: aphrodite.css(styles$L.paddedY)
|
|
26710
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
26711
|
+
label: "Use \xD7 instead of \u22C5 for multiplication",
|
|
26712
|
+
checked: this.props.times,
|
|
26713
|
+
onChange: value => {
|
|
26714
|
+
this.props.onChange({
|
|
26715
|
+
times: value
|
|
26716
|
+
});
|
|
26717
|
+
}
|
|
26718
|
+
}), /*#__PURE__*/React__namespace.createElement(InfoTip$i, null, /*#__PURE__*/React__namespace.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
26719
|
+
className: aphrodite.css(styles$L.paddedY)
|
|
26720
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingXSmall, null, "Button Sets"), buttonSetChoices), /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.HeadingSmall, null, "Answers"), /*#__PURE__*/React__namespace.createElement("p", {
|
|
26721
|
+
style: {
|
|
26722
|
+
margin: "4px 0"
|
|
26723
|
+
}
|
|
26724
|
+
}, "student responses area matched against these from top to bottom"), sortable, /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
26725
|
+
size: "small",
|
|
26726
|
+
onClick: this.newAnswer
|
|
26727
|
+
}, "Add new answer")));
|
|
26728
|
+
}
|
|
26956
26729
|
}
|
|
26957
26730
|
|
|
26958
26731
|
// Find the next element in arr after val, wrapping around to the first.
|
|
@@ -26974,6 +26747,25 @@ class AnswerOption extends React__namespace.Component {
|
|
|
26974
26747
|
return perseus.Changeable.change.apply(_this, args);
|
|
26975
26748
|
};
|
|
26976
26749
|
})();
|
|
26750
|
+
handleImSure = () => {
|
|
26751
|
+
this.props.onDelete();
|
|
26752
|
+
};
|
|
26753
|
+
handleCancelDelete = () => {
|
|
26754
|
+
this.setState({
|
|
26755
|
+
deleteFocused: false
|
|
26756
|
+
});
|
|
26757
|
+
};
|
|
26758
|
+
handleDelete = () => {
|
|
26759
|
+
this.setState({
|
|
26760
|
+
deleteFocused: true
|
|
26761
|
+
});
|
|
26762
|
+
};
|
|
26763
|
+
toggleConsidered = () => {
|
|
26764
|
+
const newVal = findNextIn(perseus.PerseusExpressionAnswerFormConsidered, this.props.considered);
|
|
26765
|
+
this.change({
|
|
26766
|
+
considered: newVal
|
|
26767
|
+
});
|
|
26768
|
+
};
|
|
26977
26769
|
render() {
|
|
26978
26770
|
const removeButton = this.state.deleteFocused ? /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
26979
26771
|
size: "small",
|
|
@@ -27025,25 +26817,6 @@ class AnswerOption extends React__namespace.Component {
|
|
|
27025
26817
|
className: aphrodite.css(styles$L.buttonRow, styles$L.paddedY)
|
|
27026
26818
|
}, removeButton)));
|
|
27027
26819
|
}
|
|
27028
|
-
handleImSure = () => {
|
|
27029
|
-
this.props.onDelete();
|
|
27030
|
-
};
|
|
27031
|
-
handleCancelDelete = () => {
|
|
27032
|
-
this.setState({
|
|
27033
|
-
deleteFocused: false
|
|
27034
|
-
});
|
|
27035
|
-
};
|
|
27036
|
-
handleDelete = () => {
|
|
27037
|
-
this.setState({
|
|
27038
|
-
deleteFocused: true
|
|
27039
|
-
});
|
|
27040
|
-
};
|
|
27041
|
-
toggleConsidered = () => {
|
|
27042
|
-
const newVal = findNextIn(perseus.PerseusExpressionAnswerFormConsidered, this.props.considered);
|
|
27043
|
-
this.change({
|
|
27044
|
-
considered: newVal
|
|
27045
|
-
});
|
|
27046
|
-
};
|
|
27047
26820
|
}
|
|
27048
26821
|
const styles$L = aphrodite.StyleSheet.create({
|
|
27049
26822
|
paddedX: {
|
|
@@ -27092,7 +26865,7 @@ const styles$L = aphrodite.StyleSheet.create({
|
|
|
27092
26865
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
27093
26866
|
const {
|
|
27094
26867
|
InlineIcon: InlineIcon$3,
|
|
27095
|
-
TextInput: TextInput$
|
|
26868
|
+
TextInput: TextInput$5
|
|
27096
26869
|
} = perseus.components;
|
|
27097
26870
|
const {
|
|
27098
26871
|
iconPlus: iconPlus$1,
|
|
@@ -27141,6 +26914,16 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27141
26914
|
hint: null
|
|
27142
26915
|
});
|
|
27143
26916
|
};
|
|
26917
|
+
getSaveWarnings = () => {
|
|
26918
|
+
return this.editor.current?.getSaveWarnings();
|
|
26919
|
+
};
|
|
26920
|
+
serialize = () => {
|
|
26921
|
+
return {
|
|
26922
|
+
title: this.props.title,
|
|
26923
|
+
...this.editor.current?.serialize(),
|
|
26924
|
+
hint: this.hintEditor.current?.serialize()
|
|
26925
|
+
};
|
|
26926
|
+
};
|
|
27144
26927
|
render() {
|
|
27145
26928
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
27146
26929
|
className: "perseus-group-editor"
|
|
@@ -27148,7 +26931,7 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27148
26931
|
className: "perseus-widget-row"
|
|
27149
26932
|
}, /*#__PURE__*/React__namespace.createElement("label", {
|
|
27150
26933
|
className: aphrodite.css(styles$K.title)
|
|
27151
|
-
}, "Title:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
26934
|
+
}, "Title:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$5, {
|
|
27152
26935
|
value: this.props.title,
|
|
27153
26936
|
className: aphrodite.css(styles$K.input)
|
|
27154
26937
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
@@ -27196,16 +26979,6 @@ class GradedGroupEditor extends React__namespace.Component {
|
|
|
27196
26979
|
onClick: this.handleRemoveHint
|
|
27197
26980
|
}, /*#__PURE__*/React__namespace.createElement(InlineIcon$3, iconTrash$2), " Remove this hint")));
|
|
27198
26981
|
}
|
|
27199
|
-
getSaveWarnings = () => {
|
|
27200
|
-
return this.editor.current?.getSaveWarnings();
|
|
27201
|
-
};
|
|
27202
|
-
serialize = () => {
|
|
27203
|
-
return {
|
|
27204
|
-
title: this.props.title,
|
|
27205
|
-
...this.editor.current?.serialize(),
|
|
27206
|
-
hint: this.hintEditor.current?.serialize()
|
|
27207
|
-
};
|
|
27208
|
-
};
|
|
27209
26982
|
}
|
|
27210
26983
|
const styles$K = aphrodite.StyleSheet.create({
|
|
27211
26984
|
title: {
|
|
@@ -27839,6 +27612,26 @@ class GrapherEditor extends React__namespace.Component {
|
|
|
27839
27612
|
return perseus.Changeable.change.apply(_this, args);
|
|
27840
27613
|
};
|
|
27841
27614
|
})();
|
|
27615
|
+
handleAvailableTypesChange = newAvailableTypes => {
|
|
27616
|
+
let correct = this.props.correct;
|
|
27617
|
+
|
|
27618
|
+
// If the currently 'correct' type is removed from the list of types,
|
|
27619
|
+
// we need to change it to avoid impossible questions.
|
|
27620
|
+
if (!___default["default"].contains(newAvailableTypes, this.props.correct.type)) {
|
|
27621
|
+
const graph = this.props.graph;
|
|
27622
|
+
const newType = chooseType(newAvailableTypes);
|
|
27623
|
+
correct = defaultPlotProps(newType, graph);
|
|
27624
|
+
}
|
|
27625
|
+
this.props.onChange({
|
|
27626
|
+
availableTypes: newAvailableTypes,
|
|
27627
|
+
correct: correct
|
|
27628
|
+
});
|
|
27629
|
+
};
|
|
27630
|
+
serialize = () => {
|
|
27631
|
+
return ___default["default"].chain(this.props).pick("correct", "availableTypes").extend({
|
|
27632
|
+
graph: ___default["default"].omit(this.props.graph, "box")
|
|
27633
|
+
}).value();
|
|
27634
|
+
};
|
|
27842
27635
|
render() {
|
|
27843
27636
|
const sizeClass = containerSizeClass$1.SMALL;
|
|
27844
27637
|
let equationString;
|
|
@@ -27904,26 +27697,6 @@ class GrapherEditor extends React__namespace.Component {
|
|
|
27904
27697
|
onChange: this.handleAvailableTypesChange
|
|
27905
27698
|
})), graph);
|
|
27906
27699
|
}
|
|
27907
|
-
handleAvailableTypesChange = newAvailableTypes => {
|
|
27908
|
-
let correct = this.props.correct;
|
|
27909
|
-
|
|
27910
|
-
// If the currently 'correct' type is removed from the list of types,
|
|
27911
|
-
// we need to change it to avoid impossible questions.
|
|
27912
|
-
if (!___default["default"].contains(newAvailableTypes, this.props.correct.type)) {
|
|
27913
|
-
const graph = this.props.graph;
|
|
27914
|
-
const newType = chooseType(newAvailableTypes);
|
|
27915
|
-
correct = defaultPlotProps(newType, graph);
|
|
27916
|
-
}
|
|
27917
|
-
this.props.onChange({
|
|
27918
|
-
availableTypes: newAvailableTypes,
|
|
27919
|
-
correct: correct
|
|
27920
|
-
});
|
|
27921
|
-
};
|
|
27922
|
-
serialize = () => {
|
|
27923
|
-
return ___default["default"].chain(this.props).pick("correct", "availableTypes").extend({
|
|
27924
|
-
graph: ___default["default"].omit(this.props.graph, "box")
|
|
27925
|
-
}).value();
|
|
27926
|
-
};
|
|
27927
27700
|
}
|
|
27928
27701
|
|
|
27929
27702
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
@@ -27946,20 +27719,6 @@ class GroupEditor extends React__namespace.Component {
|
|
|
27946
27719
|
metadata: undefined
|
|
27947
27720
|
};
|
|
27948
27721
|
editor = /*#__PURE__*/React__namespace.createRef();
|
|
27949
|
-
render() {
|
|
27950
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
27951
|
-
className: "perseus-group-editor"
|
|
27952
|
-
}, /*#__PURE__*/React__namespace.createElement("div", null, this._renderMetadataEditor()), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
27953
|
-
ref: this.editor,
|
|
27954
|
-
content: this.props.content,
|
|
27955
|
-
widgets: this.props.widgets,
|
|
27956
|
-
apiOptions: this.props.apiOptions,
|
|
27957
|
-
images: this.props.images,
|
|
27958
|
-
widgetEnabled: true,
|
|
27959
|
-
immutableWidgets: false,
|
|
27960
|
-
onChange: this.props.onChange
|
|
27961
|
-
}));
|
|
27962
|
-
}
|
|
27963
27722
|
_renderMetadataEditor = () => {
|
|
27964
27723
|
const GroupMetadataEditor = this.props.apiOptions.GroupMetadataEditor;
|
|
27965
27724
|
return /*#__PURE__*/React__namespace.createElement(GroupMetadataEditor, {
|
|
@@ -27986,6 +27745,20 @@ class GroupEditor extends React__namespace.Component {
|
|
|
27986
27745
|
metadata: this.props.metadata
|
|
27987
27746
|
});
|
|
27988
27747
|
};
|
|
27748
|
+
render() {
|
|
27749
|
+
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
27750
|
+
className: "perseus-group-editor"
|
|
27751
|
+
}, /*#__PURE__*/React__namespace.createElement("div", null, this._renderMetadataEditor()), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
27752
|
+
ref: this.editor,
|
|
27753
|
+
content: this.props.content,
|
|
27754
|
+
widgets: this.props.widgets,
|
|
27755
|
+
apiOptions: this.props.apiOptions,
|
|
27756
|
+
images: this.props.images,
|
|
27757
|
+
widgetEnabled: true,
|
|
27758
|
+
immutableWidgets: false,
|
|
27759
|
+
onChange: this.props.onChange
|
|
27760
|
+
}));
|
|
27761
|
+
}
|
|
27989
27762
|
}
|
|
27990
27763
|
|
|
27991
27764
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
@@ -28011,6 +27784,9 @@ class PairEditor extends React__namespace.Component {
|
|
|
28011
27784
|
return perseus.Changeable.change.apply(_this, args);
|
|
28012
27785
|
};
|
|
28013
27786
|
})();
|
|
27787
|
+
serialize = () => {
|
|
27788
|
+
return perseus.EditorJsonify.serialize.call(this);
|
|
27789
|
+
};
|
|
28014
27790
|
render() {
|
|
28015
27791
|
return /*#__PURE__*/React__namespace.createElement("fieldset", null, /*#__PURE__*/React__namespace.createElement("label", null, "Name:", /*#__PURE__*/React__namespace.createElement(BlurInput, {
|
|
28016
27792
|
value: this.props.name,
|
|
@@ -28020,9 +27796,6 @@ class PairEditor extends React__namespace.Component {
|
|
|
28020
27796
|
onChange: this.change("value")
|
|
28021
27797
|
})));
|
|
28022
27798
|
}
|
|
28023
|
-
serialize = () => {
|
|
28024
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
28025
|
-
};
|
|
28026
27799
|
}
|
|
28027
27800
|
/**
|
|
28028
27801
|
* This is used for editing a set of name/value pairs.
|
|
@@ -28035,19 +27808,6 @@ class PairsEditor extends React__namespace.Component {
|
|
|
28035
27808
|
value: PropTypes__default["default"].string
|
|
28036
27809
|
})).isRequired
|
|
28037
27810
|
};
|
|
28038
|
-
render() {
|
|
28039
|
-
const editors = ___default["default"].map(this.props.pairs, (pair, i) => {
|
|
28040
|
-
return /*#__PURE__*/React__namespace.createElement(PairEditor, {
|
|
28041
|
-
key: i,
|
|
28042
|
-
name: pair.name,
|
|
28043
|
-
value: pair.value
|
|
28044
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
28045
|
-
,
|
|
28046
|
-
onChange: this.handlePairChange.bind(this, i)
|
|
28047
|
-
});
|
|
28048
|
-
});
|
|
28049
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, editors);
|
|
28050
|
-
}
|
|
28051
27811
|
change = (() => {
|
|
28052
27812
|
var _this2 = this;
|
|
28053
27813
|
return function () {
|
|
@@ -28073,6 +27833,19 @@ class PairsEditor extends React__namespace.Component {
|
|
|
28073
27833
|
serialize = () => {
|
|
28074
27834
|
return perseus.EditorJsonify.serialize.call(this);
|
|
28075
27835
|
};
|
|
27836
|
+
render() {
|
|
27837
|
+
const editors = ___default["default"].map(this.props.pairs, (pair, i) => {
|
|
27838
|
+
return /*#__PURE__*/React__namespace.createElement(PairEditor, {
|
|
27839
|
+
key: i,
|
|
27840
|
+
name: pair.name,
|
|
27841
|
+
value: pair.value
|
|
27842
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
27843
|
+
,
|
|
27844
|
+
onChange: this.handlePairChange.bind(this, i)
|
|
27845
|
+
});
|
|
27846
|
+
});
|
|
27847
|
+
return /*#__PURE__*/React__namespace.createElement("div", null, editors);
|
|
27848
|
+
}
|
|
28076
27849
|
}
|
|
28077
27850
|
/**
|
|
28078
27851
|
* This is the main editor for this widget, to specify all the options.
|
|
@@ -28102,6 +27875,15 @@ class IframeEditor extends React__namespace.Component {
|
|
|
28102
27875
|
return perseus.Changeable.change.apply(_this3, args);
|
|
28103
27876
|
};
|
|
28104
27877
|
})();
|
|
27878
|
+
handleSettingsChange = settings => {
|
|
27879
|
+
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
27880
|
+
this.change({
|
|
27881
|
+
settings: settings.pairs
|
|
27882
|
+
});
|
|
27883
|
+
};
|
|
27884
|
+
serialize = () => {
|
|
27885
|
+
return perseus.EditorJsonify.serialize.call(this);
|
|
27886
|
+
};
|
|
28105
27887
|
render() {
|
|
28106
27888
|
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
28107
27889
|
style: {
|
|
@@ -28145,18 +27927,9 @@ class IframeEditor extends React__namespace.Component {
|
|
|
28145
27927
|
}
|
|
28146
27928
|
}));
|
|
28147
27929
|
}
|
|
28148
|
-
handleSettingsChange = settings => {
|
|
28149
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
28150
|
-
this.change({
|
|
28151
|
-
settings: settings.pairs
|
|
28152
|
-
});
|
|
28153
|
-
};
|
|
28154
|
-
serialize = () => {
|
|
28155
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
28156
|
-
};
|
|
28157
27930
|
}
|
|
28158
27931
|
|
|
28159
|
-
/* eslint-disable jsx-a11y/anchor-is-valid
|
|
27932
|
+
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
28160
27933
|
const {
|
|
28161
27934
|
InfoTip: InfoTip$f,
|
|
28162
27935
|
InlineIcon: InlineIcon$2,
|
|
@@ -28182,9 +27955,9 @@ const INTERNALLY_HOSTED_URL_RE = new RegExp("^(https?|web\\+graphie)://[^/]*" +
|
|
|
28182
27955
|
*/
|
|
28183
27956
|
const captionAlignments = ["center", "above", "above right", "right", "below right", "below", "below left", "left", "above left"];
|
|
28184
27957
|
class ImageEditor extends React__namespace.Component {
|
|
28185
|
-
_isMounted = false;
|
|
28186
27958
|
static displayName = "ImageEditor";
|
|
28187
27959
|
static widgetName = "image";
|
|
27960
|
+
_isMounted = false;
|
|
28188
27961
|
static defaultProps = {
|
|
28189
27962
|
title: "",
|
|
28190
27963
|
range: [defaultRange, defaultRange],
|
|
@@ -28205,48 +27978,6 @@ class ImageEditor extends React__namespace.Component {
|
|
|
28205
27978
|
componentWillUnmount() {
|
|
28206
27979
|
this._isMounted = false;
|
|
28207
27980
|
}
|
|
28208
|
-
render() {
|
|
28209
|
-
const backgroundImage = this.props.backgroundImage;
|
|
28210
|
-
const imageSettings = /*#__PURE__*/React__namespace.createElement("div", {
|
|
28211
|
-
className: "image-settings"
|
|
28212
|
-
}, !perseus.Util.isLabeledSVG(backgroundImage.url) && /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Preview:"), /*#__PURE__*/React__namespace.createElement("img", {
|
|
28213
|
-
alt: "Editor preview of image",
|
|
28214
|
-
src: backgroundImage.url,
|
|
28215
|
-
style: {
|
|
28216
|
-
width: "100%"
|
|
28217
|
-
}
|
|
28218
|
-
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Dimensions:"), /*#__PURE__*/React__namespace.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Alt text:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
28219
|
-
apiOptions: this.props.apiOptions,
|
|
28220
|
-
content: this.props.alt,
|
|
28221
|
-
onChange: props => {
|
|
28222
|
-
if (props.content != null) {
|
|
28223
|
-
this.change("alt", props.content);
|
|
28224
|
-
}
|
|
28225
|
-
},
|
|
28226
|
-
widgetEnabled: false
|
|
28227
|
-
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Caption:"), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
28228
|
-
apiOptions: this.props.apiOptions,
|
|
28229
|
-
content: this.props.caption,
|
|
28230
|
-
onChange: props => {
|
|
28231
|
-
if (props.content != null) {
|
|
28232
|
-
this.change("caption", props.content);
|
|
28233
|
-
}
|
|
28234
|
-
},
|
|
28235
|
-
widgetEnabled: false
|
|
28236
|
-
}))));
|
|
28237
|
-
const backgroundImageErrorText = /*#__PURE__*/React__namespace.createElement("div", {
|
|
28238
|
-
className: "renderer-widget-error"
|
|
28239
|
-
}, this.state.backgroundImageError);
|
|
28240
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
28241
|
-
className: "perseus-image-editor"
|
|
28242
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Image url:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React__namespace.createElement(BlurInput, {
|
|
28243
|
-
value: backgroundImage.url || "",
|
|
28244
|
-
style: {
|
|
28245
|
-
width: 332
|
|
28246
|
-
},
|
|
28247
|
-
onChange: url => this.onUrlChange(url, false)
|
|
28248
|
-
})), backgroundImage.url && imageSettings);
|
|
28249
|
-
}
|
|
28250
27981
|
_renderRowForLabel(label, i) {
|
|
28251
27982
|
return /*#__PURE__*/React__namespace.createElement("tr", {
|
|
28252
27983
|
key: i
|
|
@@ -28391,9 +28122,50 @@ class ImageEditor extends React__namespace.Component {
|
|
|
28391
28122
|
serialize() {
|
|
28392
28123
|
return perseus.EditorJsonify.serialize.call(this);
|
|
28393
28124
|
}
|
|
28125
|
+
render() {
|
|
28126
|
+
const backgroundImage = this.props.backgroundImage;
|
|
28127
|
+
const imageSettings = /*#__PURE__*/React__namespace.createElement("div", {
|
|
28128
|
+
className: "image-settings"
|
|
28129
|
+
}, !perseus.Util.isLabeledSVG(backgroundImage.url) && /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Preview:"), /*#__PURE__*/React__namespace.createElement("img", {
|
|
28130
|
+
alt: "Editor preview of image",
|
|
28131
|
+
src: backgroundImage.url,
|
|
28132
|
+
style: {
|
|
28133
|
+
width: "100%"
|
|
28134
|
+
}
|
|
28135
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Dimensions:"), /*#__PURE__*/React__namespace.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Alt text:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
28136
|
+
apiOptions: this.props.apiOptions,
|
|
28137
|
+
content: this.props.alt,
|
|
28138
|
+
onChange: props => {
|
|
28139
|
+
if (props.content != null) {
|
|
28140
|
+
this.change("alt", props.content);
|
|
28141
|
+
}
|
|
28142
|
+
},
|
|
28143
|
+
widgetEnabled: false
|
|
28144
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement("div", null, "Caption:"), /*#__PURE__*/React__namespace.createElement(Editor, {
|
|
28145
|
+
apiOptions: this.props.apiOptions,
|
|
28146
|
+
content: this.props.caption,
|
|
28147
|
+
onChange: props => {
|
|
28148
|
+
if (props.content != null) {
|
|
28149
|
+
this.change("caption", props.content);
|
|
28150
|
+
}
|
|
28151
|
+
},
|
|
28152
|
+
widgetEnabled: false
|
|
28153
|
+
}))));
|
|
28154
|
+
const backgroundImageErrorText = /*#__PURE__*/React__namespace.createElement("div", {
|
|
28155
|
+
className: "renderer-widget-error"
|
|
28156
|
+
}, this.state.backgroundImageError);
|
|
28157
|
+
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
28158
|
+
className: "perseus-image-editor"
|
|
28159
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Image url:", /*#__PURE__*/React__namespace.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React__namespace.createElement(BlurInput, {
|
|
28160
|
+
value: backgroundImage.url || "",
|
|
28161
|
+
style: {
|
|
28162
|
+
width: 332
|
|
28163
|
+
},
|
|
28164
|
+
onChange: url => this.onUrlChange(url, false)
|
|
28165
|
+
})), backgroundImage.url && imageSettings);
|
|
28166
|
+
}
|
|
28394
28167
|
}
|
|
28395
28168
|
|
|
28396
|
-
/* eslint-disable react/sort-comp */
|
|
28397
28169
|
const {
|
|
28398
28170
|
InfoTip: InfoTip$e
|
|
28399
28171
|
} = perseus.components;
|
|
@@ -28450,6 +28222,19 @@ class InputNumberEditor extends React__namespace.Component {
|
|
|
28450
28222
|
value: value
|
|
28451
28223
|
});
|
|
28452
28224
|
};
|
|
28225
|
+
focus = () => {
|
|
28226
|
+
this.input.current?.focus();
|
|
28227
|
+
return true;
|
|
28228
|
+
};
|
|
28229
|
+
serialize = () => ({
|
|
28230
|
+
value: this.props.value,
|
|
28231
|
+
simplify: this.props.simplify,
|
|
28232
|
+
size: this.props.size,
|
|
28233
|
+
inexact: this.props.inexact,
|
|
28234
|
+
maxError: this.props.maxError,
|
|
28235
|
+
answerType: this.props.answerType,
|
|
28236
|
+
rightAlign: this.props.rightAlign
|
|
28237
|
+
});
|
|
28453
28238
|
render() {
|
|
28454
28239
|
const answerTypeOptions = ___default["default"].map(answerTypes, function (v, k) {
|
|
28455
28240
|
return /*#__PURE__*/React__namespace.createElement("option", {
|
|
@@ -28533,19 +28318,6 @@ class InputNumberEditor extends React__namespace.Component {
|
|
|
28533
28318
|
}
|
|
28534
28319
|
}), " ", "Right alignment")));
|
|
28535
28320
|
}
|
|
28536
|
-
focus = () => {
|
|
28537
|
-
this.input.current?.focus();
|
|
28538
|
-
return true;
|
|
28539
|
-
};
|
|
28540
|
-
serialize = () => ({
|
|
28541
|
-
value: this.props.value,
|
|
28542
|
-
simplify: this.props.simplify,
|
|
28543
|
-
size: this.props.size,
|
|
28544
|
-
inexact: this.props.inexact,
|
|
28545
|
-
maxError: this.props.maxError,
|
|
28546
|
-
answerType: this.props.answerType,
|
|
28547
|
-
rightAlign: this.props.rightAlign
|
|
28548
|
-
});
|
|
28549
28321
|
}
|
|
28550
28322
|
|
|
28551
28323
|
/**
|
|
@@ -28681,7 +28453,7 @@ class FunctionEditor extends React__namespace.Component {
|
|
|
28681
28453
|
}
|
|
28682
28454
|
|
|
28683
28455
|
const {
|
|
28684
|
-
TextInput: TextInput$
|
|
28456
|
+
TextInput: TextInput$4
|
|
28685
28457
|
} = perseus.components;
|
|
28686
28458
|
const {
|
|
28687
28459
|
getDependencies: getDependencies$7
|
|
@@ -28715,7 +28487,7 @@ class LabelEditor extends React__namespace.Component {
|
|
|
28715
28487
|
className: "graph-settings"
|
|
28716
28488
|
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
28717
28489
|
className: "perseus-widget-row"
|
|
28718
|
-
}, /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
28490
|
+
}, /*#__PURE__*/React__namespace.createElement(TextInput$4, {
|
|
28719
28491
|
value: this.props.label,
|
|
28720
28492
|
onChange: this.change("label"),
|
|
28721
28493
|
style: {
|
|
@@ -32805,18 +32577,10 @@ const {
|
|
|
32805
32577
|
containerSizeClass,
|
|
32806
32578
|
getInteractiveBoxFromSizeClass
|
|
32807
32579
|
} = perseus.SizingUtils;
|
|
32808
|
-
const DeprecationMixin = perseus.Util.DeprecationMixin;
|
|
32809
32580
|
const InteractiveGraph = perseus.InteractiveGraphWidget.widget;
|
|
32810
32581
|
const defaultBackgroundImage = {
|
|
32811
32582
|
url: null
|
|
32812
32583
|
};
|
|
32813
|
-
const deprecatedProps = {
|
|
32814
|
-
showGraph: function (props) {
|
|
32815
|
-
return {
|
|
32816
|
-
markings: props.showGraph ? "graph" : "none"
|
|
32817
|
-
};
|
|
32818
|
-
}
|
|
32819
|
-
};
|
|
32820
32584
|
const POLYGON_SIDES = ___default["default"].map(___default["default"].range(3, 13), function (value) {
|
|
32821
32585
|
return /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
|
|
32822
32586
|
key: `polygon-sides-${value}`,
|
|
@@ -32831,9 +32595,9 @@ const POLYGON_SIDES = ___default["default"].map(___default["default"].range(3, 1
|
|
|
32831
32595
|
* Used in the exercise editor.
|
|
32832
32596
|
*/
|
|
32833
32597
|
class InteractiveGraphEditor extends React__namespace.Component {
|
|
32598
|
+
static widgetName = "interactive-graph";
|
|
32834
32599
|
displayName = "InteractiveGraphEditor";
|
|
32835
32600
|
className = "perseus-widget-interactive-graph";
|
|
32836
|
-
static widgetName = "interactive-graph";
|
|
32837
32601
|
static defaultProps = {
|
|
32838
32602
|
...InteractiveGraph.defaultProps,
|
|
32839
32603
|
valid: true,
|
|
@@ -32844,14 +32608,68 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
32844
32608
|
coords: null
|
|
32845
32609
|
}
|
|
32846
32610
|
};
|
|
32611
|
+
changeMatchType = newValue => {
|
|
32612
|
+
const correct = {
|
|
32613
|
+
...this.props.correct,
|
|
32614
|
+
match: newValue
|
|
32615
|
+
};
|
|
32616
|
+
this.props.onChange({
|
|
32617
|
+
correct: correct
|
|
32618
|
+
});
|
|
32619
|
+
};
|
|
32620
|
+
changeStartCoords = coords => {
|
|
32621
|
+
if (!this.props.graph?.type) {
|
|
32622
|
+
return;
|
|
32623
|
+
}
|
|
32624
|
+
const graph = {
|
|
32625
|
+
...this.props.graph,
|
|
32626
|
+
startCoords: coords
|
|
32627
|
+
};
|
|
32628
|
+
this.props.onChange({
|
|
32629
|
+
graph: graph
|
|
32630
|
+
});
|
|
32631
|
+
};
|
|
32847
32632
|
|
|
32848
|
-
//
|
|
32849
|
-
|
|
32633
|
+
// serialize() is what makes copy/paste work. All the properties included
|
|
32634
|
+
// in the serialization json are included when, for example, a graph
|
|
32635
|
+
// is copied from the question editor and pasted into the hint editor
|
|
32636
|
+
// (double brackets in the markdown).
|
|
32637
|
+
serialize() {
|
|
32638
|
+
const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showTooltips", "range", "gridStep", "snapStep", "lockedFigures");
|
|
32850
32639
|
|
|
32851
|
-
|
|
32852
|
-
|
|
32853
|
-
|
|
32640
|
+
// eslint-disable-next-line react/no-string-refs
|
|
32641
|
+
const graph = this.refs.graph;
|
|
32642
|
+
if (graph) {
|
|
32643
|
+
// @ts-expect-error TS2339 Property 'getUserInput' does not exist on type 'ReactInstance'. Property 'getUserInput' does not exist on type 'Component<any, {}, any>'.
|
|
32644
|
+
const correct = graph && graph.getUserInput();
|
|
32645
|
+
___default["default"].extend(json, {
|
|
32646
|
+
graph: {
|
|
32647
|
+
type: correct.type,
|
|
32648
|
+
startCoords: this.props.graph?.startCoords
|
|
32649
|
+
},
|
|
32650
|
+
correct: correct
|
|
32651
|
+
});
|
|
32652
|
+
___default["default"].each(["allowReflexAngles", "angleOffsetDeg", "numPoints", "numSides", "numSegments", "showAngles", "showSides", "snapTo", "snapDegrees"], function (key) {
|
|
32653
|
+
if (___default["default"].has(correct, key)) {
|
|
32654
|
+
// @ts-expect-error - TS2339 - Property 'graph' does not exist on type 'Pick<any, "step" | "range" | "backgroundImage" | "snapStep" | "labels" | "showTooltips" | "markings" | "gridStep" | "showProtractor">'.
|
|
32655
|
+
json.graph[key] = correct[key];
|
|
32656
|
+
}
|
|
32657
|
+
});
|
|
32658
|
+
}
|
|
32659
|
+
// @ts-expect-error TS2739 Type 'Pick<Readonly<Props> & Readonly<{ children?: ReactNode; }>, "step" | "gridStep" | "snapStep" | "backgroundImage" | "markings" | "labels" | ... 5 more ... | "range">' is missing the following properties from type 'PerseusInteractiveGraphWidgetOptions': graph, correct
|
|
32660
|
+
return json;
|
|
32854
32661
|
}
|
|
32662
|
+
getSaveWarnings = () => {
|
|
32663
|
+
const issues = [];
|
|
32664
|
+
|
|
32665
|
+
// A locked line on the graph cannot have length 0.
|
|
32666
|
+
for (const figure of this.props.lockedFigures ?? []) {
|
|
32667
|
+
if (figure.type === "line" && kmath.vector.equal(figure.points[0].coord, figure.points[1].coord)) {
|
|
32668
|
+
issues.push("The line cannot have length 0.");
|
|
32669
|
+
}
|
|
32670
|
+
}
|
|
32671
|
+
return issues;
|
|
32672
|
+
};
|
|
32855
32673
|
render() {
|
|
32856
32674
|
let graph;
|
|
32857
32675
|
let equationString;
|
|
@@ -33127,68 +32945,6 @@ class InteractiveGraphEditor extends React__namespace.Component {
|
|
|
33127
32945
|
onChange: this.props.onChange
|
|
33128
32946
|
}));
|
|
33129
32947
|
}
|
|
33130
|
-
changeMatchType = newValue => {
|
|
33131
|
-
const correct = {
|
|
33132
|
-
...this.props.correct,
|
|
33133
|
-
match: newValue
|
|
33134
|
-
};
|
|
33135
|
-
this.props.onChange({
|
|
33136
|
-
correct: correct
|
|
33137
|
-
});
|
|
33138
|
-
};
|
|
33139
|
-
changeStartCoords = coords => {
|
|
33140
|
-
if (!this.props.graph?.type) {
|
|
33141
|
-
return;
|
|
33142
|
-
}
|
|
33143
|
-
const graph = {
|
|
33144
|
-
...this.props.graph,
|
|
33145
|
-
startCoords: coords
|
|
33146
|
-
};
|
|
33147
|
-
this.props.onChange({
|
|
33148
|
-
graph: graph
|
|
33149
|
-
});
|
|
33150
|
-
};
|
|
33151
|
-
|
|
33152
|
-
// serialize() is what makes copy/paste work. All the properties included
|
|
33153
|
-
// in the serialization json are included when, for example, a graph
|
|
33154
|
-
// is copied from the question editor and pasted into the hint editor
|
|
33155
|
-
// (double brackets in the markdown).
|
|
33156
|
-
serialize() {
|
|
33157
|
-
const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showTooltips", "range", "gridStep", "snapStep", "lockedFigures");
|
|
33158
|
-
|
|
33159
|
-
// eslint-disable-next-line react/no-string-refs
|
|
33160
|
-
const graph = this.refs.graph;
|
|
33161
|
-
if (graph) {
|
|
33162
|
-
// @ts-expect-error TS2339 Property 'getUserInput' does not exist on type 'ReactInstance'. Property 'getUserInput' does not exist on type 'Component<any, {}, any>'.
|
|
33163
|
-
const correct = graph && graph.getUserInput();
|
|
33164
|
-
___default["default"].extend(json, {
|
|
33165
|
-
graph: {
|
|
33166
|
-
type: correct.type,
|
|
33167
|
-
startCoords: this.props.graph?.startCoords
|
|
33168
|
-
},
|
|
33169
|
-
correct: correct
|
|
33170
|
-
});
|
|
33171
|
-
___default["default"].each(["allowReflexAngles", "angleOffsetDeg", "numPoints", "numSides", "numSegments", "showAngles", "showSides", "snapTo", "snapDegrees"], function (key) {
|
|
33172
|
-
if (___default["default"].has(correct, key)) {
|
|
33173
|
-
// @ts-expect-error - TS2339 - Property 'graph' does not exist on type 'Pick<any, "step" | "range" | "backgroundImage" | "snapStep" | "labels" | "showTooltips" | "markings" | "gridStep" | "showProtractor">'.
|
|
33174
|
-
json.graph[key] = correct[key];
|
|
33175
|
-
}
|
|
33176
|
-
});
|
|
33177
|
-
}
|
|
33178
|
-
// @ts-expect-error TS2739 Type 'Pick<Readonly<Props> & Readonly<{ children?: ReactNode; }>, "step" | "gridStep" | "snapStep" | "backgroundImage" | "markings" | "labels" | ... 5 more ... | "range">' is missing the following properties from type 'PerseusInteractiveGraphWidgetOptions': graph, correct
|
|
33179
|
-
return json;
|
|
33180
|
-
}
|
|
33181
|
-
getSaveWarnings = () => {
|
|
33182
|
-
const issues = [];
|
|
33183
|
-
|
|
33184
|
-
// A locked line on the graph cannot have length 0.
|
|
33185
|
-
for (const figure of this.props.lockedFigures ?? []) {
|
|
33186
|
-
if (figure.type === "line" && kmath.vector.equal(figure.points[0].coord, figure.points[1].coord)) {
|
|
33187
|
-
issues.push("The line cannot have length 0.");
|
|
33188
|
-
}
|
|
33189
|
-
}
|
|
33190
|
-
return issues;
|
|
33191
|
-
};
|
|
33192
32948
|
}
|
|
33193
32949
|
const styles$a = aphrodite.StyleSheet.create({
|
|
33194
32950
|
singleSelectShort: {
|
|
@@ -33637,8 +33393,55 @@ const editorStyles = aphrodite.StyleSheet.create({
|
|
|
33637
33393
|
}
|
|
33638
33394
|
});
|
|
33639
33395
|
|
|
33640
|
-
|
|
33396
|
+
/**
|
|
33397
|
+
* Add hover behavior to another component.
|
|
33398
|
+
*
|
|
33399
|
+
* This component provides hover and focus status updates in a consistent way
|
|
33400
|
+
* across desktop and mobile.
|
|
33401
|
+
*
|
|
33402
|
+
* For advice on when to use this component instead of Button, see README.md.
|
|
33403
|
+
*
|
|
33404
|
+
* Many mobile browsers treat :hover as sticky which results in buttons looking
|
|
33405
|
+
* pressed even when the user has lifted their finger. This component ensures
|
|
33406
|
+
* that when user lifts their finger the hover state is removed.
|
|
33407
|
+
*
|
|
33408
|
+
* We also chnage how the focus state works. Browsers immediately set the
|
|
33409
|
+
* focus state as soon as you click on a button. This component only sets the
|
|
33410
|
+
* focus state when a user starts navigating between elements via keybaord.
|
|
33411
|
+
*
|
|
33412
|
+
* HoverBehavior accepts a function as 'children' which is passed state and
|
|
33413
|
+
* an object containing event handlers. The 'children' function should return
|
|
33414
|
+
* an React Element of some sort.
|
|
33415
|
+
*
|
|
33416
|
+
* Example:
|
|
33417
|
+
*
|
|
33418
|
+
* class MyButtonLikeComponent extends React.Component {
|
|
33419
|
+
* render(): React.Node {
|
|
33420
|
+
* return <HoverBehavior
|
|
33421
|
+
* disabled={this.props.disabled}
|
|
33422
|
+
* onClick={this.handleClick}
|
|
33423
|
+
* >
|
|
33424
|
+
* {({hovered}, handlers) =>
|
|
33425
|
+
* <RoundRect
|
|
33426
|
+
* textcolor='white'
|
|
33427
|
+
* backgroundColor={hovered ? 'red' : 'blue'}/>}
|
|
33428
|
+
* {...handlers}
|
|
33429
|
+
* >
|
|
33430
|
+
* {this.props.children}
|
|
33431
|
+
* </RoundRect>
|
|
33432
|
+
* }
|
|
33433
|
+
* </HoverBehavior>
|
|
33434
|
+
* }
|
|
33435
|
+
* }
|
|
33436
|
+
*
|
|
33437
|
+
* This follows a pattern call 'Function as Child Components':
|
|
33438
|
+
* https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9#.sw0jiio8b
|
|
33439
|
+
*/
|
|
33641
33440
|
class HoverBehavior extends React__namespace.Component {
|
|
33441
|
+
// @ts-expect-error - TS2564 - Property 'focusFlag' has no initializer and is not definitely assigned in the constructor.
|
|
33442
|
+
focusFlag;
|
|
33443
|
+
// @ts-expect-error - TS2564 - Property 'waitingForClick' has no initializer and is not definitely assigned in the constructor.
|
|
33444
|
+
waitingForClick;
|
|
33642
33445
|
static defaultProps = {
|
|
33643
33446
|
startHovered: false,
|
|
33644
33447
|
shouldUpdate: () => true
|
|
@@ -33650,11 +33453,6 @@ class HoverBehavior extends React__namespace.Component {
|
|
|
33650
33453
|
hovered: props.startHovered
|
|
33651
33454
|
};
|
|
33652
33455
|
}
|
|
33653
|
-
|
|
33654
|
-
// @ts-expect-error - TS2564 - Property 'focusFlag' has no initializer and is not definitely assigned in the constructor.
|
|
33655
|
-
focusFlag;
|
|
33656
|
-
// @ts-expect-error - TS2564 - Property 'waitingForClick' has no initializer and is not definitely assigned in the constructor.
|
|
33657
|
-
waitingForClick;
|
|
33658
33456
|
handleClick = e => {
|
|
33659
33457
|
if (!this.props.disabled) {
|
|
33660
33458
|
if (this.props.shouldUpdate()) {
|
|
@@ -34688,7 +34486,7 @@ const styles = aphrodite.StyleSheet.create({
|
|
|
34688
34486
|
}
|
|
34689
34487
|
});
|
|
34690
34488
|
|
|
34691
|
-
/* eslint-disable react/forbid-prop-types
|
|
34489
|
+
/* eslint-disable react/forbid-prop-types */
|
|
34692
34490
|
const {
|
|
34693
34491
|
InfoTip: InfoTip$a,
|
|
34694
34492
|
TextListEditor: TextListEditor$3
|
|
@@ -34709,6 +34507,22 @@ class MatcherEditor extends React__namespace.Component {
|
|
|
34709
34507
|
orderMatters: false,
|
|
34710
34508
|
padding: true
|
|
34711
34509
|
};
|
|
34510
|
+
onLabelChange = (index, e) => {
|
|
34511
|
+
const labels = ___default["default"].clone(this.props.labels);
|
|
34512
|
+
labels[index] = e.target.value;
|
|
34513
|
+
this.props.onChange({
|
|
34514
|
+
labels: labels
|
|
34515
|
+
});
|
|
34516
|
+
};
|
|
34517
|
+
getSaveWarnings = () => {
|
|
34518
|
+
if (this.props.left.length !== this.props.right.length) {
|
|
34519
|
+
return ["The two halves of the matcher have different numbers" + " of cards."];
|
|
34520
|
+
}
|
|
34521
|
+
return [];
|
|
34522
|
+
};
|
|
34523
|
+
serialize = () => {
|
|
34524
|
+
return ___default["default"].pick(this.props, "left", "right", "labels", "orderMatters", "padding");
|
|
34525
|
+
};
|
|
34712
34526
|
render() {
|
|
34713
34527
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
34714
34528
|
className: "perseus-matcher-editor"
|
|
@@ -34760,25 +34574,8 @@ class MatcherEditor extends React__namespace.Component {
|
|
|
34760
34574
|
}
|
|
34761
34575
|
}), /*#__PURE__*/React__namespace.createElement(InfoTip$a, null, /*#__PURE__*/React__namespace.createElement("p", null, "Padding is good for text, but not needed for images."))));
|
|
34762
34576
|
}
|
|
34763
|
-
onLabelChange = (index, e) => {
|
|
34764
|
-
const labels = ___default["default"].clone(this.props.labels);
|
|
34765
|
-
labels[index] = e.target.value;
|
|
34766
|
-
this.props.onChange({
|
|
34767
|
-
labels: labels
|
|
34768
|
-
});
|
|
34769
|
-
};
|
|
34770
|
-
getSaveWarnings = () => {
|
|
34771
|
-
if (this.props.left.length !== this.props.right.length) {
|
|
34772
|
-
return ["The two halves of the matcher have different numbers" + " of cards."];
|
|
34773
|
-
}
|
|
34774
|
-
return [];
|
|
34775
|
-
};
|
|
34776
|
-
serialize = () => {
|
|
34777
|
-
return ___default["default"].pick(this.props, "left", "right", "labels", "orderMatters", "padding");
|
|
34778
|
-
};
|
|
34779
34577
|
}
|
|
34780
34578
|
|
|
34781
|
-
/* eslint-disable react/sort-comp */
|
|
34782
34579
|
const {
|
|
34783
34580
|
RangeInput: RangeInput$3
|
|
34784
34581
|
} = perseus.components;
|
|
@@ -34827,6 +34624,33 @@ class MatrixEditor extends React__namespace.Component {
|
|
|
34827
34624
|
suffix: "",
|
|
34828
34625
|
cursorPosition: [0, 0]
|
|
34829
34626
|
};
|
|
34627
|
+
change = (() => {
|
|
34628
|
+
var _this = this;
|
|
34629
|
+
return function () {
|
|
34630
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
34631
|
+
args[_key] = arguments[_key];
|
|
34632
|
+
}
|
|
34633
|
+
return perseus.Changeable.change.apply(_this, args);
|
|
34634
|
+
};
|
|
34635
|
+
})();
|
|
34636
|
+
onMatrixBoardSizeChange = range => {
|
|
34637
|
+
const matrixSize = getMatrixSize(this.props.answers);
|
|
34638
|
+
if (range[0] !== null && range[1] !== null) {
|
|
34639
|
+
range = [Math.round(Math.min(Math.max(range[0], 1), MAX_BOARD_SIZE)), Math.round(Math.min(Math.max(range[1], 1), MAX_BOARD_SIZE))];
|
|
34640
|
+
const answers = ___default["default"](Math.min(range[0], matrixSize[0])).times(row => {
|
|
34641
|
+
return ___default["default"](Math.min(range[1], matrixSize[1])).times(col => {
|
|
34642
|
+
return this.props.answers[row][col];
|
|
34643
|
+
});
|
|
34644
|
+
});
|
|
34645
|
+
this.props.onChange({
|
|
34646
|
+
matrixBoardSize: range,
|
|
34647
|
+
answers: answers
|
|
34648
|
+
});
|
|
34649
|
+
}
|
|
34650
|
+
};
|
|
34651
|
+
serialize = () => {
|
|
34652
|
+
return perseus.EditorJsonify.serialize.call(this);
|
|
34653
|
+
};
|
|
34830
34654
|
render() {
|
|
34831
34655
|
const matrixProps = ___default["default"].extend({
|
|
34832
34656
|
numericInput: true,
|
|
@@ -34877,33 +34701,6 @@ class MatrixEditor extends React__namespace.Component {
|
|
|
34877
34701
|
}
|
|
34878
34702
|
})));
|
|
34879
34703
|
}
|
|
34880
|
-
change = (() => {
|
|
34881
|
-
var _this = this;
|
|
34882
|
-
return function () {
|
|
34883
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
34884
|
-
args[_key] = arguments[_key];
|
|
34885
|
-
}
|
|
34886
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
34887
|
-
};
|
|
34888
|
-
})();
|
|
34889
|
-
onMatrixBoardSizeChange = range => {
|
|
34890
|
-
const matrixSize = getMatrixSize(this.props.answers);
|
|
34891
|
-
if (range[0] !== null && range[1] !== null) {
|
|
34892
|
-
range = [Math.round(Math.min(Math.max(range[0], 1), MAX_BOARD_SIZE)), Math.round(Math.min(Math.max(range[1], 1), MAX_BOARD_SIZE))];
|
|
34893
|
-
const answers = ___default["default"](Math.min(range[0], matrixSize[0])).times(row => {
|
|
34894
|
-
return ___default["default"](Math.min(range[1], matrixSize[1])).times(col => {
|
|
34895
|
-
return this.props.answers[row][col];
|
|
34896
|
-
});
|
|
34897
|
-
});
|
|
34898
|
-
this.props.onChange({
|
|
34899
|
-
matrixBoardSize: range,
|
|
34900
|
-
answers: answers
|
|
34901
|
-
});
|
|
34902
|
-
}
|
|
34903
|
-
};
|
|
34904
|
-
serialize = () => {
|
|
34905
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
34906
|
-
};
|
|
34907
34704
|
}
|
|
34908
34705
|
|
|
34909
34706
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
@@ -34945,6 +34742,42 @@ class MeasurerEditor extends React__namespace.Component {
|
|
|
34945
34742
|
rulerLength: 10
|
|
34946
34743
|
};
|
|
34947
34744
|
className = "perseus-widget-measurer";
|
|
34745
|
+
change = (() => {
|
|
34746
|
+
var _this = this;
|
|
34747
|
+
return function () {
|
|
34748
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
34749
|
+
args[_key] = arguments[_key];
|
|
34750
|
+
}
|
|
34751
|
+
return perseus.Changeable.change.apply(_this, args);
|
|
34752
|
+
};
|
|
34753
|
+
})();
|
|
34754
|
+
_changeUrl = e => {
|
|
34755
|
+
this._changeImage("url", e.target.value);
|
|
34756
|
+
};
|
|
34757
|
+
_changeTop = newTop => {
|
|
34758
|
+
this._changeImage("top", newTop);
|
|
34759
|
+
};
|
|
34760
|
+
_changeLeft = newLeft => {
|
|
34761
|
+
this._changeImage("left", newLeft);
|
|
34762
|
+
};
|
|
34763
|
+
_changeImage = (subProp, newValue) => {
|
|
34764
|
+
const image = ___default["default"].clone(this.props.image);
|
|
34765
|
+
image[subProp] = newValue;
|
|
34766
|
+
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 2.
|
|
34767
|
+
this.change("image", image);
|
|
34768
|
+
};
|
|
34769
|
+
renderLabelChoices = choices => {
|
|
34770
|
+
return ___default["default"].map(choices, function (nameAndValue) {
|
|
34771
|
+
const [name, value] = nameAndValue;
|
|
34772
|
+
return /*#__PURE__*/React__namespace.createElement("option", {
|
|
34773
|
+
key: value,
|
|
34774
|
+
value: value
|
|
34775
|
+
}, name);
|
|
34776
|
+
});
|
|
34777
|
+
};
|
|
34778
|
+
serialize = () => {
|
|
34779
|
+
return perseus.EditorJsonify.serialize.call(this);
|
|
34780
|
+
};
|
|
34948
34781
|
render() {
|
|
34949
34782
|
const image = ___default["default"].extend({}, defaultImage, this.props.image);
|
|
34950
34783
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -35038,47 +34871,11 @@ class MeasurerEditor extends React__namespace.Component {
|
|
|
35038
34871
|
useArrowKeys: true
|
|
35039
34872
|
})))));
|
|
35040
34873
|
}
|
|
35041
|
-
change = (() => {
|
|
35042
|
-
var _this = this;
|
|
35043
|
-
return function () {
|
|
35044
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
35045
|
-
args[_key] = arguments[_key];
|
|
35046
|
-
}
|
|
35047
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
35048
|
-
};
|
|
35049
|
-
})();
|
|
35050
|
-
_changeUrl = e => {
|
|
35051
|
-
this._changeImage("url", e.target.value);
|
|
35052
|
-
};
|
|
35053
|
-
_changeTop = newTop => {
|
|
35054
|
-
this._changeImage("top", newTop);
|
|
35055
|
-
};
|
|
35056
|
-
_changeLeft = newLeft => {
|
|
35057
|
-
this._changeImage("left", newLeft);
|
|
35058
|
-
};
|
|
35059
|
-
_changeImage = (subProp, newValue) => {
|
|
35060
|
-
const image = ___default["default"].clone(this.props.image);
|
|
35061
|
-
image[subProp] = newValue;
|
|
35062
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 2.
|
|
35063
|
-
this.change("image", image);
|
|
35064
|
-
};
|
|
35065
|
-
renderLabelChoices = choices => {
|
|
35066
|
-
return ___default["default"].map(choices, function (nameAndValue) {
|
|
35067
|
-
const [name, value] = nameAndValue;
|
|
35068
|
-
return /*#__PURE__*/React__namespace.createElement("option", {
|
|
35069
|
-
key: value,
|
|
35070
|
-
value: value
|
|
35071
|
-
}, name);
|
|
35072
|
-
});
|
|
35073
|
-
};
|
|
35074
|
-
serialize = () => {
|
|
35075
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
35076
|
-
};
|
|
35077
34874
|
}
|
|
35078
34875
|
|
|
35079
34876
|
const {
|
|
35080
34877
|
NumberInput: NumberInput$6,
|
|
35081
|
-
TextInput: TextInput$
|
|
34878
|
+
TextInput: TextInput$3
|
|
35082
34879
|
} = perseus.components;
|
|
35083
34880
|
class MoleculeWidgetEditor extends React__namespace.Component {
|
|
35084
34881
|
static propTypes = {
|
|
@@ -35112,7 +34909,7 @@ class MoleculeWidgetEditor extends React__namespace.Component {
|
|
|
35112
34909
|
return perseus.EditorJsonify.serialize.call(this);
|
|
35113
34910
|
};
|
|
35114
34911
|
render() {
|
|
35115
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "SMILES:\xA0", /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
34912
|
+
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "SMILES:\xA0", /*#__PURE__*/React__namespace.createElement(TextInput$3, {
|
|
35116
34913
|
onChange: this.updateMolecule,
|
|
35117
34914
|
value: this.props.smiles
|
|
35118
34915
|
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Rotation (deg):\xA0", /*#__PURE__*/React__namespace.createElement(NumberInput$6, {
|
|
@@ -35437,14 +35234,14 @@ class NumberLineEditor extends React__namespace.Component {
|
|
|
35437
35234
|
}
|
|
35438
35235
|
}
|
|
35439
35236
|
|
|
35440
|
-
/* eslint-disable jsx-a11y/anchor-is-valid
|
|
35237
|
+
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
35441
35238
|
const {
|
|
35442
35239
|
ButtonGroup,
|
|
35443
35240
|
InfoTip: InfoTip$7,
|
|
35444
35241
|
InlineIcon: InlineIcon$1,
|
|
35445
35242
|
MultiButtonGroup,
|
|
35446
35243
|
NumberInput: NumberInput$4,
|
|
35447
|
-
TextInput: TextInput$
|
|
35244
|
+
TextInput: TextInput$2
|
|
35448
35245
|
} = perseus.components;
|
|
35449
35246
|
const {
|
|
35450
35247
|
iconGear,
|
|
@@ -35510,6 +35307,106 @@ class NumericInputEditor extends React__namespace.Component {
|
|
|
35510
35307
|
showOptions: ___default["default"].map(this.props.answers, () => false)
|
|
35511
35308
|
};
|
|
35512
35309
|
}
|
|
35310
|
+
change = (() => {
|
|
35311
|
+
var _this = this;
|
|
35312
|
+
return function () {
|
|
35313
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
35314
|
+
args[_key] = arguments[_key];
|
|
35315
|
+
}
|
|
35316
|
+
return perseus.Changeable.change.apply(_this, args);
|
|
35317
|
+
};
|
|
35318
|
+
})();
|
|
35319
|
+
onToggleOptions = choiceIndex => {
|
|
35320
|
+
const showOptions = this.state.showOptions.slice();
|
|
35321
|
+
showOptions[choiceIndex] = !showOptions[choiceIndex];
|
|
35322
|
+
this.setState({
|
|
35323
|
+
showOptions: showOptions
|
|
35324
|
+
});
|
|
35325
|
+
};
|
|
35326
|
+
onTrashAnswer = choiceIndex => {
|
|
35327
|
+
if (choiceIndex >= 0 && choiceIndex < this.props.answers.length) {
|
|
35328
|
+
const answers = this.props.answers.slice(0);
|
|
35329
|
+
answers.splice(choiceIndex, 1);
|
|
35330
|
+
this.props.onChange({
|
|
35331
|
+
answers: answers
|
|
35332
|
+
});
|
|
35333
|
+
}
|
|
35334
|
+
};
|
|
35335
|
+
onSpace = (() => {
|
|
35336
|
+
var _this2 = this;
|
|
35337
|
+
return function (e, callback) {
|
|
35338
|
+
if (e.key === " ") {
|
|
35339
|
+
e.preventDefault(); // prevent page shifting
|
|
35340
|
+
for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
|
|
35341
|
+
args[_key2 - 2] = arguments[_key2];
|
|
35342
|
+
}
|
|
35343
|
+
callback.apply(_this2, args);
|
|
35344
|
+
}
|
|
35345
|
+
};
|
|
35346
|
+
})();
|
|
35347
|
+
onStatusChange = choiceIndex => {
|
|
35348
|
+
const statuses = ["wrong", "ungraded", "correct"];
|
|
35349
|
+
const answers = this.props.answers;
|
|
35350
|
+
const i = ___default["default"].indexOf(statuses, answers[choiceIndex].status);
|
|
35351
|
+
const newStatus = statuses[(i + 1) % statuses.length];
|
|
35352
|
+
this.updateAnswer(choiceIndex, {
|
|
35353
|
+
status: newStatus,
|
|
35354
|
+
simplify: newStatus === "correct" ? "required" : "accepted"
|
|
35355
|
+
});
|
|
35356
|
+
};
|
|
35357
|
+
updateAnswer = (choiceIndex, update) => {
|
|
35358
|
+
if (!___default["default"].isObject(update)) {
|
|
35359
|
+
return ___default["default"].partial((choiceIndex, key, value) => {
|
|
35360
|
+
const update = {};
|
|
35361
|
+
update[key] = value;
|
|
35362
|
+
this.updateAnswer(choiceIndex, update);
|
|
35363
|
+
}, choiceIndex, update);
|
|
35364
|
+
}
|
|
35365
|
+
let answers = [
|
|
35366
|
+
// Have to do this to remove the `readonly` state from the prop
|
|
35367
|
+
...this.props.answers];
|
|
35368
|
+
|
|
35369
|
+
// Don't bother to make a new answer box unless we are editing the last
|
|
35370
|
+
// one.
|
|
35371
|
+
// TODO(oliver): This might not be necessary anymore.
|
|
35372
|
+
if (choiceIndex === answers.length) {
|
|
35373
|
+
const lastAnswer = initAnswer(this.state.lastStatus);
|
|
35374
|
+
answers = answers.concat(lastAnswer);
|
|
35375
|
+
}
|
|
35376
|
+
answers[choiceIndex] = ___default["default"].extend({}, answers[choiceIndex], update);
|
|
35377
|
+
this.props.onChange({
|
|
35378
|
+
answers: answers
|
|
35379
|
+
});
|
|
35380
|
+
};
|
|
35381
|
+
addAnswer = () => {
|
|
35382
|
+
const lastAnswer = initAnswer(this.state.lastStatus);
|
|
35383
|
+
const answers = this.props.answers.concat(lastAnswer);
|
|
35384
|
+
this.props.onChange({
|
|
35385
|
+
answers: answers
|
|
35386
|
+
});
|
|
35387
|
+
};
|
|
35388
|
+
getSaveWarnings = () => {
|
|
35389
|
+
// Filter out all the empty answers
|
|
35390
|
+
const warnings = [];
|
|
35391
|
+
// TODO(emily): This doesn't actually work, because the value is either
|
|
35392
|
+
// null or undefined when undefined, probably.
|
|
35393
|
+
if (___default["default"].contains(___default["default"].pluck(this.props.answers, "value"), "")) {
|
|
35394
|
+
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'never'.
|
|
35395
|
+
warnings.push("One or more answers is empty");
|
|
35396
|
+
}
|
|
35397
|
+
this.props.answers.forEach((answer, i) => {
|
|
35398
|
+
const formatError = answer.strict && (!answer.answerForms || answer.answerForms.length === 0);
|
|
35399
|
+
if (formatError) {
|
|
35400
|
+
warnings.push(
|
|
35401
|
+
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'never'.
|
|
35402
|
+
`Answer ${i + 1} is set to string format ` + "matching, but no format was selected");
|
|
35403
|
+
}
|
|
35404
|
+
});
|
|
35405
|
+
return warnings;
|
|
35406
|
+
};
|
|
35407
|
+
serialize = () => {
|
|
35408
|
+
return perseus.EditorJsonify.serialize.call(this);
|
|
35409
|
+
};
|
|
35513
35410
|
render() {
|
|
35514
35411
|
const answers = this.props.answers;
|
|
35515
35412
|
const unsimplifiedAnswers = i => /*#__PURE__*/React__namespace.createElement("div", {
|
|
@@ -35581,7 +35478,7 @@ class NumericInputEditor extends React__namespace.Component {
|
|
|
35581
35478
|
}));
|
|
35582
35479
|
const labelText = /*#__PURE__*/React__namespace.createElement("div", {
|
|
35583
35480
|
className: "perseus-widget-row"
|
|
35584
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Aria label", /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
35481
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Aria label", /*#__PURE__*/React__namespace.createElement(TextInput$2, {
|
|
35585
35482
|
value: this.props.labelText,
|
|
35586
35483
|
onChange: this.change("labelText")
|
|
35587
35484
|
})), /*#__PURE__*/React__namespace.createElement(InfoTip$7, null, /*#__PURE__*/React__namespace.createElement("p", null, "Text to describe this input. This will be shown to users using screenreaders.")));
|
|
@@ -35731,106 +35628,6 @@ class NumericInputEditor extends React__namespace.Component {
|
|
|
35731
35628
|
className: "msg-title"
|
|
35732
35629
|
}, "Message shown to user on attempt"), generateInputAnswerEditors(), addAnswerButton, inputSize, rightAlign, coefficientCheck, labelText);
|
|
35733
35630
|
}
|
|
35734
|
-
change = (() => {
|
|
35735
|
-
var _this = this;
|
|
35736
|
-
return function () {
|
|
35737
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
35738
|
-
args[_key] = arguments[_key];
|
|
35739
|
-
}
|
|
35740
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
35741
|
-
};
|
|
35742
|
-
})();
|
|
35743
|
-
onToggleOptions = choiceIndex => {
|
|
35744
|
-
const showOptions = this.state.showOptions.slice();
|
|
35745
|
-
showOptions[choiceIndex] = !showOptions[choiceIndex];
|
|
35746
|
-
this.setState({
|
|
35747
|
-
showOptions: showOptions
|
|
35748
|
-
});
|
|
35749
|
-
};
|
|
35750
|
-
onTrashAnswer = choiceIndex => {
|
|
35751
|
-
if (choiceIndex >= 0 && choiceIndex < this.props.answers.length) {
|
|
35752
|
-
const answers = this.props.answers.slice(0);
|
|
35753
|
-
answers.splice(choiceIndex, 1);
|
|
35754
|
-
this.props.onChange({
|
|
35755
|
-
answers: answers
|
|
35756
|
-
});
|
|
35757
|
-
}
|
|
35758
|
-
};
|
|
35759
|
-
onSpace = (() => {
|
|
35760
|
-
var _this2 = this;
|
|
35761
|
-
return function (e, callback) {
|
|
35762
|
-
if (e.key === " ") {
|
|
35763
|
-
e.preventDefault(); // prevent page shifting
|
|
35764
|
-
for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
|
|
35765
|
-
args[_key2 - 2] = arguments[_key2];
|
|
35766
|
-
}
|
|
35767
|
-
callback.apply(_this2, args);
|
|
35768
|
-
}
|
|
35769
|
-
};
|
|
35770
|
-
})();
|
|
35771
|
-
onStatusChange = choiceIndex => {
|
|
35772
|
-
const statuses = ["wrong", "ungraded", "correct"];
|
|
35773
|
-
const answers = this.props.answers;
|
|
35774
|
-
const i = ___default["default"].indexOf(statuses, answers[choiceIndex].status);
|
|
35775
|
-
const newStatus = statuses[(i + 1) % statuses.length];
|
|
35776
|
-
this.updateAnswer(choiceIndex, {
|
|
35777
|
-
status: newStatus,
|
|
35778
|
-
simplify: newStatus === "correct" ? "required" : "accepted"
|
|
35779
|
-
});
|
|
35780
|
-
};
|
|
35781
|
-
updateAnswer = (choiceIndex, update) => {
|
|
35782
|
-
if (!___default["default"].isObject(update)) {
|
|
35783
|
-
return ___default["default"].partial((choiceIndex, key, value) => {
|
|
35784
|
-
const update = {};
|
|
35785
|
-
update[key] = value;
|
|
35786
|
-
this.updateAnswer(choiceIndex, update);
|
|
35787
|
-
}, choiceIndex, update);
|
|
35788
|
-
}
|
|
35789
|
-
let answers = [
|
|
35790
|
-
// Have to do this to remove the `readonly` state from the prop
|
|
35791
|
-
...this.props.answers];
|
|
35792
|
-
|
|
35793
|
-
// Don't bother to make a new answer box unless we are editing the last
|
|
35794
|
-
// one.
|
|
35795
|
-
// TODO(oliver): This might not be necessary anymore.
|
|
35796
|
-
if (choiceIndex === answers.length) {
|
|
35797
|
-
const lastAnswer = initAnswer(this.state.lastStatus);
|
|
35798
|
-
answers = answers.concat(lastAnswer);
|
|
35799
|
-
}
|
|
35800
|
-
answers[choiceIndex] = ___default["default"].extend({}, answers[choiceIndex], update);
|
|
35801
|
-
this.props.onChange({
|
|
35802
|
-
answers: answers
|
|
35803
|
-
});
|
|
35804
|
-
};
|
|
35805
|
-
addAnswer = () => {
|
|
35806
|
-
const lastAnswer = initAnswer(this.state.lastStatus);
|
|
35807
|
-
const answers = this.props.answers.concat(lastAnswer);
|
|
35808
|
-
this.props.onChange({
|
|
35809
|
-
answers: answers
|
|
35810
|
-
});
|
|
35811
|
-
};
|
|
35812
|
-
getSaveWarnings = () => {
|
|
35813
|
-
// Filter out all the empty answers
|
|
35814
|
-
const warnings = [];
|
|
35815
|
-
// TODO(emily): This doesn't actually work, because the value is either
|
|
35816
|
-
// null or undefined when undefined, probably.
|
|
35817
|
-
if (___default["default"].contains(___default["default"].pluck(this.props.answers, "value"), "")) {
|
|
35818
|
-
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'never'.
|
|
35819
|
-
warnings.push("One or more answers is empty");
|
|
35820
|
-
}
|
|
35821
|
-
this.props.answers.forEach((answer, i) => {
|
|
35822
|
-
const formatError = answer.strict && (!answer.answerForms || answer.answerForms.length === 0);
|
|
35823
|
-
if (formatError) {
|
|
35824
|
-
warnings.push(
|
|
35825
|
-
// @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'never'.
|
|
35826
|
-
`Answer ${i + 1} is set to string format ` + "matching, but no format was selected");
|
|
35827
|
-
}
|
|
35828
|
-
});
|
|
35829
|
-
return warnings;
|
|
35830
|
-
};
|
|
35831
|
-
serialize = () => {
|
|
35832
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
35833
|
-
};
|
|
35834
35631
|
}
|
|
35835
35632
|
|
|
35836
35633
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
@@ -35861,41 +35658,6 @@ class OrdererEditor extends React__namespace.Component {
|
|
|
35861
35658
|
height: NORMAL,
|
|
35862
35659
|
layout: HORIZONTAL$1
|
|
35863
35660
|
};
|
|
35864
|
-
render() {
|
|
35865
|
-
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
35866
|
-
className: "perseus-widget-orderer"
|
|
35867
|
-
}, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Place the cards in the correct order. The same card can be used more than once in the answer but will only be displayed once at the top of a stack of identical cards."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
|
|
35868
|
-
options: ___default["default"].pluck(this.props.correctOptions, "content")
|
|
35869
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
35870
|
-
,
|
|
35871
|
-
onChange: this.onOptionsChange.bind(this, "correctOptions"),
|
|
35872
|
-
layout: this.props.layout
|
|
35873
|
-
}), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Other cards:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create cards that are not part of the answer."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
|
|
35874
|
-
options: ___default["default"].pluck(this.props.otherOptions, "content")
|
|
35875
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
35876
|
-
,
|
|
35877
|
-
onChange: this.onOptionsChange.bind(this, "otherOptions"),
|
|
35878
|
-
layout: this.props.layout
|
|
35879
|
-
}), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, " ", "Layout:", " ", /*#__PURE__*/React__namespace.createElement("select", {
|
|
35880
|
-
value: this.props.layout
|
|
35881
|
-
// @ts-expect-error - TS2322 - Type '(arg1: ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'ChangeEventHandler<HTMLSelectElement>'.
|
|
35882
|
-
,
|
|
35883
|
-
onChange: this.onLayoutChange
|
|
35884
|
-
}, /*#__PURE__*/React__namespace.createElement("option", {
|
|
35885
|
-
value: HORIZONTAL$1
|
|
35886
|
-
}, "Horizontal"), /*#__PURE__*/React__namespace.createElement("option", {
|
|
35887
|
-
value: VERTICAL$1
|
|
35888
|
-
}, "Vertical"))), /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text (e.g. proofs)."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, " ", "Height:", " ", /*#__PURE__*/React__namespace.createElement("select", {
|
|
35889
|
-
value: this.props.height
|
|
35890
|
-
// @ts-expect-error - TS2322 - Type '(arg1: ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'ChangeEventHandler<HTMLSelectElement>'.
|
|
35891
|
-
,
|
|
35892
|
-
onChange: this.onHeightChange
|
|
35893
|
-
}, /*#__PURE__*/React__namespace.createElement("option", {
|
|
35894
|
-
value: NORMAL
|
|
35895
|
-
}, "Normal"), /*#__PURE__*/React__namespace.createElement("option", {
|
|
35896
|
-
value: AUTO
|
|
35897
|
-
}, "Automatic"))), /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use \"Normal\" for text, \"Automatic\" for images."))));
|
|
35898
|
-
}
|
|
35899
35661
|
onOptionsChange = (whichOptions, options, cb) => {
|
|
35900
35662
|
const props = {};
|
|
35901
35663
|
props[whichOptions] = ___default["default"].map(options, function (option) {
|
|
@@ -35942,6 +35704,41 @@ class OrdererEditor extends React__namespace.Component {
|
|
|
35942
35704
|
layout: this.props.layout
|
|
35943
35705
|
};
|
|
35944
35706
|
};
|
|
35707
|
+
render() {
|
|
35708
|
+
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
35709
|
+
className: "perseus-widget-orderer"
|
|
35710
|
+
}, /*#__PURE__*/React__namespace.createElement("div", null, " ", "Correct answer:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Place the cards in the correct order. The same card can be used more than once in the answer but will only be displayed once at the top of a stack of identical cards."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
|
|
35711
|
+
options: ___default["default"].pluck(this.props.correctOptions, "content")
|
|
35712
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
35713
|
+
,
|
|
35714
|
+
onChange: this.onOptionsChange.bind(this, "correctOptions"),
|
|
35715
|
+
layout: this.props.layout
|
|
35716
|
+
}), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Other cards:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create cards that are not part of the answer."))), /*#__PURE__*/React__namespace.createElement(TextListEditor$2, {
|
|
35717
|
+
options: ___default["default"].pluck(this.props.otherOptions, "content")
|
|
35718
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
35719
|
+
,
|
|
35720
|
+
onChange: this.onOptionsChange.bind(this, "otherOptions"),
|
|
35721
|
+
layout: this.props.layout
|
|
35722
|
+
}), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, " ", "Layout:", " ", /*#__PURE__*/React__namespace.createElement("select", {
|
|
35723
|
+
value: this.props.layout
|
|
35724
|
+
// @ts-expect-error - TS2322 - Type '(arg1: ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'ChangeEventHandler<HTMLSelectElement>'.
|
|
35725
|
+
,
|
|
35726
|
+
onChange: this.onLayoutChange
|
|
35727
|
+
}, /*#__PURE__*/React__namespace.createElement("option", {
|
|
35728
|
+
value: HORIZONTAL$1
|
|
35729
|
+
}, "Horizontal"), /*#__PURE__*/React__namespace.createElement("option", {
|
|
35730
|
+
value: VERTICAL$1
|
|
35731
|
+
}, "Vertical"))), /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text (e.g. proofs)."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, " ", "Height:", " ", /*#__PURE__*/React__namespace.createElement("select", {
|
|
35732
|
+
value: this.props.height
|
|
35733
|
+
// @ts-expect-error - TS2322 - Type '(arg1: ChangeEvent<HTMLInputElement>) => void' is not assignable to type 'ChangeEventHandler<HTMLSelectElement>'.
|
|
35734
|
+
,
|
|
35735
|
+
onChange: this.onHeightChange
|
|
35736
|
+
}, /*#__PURE__*/React__namespace.createElement("option", {
|
|
35737
|
+
value: NORMAL
|
|
35738
|
+
}, "Normal"), /*#__PURE__*/React__namespace.createElement("option", {
|
|
35739
|
+
value: AUTO
|
|
35740
|
+
}, "Automatic"))), /*#__PURE__*/React__namespace.createElement(InfoTip$6, null, /*#__PURE__*/React__namespace.createElement("p", null, "Use \"Normal\" for text, \"Automatic\" for images."))));
|
|
35741
|
+
}
|
|
35945
35742
|
}
|
|
35946
35743
|
|
|
35947
35744
|
const {
|
|
@@ -36035,7 +35832,7 @@ class PassageEditor extends React__namespace.Component {
|
|
|
36035
35832
|
const {
|
|
36036
35833
|
InfoTip: InfoTip$4,
|
|
36037
35834
|
NumberInput: NumberInput$3,
|
|
36038
|
-
TextInput: TextInput$
|
|
35835
|
+
TextInput: TextInput$1
|
|
36039
35836
|
} = perseus.components;
|
|
36040
35837
|
class PassageRefEditor extends React__namespace.Component {
|
|
36041
35838
|
static propTypes = {
|
|
@@ -36073,7 +35870,7 @@ class PassageRefEditor extends React__namespace.Component {
|
|
|
36073
35870
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
36074
35871
|
,
|
|
36075
35872
|
onChange: this.change("referenceNumber")
|
|
36076
|
-
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Summary Text: ", /*#__PURE__*/React__namespace.createElement(TextInput$
|
|
35873
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "Summary Text: ", /*#__PURE__*/React__namespace.createElement(TextInput$1, {
|
|
36077
35874
|
value: this.props.summaryText
|
|
36078
35875
|
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
36079
35876
|
,
|
|
@@ -36125,14 +35922,29 @@ class PhetSimulationEditor extends React__namespace.Component {
|
|
|
36125
35922
|
description: ""
|
|
36126
35923
|
};
|
|
36127
35924
|
static widgetName = "phet-simulation";
|
|
35925
|
+
serialize() {
|
|
35926
|
+
return {
|
|
35927
|
+
url: this.props.url,
|
|
35928
|
+
description: this.props.description
|
|
35929
|
+
};
|
|
35930
|
+
}
|
|
35931
|
+
getSaveWarnings = () => {
|
|
35932
|
+
if (perseus.makeSafeUrl(this.props.url, "en") === null) {
|
|
35933
|
+
return ["Please enter a URL from the PhET domain."];
|
|
35934
|
+
}
|
|
35935
|
+
return [];
|
|
35936
|
+
};
|
|
36128
35937
|
render() {
|
|
36129
35938
|
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
36130
35939
|
label: "URL",
|
|
36131
35940
|
value: this.props.url,
|
|
36132
35941
|
onChange: url => this.props.onChange({
|
|
36133
35942
|
url
|
|
36134
|
-
})
|
|
36135
|
-
|
|
35943
|
+
}),
|
|
35944
|
+
style: {
|
|
35945
|
+
marginBottom: wonderBlocksTokens.spacing.large_24
|
|
35946
|
+
}
|
|
35947
|
+
}), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.LabeledTextField, {
|
|
36136
35948
|
label: "Description",
|
|
36137
35949
|
value: this.props.description,
|
|
36138
35950
|
onChange: description => this.props.onChange({
|
|
@@ -36140,12 +35952,6 @@ class PhetSimulationEditor extends React__namespace.Component {
|
|
|
36140
35952
|
})
|
|
36141
35953
|
}));
|
|
36142
35954
|
}
|
|
36143
|
-
serialize() {
|
|
36144
|
-
return {
|
|
36145
|
-
url: this.props.url,
|
|
36146
|
-
description: this.props.description
|
|
36147
|
-
};
|
|
36148
|
-
}
|
|
36149
35955
|
}
|
|
36150
35956
|
|
|
36151
35957
|
const {
|
|
@@ -36463,7 +36269,7 @@ class PlotterEditor extends React__namespace.Component {
|
|
|
36463
36269
|
*/
|
|
36464
36270
|
const {
|
|
36465
36271
|
NumberInput: NumberInput$1,
|
|
36466
|
-
TextInput
|
|
36272
|
+
TextInput
|
|
36467
36273
|
} = perseus.components;
|
|
36468
36274
|
function validateOptions(height, programID) {
|
|
36469
36275
|
const errors = [];
|
|
@@ -36505,7 +36311,7 @@ class PythonProgramEditor extends React__namespace.Component {
|
|
|
36505
36311
|
return validateOptions(this.props.height, this.props.programID);
|
|
36506
36312
|
};
|
|
36507
36313
|
render() {
|
|
36508
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "User Program ID:", " ", /*#__PURE__*/React__namespace.createElement(TextInput
|
|
36314
|
+
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("label", null, "User Program ID:", " ", /*#__PURE__*/React__namespace.createElement(TextInput, {
|
|
36509
36315
|
value: this.props.programID,
|
|
36510
36316
|
onChange: this.change("programID"),
|
|
36511
36317
|
placeholder: "123"
|
|
@@ -36517,7 +36323,7 @@ class PythonProgramEditor extends React__namespace.Component {
|
|
|
36517
36323
|
}
|
|
36518
36324
|
}
|
|
36519
36325
|
|
|
36520
|
-
/* eslint-disable jsx-a11y/anchor-is-valid, react/forbid-prop-types
|
|
36326
|
+
/* eslint-disable jsx-a11y/anchor-is-valid, react/forbid-prop-types */
|
|
36521
36327
|
const {
|
|
36522
36328
|
InlineIcon
|
|
36523
36329
|
} = perseus.components;
|
|
@@ -36610,94 +36416,6 @@ class RadioEditor extends React__namespace.Component {
|
|
|
36610
36416
|
countChoices: false,
|
|
36611
36417
|
deselectEnabled: false
|
|
36612
36418
|
};
|
|
36613
|
-
render() {
|
|
36614
|
-
const numCorrect = ___default["default"].reduce(this.props.choices, function (memo, choice) {
|
|
36615
|
-
return choice.correct ? memo + 1 : memo;
|
|
36616
|
-
}, 0);
|
|
36617
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
36618
|
-
className: "perseus-widget-row"
|
|
36619
|
-
}, /*#__PURE__*/React__namespace.createElement("a", {
|
|
36620
|
-
href:
|
|
36621
|
-
// This is an editor component, not user-facing.
|
|
36622
|
-
"https://docs.google.com/document/d/1frZf7yrWVWb1n4tVjqlzqVUiv1pn4cZXbxgP62-JDBY/edit#heading=h.8ng1isya19nu",
|
|
36623
|
-
target: "_blank"
|
|
36624
|
-
}, "Multiple choice style guide"), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36625
|
-
className: "perseus-widget-left-col"
|
|
36626
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
36627
|
-
label: "Multiple selections",
|
|
36628
|
-
checked: this.props.multipleSelect,
|
|
36629
|
-
onChange: value => {
|
|
36630
|
-
this.onMultipleSelectChange({
|
|
36631
|
-
multipleSelect: value
|
|
36632
|
-
});
|
|
36633
|
-
}
|
|
36634
|
-
})), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36635
|
-
className: "perseus-widget-right-col"
|
|
36636
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
36637
|
-
label: "Randomize order",
|
|
36638
|
-
checked: this.props.randomize,
|
|
36639
|
-
onChange: value => {
|
|
36640
|
-
this.props.onChange({
|
|
36641
|
-
randomize: value
|
|
36642
|
-
});
|
|
36643
|
-
}
|
|
36644
|
-
})), this.props.multipleSelect && /*#__PURE__*/React__namespace.createElement("div", {
|
|
36645
|
-
className: "perseus-widget-left-col"
|
|
36646
|
-
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
36647
|
-
label: "Specify number correct",
|
|
36648
|
-
checked: this.props.countChoices,
|
|
36649
|
-
onChange: value => {
|
|
36650
|
-
this.onCountChoicesChange({
|
|
36651
|
-
countChoices: value
|
|
36652
|
-
});
|
|
36653
|
-
}
|
|
36654
|
-
}))), /*#__PURE__*/React__namespace.createElement(perseus.BaseRadio, {
|
|
36655
|
-
multipleSelect: this.props.multipleSelect,
|
|
36656
|
-
countChoices: this.props.countChoices,
|
|
36657
|
-
numCorrect: numCorrect,
|
|
36658
|
-
editMode: true,
|
|
36659
|
-
labelWrap: false,
|
|
36660
|
-
apiOptions: this.props.apiOptions,
|
|
36661
|
-
choices: this.props.choices.map((choice, i) => {
|
|
36662
|
-
return {
|
|
36663
|
-
content: /*#__PURE__*/React__namespace.createElement(ChoiceEditor, {
|
|
36664
|
-
ref: `choice-editor${i}`,
|
|
36665
|
-
apiOptions: this.props.apiOptions,
|
|
36666
|
-
choice: choice,
|
|
36667
|
-
onContentChange: newProps => {
|
|
36668
|
-
if ("content" in newProps) {
|
|
36669
|
-
this.onContentChange(i, newProps.content);
|
|
36670
|
-
}
|
|
36671
|
-
},
|
|
36672
|
-
onClueChange: newProps => {
|
|
36673
|
-
if ("content" in newProps) {
|
|
36674
|
-
this.onClueChange(i, newProps.content);
|
|
36675
|
-
}
|
|
36676
|
-
},
|
|
36677
|
-
onDelete: () => this.onDelete(i),
|
|
36678
|
-
showDelete: this.props.choices.length >= 2
|
|
36679
|
-
}),
|
|
36680
|
-
isNoneOfTheAbove: choice.isNoneOfTheAbove,
|
|
36681
|
-
checked: choice.correct
|
|
36682
|
-
};
|
|
36683
|
-
}, this),
|
|
36684
|
-
onChange: this.onChange
|
|
36685
|
-
}), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36686
|
-
className: "add-choice-container"
|
|
36687
|
-
}, /*#__PURE__*/React__namespace.createElement("a", {
|
|
36688
|
-
className: "simple-button orange",
|
|
36689
|
-
href: "#"
|
|
36690
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
36691
|
-
,
|
|
36692
|
-
onClick: this.addChoice.bind(this, false)
|
|
36693
|
-
}, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconPlus), " Add a choice", " "), !this.props.hasNoneOfTheAbove && /*#__PURE__*/React__namespace.createElement("a", {
|
|
36694
|
-
className: "simple-button",
|
|
36695
|
-
href: "#"
|
|
36696
|
-
// eslint-disable-next-line react/jsx-no-bind
|
|
36697
|
-
,
|
|
36698
|
-
onClick: this.addChoice.bind(this, true)
|
|
36699
|
-
}, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconPlus), " None of the above", " ")));
|
|
36700
|
-
}
|
|
36701
36419
|
change = (() => {
|
|
36702
36420
|
var _this = this;
|
|
36703
36421
|
return function () {
|
|
@@ -36816,64 +36534,94 @@ class RadioEditor extends React__namespace.Component {
|
|
|
36816
36534
|
serialize = () => {
|
|
36817
36535
|
return ___default["default"].pick(this.props, "choices", "randomize", "multipleSelect", "countChoices", "displayCount", "hasNoneOfTheAbove", "deselectEnabled");
|
|
36818
36536
|
};
|
|
36819
|
-
}
|
|
36820
|
-
|
|
36821
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
36822
|
-
class TextArea extends React__namespace.Component {
|
|
36823
|
-
render() {
|
|
36824
|
-
return /*#__PURE__*/React__namespace.createElement("textarea", {
|
|
36825
|
-
// eslint-disable-next-line react/no-string-refs
|
|
36826
|
-
ref: "input",
|
|
36827
|
-
value: this.props.value || "",
|
|
36828
|
-
onChange: this.changeValue
|
|
36829
|
-
});
|
|
36830
|
-
}
|
|
36831
|
-
focus = () => {
|
|
36832
|
-
// eslint-disable-next-line react/no-string-refs
|
|
36833
|
-
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
|
|
36834
|
-
this.refs.input.focus();
|
|
36835
|
-
return true;
|
|
36836
|
-
};
|
|
36837
|
-
changeValue = e => {
|
|
36838
|
-
// Translating from the js event e to the value
|
|
36839
|
-
// of the textbox to send to onChange
|
|
36840
|
-
this.props.onChange(e.target.value);
|
|
36841
|
-
};
|
|
36842
|
-
}
|
|
36843
|
-
class SimpleMarkdownTesterEditor extends React__namespace.Component {
|
|
36844
|
-
static propTypes = {
|
|
36845
|
-
...perseus.Changeable.propTypes
|
|
36846
|
-
};
|
|
36847
|
-
static widgetName = "simple-markdown-tester";
|
|
36848
|
-
static defaultProps = {
|
|
36849
|
-
value: ""
|
|
36850
|
-
};
|
|
36851
|
-
input = /*#__PURE__*/React__namespace.createRef();
|
|
36852
36537
|
render() {
|
|
36853
|
-
|
|
36854
|
-
|
|
36855
|
-
|
|
36538
|
+
const numCorrect = ___default["default"].reduce(this.props.choices, function (memo, choice) {
|
|
36539
|
+
return choice.correct ? memo + 1 : memo;
|
|
36540
|
+
}, 0);
|
|
36541
|
+
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
36542
|
+
className: "perseus-widget-row"
|
|
36543
|
+
}, /*#__PURE__*/React__namespace.createElement("a", {
|
|
36544
|
+
href:
|
|
36545
|
+
// This is an editor component, not user-facing.
|
|
36546
|
+
"https://docs.google.com/document/d/1frZf7yrWVWb1n4tVjqlzqVUiv1pn4cZXbxgP62-JDBY/edit#heading=h.8ng1isya19nu",
|
|
36547
|
+
target: "_blank"
|
|
36548
|
+
}, "Multiple choice style guide"), /*#__PURE__*/React__namespace.createElement("br", null), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36549
|
+
className: "perseus-widget-left-col"
|
|
36550
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
36551
|
+
label: "Multiple selections",
|
|
36552
|
+
checked: this.props.multipleSelect,
|
|
36553
|
+
onChange: value => {
|
|
36554
|
+
this.onMultipleSelectChange({
|
|
36555
|
+
multipleSelect: value
|
|
36556
|
+
});
|
|
36557
|
+
}
|
|
36558
|
+
})), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36559
|
+
className: "perseus-widget-right-col"
|
|
36560
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
36561
|
+
label: "Randomize order",
|
|
36562
|
+
checked: this.props.randomize,
|
|
36563
|
+
onChange: value => {
|
|
36564
|
+
this.props.onChange({
|
|
36565
|
+
randomize: value
|
|
36566
|
+
});
|
|
36567
|
+
}
|
|
36568
|
+
})), this.props.multipleSelect && /*#__PURE__*/React__namespace.createElement("div", {
|
|
36569
|
+
className: "perseus-widget-left-col"
|
|
36570
|
+
}, /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.Checkbox, {
|
|
36571
|
+
label: "Specify number correct",
|
|
36572
|
+
checked: this.props.countChoices,
|
|
36573
|
+
onChange: value => {
|
|
36574
|
+
this.onCountChoicesChange({
|
|
36575
|
+
countChoices: value
|
|
36576
|
+
});
|
|
36577
|
+
}
|
|
36578
|
+
}))), /*#__PURE__*/React__namespace.createElement(perseus.BaseRadio, {
|
|
36579
|
+
multipleSelect: this.props.multipleSelect,
|
|
36580
|
+
countChoices: this.props.countChoices,
|
|
36581
|
+
numCorrect: numCorrect,
|
|
36582
|
+
editMode: true,
|
|
36583
|
+
labelWrap: false,
|
|
36584
|
+
apiOptions: this.props.apiOptions,
|
|
36585
|
+
choices: this.props.choices.map((choice, i) => {
|
|
36586
|
+
return {
|
|
36587
|
+
content: /*#__PURE__*/React__namespace.createElement(ChoiceEditor, {
|
|
36588
|
+
ref: `choice-editor${i}`,
|
|
36589
|
+
apiOptions: this.props.apiOptions,
|
|
36590
|
+
choice: choice,
|
|
36591
|
+
onContentChange: newProps => {
|
|
36592
|
+
if ("content" in newProps) {
|
|
36593
|
+
this.onContentChange(i, newProps.content);
|
|
36594
|
+
}
|
|
36595
|
+
},
|
|
36596
|
+
onClueChange: newProps => {
|
|
36597
|
+
if ("content" in newProps) {
|
|
36598
|
+
this.onClueChange(i, newProps.content);
|
|
36599
|
+
}
|
|
36600
|
+
},
|
|
36601
|
+
onDelete: () => this.onDelete(i),
|
|
36602
|
+
showDelete: this.props.choices.length >= 2
|
|
36603
|
+
}),
|
|
36604
|
+
isNoneOfTheAbove: choice.isNoneOfTheAbove,
|
|
36605
|
+
checked: choice.correct
|
|
36606
|
+
};
|
|
36607
|
+
}, this),
|
|
36608
|
+
onChange: this.onChange
|
|
36609
|
+
}), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36610
|
+
className: "add-choice-container"
|
|
36611
|
+
}, /*#__PURE__*/React__namespace.createElement("a", {
|
|
36612
|
+
className: "simple-button orange",
|
|
36613
|
+
href: "#"
|
|
36614
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
36856
36615
|
,
|
|
36857
|
-
|
|
36858
|
-
|
|
36859
|
-
|
|
36616
|
+
onClick: this.addChoice.bind(this, false)
|
|
36617
|
+
}, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconPlus), " Add a choice", " "), !this.props.hasNoneOfTheAbove && /*#__PURE__*/React__namespace.createElement("a", {
|
|
36618
|
+
className: "simple-button",
|
|
36619
|
+
href: "#"
|
|
36620
|
+
// eslint-disable-next-line react/jsx-no-bind
|
|
36621
|
+
,
|
|
36622
|
+
onClick: this.addChoice.bind(this, true)
|
|
36623
|
+
}, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconPlus), " None of the above", " ")));
|
|
36860
36624
|
}
|
|
36861
|
-
change = (() => {
|
|
36862
|
-
var _this = this;
|
|
36863
|
-
return function () {
|
|
36864
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
36865
|
-
args[_key] = arguments[_key];
|
|
36866
|
-
}
|
|
36867
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
36868
|
-
};
|
|
36869
|
-
})();
|
|
36870
|
-
focus = () => {
|
|
36871
|
-
this.input.current?.focus();
|
|
36872
|
-
return true;
|
|
36873
|
-
};
|
|
36874
|
-
serialize = () => {
|
|
36875
|
-
return perseus.EditorJsonify.serialize.call(this);
|
|
36876
|
-
};
|
|
36877
36625
|
}
|
|
36878
36626
|
|
|
36879
36627
|
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
@@ -36936,7 +36684,6 @@ class SorterEditor extends React__namespace.Component {
|
|
|
36936
36684
|
}
|
|
36937
36685
|
}
|
|
36938
36686
|
|
|
36939
|
-
/* eslint-disable react/sort-comp */
|
|
36940
36687
|
const {
|
|
36941
36688
|
InfoTip: InfoTip$1,
|
|
36942
36689
|
NumberInput
|
|
@@ -36967,41 +36714,6 @@ class TableEditor extends React__namespace.Component {
|
|
|
36967
36714
|
focus = () => {
|
|
36968
36715
|
this.numberOfColumns.current?.focus();
|
|
36969
36716
|
};
|
|
36970
|
-
render() {
|
|
36971
|
-
const tableProps = ___default["default"].pick(this.props, "headers", "answers", "onChange", "apiOptions");
|
|
36972
|
-
___default["default"].extend(tableProps, {
|
|
36973
|
-
editableHeaders: true,
|
|
36974
|
-
Editor,
|
|
36975
|
-
onFocus: () => {},
|
|
36976
|
-
onBlur: () => {},
|
|
36977
|
-
trackInteraction: () => {}
|
|
36978
|
-
});
|
|
36979
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
36980
|
-
className: "perseus-widget-row"
|
|
36981
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Number of columns:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput, {
|
|
36982
|
-
ref: this.numberOfColumns,
|
|
36983
|
-
value: this.props.columns,
|
|
36984
|
-
onChange: val => {
|
|
36985
|
-
if (val) {
|
|
36986
|
-
this.onSizeInput(this.props.rows, val);
|
|
36987
|
-
}
|
|
36988
|
-
},
|
|
36989
|
-
useArrowKeys: true
|
|
36990
|
-
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36991
|
-
className: "perseus-widget-row"
|
|
36992
|
-
}, /*#__PURE__*/React__namespace.createElement("label", null, "Number of rows:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput
|
|
36993
|
-
// eslint-disable-next-line react/no-string-refs
|
|
36994
|
-
, {
|
|
36995
|
-
ref: "numberOfRows",
|
|
36996
|
-
value: this.props.rows,
|
|
36997
|
-
onChange: val => {
|
|
36998
|
-
if (val) {
|
|
36999
|
-
this.onSizeInput(val, this.props.columns);
|
|
37000
|
-
}
|
|
37001
|
-
},
|
|
37002
|
-
useArrowKeys: true
|
|
37003
|
-
}))), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Table of answers:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$1, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(Table, tableProps)));
|
|
37004
|
-
}
|
|
37005
36717
|
onSizeInput = (numRawRows, numRawColumns) => {
|
|
37006
36718
|
let rows = +numRawRows || 0;
|
|
37007
36719
|
let columns = +numRawColumns || 0;
|
|
@@ -37044,6 +36756,41 @@ class TableEditor extends React__namespace.Component {
|
|
|
37044
36756
|
answers: ___default["default"].map(this.props.answers, ___default["default"].clone)
|
|
37045
36757
|
});
|
|
37046
36758
|
};
|
|
36759
|
+
render() {
|
|
36760
|
+
const tableProps = ___default["default"].pick(this.props, "headers", "answers", "onChange", "apiOptions");
|
|
36761
|
+
___default["default"].extend(tableProps, {
|
|
36762
|
+
editableHeaders: true,
|
|
36763
|
+
Editor,
|
|
36764
|
+
onFocus: () => {},
|
|
36765
|
+
onBlur: () => {},
|
|
36766
|
+
trackInteraction: () => {}
|
|
36767
|
+
});
|
|
36768
|
+
return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
|
|
36769
|
+
className: "perseus-widget-row"
|
|
36770
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Number of columns:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput, {
|
|
36771
|
+
ref: this.numberOfColumns,
|
|
36772
|
+
value: this.props.columns,
|
|
36773
|
+
onChange: val => {
|
|
36774
|
+
if (val) {
|
|
36775
|
+
this.onSizeInput(this.props.rows, val);
|
|
36776
|
+
}
|
|
36777
|
+
},
|
|
36778
|
+
useArrowKeys: true
|
|
36779
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", {
|
|
36780
|
+
className: "perseus-widget-row"
|
|
36781
|
+
}, /*#__PURE__*/React__namespace.createElement("label", null, "Number of rows:", " ", /*#__PURE__*/React__namespace.createElement(NumberInput
|
|
36782
|
+
// eslint-disable-next-line react/no-string-refs
|
|
36783
|
+
, {
|
|
36784
|
+
ref: "numberOfRows",
|
|
36785
|
+
value: this.props.rows,
|
|
36786
|
+
onChange: val => {
|
|
36787
|
+
if (val) {
|
|
36788
|
+
this.onSizeInput(val, this.props.columns);
|
|
36789
|
+
}
|
|
36790
|
+
},
|
|
36791
|
+
useArrowKeys: true
|
|
36792
|
+
}))), /*#__PURE__*/React__namespace.createElement("div", null, " ", "Table of answers:", " ", /*#__PURE__*/React__namespace.createElement(InfoTip$1, null, /*#__PURE__*/React__namespace.createElement("p", null, "The student has to fill out all cells in the table. For partially filled tables create a table using the template, and insert text input boxes as desired."))), /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(Table, tableProps)));
|
|
36793
|
+
}
|
|
37047
36794
|
}
|
|
37048
36795
|
|
|
37049
36796
|
const {
|
|
@@ -37103,230 +36850,18 @@ class VideoEditor extends React__namespace.Component {
|
|
|
37103
36850
|
}
|
|
37104
36851
|
}
|
|
37105
36852
|
|
|
37106
|
-
var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor,
|
|
37107
|
-
|
|
37108
|
-
/* eslint-disable @khanacademy/ts-no-error-suppressions */
|
|
37109
|
-
class TextInput extends React__namespace.Component {
|
|
37110
|
-
input = /*#__PURE__*/React__namespace.createRef();
|
|
37111
|
-
render() {
|
|
37112
|
-
return /*#__PURE__*/React__namespace.createElement("input", {
|
|
37113
|
-
ref: this.input,
|
|
37114
|
-
value: this.props.value || "",
|
|
37115
|
-
onChange: this.changeValue
|
|
37116
|
-
});
|
|
37117
|
-
}
|
|
37118
|
-
focus = () => {
|
|
37119
|
-
this.input.current?.focus();
|
|
37120
|
-
return true;
|
|
37121
|
-
};
|
|
37122
|
-
changeValue = e => {
|
|
37123
|
-
// Translating from the js event e to the value
|
|
37124
|
-
// of the textbox to send to onChange
|
|
37125
|
-
this.props.onChange(e.target.value);
|
|
37126
|
-
};
|
|
37127
|
-
}
|
|
37128
|
-
/**
|
|
37129
|
-
* This is the widget's renderer. It shows up in the right column
|
|
37130
|
-
* in the demo, and is what is visible to users, and where
|
|
37131
|
-
* users enter their answers.
|
|
37132
|
-
*/
|
|
37133
|
-
class ExampleWidget extends React__namespace.Component {
|
|
37134
|
-
static defaultProps = {
|
|
37135
|
-
value: ""
|
|
37136
|
-
};
|
|
37137
|
-
input = /*#__PURE__*/React__namespace.createRef();
|
|
37138
|
-
|
|
37139
|
-
/**
|
|
37140
|
-
* This is the widget's grading function. simpleValidate generally
|
|
37141
|
-
* defers to this function.
|
|
37142
|
-
*
|
|
37143
|
-
* value is usually the result of getUserInput on the widget
|
|
37144
|
-
* rubric is the result of calling serialize() on the editor
|
|
37145
|
-
*/
|
|
37146
|
-
static validate(value, rubric) {
|
|
37147
|
-
if (value === "") {
|
|
37148
|
-
return {
|
|
37149
|
-
type: "invalid",
|
|
37150
|
-
message: "It looks like you haven't answered all of the " + "question yet."
|
|
37151
|
-
};
|
|
37152
|
-
}
|
|
37153
|
-
if (value === rubric.correct) {
|
|
37154
|
-
return {
|
|
37155
|
-
type: "points",
|
|
37156
|
-
earned: 1,
|
|
37157
|
-
total: 1,
|
|
37158
|
-
message: null
|
|
37159
|
-
};
|
|
37160
|
-
}
|
|
37161
|
-
return {
|
|
37162
|
-
type: "points",
|
|
37163
|
-
earned: 0,
|
|
37164
|
-
total: 1,
|
|
37165
|
-
message: null
|
|
37166
|
-
};
|
|
37167
|
-
}
|
|
37168
|
-
|
|
37169
|
-
/**
|
|
37170
|
-
* Tell our parent to update our props.
|
|
37171
|
-
*/
|
|
37172
|
-
change = (() => {
|
|
37173
|
-
var _this = this;
|
|
37174
|
-
return function () {
|
|
37175
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
37176
|
-
args[_key] = arguments[_key];
|
|
37177
|
-
}
|
|
37178
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
37179
|
-
};
|
|
37180
|
-
})();
|
|
37181
|
-
render() {
|
|
37182
|
-
return /*#__PURE__*/React__namespace.createElement(TextInput, {
|
|
37183
|
-
ref: this.input,
|
|
37184
|
-
value: this.props.value
|
|
37185
|
-
// @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
|
|
37186
|
-
,
|
|
37187
|
-
onChange: this.change("value")
|
|
37188
|
-
});
|
|
37189
|
-
}
|
|
37190
|
-
getUserInput = () => {
|
|
37191
|
-
return this.props.value;
|
|
37192
|
-
};
|
|
37193
|
-
|
|
37194
|
-
/**
|
|
37195
|
-
* Widgets that are focusable should add a focus method that returns
|
|
37196
|
-
* true if focusing succeeded. The first such widget found will be
|
|
37197
|
-
* focused on page load.
|
|
37198
|
-
*/
|
|
37199
|
-
focus = () => {
|
|
37200
|
-
this.input.current?.focus();
|
|
37201
|
-
return true;
|
|
37202
|
-
};
|
|
37203
|
-
|
|
37204
|
-
/**
|
|
37205
|
-
* simpleValidate is called for grading. Rubric is the result of calling
|
|
37206
|
-
* getUserInput() on the editor that created this widget.
|
|
37207
|
-
*
|
|
37208
|
-
* Should return an object representing the grading result, such as
|
|
37209
|
-
* {
|
|
37210
|
-
* type: "points",
|
|
37211
|
-
* earned: 1,
|
|
37212
|
-
* total: 1,
|
|
37213
|
-
* message: null
|
|
37214
|
-
* }
|
|
37215
|
-
*/
|
|
37216
|
-
simpleValidate = rubric => {
|
|
37217
|
-
return ExampleWidget.validate(this.getUserInput(), rubric);
|
|
37218
|
-
};
|
|
37219
|
-
}
|
|
37220
|
-
|
|
37221
|
-
/**
|
|
37222
|
-
* For this widget to work, we must import this file in src/all-widgets.js
|
|
37223
|
-
*/
|
|
37224
|
-
var ExampleWidget$1 = {
|
|
37225
|
-
name: "example-widget",
|
|
37226
|
-
displayName: "Example Widget",
|
|
37227
|
-
// Tell the renderer what type of `display:` style we would like
|
|
37228
|
-
// for the component wrapping this one.
|
|
37229
|
-
defaultAlignment: "inline-block",
|
|
37230
|
-
hidden: true,
|
|
37231
|
-
// Hides this widget from the Perseus.Editor widget select
|
|
37232
|
-
widget: ExampleWidget
|
|
37233
|
-
};
|
|
37234
|
-
|
|
37235
|
-
/* eslint-disable react/sort-comp */
|
|
37236
|
-
const mdParse = perseus.PerseusMarkdown.parse;
|
|
37237
|
-
const mdOutput = perseus.PerseusMarkdown.basicOutput;
|
|
37238
|
-
class SimpleMarkdownTester extends React__namespace.Component {
|
|
37239
|
-
static defaultProps = {
|
|
37240
|
-
value: ""
|
|
37241
|
-
};
|
|
37242
|
-
|
|
37243
|
-
/**
|
|
37244
|
-
* This is the widget's grading function.
|
|
37245
|
-
*
|
|
37246
|
-
* simpleValidate generally defers to this function
|
|
37247
|
-
*
|
|
37248
|
-
* state is usually the result of toJSON on the widget
|
|
37249
|
-
* rubric is the result of calling toJSON() on the editor
|
|
37250
|
-
*/
|
|
37251
|
-
static validate(state, rubric) {
|
|
37252
|
-
return {
|
|
37253
|
-
type: "points",
|
|
37254
|
-
earned: 0,
|
|
37255
|
-
total: 0,
|
|
37256
|
-
message: null
|
|
37257
|
-
};
|
|
37258
|
-
}
|
|
37259
|
-
change = (() => {
|
|
37260
|
-
var _this = this;
|
|
37261
|
-
return function () {
|
|
37262
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
37263
|
-
args[_key] = arguments[_key];
|
|
37264
|
-
}
|
|
37265
|
-
return perseus.Changeable.change.apply(_this, args);
|
|
37266
|
-
};
|
|
37267
|
-
})();
|
|
37268
|
-
toJSON = () => {
|
|
37269
|
-
return {};
|
|
37270
|
-
};
|
|
37271
|
-
render() {
|
|
37272
|
-
// @ts-expect-error - TS2554 - Expected 2 arguments, but got 1.
|
|
37273
|
-
const parsed = mdParse(this.props.value);
|
|
37274
|
-
const output = mdOutput(parsed);
|
|
37275
|
-
return /*#__PURE__*/React__namespace.createElement("div", null, output);
|
|
37276
|
-
}
|
|
37277
|
-
|
|
37278
|
-
/**
|
|
37279
|
-
* Widgets that are focusable should add a focus method that returns
|
|
37280
|
-
* true if focusing succeeded. The first such widget found will be
|
|
37281
|
-
* focused on page load.
|
|
37282
|
-
*/
|
|
37283
|
-
focus = () => {
|
|
37284
|
-
// eslint-disable-next-line react/no-string-refs
|
|
37285
|
-
// @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
|
|
37286
|
-
this.refs.input.focus();
|
|
37287
|
-
return true;
|
|
37288
|
-
};
|
|
37289
|
-
|
|
37290
|
-
/**
|
|
37291
|
-
* simpleValidate is called for grading. Rubric is the result of calling
|
|
37292
|
-
* toJSON() on the editor that created this widget.
|
|
37293
|
-
*
|
|
37294
|
-
* Should return an object representing the grading result, such as
|
|
37295
|
-
* {
|
|
37296
|
-
* type: "points",
|
|
37297
|
-
* earned: 1,
|
|
37298
|
-
* total: 1,
|
|
37299
|
-
* message: null
|
|
37300
|
-
* }
|
|
37301
|
-
*/
|
|
37302
|
-
simpleValidate = rubric => {
|
|
37303
|
-
return SimpleMarkdownTester.validate(this.toJSON(), rubric);
|
|
37304
|
-
};
|
|
37305
|
-
}
|
|
37306
|
-
|
|
37307
|
-
/**
|
|
37308
|
-
* For this widget to work, we must import this file in src/all-widgets.js
|
|
37309
|
-
*/
|
|
37310
|
-
var SimpleMarkdownTester$1 = {
|
|
37311
|
-
name: "simple-markdown-tester",
|
|
37312
|
-
displayName: "Simple Markdown Tester",
|
|
37313
|
-
hidden: true,
|
|
37314
|
-
// Hides this widget from the Perseus.Editor widget select
|
|
37315
|
-
widget: SimpleMarkdownTester,
|
|
37316
|
-
transform: ___default["default"].identity
|
|
37317
|
-
};
|
|
37318
|
-
|
|
37319
|
-
var testingWidgets = [ExampleGraphieWidget$2, ExampleWidget$1, SimpleMarkdownTester$1];
|
|
37320
|
-
|
|
37321
|
-
var AllWidgets = [...perseus.widgets, ...testingWidgets];
|
|
36853
|
+
var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExplanationEditor, ExpressionEditor, GradedGroupEditor, GradedGroupSetEditor, GrapherEditor, GroupEditor, IframeEditor, ImageEditor, InputNumberEditor, InteractionEditor, InteractiveGraphEditor, LabelImageEditor, MatcherEditor, MatrixEditor, MeasurerEditor, MoleculeWidgetEditor, NumberLineEditor, NumericInputEditor, OrdererEditor, PassageEditor, PassageRefEditor, PassageRefTargetEditor, PhetSimulationEditor, PlotterEditor, PythonProgramEditor, SorterEditor, TableEditor, VideoEditor, RadioEditor, DeprecatedStandinEditor];
|
|
37322
36854
|
|
|
37323
36855
|
perseus.Widgets.registerEditors(AllEditors);
|
|
37324
|
-
perseus.Widgets.registerWidgets(
|
|
36856
|
+
perseus.Widgets.registerWidgets(perseus.widgets);
|
|
37325
36857
|
perseus.Widgets.replaceDeprecatedWidgets();
|
|
37326
36858
|
perseus.Widgets.replaceDeprecatedEditors();
|
|
37327
36859
|
|
|
36860
|
+
Object.defineProperty(exports, 'widgets', {
|
|
36861
|
+
enumerable: true,
|
|
36862
|
+
get: function () { return perseus.widgets; }
|
|
36863
|
+
});
|
|
37328
36864
|
exports.AllEditors = AllEditors;
|
|
37329
|
-
exports.AllWidgets = AllWidgets;
|
|
37330
36865
|
exports.ArticleDiff = ArticleDiff;
|
|
37331
36866
|
exports.ArticleEditor = ArticleEditor;
|
|
37332
36867
|
exports.DeviceFramer = DeviceFramer;
|