@khanacademy/perseus-editor 13.1.0 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/all-editors.d.ts +1 -4
  2. package/dist/components/hover-behavior.d.ts +2 -2
  3. package/dist/components/widget-editor.d.ts +1 -1
  4. package/dist/es/index.js +188 -611
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.js +748 -1197
  8. package/dist/index.js.map +1 -1
  9. package/dist/widgets/expression-editor.d.ts +1 -1
  10. package/dist/widgets/graded-group-editor.d.ts +1 -1
  11. package/dist/widgets/grapher-editor.d.ts +1 -1
  12. package/dist/widgets/group-editor.d.ts +1 -1
  13. package/dist/widgets/iframe-editor.d.ts +1 -1
  14. package/dist/widgets/image-editor.d.ts +2 -2
  15. package/dist/widgets/input-number-editor.d.ts +1 -1
  16. package/dist/widgets/interactive-graph-editor.d.ts +6 -22
  17. package/dist/widgets/matcher-editor.d.ts +1 -1
  18. package/dist/widgets/matrix-editor.d.ts +1 -1
  19. package/dist/widgets/measurer-editor.d.ts +1 -1
  20. package/dist/widgets/numeric-input-editor.d.ts +1 -1
  21. package/dist/widgets/orderer-editor.d.ts +1 -1
  22. package/dist/widgets/phet-simulation-editor.d.ts +2 -1
  23. package/dist/widgets/radio/editor.d.ts +1 -1
  24. package/dist/widgets/table-editor.d.ts +1 -1
  25. package/package.json +2 -2
  26. package/dist/all-widgets.d.ts +0 -22
  27. package/dist/testing-widgets.d.ts +0 -22
  28. package/dist/widgets/example-graphie-widget-editor.d.ts +0 -18
  29. package/dist/widgets/example-graphie-widget.d.ts +0 -61
  30. package/dist/widgets/example-widget-editor.d.ts +0 -20
  31. package/dist/widgets/example-widget.d.ts +0 -89
  32. package/dist/widgets/simple-markdown-tester-editor.d.ts +0 -21
  33. package/dist/widgets/simple-markdown-tester.d.ts +0 -54
package/dist/es/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { addLibraryVersionToPerseusDebug, PerseusError, Errors } from '@khanacademy/perseus-core';
2
- import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, ItemExtras, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, PerseusI18nContext, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, getAngleCoords, getPolygonCoords, getPointCoords, getQuadraticCoords, getSinusoidCoords, getCircleCoords, getLinearSystemCoords, getSegmentCoords, getLineCoords, lockedFigureColors, lockedFigureFillStyles, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, widgets } from '@khanacademy/perseus';
2
+ import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, ItemExtras, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, PerseusI18nContext, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, getAngleCoords, getPolygonCoords, getPointCoords, getQuadraticCoords, getSinusoidCoords, getCircleCoords, getLinearSystemCoords, getSegmentCoords, getLineCoords, lockedFigureColors, lockedFigureFillStyles, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, makeSafeUrl, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, widgets } from '@khanacademy/perseus';
3
+ export { widgets } from '@khanacademy/perseus';
3
4
  import * as React from 'react';
4
5
  import { useRef, useEffect, useState } from 'react';
5
6
  import _ from 'underscore';
@@ -16,12 +17,12 @@ import caretRight from '@phosphor-icons/core/bold/caret-right-bold.svg';
16
17
  import classNames from 'classnames';
17
18
  import { Checkbox as Checkbox$1, LabeledTextField, TextField } from '@khanacademy/wonder-blocks-form';
18
19
  import ReactDOM from 'react-dom';
19
- import { point, vector, number } from '@khanacademy/kmath';
20
20
  import * as KAS from '@khanacademy/kas';
21
21
  import Button from '@khanacademy/wonder-blocks-button';
22
22
  import { HeadingSmall, HeadingXSmall, LabelSmall, LabelLarge, LabelMedium, LabelXSmall, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
23
23
  import { isTruthy, UnreachableCaseError } from '@khanacademy/wonder-stuff-core';
24
24
  import { useMathInputI18n, createMathField } from '@khanacademy/math-input';
25
+ import { vector, number } from '@khanacademy/kmath';
25
26
  import { ActionMenu, ActionItem, SingleSelect, OptionItem } from '@khanacademy/wonder-blocks-dropdown';
26
27
  import { AccordionSection } from '@khanacademy/wonder-blocks-accordion';
27
28
  import IconButton from '@khanacademy/wonder-blocks-icon-button';
@@ -41,7 +42,7 @@ import arrowCounterClockwise from '@phosphor-icons/core/bold/arrow-counter-clock
41
42
 
42
43
  // This file is processed by a Rollup plugin (replace) to inject the production
43
44
  const libName = "@khanacademy/perseus-editor";
44
- const libVersion = "13.1.0";
45
+ const libVersion = "14.0.0";
45
46
  addLibraryVersionToPerseusDebug(libName, libVersion);
46
47
 
47
48
  function _extends() {
@@ -128,16 +129,6 @@ const JsonEditor = createReactClass({
128
129
  this.setState(this.getInitialState());
129
130
  }
130
131
  },
131
- render: function () {
132
- const classes = "perseus-json-editor " + (this.state.valid ? "valid" : "invalid");
133
- return /*#__PURE__*/React.createElement("textarea", {
134
- className: classes,
135
- value: this.state.currentValue,
136
- onChange: this.handleChange,
137
- onKeyDown: this.handleKeyDown,
138
- onBlur: this.handleBlur
139
- });
140
- },
141
132
  handleKeyDown: function (e) {
142
133
  // This handler allows the tab character to be entered by pressing
143
134
  // tab, instead of jumping to the next (non-existant) field
@@ -204,6 +195,16 @@ const JsonEditor = createReactClass({
204
195
  valid: true
205
196
  });
206
197
  }
198
+ },
199
+ render: function () {
200
+ const classes = "perseus-json-editor " + (this.state.valid ? "valid" : "invalid");
201
+ return /*#__PURE__*/React.createElement("textarea", {
202
+ className: classes,
203
+ value: this.state.currentValue,
204
+ onChange: this.handleChange,
205
+ onKeyDown: this.handleKeyDown,
206
+ onBlur: this.handleBlur
207
+ });
207
208
  }
208
209
  });
209
210
 
@@ -25551,7 +25552,7 @@ const styles$N = StyleSheet.create({
25551
25552
  }
25552
25553
  });
25553
25554
 
25554
- /* eslint-disable react/no-unsafe, react/sort-comp */
25555
+ /* eslint-disable react/no-unsafe */
25555
25556
 
25556
25557
  /* Renders an EditorPage (or an ArticleEditor) as a non-controlled component.
25557
25558
  *
@@ -25570,10 +25571,6 @@ const StatefulEditorPage = createReactClass({
25570
25571
  componentClass: EditorPage
25571
25572
  };
25572
25573
  },
25573
- render: function () {
25574
- const Component = this.props.componentClass;
25575
- return /*#__PURE__*/React.createElement(Component, this.state);
25576
- },
25577
25574
  getInitialState: function () {
25578
25575
  return _({}).extend(_.omit(this.props, "componentClass"), {
25579
25576
  onChange: this.handleChange,
@@ -25583,9 +25580,6 @@ const StatefulEditorPage = createReactClass({
25583
25580
  componentDidMount: function () {
25584
25581
  this._isMounted = true;
25585
25582
  },
25586
- componentWillUnmount: function () {
25587
- this._isMounted = false;
25588
- },
25589
25583
  // getInitialState isn't called if the react component is re-rendered
25590
25584
  // in-place on the dom, in which case this is called instead, so we
25591
25585
  // need to update the state here.
@@ -25593,6 +25587,9 @@ const StatefulEditorPage = createReactClass({
25593
25587
  UNSAFE_componentWillReceiveProps: function (nextProps) {
25594
25588
  this.setState(_(nextProps).pick("apiOptions", "imageUploader", "developerMode", "problemNum", "previewDevice", "frameSource"));
25595
25589
  },
25590
+ componentWillUnmount: function () {
25591
+ this._isMounted = false;
25592
+ },
25596
25593
  getSaveWarnings: function () {
25597
25594
  // eslint-disable-next-line react/no-string-refs
25598
25595
  return this.refs.editor.getSaveWarnings();
@@ -25609,6 +25606,10 @@ const StatefulEditorPage = createReactClass({
25609
25606
  scorePreview: function () {
25610
25607
  // eslint-disable-next-line react/no-string-refs
25611
25608
  return this.refs.editor.scorePreview();
25609
+ },
25610
+ render: function () {
25611
+ const Component = this.props.componentClass;
25612
+ return /*#__PURE__*/React.createElement(Component, this.state);
25612
25613
  }
25613
25614
  });
25614
25615
 
@@ -25939,7 +25940,7 @@ CSProgramEditor.defaultProps = {
25939
25940
  };
25940
25941
 
25941
25942
  const {
25942
- TextInput: TextInput$8
25943
+ TextInput: TextInput$7
25943
25944
  } = components;
25944
25945
  class DefinitionEditor extends React.Component {
25945
25946
  constructor(..._args) {
@@ -25959,7 +25960,7 @@ class DefinitionEditor extends React.Component {
25959
25960
  target: "_blank"
25960
25961
  }, "Definition style guide"), /*#__PURE__*/React.createElement("div", {
25961
25962
  className: "perseus-widget-row"
25962
- }, /*#__PURE__*/React.createElement("label", null, "Word to be defined:", " ", /*#__PURE__*/React.createElement(TextInput$8, {
25963
+ }, /*#__PURE__*/React.createElement("label", null, "Word to be defined:", " ", /*#__PURE__*/React.createElement(TextInput$7, {
25963
25964
  value: this.props.togglePrompt
25964
25965
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
25965
25966
  ,
@@ -26153,222 +26154,8 @@ DropdownEditor.defaultProps = {
26153
26154
  }]
26154
26155
  };
26155
26156
 
26156
- /* eslint-disable @typescript-eslint/no-unused-vars, react/forbid-prop-types, react/sort-comp */
26157
- const {
26158
- Graphie
26159
- } = components;
26160
-
26161
- // @ts-expect-error - TS2339 - Property 'MovablePoint' does not exist on type 'typeof Graphie'.
26162
- const MovablePoint = Graphie.MovablePoint;
26163
- /**
26164
- * This is the widget's renderer. It shows up in the right column
26165
- * in the demo, and is what is visible to users, and where
26166
- * users enter their answers.
26167
- */
26168
- class ExampleGraphieWidget$1 extends React.Component {
26169
- constructor(..._args) {
26170
- super(..._args);
26171
- this.getUserInput = () => {
26172
- return WidgetJsonifyDeprecated.getUserInput.call(this);
26173
- };
26174
- this.change = (...args) => {
26175
- return Changeable.change.apply(this, args);
26176
- };
26177
- this.movePoint = newCoord => {
26178
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26179
- this.change({
26180
- coord: newCoord
26181
- });
26182
- };
26183
- this._getGridConfig = options => {
26184
- return _.map(options.step, function (step, i) {
26185
- return Util.gridDimensionConfig(step, options.range[i], options.box[i], options.gridStep[i]);
26186
- });
26187
- };
26188
- this.setupGraphie = (graphie, options) => {
26189
- const gridConfig = this._getGridConfig(options);
26190
- graphie.graphInit({
26191
- range: options.range,
26192
- scale: _.pluck(gridConfig, "scale"),
26193
- axisArrows: "<->",
26194
- labelFormat: function (s) {
26195
- return "\\small{" + s + "}";
26196
- },
26197
- gridStep: options.gridStep,
26198
- tickStep: _.pluck(gridConfig, "tickStep"),
26199
- labelStep: 1,
26200
- unityLabels: _.pluck(gridConfig, "unityLabel")
26201
- });
26202
- graphie.label([0, options.range[1][1]], options.labels[1], "above");
26203
- };
26204
- this.simpleValidate = rubric => {
26205
- return ExampleGraphieWidget$1.validate(this.getUserInput(), rubric);
26206
- };
26207
- }
26208
- /**
26209
- * This is the widget's grading function
26210
- */
26211
- static validate(state, rubric) {
26212
- if (state.coord == null) {
26213
- return {
26214
- type: "invalid",
26215
- message: null
26216
- };
26217
- }
26218
- if (point.equal(state.coord, rubric.correct)) {
26219
- return {
26220
- type: "points",
26221
- earned: 1,
26222
- total: 1,
26223
- message: null
26224
- };
26225
- }
26226
- return {
26227
- type: "points",
26228
- earned: 0,
26229
- total: 1,
26230
- message: null
26231
- };
26232
- }
26233
- render() {
26234
- var _this$props$apiOption;
26235
- return /*#__PURE__*/React.createElement(Graphie
26236
- // eslint-disable-next-line react/no-string-refs
26237
- , {
26238
- ref: "graphie",
26239
- box: this.props.graph.box,
26240
- range: this.props.graph.range,
26241
- options: this.props.graph,
26242
- setup: this.setupGraphie,
26243
- setDrawingAreaAvailable: (_this$props$apiOption = this.props.apiOptions) == null ? void 0 : _this$props$apiOption.setDrawingAreaAvailable
26244
- }, /*#__PURE__*/React.createElement(MovablePoint, {
26245
- pointSize: 5,
26246
- coord: this.props.coord || [0, 0],
26247
- constraints: [MovablePoint.constraints.snap(), MovablePoint.constraints.bound()],
26248
- onMove: this.movePoint
26249
- }));
26250
- }
26251
- }
26252
-
26253
- /**
26254
- * For this widget to work, we must export it.
26255
- * We also must import this file in src/all-widgets.js
26256
- */
26257
- ExampleGraphieWidget$1.defaultProps = {
26258
- // We want to allow our coord to be null to test if the
26259
- // user has interacted with this widget yet when grading it
26260
- coord: null,
26261
- graph: {
26262
- box: [400, 400],
26263
- labels: ["x", "y"],
26264
- range: [[-10, 10], [-10, 10]],
26265
- step: [1, 1],
26266
- gridStep: [1, 1],
26267
- valid: true,
26268
- backgroundImage: null,
26269
- markings: "grid",
26270
- showProtractor: false
26271
- }
26272
- };
26273
- var ExampleGraphieWidget$2 = {
26274
- name: "example-graphie-widget",
26275
- displayName: "Example Graphie Widget",
26276
- hidden: true,
26277
- // Hides this widget from the Perseus.Editor widget select
26278
- widget: ExampleGraphieWidget$1
26279
- };
26280
-
26281
- const ExampleGraphieWidget = ExampleGraphieWidget$2.widget;
26282
- /**
26283
- * This is the widget's editor. This is what shows up on the left side
26284
- * of the screen in the demo page. Only the question writer sees this.
26285
- */
26286
- class ExampleGraphieWidgetEditor extends React.Component {
26287
- constructor(..._args) {
26288
- super(..._args);
26289
- this.change = (...args) => {
26290
- return Changeable.change.apply(this, args);
26291
- };
26292
- this.handleChange = newProps => {
26293
- if (newProps.coord) {
26294
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26295
- this.change({
26296
- correct: newProps.coord
26297
- });
26298
- }
26299
- };
26300
- this.serialize = () => {
26301
- return EditorJsonify.serialize.call(this);
26302
- };
26303
- }
26304
- render() {
26305
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(ExampleGraphieWidget, {
26306
- graph: this.props.graph,
26307
- coord: this.props.correct,
26308
- onChange: this.handleChange,
26309
- apiOptions: this.props.apiOptions
26310
- }));
26311
- }
26312
- }
26313
- ExampleGraphieWidgetEditor.propTypes = _extends({}, Changeable.propTypes);
26314
- ExampleGraphieWidgetEditor.widgetName = "example-graphie-widget";
26315
- ExampleGraphieWidgetEditor.defaultProps = {
26316
- correct: [4, 4],
26317
- graph: {
26318
- box: [340, 340],
26319
- labels: ["x", "y"],
26320
- range: [[-10, 10], [-10, 10]],
26321
- step: [1, 1],
26322
- gridStep: [1, 1],
26323
- valid: true,
26324
- backgroundImage: null,
26325
- markings: "grid",
26326
- showProtractor: false
26327
- }
26328
- };
26329
-
26330
- /**
26331
- * This is the widget's editor. This is what shows up on the left side
26332
- * of the screen in the demo. Only the question writer sees this.
26333
- */
26334
- class ExampleWidgetEditor extends React.Component {
26335
- constructor(..._args) {
26336
- super(..._args);
26337
- this.input = /*#__PURE__*/React.createRef();
26338
- this.handleAnswerChange = event => {
26339
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26340
- this.change({
26341
- correct: event.target.value
26342
- });
26343
- };
26344
- this.change = (...args) => {
26345
- return Changeable.change.apply(this, args);
26346
- };
26347
- this.focus = () => {
26348
- var _this$input$current;
26349
- (_this$input$current = this.input.current) == null || _this$input$current.focus();
26350
- return true;
26351
- };
26352
- this.serialize = () => {
26353
- return EditorJsonify.serialize.call(this);
26354
- };
26355
- }
26356
- render() {
26357
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Correct answer:", /*#__PURE__*/React.createElement("input", {
26358
- value: this.props.correct,
26359
- onChange: this.handleAnswerChange,
26360
- ref: this.input
26361
- })));
26362
- }
26363
- }
26364
- ExampleWidgetEditor.propTypes = _extends({}, Changeable.propTypes);
26365
- ExampleWidgetEditor.widgetName = "example-widget";
26366
- ExampleWidgetEditor.defaultProps = {
26367
- correct: ""
26368
- };
26369
-
26370
26157
  const {
26371
- TextInput: TextInput$7
26158
+ TextInput: TextInput$6
26372
26159
  } = components;
26373
26160
  const defaultExplanationProps = {
26374
26161
  showPrompt: "Explain",
@@ -26392,14 +26179,14 @@ class ExplanationEditor extends React.Component {
26392
26179
  className: "perseus-widget-explanation-editor"
26393
26180
  }, /*#__PURE__*/React.createElement("div", {
26394
26181
  className: "perseus-widget-row"
26395
- }, /*#__PURE__*/React.createElement("label", null, "Prompt to show explanation:", " ", /*#__PURE__*/React.createElement(TextInput$7, {
26182
+ }, /*#__PURE__*/React.createElement("label", null, "Prompt to show explanation:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
26396
26183
  value: this.props.showPrompt
26397
26184
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26398
26185
  ,
26399
26186
  onChange: this.change("showPrompt")
26400
26187
  }))), /*#__PURE__*/React.createElement("div", {
26401
26188
  className: "perseus-widget-row"
26402
- }, /*#__PURE__*/React.createElement("label", null, "Prompt to hide explanation:", " ", /*#__PURE__*/React.createElement(TextInput$7, {
26189
+ }, /*#__PURE__*/React.createElement("label", null, "Prompt to hide explanation:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
26403
26190
  value: this.props.hidePrompt
26404
26191
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26405
26192
  ,
@@ -27048,7 +26835,7 @@ const styles$L = StyleSheet.create({
27048
26835
 
27049
26836
  const {
27050
26837
  InlineIcon: InlineIcon$3,
27051
- TextInput: TextInput$6
26838
+ TextInput: TextInput$5
27052
26839
  } = components;
27053
26840
  const {
27054
26841
  iconPlus: iconPlus$1,
@@ -27098,7 +26885,7 @@ class GradedGroupEditor extends React.Component {
27098
26885
  className: "perseus-widget-row"
27099
26886
  }, /*#__PURE__*/React.createElement("label", {
27100
26887
  className: css(styles$K.title)
27101
- }, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
26888
+ }, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$5, {
27102
26889
  value: this.props.title,
27103
26890
  className: css(styles$K.input)
27104
26891
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
@@ -28076,7 +27863,7 @@ IframeEditor.defaultProps = {
28076
27863
  allowTopNavigation: false
28077
27864
  };
28078
27865
 
28079
- /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
27866
+ /* eslint-disable jsx-a11y/anchor-is-valid */
28080
27867
  const {
28081
27868
  InfoTip: InfoTip$f,
28082
27869
  InlineIcon: InlineIcon$2,
@@ -28117,48 +27904,6 @@ class ImageEditor extends React.Component {
28117
27904
  componentWillUnmount() {
28118
27905
  this._isMounted = false;
28119
27906
  }
28120
- render() {
28121
- const backgroundImage = this.props.backgroundImage;
28122
- const imageSettings = /*#__PURE__*/React.createElement("div", {
28123
- className: "image-settings"
28124
- }, !Util.isLabeledSVG(backgroundImage.url) && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Preview:"), /*#__PURE__*/React.createElement("img", {
28125
- alt: "Editor preview of image",
28126
- src: backgroundImage.url,
28127
- style: {
28128
- width: "100%"
28129
- }
28130
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.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.createElement(Editor, {
28131
- apiOptions: this.props.apiOptions,
28132
- content: this.props.alt,
28133
- onChange: props => {
28134
- if (props.content != null) {
28135
- this.change("alt", props.content);
28136
- }
28137
- },
28138
- widgetEnabled: false
28139
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Caption:"), /*#__PURE__*/React.createElement(Editor, {
28140
- apiOptions: this.props.apiOptions,
28141
- content: this.props.caption,
28142
- onChange: props => {
28143
- if (props.content != null) {
28144
- this.change("caption", props.content);
28145
- }
28146
- },
28147
- widgetEnabled: false
28148
- }))));
28149
- const backgroundImageErrorText = /*#__PURE__*/React.createElement("div", {
28150
- className: "renderer-widget-error"
28151
- }, this.state.backgroundImageError);
28152
- return /*#__PURE__*/React.createElement("div", {
28153
- className: "perseus-image-editor"
28154
- }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28155
- value: backgroundImage.url || "",
28156
- style: {
28157
- width: 332
28158
- },
28159
- onChange: url => this.onUrlChange(url, false)
28160
- })), backgroundImage.url && imageSettings);
28161
- }
28162
27907
  _renderRowForLabel(label, i) {
28163
27908
  return /*#__PURE__*/React.createElement("tr", {
28164
27909
  key: i
@@ -28300,6 +28045,48 @@ class ImageEditor extends React.Component {
28300
28045
  serialize() {
28301
28046
  return EditorJsonify.serialize.call(this);
28302
28047
  }
28048
+ render() {
28049
+ const backgroundImage = this.props.backgroundImage;
28050
+ const imageSettings = /*#__PURE__*/React.createElement("div", {
28051
+ className: "image-settings"
28052
+ }, !Util.isLabeledSVG(backgroundImage.url) && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Preview:"), /*#__PURE__*/React.createElement("img", {
28053
+ alt: "Editor preview of image",
28054
+ src: backgroundImage.url,
28055
+ style: {
28056
+ width: "100%"
28057
+ }
28058
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.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.createElement(Editor, {
28059
+ apiOptions: this.props.apiOptions,
28060
+ content: this.props.alt,
28061
+ onChange: props => {
28062
+ if (props.content != null) {
28063
+ this.change("alt", props.content);
28064
+ }
28065
+ },
28066
+ widgetEnabled: false
28067
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Caption:"), /*#__PURE__*/React.createElement(Editor, {
28068
+ apiOptions: this.props.apiOptions,
28069
+ content: this.props.caption,
28070
+ onChange: props => {
28071
+ if (props.content != null) {
28072
+ this.change("caption", props.content);
28073
+ }
28074
+ },
28075
+ widgetEnabled: false
28076
+ }))));
28077
+ const backgroundImageErrorText = /*#__PURE__*/React.createElement("div", {
28078
+ className: "renderer-widget-error"
28079
+ }, this.state.backgroundImageError);
28080
+ return /*#__PURE__*/React.createElement("div", {
28081
+ className: "perseus-image-editor"
28082
+ }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28083
+ value: backgroundImage.url || "",
28084
+ style: {
28085
+ width: 332
28086
+ },
28087
+ onChange: url => this.onUrlChange(url, false)
28088
+ })), backgroundImage.url && imageSettings);
28089
+ }
28303
28090
  }
28304
28091
  ImageEditor.displayName = "ImageEditor";
28305
28092
  ImageEditor.widgetName = "image";
@@ -28313,7 +28100,6 @@ ImageEditor.defaultProps = {
28313
28100
  caption: ""
28314
28101
  };
28315
28102
 
28316
- /* eslint-disable react/sort-comp */
28317
28103
  const {
28318
28104
  InfoTip: InfoTip$e
28319
28105
  } = components;
@@ -28601,7 +28387,7 @@ FunctionEditor.defaultProps = {
28601
28387
  };
28602
28388
 
28603
28389
  const {
28604
- TextInput: TextInput$5
28390
+ TextInput: TextInput$4
28605
28391
  } = components;
28606
28392
  const {
28607
28393
  getDependencies: getDependencies$7
@@ -28626,7 +28412,7 @@ class LabelEditor extends React.Component {
28626
28412
  className: "graph-settings"
28627
28413
  }, /*#__PURE__*/React.createElement("div", {
28628
28414
  className: "perseus-widget-row"
28629
- }, /*#__PURE__*/React.createElement(TextInput$5, {
28415
+ }, /*#__PURE__*/React.createElement(TextInput$4, {
28630
28416
  value: this.props.label,
28631
28417
  onChange: this.change("label"),
28632
28418
  style: {
@@ -32726,8 +32512,38 @@ class InteractiveGraphEditor extends React.Component {
32726
32512
  UNSAFE_componentWillMount() {
32727
32513
  DeprecationMixin.UNSAFE_componentWillMount.call(this);
32728
32514
  }
32515
+ // serialize() is what makes copy/paste work. All the properties included
32516
+ // in the serialization json are included when, for example, a graph
32517
+ // is copied from the question editor and pasted into the hint editor
32518
+ // (double brackets in the markdown).
32519
+ serialize() {
32520
+ const json = _.pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showTooltips", "range", "gridStep", "snapStep", "lockedFigures");
32521
+
32522
+ // eslint-disable-next-line react/no-string-refs
32523
+ const graph = this.refs.graph;
32524
+ if (graph) {
32525
+ var _this$props$graph2;
32526
+ // @ts-expect-error TS2339 Property 'getUserInput' does not exist on type 'ReactInstance'. Property 'getUserInput' does not exist on type 'Component<any, {}, any>'.
32527
+ const correct = graph && graph.getUserInput();
32528
+ _.extend(json, {
32529
+ graph: {
32530
+ type: correct.type,
32531
+ startCoords: (_this$props$graph2 = this.props.graph) == null ? void 0 : _this$props$graph2.startCoords
32532
+ },
32533
+ correct: correct
32534
+ });
32535
+ _.each(["allowReflexAngles", "angleOffsetDeg", "numPoints", "numSides", "numSegments", "showAngles", "showSides", "snapTo", "snapDegrees"], function (key) {
32536
+ if (_.has(correct, key)) {
32537
+ // @ts-expect-error - TS2339 - Property 'graph' does not exist on type 'Pick<any, "step" | "range" | "backgroundImage" | "snapStep" | "labels" | "showTooltips" | "markings" | "gridStep" | "showProtractor">'.
32538
+ json.graph[key] = correct[key];
32539
+ }
32540
+ });
32541
+ }
32542
+ // @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
32543
+ return json;
32544
+ }
32729
32545
  render() {
32730
- var _this$props$graph$typ, _this$props$graph2, _this$props$correct, _this$props$correct2, _this$props$correct3, _this$props$correct4, _this$props$correct5, _this$props$correct6, _this$props$correct7, _this$props$correct8, _this$props$correct9, _this$props$correct10, _this$props$correct11, _this$props$graph5, _this$props$apiOption, _this$props$apiOption2, _this$props$apiOption3;
32546
+ var _this$props$graph$typ, _this$props$graph3, _this$props$correct, _this$props$correct2, _this$props$correct3, _this$props$correct4, _this$props$correct5, _this$props$correct6, _this$props$correct7, _this$props$correct8, _this$props$correct9, _this$props$correct10, _this$props$correct11, _this$props$graph6, _this$props$apiOption, _this$props$apiOption2, _this$props$apiOption3;
32731
32547
  let graph;
32732
32548
  let equationString;
32733
32549
  const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, interactiveSizes.defaultBoxSize);
@@ -32791,7 +32607,7 @@ class InteractiveGraphEditor extends React.Component {
32791
32607
  return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(LabeledRow, {
32792
32608
  label: "Type of Graph:"
32793
32609
  }, /*#__PURE__*/React.createElement(GraphTypeSelector, {
32794
- graphType: (_this$props$graph$typ = (_this$props$graph2 = this.props.graph) == null ? void 0 : _this$props$graph2.type) != null ? _this$props$graph$typ : InteractiveGraph.defaultProps.graph.type,
32610
+ graphType: (_this$props$graph$typ = (_this$props$graph3 = this.props.graph) == null ? void 0 : _this$props$graph3.type) != null ? _this$props$graph$typ : InteractiveGraph.defaultProps.graph.type,
32795
32611
  onChange: type => {
32796
32612
  this.props.onChange({
32797
32613
  graph: {
@@ -32880,8 +32696,8 @@ class InteractiveGraphEditor extends React.Component {
32880
32696
  // Don't show indeterminate checkbox state
32881
32697
  !!((_this$props$correct8 = this.props.correct) != null && _this$props$correct8.showAngles),
32882
32698
  onChange: () => {
32883
- var _this$props$graph3;
32884
- if (((_this$props$graph3 = this.props.graph) == null ? void 0 : _this$props$graph3.type) === "polygon") {
32699
+ var _this$props$graph4;
32700
+ if (((_this$props$graph4 = this.props.graph) == null ? void 0 : _this$props$graph4.type) === "polygon") {
32885
32701
  this.props.onChange({
32886
32702
  correct: _extends({}, this.props.correct, {
32887
32703
  showAngles: !this.props.correct.showAngles
@@ -32900,8 +32716,8 @@ class InteractiveGraphEditor extends React.Component {
32900
32716
  // Don't show indeterminate checkbox state
32901
32717
  !!((_this$props$correct9 = this.props.correct) != null && _this$props$correct9.showSides),
32902
32718
  onChange: () => {
32903
- var _this$props$graph4;
32904
- if (((_this$props$graph4 = this.props.graph) == null ? void 0 : _this$props$graph4.type) === "polygon") {
32719
+ var _this$props$graph5;
32720
+ if (((_this$props$graph5 = this.props.graph) == null ? void 0 : _this$props$graph5.type) === "polygon") {
32905
32721
  this.props.onChange({
32906
32722
  correct: _extends({}, this.props.correct, {
32907
32723
  showSides: !this.props.correct.showSides
@@ -32929,7 +32745,7 @@ class InteractiveGraphEditor extends React.Component {
32929
32745
  }
32930
32746
  });
32931
32747
  }
32932
- })), ((_this$props$graph5 = this.props.graph) == null ? void 0 : _this$props$graph5.type) &&
32748
+ })), ((_this$props$graph6 = this.props.graph) == null ? void 0 : _this$props$graph6.type) &&
32933
32749
  // TODO(LEMS-2228): Remove flags once this is fully released
32934
32750
  shouldShowStartCoordsUI(this.props.apiOptions.flags, this.props.graph) && /*#__PURE__*/React.createElement(StartCoordsSettings, _extends({}, this.props.graph, {
32935
32751
  range: this.props.range,
@@ -32994,36 +32810,6 @@ class InteractiveGraphEditor extends React.Component {
32994
32810
  onChange: this.props.onChange
32995
32811
  }));
32996
32812
  }
32997
- // serialize() is what makes copy/paste work. All the properties included
32998
- // in the serialization json are included when, for example, a graph
32999
- // is copied from the question editor and pasted into the hint editor
33000
- // (double brackets in the markdown).
33001
- serialize() {
33002
- const json = _.pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showTooltips", "range", "gridStep", "snapStep", "lockedFigures");
33003
-
33004
- // eslint-disable-next-line react/no-string-refs
33005
- const graph = this.refs.graph;
33006
- if (graph) {
33007
- var _this$props$graph6;
33008
- // @ts-expect-error TS2339 Property 'getUserInput' does not exist on type 'ReactInstance'. Property 'getUserInput' does not exist on type 'Component<any, {}, any>'.
33009
- const correct = graph && graph.getUserInput();
33010
- _.extend(json, {
33011
- graph: {
33012
- type: correct.type,
33013
- startCoords: (_this$props$graph6 = this.props.graph) == null ? void 0 : _this$props$graph6.startCoords
33014
- },
33015
- correct: correct
33016
- });
33017
- _.each(["allowReflexAngles", "angleOffsetDeg", "numPoints", "numSides", "numSegments", "showAngles", "showSides", "snapTo", "snapDegrees"], function (key) {
33018
- if (_.has(correct, key)) {
33019
- // @ts-expect-error - TS2339 - Property 'graph' does not exist on type 'Pick<any, "step" | "range" | "backgroundImage" | "snapStep" | "labels" | "showTooltips" | "markings" | "gridStep" | "showProtractor">'.
33020
- json.graph[key] = correct[key];
33021
- }
33022
- });
33023
- }
33024
- // @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
33025
- return json;
33026
- }
33027
32813
  }
33028
32814
  InteractiveGraphEditor.widgetName = "interactive-graph";
33029
32815
  InteractiveGraphEditor.defaultProps = _extends({}, InteractiveGraph.defaultProps, {
@@ -33468,7 +33254,50 @@ const editorStyles = StyleSheet.create({
33468
33254
  }
33469
33255
  });
33470
33256
 
33471
- /* eslint-disable react/sort-comp */
33257
+ /**
33258
+ * Add hover behavior to another component.
33259
+ *
33260
+ * This component provides hover and focus status updates in a consistent way
33261
+ * across desktop and mobile.
33262
+ *
33263
+ * For advice on when to use this component instead of Button, see README.md.
33264
+ *
33265
+ * Many mobile browsers treat :hover as sticky which results in buttons looking
33266
+ * pressed even when the user has lifted their finger. This component ensures
33267
+ * that when user lifts their finger the hover state is removed.
33268
+ *
33269
+ * We also chnage how the focus state works. Browsers immediately set the
33270
+ * focus state as soon as you click on a button. This component only sets the
33271
+ * focus state when a user starts navigating between elements via keybaord.
33272
+ *
33273
+ * HoverBehavior accepts a function as 'children' which is passed state and
33274
+ * an object containing event handlers. The 'children' function should return
33275
+ * an React Element of some sort.
33276
+ *
33277
+ * Example:
33278
+ *
33279
+ * class MyButtonLikeComponent extends React.Component {
33280
+ * render(): React.Node {
33281
+ * return <HoverBehavior
33282
+ * disabled={this.props.disabled}
33283
+ * onClick={this.handleClick}
33284
+ * >
33285
+ * {({hovered}, handlers) =>
33286
+ * <RoundRect
33287
+ * textcolor='white'
33288
+ * backgroundColor={hovered ? 'red' : 'blue'}/>}
33289
+ * {...handlers}
33290
+ * >
33291
+ * {this.props.children}
33292
+ * </RoundRect>
33293
+ * }
33294
+ * </HoverBehavior>
33295
+ * }
33296
+ * }
33297
+ *
33298
+ * This follows a pattern call 'Function as Child Components':
33299
+ * https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9#.sw0jiio8b
33300
+ */
33472
33301
  class HoverBehavior extends React.Component {
33473
33302
  constructor(props) {
33474
33303
  super(props);
@@ -34505,7 +34334,7 @@ const styles = StyleSheet.create({
34505
34334
  }
34506
34335
  });
34507
34336
 
34508
- /* eslint-disable react/forbid-prop-types, react/sort-comp */
34337
+ /* eslint-disable react/forbid-prop-types */
34509
34338
  const {
34510
34339
  InfoTip: InfoTip$a,
34511
34340
  TextListEditor: TextListEditor$3
@@ -34888,7 +34717,7 @@ MeasurerEditor.defaultProps = {
34888
34717
 
34889
34718
  const {
34890
34719
  NumberInput: NumberInput$6,
34891
- TextInput: TextInput$4
34720
+ TextInput: TextInput$3
34892
34721
  } = components;
34893
34722
  class MoleculeWidgetEditor extends React.Component {
34894
34723
  constructor(..._args) {
@@ -34913,7 +34742,7 @@ class MoleculeWidgetEditor extends React.Component {
34913
34742
  };
34914
34743
  }
34915
34744
  render() {
34916
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "SMILES:\xA0", /*#__PURE__*/React.createElement(TextInput$4, {
34745
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "SMILES:\xA0", /*#__PURE__*/React.createElement(TextInput$3, {
34917
34746
  onChange: this.updateMolecule,
34918
34747
  value: this.props.smiles
34919
34748
  }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Rotation (deg):\xA0", /*#__PURE__*/React.createElement(NumberInput$6, {
@@ -35246,14 +35075,14 @@ NumberLineEditor.defaultProps = {
35246
35075
  showTooltips: false
35247
35076
  };
35248
35077
 
35249
- /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
35078
+ /* eslint-disable jsx-a11y/anchor-is-valid */
35250
35079
  const {
35251
35080
  ButtonGroup,
35252
35081
  InfoTip: InfoTip$7,
35253
35082
  InlineIcon: InlineIcon$1,
35254
35083
  MultiButtonGroup,
35255
35084
  NumberInput: NumberInput$4,
35256
- TextInput: TextInput$3
35085
+ TextInput: TextInput$2
35257
35086
  } = components;
35258
35087
  const {
35259
35088
  iconGear,
@@ -35468,7 +35297,7 @@ class NumericInputEditor extends React.Component {
35468
35297
  }));
35469
35298
  const labelText = /*#__PURE__*/React.createElement("div", {
35470
35299
  className: "perseus-widget-row"
35471
- }, /*#__PURE__*/React.createElement("label", null, "Aria label", /*#__PURE__*/React.createElement(TextInput$3, {
35300
+ }, /*#__PURE__*/React.createElement("label", null, "Aria label", /*#__PURE__*/React.createElement(TextInput$2, {
35472
35301
  value: this.props.labelText,
35473
35302
  onChange: this.change("labelText")
35474
35303
  })), /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "Text to describe this input. This will be shown to users using screenreaders.")));
@@ -35830,7 +35659,7 @@ PassageEditor.defaultProps = {
35830
35659
  const {
35831
35660
  InfoTip: InfoTip$4,
35832
35661
  NumberInput: NumberInput$3,
35833
- TextInput: TextInput$2
35662
+ TextInput: TextInput$1
35834
35663
  } = components;
35835
35664
  class PassageRefEditor extends React.Component {
35836
35665
  constructor(..._args) {
@@ -35853,7 +35682,7 @@ class PassageRefEditor extends React.Component {
35853
35682
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
35854
35683
  ,
35855
35684
  onChange: this.change("referenceNumber")
35856
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Summary Text: ", /*#__PURE__*/React.createElement(TextInput$2, {
35685
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Summary Text: ", /*#__PURE__*/React.createElement(TextInput$1, {
35857
35686
  value: this.props.summaryText
35858
35687
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
35859
35688
  ,
@@ -35907,14 +35736,32 @@ PassageRefTargetEditor.defaultProps = {
35907
35736
 
35908
35737
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
35909
35738
  class PhetSimulationEditor extends React.Component {
35739
+ constructor(...args) {
35740
+ super(...args);
35741
+ this.getSaveWarnings = () => {
35742
+ if (makeSafeUrl(this.props.url, "en") === null) {
35743
+ return ["Please enter a URL from the PhET domain."];
35744
+ }
35745
+ return [];
35746
+ };
35747
+ }
35748
+ serialize() {
35749
+ return {
35750
+ url: this.props.url,
35751
+ description: this.props.description
35752
+ };
35753
+ }
35910
35754
  render() {
35911
35755
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(LabeledTextField, {
35912
35756
  label: "URL",
35913
35757
  value: this.props.url,
35914
35758
  onChange: url => this.props.onChange({
35915
35759
  url
35916
- })
35917
- }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(LabeledTextField, {
35760
+ }),
35761
+ style: {
35762
+ marginBottom: spacing.large_24
35763
+ }
35764
+ }), /*#__PURE__*/React.createElement(LabeledTextField, {
35918
35765
  label: "Description",
35919
35766
  value: this.props.description,
35920
35767
  onChange: description => this.props.onChange({
@@ -35922,12 +35769,6 @@ class PhetSimulationEditor extends React.Component {
35922
35769
  })
35923
35770
  }));
35924
35771
  }
35925
- serialize() {
35926
- return {
35927
- url: this.props.url,
35928
- description: this.props.description
35929
- };
35930
- }
35931
35772
  }
35932
35773
  PhetSimulationEditor.defaultProps = {
35933
35774
  url: "",
@@ -36249,7 +36090,7 @@ PlotterEditor.defaultProps = _extends({}, editorDefaults, {
36249
36090
  */
36250
36091
  const {
36251
36092
  NumberInput: NumberInput$1,
36252
- TextInput: TextInput$1
36093
+ TextInput
36253
36094
  } = components;
36254
36095
  function validateOptions(height, programID) {
36255
36096
  const errors = [];
@@ -36283,7 +36124,7 @@ class PythonProgramEditor extends React.Component {
36283
36124
  };
36284
36125
  }
36285
36126
  render() {
36286
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "User Program ID:", " ", /*#__PURE__*/React.createElement(TextInput$1, {
36127
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "User Program ID:", " ", /*#__PURE__*/React.createElement(TextInput, {
36287
36128
  value: this.props.programID,
36288
36129
  onChange: this.change("programID"),
36289
36130
  placeholder: "123"
@@ -36595,62 +36436,6 @@ RadioEditor.defaultProps = {
36595
36436
  deselectEnabled: false
36596
36437
  };
36597
36438
 
36598
- class TextArea extends React.Component {
36599
- constructor(...args) {
36600
- super(...args);
36601
- this.focus = () => {
36602
- // eslint-disable-next-line react/no-string-refs
36603
- // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
36604
- this.refs.input.focus();
36605
- return true;
36606
- };
36607
- this.changeValue = e => {
36608
- // Translating from the js event e to the value
36609
- // of the textbox to send to onChange
36610
- this.props.onChange(e.target.value);
36611
- };
36612
- }
36613
- render() {
36614
- return /*#__PURE__*/React.createElement("textarea", {
36615
- // eslint-disable-next-line react/no-string-refs
36616
- ref: "input",
36617
- value: this.props.value || "",
36618
- onChange: this.changeValue
36619
- });
36620
- }
36621
- }
36622
- class SimpleMarkdownTesterEditor extends React.Component {
36623
- constructor(..._args) {
36624
- super(..._args);
36625
- this.input = /*#__PURE__*/React.createRef();
36626
- this.change = (...args) => {
36627
- return Changeable.change.apply(this, args);
36628
- };
36629
- this.focus = () => {
36630
- var _this$input$current;
36631
- (_this$input$current = this.input.current) == null || _this$input$current.focus();
36632
- return true;
36633
- };
36634
- this.serialize = () => {
36635
- return EditorJsonify.serialize.call(this);
36636
- };
36637
- }
36638
- render() {
36639
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Simple markdown contents:"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(TextArea, {
36640
- value: this.props.value
36641
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
36642
- ,
36643
- onChange: this.change("value"),
36644
- ref: this.input
36645
- }))));
36646
- }
36647
- }
36648
- SimpleMarkdownTesterEditor.propTypes = _extends({}, Changeable.propTypes);
36649
- SimpleMarkdownTesterEditor.widgetName = "simple-markdown-tester";
36650
- SimpleMarkdownTesterEditor.defaultProps = {
36651
- value: ""
36652
- };
36653
-
36654
36439
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
36655
36440
  const {
36656
36441
  InfoTip: InfoTip$2,
@@ -36714,7 +36499,6 @@ SorterEditor.defaultProps = {
36714
36499
  padding: true
36715
36500
  };
36716
36501
 
36717
- /* eslint-disable react/sort-comp */
36718
36502
  const {
36719
36503
  InfoTip: InfoTip$1,
36720
36504
  NumberInput
@@ -36881,219 +36665,12 @@ VideoEditor.defaultProps = {
36881
36665
  location: ""
36882
36666
  };
36883
36667
 
36884
- var AllEditors = [CategorizerEditor, CSProgramEditor, DefinitionEditor, DropdownEditor, ExampleGraphieWidgetEditor, ExampleWidgetEditor, 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, SimpleMarkdownTesterEditor, SorterEditor, TableEditor, VideoEditor, RadioEditor, DeprecatedStandinEditor];
36885
-
36886
- /* eslint-disable @khanacademy/ts-no-error-suppressions */
36887
- class TextInput extends React.Component {
36888
- constructor(...args) {
36889
- super(...args);
36890
- this.input = /*#__PURE__*/React.createRef();
36891
- this.focus = () => {
36892
- var _this$input$current;
36893
- (_this$input$current = this.input.current) == null || _this$input$current.focus();
36894
- return true;
36895
- };
36896
- this.changeValue = e => {
36897
- // Translating from the js event e to the value
36898
- // of the textbox to send to onChange
36899
- this.props.onChange(e.target.value);
36900
- };
36901
- }
36902
- render() {
36903
- return /*#__PURE__*/React.createElement("input", {
36904
- ref: this.input,
36905
- value: this.props.value || "",
36906
- onChange: this.changeValue
36907
- });
36908
- }
36909
- }
36910
- /**
36911
- * This is the widget's renderer. It shows up in the right column
36912
- * in the demo, and is what is visible to users, and where
36913
- * users enter their answers.
36914
- */
36915
- class ExampleWidget extends React.Component {
36916
- constructor(..._args) {
36917
- super(..._args);
36918
- this.input = /*#__PURE__*/React.createRef();
36919
- /**
36920
- * Tell our parent to update our props.
36921
- */
36922
- this.change = (...args) => {
36923
- return Changeable.change.apply(this, args);
36924
- };
36925
- this.getUserInput = () => {
36926
- return this.props.value;
36927
- };
36928
- /**
36929
- * Widgets that are focusable should add a focus method that returns
36930
- * true if focusing succeeded. The first such widget found will be
36931
- * focused on page load.
36932
- */
36933
- this.focus = () => {
36934
- var _this$input$current2;
36935
- (_this$input$current2 = this.input.current) == null || _this$input$current2.focus();
36936
- return true;
36937
- };
36938
- /**
36939
- * simpleValidate is called for grading. Rubric is the result of calling
36940
- * getUserInput() on the editor that created this widget.
36941
- *
36942
- * Should return an object representing the grading result, such as
36943
- * {
36944
- * type: "points",
36945
- * earned: 1,
36946
- * total: 1,
36947
- * message: null
36948
- * }
36949
- */
36950
- this.simpleValidate = rubric => {
36951
- return ExampleWidget.validate(this.getUserInput(), rubric);
36952
- };
36953
- }
36954
- /**
36955
- * This is the widget's grading function. simpleValidate generally
36956
- * defers to this function.
36957
- *
36958
- * value is usually the result of getUserInput on the widget
36959
- * rubric is the result of calling serialize() on the editor
36960
- */
36961
- static validate(value, rubric) {
36962
- if (value === "") {
36963
- return {
36964
- type: "invalid",
36965
- message: "It looks like you haven't answered all of the " + "question yet."
36966
- };
36967
- }
36968
- if (value === rubric.correct) {
36969
- return {
36970
- type: "points",
36971
- earned: 1,
36972
- total: 1,
36973
- message: null
36974
- };
36975
- }
36976
- return {
36977
- type: "points",
36978
- earned: 0,
36979
- total: 1,
36980
- message: null
36981
- };
36982
- }
36983
- render() {
36984
- return /*#__PURE__*/React.createElement(TextInput, {
36985
- ref: this.input,
36986
- value: this.props.value
36987
- // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
36988
- ,
36989
- onChange: this.change("value")
36990
- });
36991
- }
36992
- }
36993
-
36994
- /**
36995
- * For this widget to work, we must import this file in src/all-widgets.js
36996
- */
36997
- ExampleWidget.defaultProps = {
36998
- value: ""
36999
- };
37000
- var ExampleWidget$1 = {
37001
- name: "example-widget",
37002
- displayName: "Example Widget",
37003
- // Tell the renderer what type of `display:` style we would like
37004
- // for the component wrapping this one.
37005
- defaultAlignment: "inline-block",
37006
- hidden: true,
37007
- // Hides this widget from the Perseus.Editor widget select
37008
- widget: ExampleWidget
37009
- };
37010
-
37011
- /* eslint-disable react/sort-comp */
37012
- const mdParse = PerseusMarkdown.parse;
37013
- const mdOutput = PerseusMarkdown.basicOutput;
37014
- class SimpleMarkdownTester extends React.Component {
37015
- constructor(..._args) {
37016
- super(..._args);
37017
- this.change = (...args) => {
37018
- return Changeable.change.apply(this, args);
37019
- };
37020
- this.toJSON = () => {
37021
- return {};
37022
- };
37023
- /**
37024
- * Widgets that are focusable should add a focus method that returns
37025
- * true if focusing succeeded. The first such widget found will be
37026
- * focused on page load.
37027
- */
37028
- this.focus = () => {
37029
- // eslint-disable-next-line react/no-string-refs
37030
- // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
37031
- this.refs.input.focus();
37032
- return true;
37033
- };
37034
- /**
37035
- * simpleValidate is called for grading. Rubric is the result of calling
37036
- * toJSON() on the editor that created this widget.
37037
- *
37038
- * Should return an object representing the grading result, such as
37039
- * {
37040
- * type: "points",
37041
- * earned: 1,
37042
- * total: 1,
37043
- * message: null
37044
- * }
37045
- */
37046
- this.simpleValidate = rubric => {
37047
- return SimpleMarkdownTester.validate(this.toJSON(), rubric);
37048
- };
37049
- }
37050
- /**
37051
- * This is the widget's grading function.
37052
- *
37053
- * simpleValidate generally defers to this function
37054
- *
37055
- * state is usually the result of toJSON on the widget
37056
- * rubric is the result of calling toJSON() on the editor
37057
- */
37058
- static validate(state, rubric) {
37059
- return {
37060
- type: "points",
37061
- earned: 0,
37062
- total: 0,
37063
- message: null
37064
- };
37065
- }
37066
- render() {
37067
- // @ts-expect-error - TS2554 - Expected 2 arguments, but got 1.
37068
- const parsed = mdParse(this.props.value);
37069
- const output = mdOutput(parsed);
37070
- return /*#__PURE__*/React.createElement("div", null, output);
37071
- }
37072
- }
37073
-
37074
- /**
37075
- * For this widget to work, we must import this file in src/all-widgets.js
37076
- */
37077
- SimpleMarkdownTester.defaultProps = {
37078
- value: ""
37079
- };
37080
- var SimpleMarkdownTester$1 = {
37081
- name: "simple-markdown-tester",
37082
- displayName: "Simple Markdown Tester",
37083
- hidden: true,
37084
- // Hides this widget from the Perseus.Editor widget select
37085
- widget: SimpleMarkdownTester,
37086
- transform: _.identity
37087
- };
37088
-
37089
- var testingWidgets = [ExampleGraphieWidget$2, ExampleWidget$1, SimpleMarkdownTester$1];
37090
-
37091
- var AllWidgets = [...widgets, ...testingWidgets];
36668
+ 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];
37092
36669
 
37093
36670
  Widgets.registerEditors(AllEditors);
37094
- Widgets.registerWidgets(AllWidgets);
36671
+ Widgets.registerWidgets(widgets);
37095
36672
  Widgets.replaceDeprecatedWidgets();
37096
36673
  Widgets.replaceDeprecatedEditors();
37097
36674
 
37098
- export { AllEditors, AllWidgets, ArticleDiff, ArticleEditor, DeviceFramer, Editor, EditorPage, IframeContentRenderer, ItemDiff, MultiRendererEditor, StatefulEditorPage, StructuredItemDiff, ViewportResizer, i18n, libVersion };
36675
+ export { AllEditors, ArticleDiff, ArticleEditor, DeviceFramer, Editor, EditorPage, IframeContentRenderer, ItemDiff, MultiRendererEditor, StatefulEditorPage, StructuredItemDiff, ViewportResizer, i18n, libVersion };
37099
36676
  //# sourceMappingURL=index.js.map