@khanacademy/perseus-editor 2.8.4 → 2.9.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @khanacademy/perseus-editor
2
2
 
3
+ ## 2.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#796](https://github.com/Khan/perseus/pull/796) [`c26fbdde`](https://github.com/Khan/perseus/commit/c26fbdde0d0bce0e7e88046eaddf88307f722eb9) Thanks [@nedredmond](https://github.com/nedredmond)! - Add option to show key on periodic table
8
+
9
+ ### Patch Changes
10
+
11
+ - [#670](https://github.com/Khan/perseus/pull/670) [`88616529`](https://github.com/Khan/perseus/commit/88616529c70f6c03529c26c2a4f04e5bb9f92b38) Thanks [@handeyeco](https://github.com/handeyeco)! - Update types for Plotter widget
12
+
13
+ - Updated dependencies [[`88616529`](https://github.com/Khan/perseus/commit/88616529c70f6c03529c26c2a4f04e5bb9f92b38), [`c26fbdde`](https://github.com/Khan/perseus/commit/c26fbdde0d0bce0e7e88046eaddf88307f722eb9), [`847b0568`](https://github.com/Khan/perseus/commit/847b0568bd5bb23ef08ddd8cbbe24f7158eeaaca), [`af4ebf37`](https://github.com/Khan/perseus/commit/af4ebf37dfed15ffd93a8cf2a20d0be464120dd7)]:
14
+ - @khanacademy/perseus@13.0.0
15
+
16
+ ## 2.8.5
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [[`cfff6ad1`](https://github.com/Khan/perseus/commit/cfff6ad16a3923418a3c75816af7c99689b94da4), [`79403e06`](https://github.com/Khan/perseus/commit/79403e06eedb597d7818d6c858bbba6f51ff3fe1)]:
21
+ - @khanacademy/perseus@12.4.0
22
+ - @khanacademy/perseus-core@1.3.0
23
+ - @khanacademy/kas@0.3.5
24
+ - @khanacademy/kmath@0.1.6
25
+
3
26
  ## 2.8.4
4
27
 
5
28
  ### Patch Changes
package/dist/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { addLibraryVersionToPerseusDebug } from '@khanacademy/perseus-core';
2
- import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusError, Errors, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, BaseRadio, TableWidget, TransformerWidget, displaySigFigs, widgets } from '@khanacademy/perseus';
2
+ import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, PerseusError, Errors, PerseusMarkdown, preprocessTex, ApiOptions, buildMapper, itemToTree, buildEmptyItemTreeForShape, shapes, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, TransformerWidget, displaySigFigs, widgets } from '@khanacademy/perseus';
3
3
  import * as React from 'react';
4
4
  import _ from 'underscore';
5
5
  import PropTypes from 'prop-types';
@@ -22,7 +22,7 @@ import * as i18n$1 from '@khanacademy/wonder-blocks-i18n';
22
22
 
23
23
  // This file is processed by a Rollup plugin (replace) to inject the production
24
24
  const libName = "@khanacademy/perseus-editor";
25
- const libVersion = "2.8.4";
25
+ const libVersion = "2.9.0";
26
26
  addLibraryVersionToPerseusDebug(libName, libVersion);
27
27
 
28
28
  function _extends() {
@@ -20927,6 +20927,10 @@ class Editor extends React.Component {
20927
20927
  content: textarea.value.replace(re, "")
20928
20928
  });
20929
20929
  };
20930
+ /**
20931
+ * Calculate the size of all the images in props.content, and send
20932
+ * those sizes to this.props.images using props.onChange.
20933
+ */
20930
20934
  this._sizeImages = props => {
20931
20935
  const imageUrls = imageUrlsFromContent(props.content);
20932
20936
 
@@ -21693,9 +21697,12 @@ class IframeContentRenderer extends React.Component {
21693
21697
  constructor(...args) {
21694
21698
  super(...args);
21695
21699
  this._frame = void 0;
21700
+ // @ts-expect-error - TS2564 - Property '_isMounted' has no initializer and is not definitely assigned in the constructor.
21696
21701
  this._isMounted = void 0;
21697
21702
  this._lastData = void 0;
21703
+ // @ts-expect-error - TS2564 - Property '_lastHeight' has no initializer and is not definitely assigned in the constructor.
21698
21704
  this._lastHeight = void 0;
21705
+ // @ts-expect-error - TS2564 - Property 'iframeID' has no initializer and is not definitely assigned in the constructor.
21699
21706
  this.iframeID = void 0;
21700
21707
  }
21701
21708
  componentDidMount() {
@@ -23120,7 +23127,6 @@ const filterWidgetInfo = function filterWidgetInfo(widgetInfo, showAlignmentOpti
23120
23127
 
23121
23128
  // TODO(michaelpolyak): This type is very similar to `PerseusRenderer` type
23122
23129
  // found in `perseus-all-package/perseus-type.js`, consider just using it.
23123
-
23124
23130
  class RendererDiff extends React.Component {
23125
23131
  render() {
23126
23132
  var _before$widgets, _after$widgets;
@@ -23835,6 +23841,7 @@ class ItemExtrasEditor extends React.Component {
23835
23841
  calculator: this.props.calculator,
23836
23842
  chi2Table: this.props.chi2Table,
23837
23843
  periodicTable: this.props.periodicTable,
23844
+ periodicTableWithKey: this.props.periodicTableWithKey,
23838
23845
  tTable: this.props.tTable,
23839
23846
  zTable: this.props.zTable
23840
23847
  };
@@ -23861,7 +23868,15 @@ class ItemExtrasEditor extends React.Component {
23861
23868
  periodicTable: e.target.checked
23862
23869
  });
23863
23870
  }
23864
- })), /*#__PURE__*/React.createElement(InfoTip$m, null, "This provides the student with the ability to view a periodic table of the elements, e.g., for answering chemistry questions.")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Show z table (statistics):", " ", /*#__PURE__*/React.createElement("input", {
23871
+ })), /*#__PURE__*/React.createElement(InfoTip$m, null, "This provides the student with the ability to view a periodic table of the elements, e.g., for answering chemistry questions.")), this.props.periodicTable && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Include key/legend with periodic table:", " ", /*#__PURE__*/React.createElement("input", {
23872
+ type: "checkbox",
23873
+ checked: this.props.periodicTableWithKey,
23874
+ onChange: e => {
23875
+ this.props.onChange({
23876
+ periodicTableWithKey: e.target.checked
23877
+ });
23878
+ }
23879
+ })), /*#__PURE__*/React.createElement(InfoTip$m, null, "Include a key for HS courses, omit for AP chemistry.")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Show z table (statistics):", " ", /*#__PURE__*/React.createElement("input", {
23865
23880
  type: "checkbox",
23866
23881
  checked: this.props.zTable,
23867
23882
  onChange: e => {
@@ -23893,6 +23908,7 @@ ItemExtrasEditor.propTypes = {
23893
23908
  chi2Table: PropTypes.bool,
23894
23909
  onChange: PropTypes.func.isRequired,
23895
23910
  periodicTable: PropTypes.bool,
23911
+ periodicTableWithKey: PropTypes.bool,
23896
23912
  tTable: PropTypes.bool,
23897
23913
  zTable: PropTypes.bool
23898
23914
  };
@@ -23900,6 +23916,7 @@ ItemExtrasEditor.defaultProps = {
23900
23916
  calculator: false,
23901
23917
  chi2Table: false,
23902
23918
  periodicTable: false,
23919
+ periodicTableWithKey: false,
23903
23920
  tTable: false,
23904
23921
  zTable: false
23905
23922
  };
@@ -23908,6 +23925,7 @@ const ITEM_DATA_VERSION = itemDataVersion;
23908
23925
  class ItemEditor extends React.Component {
23909
23926
  constructor(...args) {
23910
23927
  super(...args);
23928
+ // Notify the parent that the question or answer area has been updated.
23911
23929
  this.updateProps = (newProps, cb, silent) => {
23912
23930
  const props = _(this.props).pick("question", "answerArea");
23913
23931
  this.props.onChange(_(props).extend(newProps), cb, silent);
@@ -24022,11 +24040,10 @@ const {
24022
24040
  HUD
24023
24041
  } = components;
24024
24042
  class EditorPage extends React.Component {
24025
- // @ts-expect-error - TS2564 - Property 'rendererMountNode' has no initializer and is not definitely assigned in the constructor.
24026
-
24027
24043
  constructor(props) {
24028
24044
  super(props);
24029
24045
  this._isMounted = void 0;
24046
+ // @ts-expect-error - TS2564 - Property 'rendererMountNode' has no initializer and is not definitely assigned in the constructor.
24030
24047
  this.rendererMountNode = void 0;
24031
24048
  this.renderer = void 0;
24032
24049
  this.toggleJsonMode = () => {
@@ -24893,7 +24910,6 @@ function multiPath(path) {
24893
24910
 
24894
24911
  // Return an h1 if depth=0, h2 if depth=1, etc.
24895
24912
  // NOTE: This component accepts pass-through props.
24896
-
24897
24913
  const Header = _ref => {
24898
24914
  let {
24899
24915
  depth
@@ -24906,6 +24922,9 @@ const Header = _ref => {
24906
24922
 
24907
24923
  // Actions is inexact so that we can pass an instance MultiRendererEditor.
24908
24924
 
24925
+ // This type is used to define prop types for various nodes. The S and D type
24926
+ // params should match when used, e.g. the prop types for `HintNodeContent` is
24927
+ // `NodePropTypes<HintShape, HintNode>`.
24909
24928
  /**
24910
24929
  * Render a node in the editor tree, given the shape of the target
24911
24930
  * node, the data stored in the target node, the path to the target
@@ -25109,6 +25128,7 @@ const withStickiness = WrappedComponent => {
25109
25128
  return class StickyComponent extends React.Component {
25110
25129
  constructor(...args) {
25111
25130
  super(...args);
25131
+ // @ts-expect-error - TS2564 - Property 'stickynessTimer' has no initializer and is not definitely assigned in the constructor.
25112
25132
  this.stickynessTimer = void 0;
25113
25133
  this.state = {
25114
25134
  sticky: false
@@ -25843,8 +25863,7 @@ CategorizerEditor.defaultProps = {
25843
25863
  *
25844
25864
  * Enough melodrama. Its an input that only sends changes
25845
25865
  * to its parent on blur.
25846
- */
25847
- // eslint-disable-next-line react/no-unsafe
25866
+ */ // eslint-disable-next-line react/no-unsafe
25848
25867
  class BlurInput extends React.Component {
25849
25868
  constructor(props) {
25850
25869
  super(props);
@@ -26740,6 +26759,9 @@ const {
26740
26759
  const {
26741
26760
  getDependencies: getDependencies$2
26742
26761
  } = Dependencies;
26762
+
26763
+ // types for iterables
26764
+
26743
26765
  const parseAnswerKey = ({
26744
26766
  key
26745
26767
  }) => {
@@ -26851,6 +26873,8 @@ class ExpressionEditor extends React.Component {
26851
26873
  answerForms
26852
26874
  });
26853
26875
  };
26876
+ // called when the options (including the expression itself) to an answer
26877
+ // form change
26854
26878
  this.updateForm = (i, props) => {
26855
26879
  const answerForms = lens(this.props.answerForms).merge([i], props).freeze();
26856
26880
  this.change({
@@ -26868,6 +26892,7 @@ class ExpressionEditor extends React.Component {
26868
26892
  answerForms
26869
26893
  });
26870
26894
  };
26895
+ // called when the selected buttonset changes
26871
26896
  this.handleButtonSet = changingName => {
26872
26897
  const buttonSetNames = Object.keys(TexButtons.buttonSets);
26873
26898
 
@@ -26897,11 +26922,13 @@ class ExpressionEditor extends React.Component {
26897
26922
  const buttonSets = this.props.buttonSets.filter(set => set !== remove).concat(keep);
26898
26923
  this.change("buttonSets", buttonSets);
26899
26924
  };
26925
+ // called when the correct answer changes
26900
26926
  this.handleTexInsert = str => {
26901
26927
  // eslint-disable-next-line react/no-string-refs
26902
26928
  // @ts-expect-error - TS2339 - Property 'insert' does not exist on type 'ReactInstance'.
26903
26929
  this.refs.expression.insert(str);
26904
26930
  };
26931
+ // called when the function variables change
26905
26932
  this.handleFunctions = e => {
26906
26933
  const newProps = {};
26907
26934
  newProps.functions = e.target.value.split(/[ ,]+/).filter(isTruthy);
@@ -27260,6 +27287,7 @@ const styles$a = StyleSheet.create({
27260
27287
  class GradedGroupSetEditor extends React.Component {
27261
27288
  constructor(..._args) {
27262
27289
  super(..._args);
27290
+ // @ts-expect-error - TS2564 - Property '_editors' has no initializer and is not definitely assigned in the constructor.
27263
27291
  this._editors = void 0;
27264
27292
  this.change = (...args) => {
27265
27293
  return Changeable.change.apply(this, args);
@@ -29736,6 +29764,7 @@ class InteractionEditor extends React.Component {
29736
29764
  /* eslint-enable max-len */
29737
29765
  }
29738
29766
  }
29767
+ // TODO(eater): Make more better
29739
29768
  InteractionEditor.propTypes = _extends({}, Changeable.propTypes, {
29740
29769
  // eslint-disable-next-line react/forbid-prop-types
29741
29770
  elements: PropTypes.arrayOf(PropTypes.object),
@@ -29838,7 +29867,6 @@ const deprecatedProps = {
29838
29867
  }
29839
29868
  };
29840
29869
  // [min, max]
29841
-
29842
29870
  // Renders the given children in a View laid out horizontally.
29843
29871
  const Row = props => {
29844
29872
  const {
@@ -29864,6 +29892,7 @@ class InteractiveGraphEditor extends React.Component {
29864
29892
  super(...args);
29865
29893
  this.displayName = "InteractiveGraphEditor";
29866
29894
  this.className = "perseus-widget-interactive-graph";
29895
+ // TODO(jack): Use versioning instead of DeprecationMixin
29867
29896
  this.deprecatedProps = deprecatedProps;
29868
29897
  }
29869
29898
  // TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
@@ -30545,7 +30574,9 @@ const editorStyles = StyleSheet.create({
30545
30574
  class HoverBehavior extends React.Component {
30546
30575
  constructor(props) {
30547
30576
  super(props);
30577
+ // @ts-expect-error - TS2564 - Property 'focusFlag' has no initializer and is not definitely assigned in the constructor.
30548
30578
  this.focusFlag = void 0;
30579
+ // @ts-expect-error - TS2564 - Property 'waitingForClick' has no initializer and is not definitely assigned in the constructor.
30549
30580
  this.waitingForClick = void 0;
30550
30581
  this.handleClick = e => {
30551
30582
  if (!this.props.disabled) {
@@ -30617,9 +30648,6 @@ class HoverBehavior extends React.Component {
30617
30648
  hovered: props.startHovered
30618
30649
  };
30619
30650
  }
30620
-
30621
- // @ts-expect-error - TS2564 - Property 'focusFlag' has no initializer and is not definitely assigned in the constructor.
30622
-
30623
30651
  render() {
30624
30652
  const handlers = {
30625
30653
  onBlur: this.handleBlur,
@@ -30877,6 +30905,7 @@ const optionHeight = 30;
30877
30905
  class Option extends React.Component {
30878
30906
  constructor(...args) {
30879
30907
  super(...args);
30908
+ // @ts-expect-error - TS2564 - Property 'node' has no initializer and is not definitely assigned in the constructor.
30880
30909
  this.node = void 0;
30881
30910
  }
30882
30911
  handleKeyDown(event) {
@@ -30958,6 +30987,7 @@ class Option extends React.Component {
30958
30987
  class OptionGroup extends React.Component {
30959
30988
  constructor(...args) {
30960
30989
  super(...args);
30990
+ // @ts-expect-error - TS2564 - Property 'focusedElement' has no initializer and is not definitely assigned in the constructor.
30961
30991
  this.focusedElement = void 0;
30962
30992
  }
30963
30993
  componentDidMount() {
@@ -33140,12 +33170,6 @@ const {
33140
33170
  TextListEditor: TextListEditor$1
33141
33171
  } = components;
33142
33172
  const Plotter = PlotterWidget.widget;
33143
- const BAR = "bar";
33144
- const LINE = "line";
33145
- const PIC = "pic";
33146
- const HISTOGRAM = "histogram";
33147
- const DOTPLOT = "dotplot";
33148
- const plotTypes = [BAR, LINE, PIC, HISTOGRAM, DOTPLOT];
33149
33173
  const STARTING = "starting";
33150
33174
  const CORRECT = "correct";
33151
33175
  const editingStates = [STARTING, CORRECT];
@@ -33210,7 +33234,7 @@ class PlotterEditor extends React.Component {
33210
33234
  };
33211
33235
  this.changeType = type => {
33212
33236
  let categories;
33213
- if (type === HISTOGRAM) {
33237
+ if (type === "histogram") {
33214
33238
  // Switching to histogram, add a label (0) to the left
33215
33239
  // @ts-expect-error - TS2769
33216
33240
  categories = [formatNumber(0)].concat(this.props.categories);
@@ -33218,7 +33242,7 @@ class PlotterEditor extends React.Component {
33218
33242
  type: type,
33219
33243
  categories: categories
33220
33244
  });
33221
- } else if (this.props.type === HISTOGRAM) {
33245
+ } else if (this.props.type === "histogram") {
33222
33246
  // Switching from histogram, remove a label from the left
33223
33247
  categories = this.props.categories.slice(1);
33224
33248
  this.props.onChange({
@@ -33255,7 +33279,7 @@ class PlotterEditor extends React.Component {
33255
33279
  };
33256
33280
  this.changeCategories = categories => {
33257
33281
  let n = categories.length;
33258
- if (this.props.type === HISTOGRAM) {
33282
+ if (this.props.type === "histogram") {
33259
33283
  // Histograms with n labels/categories have n - 1 buckets
33260
33284
  n--;
33261
33285
  }
@@ -33304,7 +33328,7 @@ class PlotterEditor extends React.Component {
33304
33328
  const max = this.state.maxX || 0;
33305
33329
  const length = Math.floor((max - min) / scale) * scale;
33306
33330
  let categories;
33307
- if (this.props.type === HISTOGRAM || this.props.type === DOTPLOT) {
33331
+ if (this.props.type === "histogram" || this.props.type === "dotplot") {
33308
33332
  // Ranges for histogram and dotplot labels should start at zero
33309
33333
  categories = _.range(0, length + scale, scale);
33310
33334
  } else {
@@ -33322,7 +33346,7 @@ class PlotterEditor extends React.Component {
33322
33346
  };
33323
33347
  this.serialize = () => {
33324
33348
  const json = _.pick(this.props, "correct", "starting", "type", "labels", "categories", "scaleY", "maxY", "snapsPerLine", "labelInterval");
33325
- if (this.props.type === PIC) {
33349
+ if (this.props.type === "pic") {
33326
33350
  // @ts-expect-error - TS2339 - Property 'picUrl' does not exist on type 'Pick<Readonly<any> & Readonly<{ children?: ReactNode; }>, "type" | "correct" | "labels" | "categories" | "starting" | "scaleY" | "maxY" | "snapsPerLine" | "labelInterval">'.
33327
33351
  json.picUrl = this.props.picUrl;
33328
33352
  }
@@ -33342,14 +33366,14 @@ class PlotterEditor extends React.Component {
33342
33366
  }
33343
33367
  }
33344
33368
  render() {
33345
- const setFromScale = _.contains([LINE, HISTOGRAM, DOTPLOT], this.props.type);
33346
- const canChangeSnaps = !_.contains([PIC, DOTPLOT], this.props.type);
33369
+ const setFromScale = _.contains(["line", "histogram", "dotplot"], this.props.type);
33370
+ const canChangeSnaps = !_.contains(["pic", "dotplot"], this.props.type);
33347
33371
  const props = _extends({
33348
33372
  trackInteraction: () => {}
33349
33373
  }, this.props);
33350
33374
  return /*#__PURE__*/React.createElement("div", {
33351
33375
  className: "perseus-widget-plotter-editor"
33352
- }, /*#__PURE__*/React.createElement("div", null, "Chart type:", " ", plotTypes.map(type => {
33376
+ }, /*#__PURE__*/React.createElement("div", null, "Chart type:", " ", plotterPlotTypes.map(type => {
33353
33377
  return /*#__PURE__*/React.createElement("label", {
33354
33378
  key: type
33355
33379
  }, /*#__PURE__*/React.createElement("input", {
@@ -33386,7 +33410,7 @@ class PlotterEditor extends React.Component {
33386
33410
  useArrowKeys: true,
33387
33411
  value: this.props.labelInterval,
33388
33412
  onChange: this.changeLabelInterval
33389
- })), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "Which ticks to display the labels for. For instance, setting this to \"4\" will only show every 4th label (plus the last one)"))), this.props.type === PIC && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Picture:", " ", /*#__PURE__*/React.createElement(BlurInput, {
33413
+ })), /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "Which ticks to display the labels for. For instance, setting this to \"4\" will only show every 4th label (plus the last one)"))), this.props.type === "pic" && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Picture:", " ", /*#__PURE__*/React.createElement(BlurInput, {
33390
33414
  className: "pic-url",
33391
33415
  value: this.props.picUrl,
33392
33416
  onChange: this.changePicUrl
@@ -33431,7 +33455,7 @@ PlotterEditor.widgetName = "plotter";
33431
33455
  PlotterEditor.defaultProps = _extends({}, editorDefaults, {
33432
33456
  correct: [1],
33433
33457
  starting: [1],
33434
- type: BAR,
33458
+ type: "bar",
33435
33459
  labels: ["", ""],
33436
33460
  categories: [""],
33437
33461
  picSize: 30,
@@ -34857,6 +34881,7 @@ const ShapeTypes = {
34857
34881
  class TransformationsShapeEditor extends React.Component {
34858
34882
  constructor(...args) {
34859
34883
  super(...args);
34884
+ /* Return the option string for a given type */
34860
34885
  this.getTypeString = type => {
34861
34886
  if (_.isArray(type)) {
34862
34887
  return _.map(type, this.getTypeString).join(",");
@@ -34866,6 +34891,10 @@ class TransformationsShapeEditor extends React.Component {
34866
34891
  }
34867
34892
  return type;
34868
34893
  };
34894
+ /* Change the type on the window event e
34895
+ *
34896
+ * e.target.value is the new type string
34897
+ */
34869
34898
  this.changeType = e => {
34870
34899
  const types = String(e.target.value).split(",");
34871
34900
  const pointCount = arraySum(_.map(types, ShapeTypes.getPointCountForType));
@@ -34940,9 +34969,6 @@ class TransformationsShapeEditor extends React.Component {
34940
34969
  value: "circle"
34941
34970
  }, "Circle")));
34942
34971
  }
34943
-
34944
- /* Return the option string for a given type */
34945
-
34946
34972
  componentDidMount() {
34947
34973
  // eslint-disable-next-line react/no-string-refs
34948
34974
  // @ts-expect-error - TS2339 - Property 'graphie' does not exist on type 'ReactInstance'.
@@ -34959,18 +34985,23 @@ class TransformationsShapeEditor extends React.Component {
34959
34985
  class TransformerEditor extends React.Component {
34960
34986
  constructor(...args) {
34961
34987
  super(...args);
34988
+ // propagate a props change on our graph settings to
34989
+ // this.props.graph
34962
34990
  this.changeGraph = (graphChanges, callback) => {
34963
34991
  const newGraph = _.extend({}, this.props.graph, graphChanges);
34964
34992
  this.props.onChange({
34965
34993
  graph: newGraph
34966
34994
  }, callback);
34967
34995
  };
34996
+ // propagate a props change on our starting graph to
34997
+ // this.props.starting
34968
34998
  this.changeStarting = startingChanges => {
34969
34999
  const newStarting = _.extend({}, this.props.starting, startingChanges);
34970
35000
  this.props.onChange({
34971
35001
  starting: newStarting
34972
35002
  });
34973
35003
  };
35004
+ // propagate a transformations change onto correct.transformations
34974
35005
  this.changeTransformer = (changes, callback) => {
34975
35006
  if (changes.transformations) {
34976
35007
  changes.correct = _extends({}, this.props.correct, {
@@ -35043,10 +35074,9 @@ class TransformerEditor extends React.Component {
35043
35074
  trackInteraction: () => {}
35044
35075
  }));
35045
35076
  }
35046
-
35047
- // propagate a props change on our graph settings to
35048
- // this.props.graph
35049
35077
  }
35078
+ // TODO (jack): These should be refactored into a nice object at the top
35079
+ // so that we don't have all this duplication
35050
35080
  TransformerEditor.defaultProps = defaultTransformerProps;
35051
35081
  TransformerEditor.widgetName = "transformer";
35052
35082
 
@@ -35366,18 +35396,38 @@ class TextInput extends React.Component {
35366
35396
  class ExampleWidget extends React.Component {
35367
35397
  constructor(..._args) {
35368
35398
  super(..._args);
35399
+ /**
35400
+ * Tell our parent to update our props.
35401
+ */
35369
35402
  this.change = (...args) => {
35370
35403
  return Changeable.change.apply(this, args);
35371
35404
  };
35372
35405
  this.getUserInput = () => {
35373
35406
  return this.props.value;
35374
35407
  };
35408
+ /**
35409
+ * Widgets that are focusable should add a focus method that returns
35410
+ * true if focusing succeeded. The first such widget found will be
35411
+ * focused on page load.
35412
+ */
35375
35413
  this.focus = () => {
35376
35414
  // eslint-disable-next-line react/no-string-refs
35377
35415
  // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
35378
35416
  this.refs.input.focus();
35379
35417
  return true;
35380
35418
  };
35419
+ /**
35420
+ * simpleValidate is called for grading. Rubric is the result of calling
35421
+ * getUserInput() on the editor that created this widget.
35422
+ *
35423
+ * Should return an object representing the grading result, such as
35424
+ * {
35425
+ * type: "points",
35426
+ * earned: 1,
35427
+ * total: 1,
35428
+ * message: null
35429
+ * }
35430
+ */
35381
35431
  this.simpleValidate = rubric => {
35382
35432
  return ExampleWidget.validate(this.getUserInput(), rubric);
35383
35433
  };
@@ -35411,11 +35461,6 @@ class ExampleWidget extends React.Component {
35411
35461
  message: null
35412
35462
  };
35413
35463
  }
35414
-
35415
- /**
35416
- * Tell our parent to update our props.
35417
- */
35418
-
35419
35464
  render() {
35420
35465
  return /*#__PURE__*/React.createElement(TextInput
35421
35466
  // eslint-disable-next-line react/no-string-refs
@@ -35460,12 +35505,29 @@ class SimpleMarkdownTester extends React.Component {
35460
35505
  this.toJSON = () => {
35461
35506
  return {};
35462
35507
  };
35508
+ /**
35509
+ * Widgets that are focusable should add a focus method that returns
35510
+ * true if focusing succeeded. The first such widget found will be
35511
+ * focused on page load.
35512
+ */
35463
35513
  this.focus = () => {
35464
35514
  // eslint-disable-next-line react/no-string-refs
35465
35515
  // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'ReactInstance'.
35466
35516
  this.refs.input.focus();
35467
35517
  return true;
35468
35518
  };
35519
+ /**
35520
+ * simpleValidate is called for grading. Rubric is the result of calling
35521
+ * toJSON() on the editor that created this widget.
35522
+ *
35523
+ * Should return an object representing the grading result, such as
35524
+ * {
35525
+ * type: "points",
35526
+ * earned: 1,
35527
+ * total: 1,
35528
+ * message: null
35529
+ * }
35530
+ */
35469
35531
  this.simpleValidate = rubric => {
35470
35532
  return SimpleMarkdownTester.validate(this.toJSON(), rubric);
35471
35533
  };
@@ -35492,12 +35554,6 @@ class SimpleMarkdownTester extends React.Component {
35492
35554
  const output = mdOutput(parsed);
35493
35555
  return /*#__PURE__*/React.createElement("div", null, output);
35494
35556
  }
35495
-
35496
- /**
35497
- * Widgets that are focusable should add a focus method that returns
35498
- * true if focusing succeeded. The first such widget found will be
35499
- * focused on page load.
35500
- */
35501
35557
  }
35502
35558
 
35503
35559
  /**