@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.
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 +187 -624
  5. package/dist/es/index.js.map +1 -1
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.js +745 -1210
  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 +30 -38
  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.1";
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
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
- 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: {
@@ -32657,18 +32443,10 @@ const {
32657
32443
  containerSizeClass,
32658
32444
  getInteractiveBoxFromSizeClass
32659
32445
  } = SizingUtils;
32660
- const DeprecationMixin = Util.DeprecationMixin;
32661
32446
  const InteractiveGraph = InteractiveGraphWidget.widget;
32662
32447
  const defaultBackgroundImage = {
32663
32448
  url: null
32664
32449
  };
32665
- const deprecatedProps = {
32666
- showGraph: function (props) {
32667
- return {
32668
- markings: props.showGraph ? "graph" : "none"
32669
- };
32670
- }
32671
- };
32672
32450
  const POLYGON_SIDES = _.map(_.range(3, 13), function (value) {
32673
32451
  return /*#__PURE__*/React.createElement(OptionItem, {
32674
32452
  key: `polygon-sides-${value}`,
@@ -32687,8 +32465,6 @@ class InteractiveGraphEditor extends React.Component {
32687
32465
  super(...args);
32688
32466
  this.displayName = "InteractiveGraphEditor";
32689
32467
  this.className = "perseus-widget-interactive-graph";
32690
- // TODO(jack): Use versioning instead of DeprecationMixin
32691
- this.deprecatedProps = deprecatedProps;
32692
32468
  this.changeMatchType = newValue => {
32693
32469
  const correct = _extends({}, this.props.correct, {
32694
32470
  match: newValue
@@ -32722,12 +32498,38 @@ class InteractiveGraphEditor extends React.Component {
32722
32498
  return issues;
32723
32499
  };
32724
32500
  }
32725
- // TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
32726
- UNSAFE_componentWillMount() {
32727
- DeprecationMixin.UNSAFE_componentWillMount.call(this);
32501
+ // serialize() is what makes copy/paste work. All the properties included
32502
+ // in the serialization json are included when, for example, a graph
32503
+ // is copied from the question editor and pasted into the hint editor
32504
+ // (double brackets in the markdown).
32505
+ serialize() {
32506
+ const json = _.pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showTooltips", "range", "gridStep", "snapStep", "lockedFigures");
32507
+
32508
+ // eslint-disable-next-line react/no-string-refs
32509
+ const graph = this.refs.graph;
32510
+ if (graph) {
32511
+ var _this$props$graph2;
32512
+ // @ts-expect-error TS2339 Property 'getUserInput' does not exist on type 'ReactInstance'. Property 'getUserInput' does not exist on type 'Component<any, {}, any>'.
32513
+ const correct = graph && graph.getUserInput();
32514
+ _.extend(json, {
32515
+ graph: {
32516
+ type: correct.type,
32517
+ startCoords: (_this$props$graph2 = this.props.graph) == null ? void 0 : _this$props$graph2.startCoords
32518
+ },
32519
+ correct: correct
32520
+ });
32521
+ _.each(["allowReflexAngles", "angleOffsetDeg", "numPoints", "numSides", "numSegments", "showAngles", "showSides", "snapTo", "snapDegrees"], function (key) {
32522
+ if (_.has(correct, key)) {
32523
+ // @ts-expect-error - TS2339 - Property 'graph' does not exist on type 'Pick<any, "step" | "range" | "backgroundImage" | "snapStep" | "labels" | "showTooltips" | "markings" | "gridStep" | "showProtractor">'.
32524
+ json.graph[key] = correct[key];
32525
+ }
32526
+ });
32527
+ }
32528
+ // @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
32529
+ return json;
32728
32530
  }
32729
32531
  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;
32532
+ 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
32533
  let graph;
32732
32534
  let equationString;
32733
32535
  const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, interactiveSizes.defaultBoxSize);
@@ -32791,7 +32593,7 @@ class InteractiveGraphEditor extends React.Component {
32791
32593
  return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(LabeledRow, {
32792
32594
  label: "Type of Graph:"
32793
32595
  }, /*#__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,
32596
+ 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
32597
  onChange: type => {
32796
32598
  this.props.onChange({
32797
32599
  graph: {
@@ -32880,8 +32682,8 @@ class InteractiveGraphEditor extends React.Component {
32880
32682
  // Don't show indeterminate checkbox state
32881
32683
  !!((_this$props$correct8 = this.props.correct) != null && _this$props$correct8.showAngles),
32882
32684
  onChange: () => {
32883
- var _this$props$graph3;
32884
- if (((_this$props$graph3 = this.props.graph) == null ? void 0 : _this$props$graph3.type) === "polygon") {
32685
+ var _this$props$graph4;
32686
+ if (((_this$props$graph4 = this.props.graph) == null ? void 0 : _this$props$graph4.type) === "polygon") {
32885
32687
  this.props.onChange({
32886
32688
  correct: _extends({}, this.props.correct, {
32887
32689
  showAngles: !this.props.correct.showAngles
@@ -32900,8 +32702,8 @@ class InteractiveGraphEditor extends React.Component {
32900
32702
  // Don't show indeterminate checkbox state
32901
32703
  !!((_this$props$correct9 = this.props.correct) != null && _this$props$correct9.showSides),
32902
32704
  onChange: () => {
32903
- var _this$props$graph4;
32904
- if (((_this$props$graph4 = this.props.graph) == null ? void 0 : _this$props$graph4.type) === "polygon") {
32705
+ var _this$props$graph5;
32706
+ if (((_this$props$graph5 = this.props.graph) == null ? void 0 : _this$props$graph5.type) === "polygon") {
32905
32707
  this.props.onChange({
32906
32708
  correct: _extends({}, this.props.correct, {
32907
32709
  showSides: !this.props.correct.showSides
@@ -32929,7 +32731,7 @@ class InteractiveGraphEditor extends React.Component {
32929
32731
  }
32930
32732
  });
32931
32733
  }
32932
- })), ((_this$props$graph5 = this.props.graph) == null ? void 0 : _this$props$graph5.type) &&
32734
+ })), ((_this$props$graph6 = this.props.graph) == null ? void 0 : _this$props$graph6.type) &&
32933
32735
  // TODO(LEMS-2228): Remove flags once this is fully released
32934
32736
  shouldShowStartCoordsUI(this.props.apiOptions.flags, this.props.graph) && /*#__PURE__*/React.createElement(StartCoordsSettings, _extends({}, this.props.graph, {
32935
32737
  range: this.props.range,
@@ -32994,36 +32796,6 @@ class InteractiveGraphEditor extends React.Component {
32994
32796
  onChange: this.props.onChange
32995
32797
  }));
32996
32798
  }
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
32799
  }
33028
32800
  InteractiveGraphEditor.widgetName = "interactive-graph";
33029
32801
  InteractiveGraphEditor.defaultProps = _extends({}, InteractiveGraph.defaultProps, {
@@ -33468,7 +33240,50 @@ const editorStyles = StyleSheet.create({
33468
33240
  }
33469
33241
  });
33470
33242
 
33471
- /* eslint-disable react/sort-comp */
33243
+ /**
33244
+ * Add hover behavior to another component.
33245
+ *
33246
+ * This component provides hover and focus status updates in a consistent way
33247
+ * across desktop and mobile.
33248
+ *
33249
+ * For advice on when to use this component instead of Button, see README.md.
33250
+ *
33251
+ * Many mobile browsers treat :hover as sticky which results in buttons looking
33252
+ * pressed even when the user has lifted their finger. This component ensures
33253
+ * that when user lifts their finger the hover state is removed.
33254
+ *
33255
+ * We also chnage how the focus state works. Browsers immediately set the
33256
+ * focus state as soon as you click on a button. This component only sets the
33257
+ * focus state when a user starts navigating between elements via keybaord.
33258
+ *
33259
+ * HoverBehavior accepts a function as 'children' which is passed state and
33260
+ * an object containing event handlers. The 'children' function should return
33261
+ * an React Element of some sort.
33262
+ *
33263
+ * Example:
33264
+ *
33265
+ * class MyButtonLikeComponent extends React.Component {
33266
+ * render(): React.Node {
33267
+ * return <HoverBehavior
33268
+ * disabled={this.props.disabled}
33269
+ * onClick={this.handleClick}
33270
+ * >
33271
+ * {({hovered}, handlers) =>
33272
+ * <RoundRect
33273
+ * textcolor='white'
33274
+ * backgroundColor={hovered ? 'red' : 'blue'}/>}
33275
+ * {...handlers}
33276
+ * >
33277
+ * {this.props.children}
33278
+ * </RoundRect>
33279
+ * }
33280
+ * </HoverBehavior>
33281
+ * }
33282
+ * }
33283
+ *
33284
+ * This follows a pattern call 'Function as Child Components':
33285
+ * https://medium.com/merrickchristensen/function-as-child-components-5f3920a9ace9#.sw0jiio8b
33286
+ */
33472
33287
  class HoverBehavior extends React.Component {
33473
33288
  constructor(props) {
33474
33289
  super(props);
@@ -34505,7 +34320,7 @@ const styles = StyleSheet.create({
34505
34320
  }
34506
34321
  });
34507
34322
 
34508
- /* eslint-disable react/forbid-prop-types, react/sort-comp */
34323
+ /* eslint-disable react/forbid-prop-types */
34509
34324
  const {
34510
34325
  InfoTip: InfoTip$a,
34511
34326
  TextListEditor: TextListEditor$3
@@ -34888,7 +34703,7 @@ MeasurerEditor.defaultProps = {
34888
34703
 
34889
34704
  const {
34890
34705
  NumberInput: NumberInput$6,
34891
- TextInput: TextInput$4
34706
+ TextInput: TextInput$3
34892
34707
  } = components;
34893
34708
  class MoleculeWidgetEditor extends React.Component {
34894
34709
  constructor(..._args) {
@@ -34913,7 +34728,7 @@ class MoleculeWidgetEditor extends React.Component {
34913
34728
  };
34914
34729
  }
34915
34730
  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, {
34731
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "SMILES:\xA0", /*#__PURE__*/React.createElement(TextInput$3, {
34917
34732
  onChange: this.updateMolecule,
34918
34733
  value: this.props.smiles
34919
34734
  }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Rotation (deg):\xA0", /*#__PURE__*/React.createElement(NumberInput$6, {
@@ -35246,14 +35061,14 @@ NumberLineEditor.defaultProps = {
35246
35061
  showTooltips: false
35247
35062
  };
35248
35063
 
35249
- /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
35064
+ /* eslint-disable jsx-a11y/anchor-is-valid */
35250
35065
  const {
35251
35066
  ButtonGroup,
35252
35067
  InfoTip: InfoTip$7,
35253
35068
  InlineIcon: InlineIcon$1,
35254
35069
  MultiButtonGroup,
35255
35070
  NumberInput: NumberInput$4,
35256
- TextInput: TextInput$3
35071
+ TextInput: TextInput$2
35257
35072
  } = components;
35258
35073
  const {
35259
35074
  iconGear,
@@ -35468,7 +35283,7 @@ class NumericInputEditor extends React.Component {
35468
35283
  }));
35469
35284
  const labelText = /*#__PURE__*/React.createElement("div", {
35470
35285
  className: "perseus-widget-row"
35471
- }, /*#__PURE__*/React.createElement("label", null, "Aria label", /*#__PURE__*/React.createElement(TextInput$3, {
35286
+ }, /*#__PURE__*/React.createElement("label", null, "Aria label", /*#__PURE__*/React.createElement(TextInput$2, {
35472
35287
  value: this.props.labelText,
35473
35288
  onChange: this.change("labelText")
35474
35289
  })), /*#__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 +35645,7 @@ PassageEditor.defaultProps = {
35830
35645
  const {
35831
35646
  InfoTip: InfoTip$4,
35832
35647
  NumberInput: NumberInput$3,
35833
- TextInput: TextInput$2
35648
+ TextInput: TextInput$1
35834
35649
  } = components;
35835
35650
  class PassageRefEditor extends React.Component {
35836
35651
  constructor(..._args) {
@@ -35853,7 +35668,7 @@ class PassageRefEditor extends React.Component {
35853
35668
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
35854
35669
  ,
35855
35670
  onChange: this.change("referenceNumber")
35856
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Summary Text: ", /*#__PURE__*/React.createElement(TextInput$2, {
35671
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Summary Text: ", /*#__PURE__*/React.createElement(TextInput$1, {
35857
35672
  value: this.props.summaryText
35858
35673
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
35859
35674
  ,
@@ -35907,14 +35722,32 @@ PassageRefTargetEditor.defaultProps = {
35907
35722
 
35908
35723
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
35909
35724
  class PhetSimulationEditor extends React.Component {
35725
+ constructor(...args) {
35726
+ super(...args);
35727
+ this.getSaveWarnings = () => {
35728
+ if (makeSafeUrl(this.props.url, "en") === null) {
35729
+ return ["Please enter a URL from the PhET domain."];
35730
+ }
35731
+ return [];
35732
+ };
35733
+ }
35734
+ serialize() {
35735
+ return {
35736
+ url: this.props.url,
35737
+ description: this.props.description
35738
+ };
35739
+ }
35910
35740
  render() {
35911
35741
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(LabeledTextField, {
35912
35742
  label: "URL",
35913
35743
  value: this.props.url,
35914
35744
  onChange: url => this.props.onChange({
35915
35745
  url
35916
- })
35917
- }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(LabeledTextField, {
35746
+ }),
35747
+ style: {
35748
+ marginBottom: spacing.large_24
35749
+ }
35750
+ }), /*#__PURE__*/React.createElement(LabeledTextField, {
35918
35751
  label: "Description",
35919
35752
  value: this.props.description,
35920
35753
  onChange: description => this.props.onChange({
@@ -35922,12 +35755,6 @@ class PhetSimulationEditor extends React.Component {
35922
35755
  })
35923
35756
  }));
35924
35757
  }
35925
- serialize() {
35926
- return {
35927
- url: this.props.url,
35928
- description: this.props.description
35929
- };
35930
- }
35931
35758
  }
35932
35759
  PhetSimulationEditor.defaultProps = {
35933
35760
  url: "",
@@ -36249,7 +36076,7 @@ PlotterEditor.defaultProps = _extends({}, editorDefaults, {
36249
36076
  */
36250
36077
  const {
36251
36078
  NumberInput: NumberInput$1,
36252
- TextInput: TextInput$1
36079
+ TextInput
36253
36080
  } = components;
36254
36081
  function validateOptions(height, programID) {
36255
36082
  const errors = [];
@@ -36283,7 +36110,7 @@ class PythonProgramEditor extends React.Component {
36283
36110
  };
36284
36111
  }
36285
36112
  render() {
36286
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "User Program ID:", " ", /*#__PURE__*/React.createElement(TextInput$1, {
36113
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "User Program ID:", " ", /*#__PURE__*/React.createElement(TextInput, {
36287
36114
  value: this.props.programID,
36288
36115
  onChange: this.change("programID"),
36289
36116
  placeholder: "123"
@@ -36595,62 +36422,6 @@ RadioEditor.defaultProps = {
36595
36422
  deselectEnabled: false
36596
36423
  };
36597
36424
 
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
36425
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
36655
36426
  const {
36656
36427
  InfoTip: InfoTip$2,
@@ -36714,7 +36485,6 @@ SorterEditor.defaultProps = {
36714
36485
  padding: true
36715
36486
  };
36716
36487
 
36717
- /* eslint-disable react/sort-comp */
36718
36488
  const {
36719
36489
  InfoTip: InfoTip$1,
36720
36490
  NumberInput
@@ -36881,219 +36651,12 @@ VideoEditor.defaultProps = {
36881
36651
  location: ""
36882
36652
  };
36883
36653
 
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];
36654
+ 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
36655
 
37093
36656
  Widgets.registerEditors(AllEditors);
37094
- Widgets.registerWidgets(AllWidgets);
36657
+ Widgets.registerWidgets(widgets);
37095
36658
  Widgets.replaceDeprecatedWidgets();
37096
36659
  Widgets.replaceDeprecatedEditors();
37097
36660
 
37098
- export { AllEditors, AllWidgets, ArticleDiff, ArticleEditor, DeviceFramer, Editor, EditorPage, IframeContentRenderer, ItemDiff, MultiRendererEditor, StatefulEditorPage, StructuredItemDiff, ViewportResizer, i18n, libVersion };
36661
+ export { AllEditors, ArticleDiff, ArticleEditor, DeviceFramer, Editor, EditorPage, IframeContentRenderer, ItemDiff, MultiRendererEditor, StatefulEditorPage, StructuredItemDiff, ViewportResizer, i18n, libVersion };
37099
36662
  //# sourceMappingURL=index.js.map