@khanacademy/perseus-editor 5.2.13 → 5.3.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/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, ItemExtras, 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, 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, ItemExtras, itemDataVersion, ClassNames, MultiItems, traverse, Categorizer as Categorizer$1, Changeable, EditorJsonify, Dependencies, WidgetJsonifyDeprecated, PerseusExpressionAnswerFormConsidered, Expression, interactiveSizes, KhanMath, GrapherWidget, GrapherUtil, SizingUtils, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, lockedFigureColors, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, displaySigFigs, widgets } from '@khanacademy/perseus';
3
3
  import * as React from 'react';
4
4
  import { useRef, useEffect } from 'react';
5
5
  import _ from 'underscore';
@@ -16,33 +16,33 @@ import classNames from 'classnames';
16
16
  import ReactDOM from 'react-dom';
17
17
  import { point, number } from '@khanacademy/kmath';
18
18
  import * as KAS from '@khanacademy/kas';
19
- import { isTruthy } from '@khanacademy/wonder-stuff-core';
19
+ import { isTruthy, UnreachableCaseError } from '@khanacademy/wonder-stuff-core';
20
20
  import { createMathField } from '@khanacademy/math-input';
21
21
  import { SingleSelect, OptionItem, ActionMenu, ActionItem } from '@khanacademy/wonder-blocks-dropdown';
22
22
  import { TextField, Checkbox as Checkbox$1 } from '@khanacademy/wonder-blocks-form';
23
- import { LabelSmall, LabelLarge, LabelMedium, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
23
+ import { LabelSmall, LabelMedium, LabelLarge, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
24
+ import { AccordionSection } from '@khanacademy/wonder-blocks-accordion';
24
25
  import IconButton from '@khanacademy/wonder-blocks-icon-button';
26
+ import Switch from '@khanacademy/wonder-blocks-switch';
25
27
  import trashIcon from '@phosphor-icons/core/bold/trash-bold.svg';
26
28
  import Button from '@khanacademy/wonder-blocks-button';
27
29
  import * as i18n$1 from '@khanacademy/wonder-blocks-i18n';
28
30
 
29
31
  // This file is processed by a Rollup plugin (replace) to inject the production
30
32
  const libName = "@khanacademy/perseus-editor";
31
- const libVersion = "5.2.13";
33
+ const libVersion = "5.3.0";
32
34
  addLibraryVersionToPerseusDebug(libName, libVersion);
33
35
 
34
36
  function _extends() {
35
37
  _extends = Object.assign ? Object.assign.bind() : function (target) {
36
38
  for (var i = 1; i < arguments.length; i++) {
37
39
  var source = arguments[i];
38
-
39
40
  for (var key in source) {
40
41
  if (Object.prototype.hasOwnProperty.call(source, key)) {
41
42
  target[key] = source[key];
42
43
  }
43
44
  }
44
45
  }
45
-
46
46
  return target;
47
47
  };
48
48
  return _extends.apply(this, arguments);
@@ -220,7 +220,7 @@ class SectionControlButton extends React.Component {
220
220
  role: "button",
221
221
  hideDefaultFocusRing: true,
222
222
  "aria-label": title,
223
- style: styles$q.button
223
+ style: styles$r.button
224
224
  }, ({
225
225
  hovered,
226
226
  focused,
@@ -228,7 +228,7 @@ class SectionControlButton extends React.Component {
228
228
  }) => /*#__PURE__*/React.createElement(InlineIcon$b, icon));
229
229
  }
230
230
  }
231
- const styles$q = StyleSheet.create({
231
+ const styles$r = StyleSheet.create({
232
232
  button: {
233
233
  backgroundColor: color.gold,
234
234
  margin: 2,
@@ -20750,19 +20750,19 @@ class TexErrorView extends React.Component {
20750
20750
  const {
20751
20751
  showErrors
20752
20752
  } = this.state;
20753
- const iconStyle = showErrors ? styles$p.iconExpanded : styles$p.iconCollapsed;
20753
+ const iconStyle = showErrors ? styles$q.iconExpanded : styles$q.iconCollapsed;
20754
20754
  return /*#__PURE__*/React.createElement(View, {
20755
- style: styles$p.errorContainer
20755
+ style: styles$q.errorContainer
20756
20756
  }, /*#__PURE__*/React.createElement(View, {
20757
- style: styles$p.title,
20757
+ style: styles$q.title,
20758
20758
  onClick: this.handleToggleTexErrors
20759
20759
  }, /*#__PURE__*/React.createElement(PhosphorIcon, {
20760
20760
  icon: caretRight,
20761
20761
  style: iconStyle
20762
20762
  }), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React.createElement(View, {
20763
- style: styles$p.errorExplanation
20763
+ style: styles$q.errorExplanation
20764
20764
  }, "If your math doesn't display correctly, these errors might help you troubleshoot. Message #content-kitchen for help."), showErrors && errorList.map((e, index) => /*#__PURE__*/React.createElement(View, {
20765
- style: styles$p.error,
20765
+ style: styles$q.error,
20766
20766
  key: index
20767
20767
  }, /*#__PURE__*/React.createElement(View, {
20768
20768
  style: {
@@ -20771,7 +20771,7 @@ class TexErrorView extends React.Component {
20771
20771
  }, e.math), /*#__PURE__*/React.createElement(View, null, e.message))));
20772
20772
  }
20773
20773
  }
20774
- const styles$p = StyleSheet.create({
20774
+ const styles$q = StyleSheet.create({
20775
20775
  title: {
20776
20776
  backgroundColor: "#eee",
20777
20777
  fontSize: "1.25em",
@@ -24336,13 +24336,11 @@ function _objectWithoutPropertiesLoose(source, excluded) {
24336
24336
  var target = {};
24337
24337
  var sourceKeys = Object.keys(source);
24338
24338
  var key, i;
24339
-
24340
24339
  for (i = 0; i < sourceKeys.length; i++) {
24341
24340
  key = sourceKeys[i];
24342
24341
  if (excluded.indexOf(key) >= 0) continue;
24343
24342
  target[key] = source[key];
24344
24343
  }
24345
-
24346
24344
  return target;
24347
24345
  }
24348
24346
 
@@ -24574,7 +24572,7 @@ class SimpleButton extends React.Component {
24574
24572
  } = _this$props,
24575
24573
  otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$3);
24576
24574
  return /*#__PURE__*/React.createElement("div", _extends({
24577
- className: css(styles$o.baseButton, color === "green" && styles$o.green, color === "orange" && styles$o.orange),
24575
+ className: css(styles$p.baseButton, color === "green" && styles$p.green, color === "orange" && styles$p.orange),
24578
24576
  onClick: onClick
24579
24577
  }, otherProps), children);
24580
24578
  }
@@ -24589,7 +24587,7 @@ SimpleButton.defaultProps = {
24589
24587
  color: "green",
24590
24588
  onClick: () => {}
24591
24589
  };
24592
- const styles$o = StyleSheet.create({
24590
+ const styles$p = StyleSheet.create({
24593
24591
  baseButton: {
24594
24592
  top: "0",
24595
24593
  fontSize: "11px",
@@ -24809,23 +24807,23 @@ const LeafContainer = ({
24809
24807
  }) => {
24810
24808
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
24811
24809
  const previewHeading = hasPreviewHeading && /*#__PURE__*/React.createElement("div", {
24812
- className: css(styles$n.containerHeader)
24810
+ className: css(styles$o.containerHeader)
24813
24811
  }, /*#__PURE__*/React.createElement(Header, {
24814
24812
  depth: path.length,
24815
- className: css(styles$n.containerTitle)
24813
+ className: css(styles$o.containerTitle)
24816
24814
  }, capitalize(name)));
24817
24815
  return /*#__PURE__*/React.createElement("div", {
24818
- className: css(styles$n.container)
24816
+ className: css(styles$o.container)
24819
24817
  }, /*#__PURE__*/React.createElement("span", {
24820
- className: css(styles$n.row, styles$n.rowHeading)
24818
+ className: css(styles$o.row, styles$o.rowHeading)
24821
24819
  }, /*#__PURE__*/React.createElement("div", {
24822
- className: css(styles$n.columnLeft)
24820
+ className: css(styles$o.columnLeft)
24823
24821
  }, /*#__PURE__*/React.createElement("div", {
24824
- className: "pod-title " + css(styles$n.containerHeader)
24822
+ className: "pod-title " + css(styles$o.containerHeader)
24825
24823
  }, /*#__PURE__*/React.createElement("div", {
24826
- className: css(styles$n.containerTitle)
24824
+ className: css(styles$o.containerTitle)
24827
24825
  }, capitalize(name)), controls)), /*#__PURE__*/React.createElement("div", {
24828
- className: css(styles$n.columnRight)
24826
+ className: css(styles$o.columnRight)
24829
24827
  }, previewHeading)), children);
24830
24828
  };
24831
24829
  const ArrayContainer = props => {
@@ -24838,11 +24836,11 @@ const ArrayContainer = props => {
24838
24836
  actions
24839
24837
  } = props;
24840
24838
  return /*#__PURE__*/React.createElement("div", {
24841
- className: css(styles$n.container)
24839
+ className: css(styles$o.container)
24842
24840
  }, controls && /*#__PURE__*/React.createElement("div", {
24843
- className: css(styles$n.columnLeft, styles$n.containerHeader)
24841
+ className: css(styles$o.columnLeft, styles$o.containerHeader)
24844
24842
  }, controls), /*#__PURE__*/React.createElement("div", null, children), /*#__PURE__*/React.createElement("div", {
24845
- className: css(styles$n.columnLeft)
24843
+ className: css(styles$o.columnLeft)
24846
24844
  }, /*#__PURE__*/React.createElement("a", {
24847
24845
  href: "javascript:void 0",
24848
24846
  onClick: () => actions.addArrayElement(path, shape.elementShape)
@@ -24855,28 +24853,28 @@ const ObjectContainer = ({
24855
24853
  path
24856
24854
  }) => {
24857
24855
  const headingEditor = /*#__PURE__*/React.createElement("div", {
24858
- className: css(styles$n.containerHeader)
24856
+ className: css(styles$o.containerHeader)
24859
24857
  }, /*#__PURE__*/React.createElement(Header, {
24860
24858
  depth: path.length,
24861
- className: css(styles$n.containerTitle)
24859
+ className: css(styles$o.containerTitle)
24862
24860
  }, capitalize(name)), controls);
24863
24861
  const headingPreview = (name || controls) && /*#__PURE__*/React.createElement("div", {
24864
- className: css(styles$n.containerHeader, styles$n.previewCollectionHeader)
24862
+ className: css(styles$o.containerHeader, styles$o.previewCollectionHeader)
24865
24863
  }, /*#__PURE__*/React.createElement(Header, {
24866
24864
  depth: path.length,
24867
- className: css(styles$n.containerTitle)
24865
+ className: css(styles$o.containerTitle)
24868
24866
  }, capitalize(name)));
24869
24867
  const hasBothHeadings = headingEditor && headingPreview;
24870
24868
  return /*#__PURE__*/React.createElement("div", {
24871
- className: css(styles$n.container)
24869
+ className: css(styles$o.container)
24872
24870
  }, hasBothHeadings && /*#__PURE__*/React.createElement("span", {
24873
- className: css(styles$n.row)
24871
+ className: css(styles$o.row)
24874
24872
  }, /*#__PURE__*/React.createElement("div", {
24875
- className: css(styles$n.columnLeft)
24873
+ className: css(styles$o.columnLeft)
24876
24874
  }, headingEditor), /*#__PURE__*/React.createElement("div", {
24877
- className: css(styles$n.columnRight)
24875
+ className: css(styles$o.columnRight)
24878
24876
  }, headingPreview)), /*#__PURE__*/React.createElement("div", {
24879
- className: css(path.length > 0 && styles$n.contentIndent)
24877
+ className: css(path.length > 0 && styles$o.contentIndent)
24880
24878
  }, children));
24881
24879
  };
24882
24880
 
@@ -24999,11 +24997,11 @@ const ItemNodeContent = withStickiness(props => {
24999
24997
  className: "framework-perseus"
25000
24998
  }, lens(renderers).get(path));
25001
24999
  return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
25002
- className: css(styles$n.row)
25000
+ className: css(styles$o.row)
25003
25001
  }, /*#__PURE__*/React.createElement("div", {
25004
- className: css(styles$n.columnLeft)
25002
+ className: css(styles$o.columnLeft)
25005
25003
  }, /*#__PURE__*/React.createElement("div", {
25006
- className: css(sticky && styles$n.sticky)
25004
+ className: css(sticky && styles$o.sticky)
25007
25005
  },
25008
25006
  /*#__PURE__*/
25009
25007
  // @ts-expect-error - TS2769 - No overload matches this call.
@@ -25011,9 +25009,9 @@ const ItemNodeContent = withStickiness(props => {
25011
25009
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25012
25010
  apiOptions: apiOptions
25013
25011
  })))), /*#__PURE__*/React.createElement("div", {
25014
- className: css(styles$n.columnRight)
25012
+ className: css(styles$o.columnRight)
25015
25013
  }, /*#__PURE__*/React.createElement("div", {
25016
- className: css(sticky && styles$n.sticky)
25014
+ className: css(sticky && styles$o.sticky)
25017
25015
  }, preview))));
25018
25016
  });
25019
25017
  const HintNodeContent = withStickiness(props => {
@@ -25029,13 +25027,13 @@ const HintNodeContent = withStickiness(props => {
25029
25027
  className: "framework-perseus"
25030
25028
  }, lens(renderers).get(path));
25031
25029
  return /*#__PURE__*/React.createElement("div", {
25032
- className: css(styles$n.row)
25030
+ className: css(styles$o.row)
25033
25031
  }, /*#__PURE__*/React.createElement("div", {
25034
- className: css(styles$n.columnLeft)
25032
+ className: css(styles$o.columnLeft)
25035
25033
  }, /*#__PURE__*/React.createElement("div", {
25036
- className: css(sticky && styles$n.sticky)
25034
+ className: css(sticky && styles$o.sticky)
25037
25035
  }, /*#__PURE__*/React.createElement(HintEditor, _extends({}, data, {
25038
- className: css(styles$n.hintEditor),
25036
+ className: css(styles$o.hintEditor),
25039
25037
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25040
25038
  apiOptions: apiOptions,
25041
25039
  showTitle: false,
@@ -25050,9 +25048,9 @@ const HintNodeContent = withStickiness(props => {
25050
25048
  isFirst: true,
25051
25049
  isLast: true
25052
25050
  })))), /*#__PURE__*/React.createElement("div", {
25053
- className: css(styles$n.columnRight)
25051
+ className: css(styles$o.columnRight)
25054
25052
  }, /*#__PURE__*/React.createElement("div", {
25055
- className: css(sticky && styles$n.sticky)
25053
+ className: css(sticky && styles$o.sticky)
25056
25054
  }, preview)));
25057
25055
  });
25058
25056
  const TagsNodeContent = props => {
@@ -25069,9 +25067,9 @@ const TagsNodeContent = props => {
25069
25067
  return null;
25070
25068
  }
25071
25069
  return /*#__PURE__*/React.createElement("div", {
25072
- className: css(styles$n.columnLeft)
25070
+ className: css(styles$o.columnLeft)
25073
25071
  }, /*#__PURE__*/React.createElement("div", {
25074
- className: css(styles$n.tagsEditor)
25072
+ className: css(styles$o.tagsEditor)
25075
25073
  }, /*#__PURE__*/React.createElement(GroupMetadataEditor, {
25076
25074
  value: data,
25077
25075
  onChange: newVal => actions.setValueAtPath(path, newVal),
@@ -25102,23 +25100,23 @@ const ArrayNodeContent = props => {
25102
25100
  const subpath = path.concat(i);
25103
25101
  const controls = [i > 0 && /*#__PURE__*/React.createElement("div", {
25104
25102
  key: "moveArrayElementUp",
25105
- className: css(styles$n.control)
25103
+ className: css(styles$o.control)
25106
25104
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25107
25105
  color: "orange",
25108
25106
  title: "Move up",
25109
25107
  onClick: () => actions.moveArrayElementUp(subpath)
25110
25108
  }, /*#__PURE__*/React.createElement("div", {
25111
- className: css(styles$n.verticalFlip)
25109
+ className: css(styles$o.verticalFlip)
25112
25110
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React.createElement("div", {
25113
25111
  key: "moveArrayElementDown",
25114
- className: css(styles$n.control)
25112
+ className: css(styles$o.control)
25115
25113
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25116
25114
  color: "orange",
25117
25115
  title: "Move down",
25118
25116
  onClick: () => actions.moveArrayElementDown(subpath)
25119
25117
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React.createElement("div", {
25120
25118
  key: "removeArrayElement",
25121
- className: css(styles$n.control)
25119
+ className: css(styles$o.control)
25122
25120
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25123
25121
  color: "orange",
25124
25122
  title: "Delete",
@@ -25126,7 +25124,7 @@ const ArrayNodeContent = props => {
25126
25124
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconTrash$4)))];
25127
25125
  return /*#__PURE__*/React.createElement("div", {
25128
25126
  key: i,
25129
- className: css(styles$n.arrayElement, !elementIsLeaf && styles$n.arrayElementAndNotLeaf)
25127
+ className: css(styles$o.arrayElement, !elementIsLeaf && styles$o.arrayElementAndNotLeaf)
25130
25128
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25131
25129
  key: i,
25132
25130
  shape: shape.elementShape,
@@ -25152,7 +25150,7 @@ const ObjectNodeContent = props => {
25152
25150
  // made sense to the shape's author is the order in which we'll iterate :)
25153
25151
  const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React.createElement("div", {
25154
25152
  key: subkey,
25155
- className: css(styles$n.objectElement)
25153
+ className: css(styles$o.objectElement)
25156
25154
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25157
25155
  shape: shape.shape[subkey],
25158
25156
  data: data[subkey],
@@ -25319,7 +25317,7 @@ class MultiRendererEditor extends React.Component {
25319
25317
  }, this._renderContent());
25320
25318
  }
25321
25319
  }
25322
- const styles$n = StyleSheet.create({
25320
+ const styles$o = StyleSheet.create({
25323
25321
  // This is used in a number of places throughout this file.
25324
25322
  container: {},
25325
25323
  // eslint-disable-next-line react-native/no-unused-styles
@@ -25471,47 +25469,47 @@ const StatefulArticleEditor = createReactClass({
25471
25469
  screen
25472
25470
  } = this.state;
25473
25471
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
25474
- style: styles$m.controlBar
25472
+ style: styles$n.controlBar
25475
25473
  }, /*#__PURE__*/React.createElement("span", {
25476
- style: styles$m.controls
25474
+ style: styles$n.controls
25477
25475
  }, "Mode:", " ", /*#__PURE__*/React.createElement("span", {
25478
25476
  onClick: () => this.setState({
25479
25477
  mode: "edit"
25480
25478
  }),
25481
- style: mode === "edit" ? styles$m.controlSelected : styles$m.control
25479
+ style: mode === "edit" ? styles$n.controlSelected : styles$n.control
25482
25480
  }, "EDIT"), " | ", /*#__PURE__*/React.createElement("span", {
25483
25481
  onClick: () => this.setState({
25484
25482
  mode: "preview"
25485
25483
  }),
25486
- style: mode === "preview" ? styles$m.controlSelected : styles$m.control
25484
+ style: mode === "preview" ? styles$n.controlSelected : styles$n.control
25487
25485
  }, "PREVIEW"), " | ", /*#__PURE__*/React.createElement("span", {
25488
25486
  onClick: () => this.setState({
25489
25487
  mode: "json"
25490
25488
  }),
25491
- style: mode === "json" ? styles$m.controlSelected : styles$m.control
25489
+ style: mode === "json" ? styles$n.controlSelected : styles$n.control
25492
25490
  }, "JSON")), /*#__PURE__*/React.createElement("span", {
25493
- style: styles$m.controls
25491
+ style: styles$n.controls
25494
25492
  }, "Screen:", " ", /*#__PURE__*/React.createElement("span", {
25495
25493
  onClick: () => this.setState({
25496
25494
  screen: "phone"
25497
25495
  }),
25498
- style: screen === "phone" ? styles$m.controlSelected : styles$m.control
25496
+ style: screen === "phone" ? styles$n.controlSelected : styles$n.control
25499
25497
  }, "PHONE"), " | ", /*#__PURE__*/React.createElement("span", {
25500
25498
  onClick: () => this.setState({
25501
25499
  screen: "tablet"
25502
25500
  }),
25503
- style: screen === "tablet" ? styles$m.controlSelected : styles$m.control
25501
+ style: screen === "tablet" ? styles$n.controlSelected : styles$n.control
25504
25502
  }, "TABLET"), " | ", /*#__PURE__*/React.createElement("span", {
25505
25503
  onClick: () => this.setState({
25506
25504
  screen: "desktop"
25507
25505
  }),
25508
- style: screen === "desktop" ? styles$m.controlSelected : styles$m.control
25506
+ style: screen === "desktop" ? styles$n.controlSelected : styles$n.control
25509
25507
  }, "DESKTOP"))), /*#__PURE__*/React.createElement("div", {
25510
- style: styles$m.editor
25508
+ style: styles$n.editor
25511
25509
  }, /*#__PURE__*/React.createElement(ArticleEditor, this.state)));
25512
25510
  }
25513
25511
  });
25514
- const styles$m = {
25512
+ const styles$n = {
25515
25513
  controlBar: {
25516
25514
  marginBottom: 25,
25517
25515
  marginTop: 5
@@ -27001,10 +26999,10 @@ class GradedGroupEditor extends React.Component {
27001
26999
  }, /*#__PURE__*/React.createElement("div", {
27002
27000
  className: "perseus-widget-row"
27003
27001
  }, /*#__PURE__*/React.createElement("label", {
27004
- className: css(styles$l.title)
27002
+ className: css(styles$m.title)
27005
27003
  }, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
27006
27004
  value: this.props.title,
27007
- className: css(styles$l.input)
27005
+ className: css(styles$m.input)
27008
27006
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
27009
27007
  ,
27010
27008
  onChange: this.change("title")
@@ -27029,7 +27027,7 @@ class GradedGroupEditor extends React.Component {
27029
27027
  }, /*#__PURE__*/React.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React.createElement("div", {
27030
27028
  className: "perseus-hint-editor"
27031
27029
  }, /*#__PURE__*/React.createElement("div", {
27032
- className: css(styles$l.hintsTitle)
27030
+ className: css(styles$m.hintsTitle)
27033
27031
  }, "Hint"), /*#__PURE__*/React.createElement(Editor, {
27034
27032
  ref: this.hintEditor,
27035
27033
  content: this.props.hint ? this.props.hint.content : "",
@@ -27066,7 +27064,7 @@ GradedGroupEditor.defaultProps = {
27066
27064
  images: {},
27067
27065
  hint: null
27068
27066
  };
27069
- const styles$l = StyleSheet.create({
27067
+ const styles$m = StyleSheet.create({
27070
27068
  title: {
27071
27069
  fontSize: 18,
27072
27070
  fontWeight: "bold"
@@ -28400,13 +28398,13 @@ function MathquillInput(props) {
28400
28398
  }
28401
28399
  });
28402
28400
  return /*#__PURE__*/React.createElement(View, {
28403
- style: styles$k.outerWrapper
28401
+ style: styles$l.outerWrapper
28404
28402
  }, /*#__PURE__*/React.createElement("span", {
28405
28403
  ref: mathFieldWrapperRef,
28406
28404
  className: "perseus-math-input mq-editable-field mq-math-mode"
28407
28405
  }));
28408
28406
  }
28409
- const styles$k = StyleSheet.create({
28407
+ const styles$l = StyleSheet.create({
28410
28408
  outerWrapper: {
28411
28409
  display: "inline-block",
28412
28410
  borderStyle: "solid",
@@ -29467,7 +29465,7 @@ const GraphPointsCountSelector = ({
29467
29465
  // Never uses placeholder, always has value
29468
29466
  ,
29469
29467
  placeholder: "",
29470
- style: styles$j.singleSelectShort
29468
+ style: styles$k.singleSelectShort
29471
29469
  }, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
29472
29470
  key: n,
29473
29471
  value: `${n}`,
@@ -29478,7 +29476,7 @@ const GraphPointsCountSelector = ({
29478
29476
  label: "unlimited"
29479
29477
  })]);
29480
29478
  };
29481
- const styles$j = StyleSheet.create({
29479
+ const styles$k = StyleSheet.create({
29482
29480
  singleSelectShort: {
29483
29481
  // Non-standard spacing, but it's the smallest we can go
29484
29482
  // without running into styling issues with the dropdown.
@@ -29491,7 +29489,7 @@ const GraphTypeSelector = props => {
29491
29489
  selectedValue: props.graphType,
29492
29490
  onChange: props.onChange,
29493
29491
  placeholder: "Select a graph type",
29494
- style: styles$i.singleSelectShort
29492
+ style: styles$j.singleSelectShort
29495
29493
  }, /*#__PURE__*/React.createElement(OptionItem, {
29496
29494
  value: "linear",
29497
29495
  label: "Linear function"
@@ -29524,7 +29522,7 @@ const GraphTypeSelector = props => {
29524
29522
  label: "Angle"
29525
29523
  }));
29526
29524
  };
29527
- const styles$i = StyleSheet.create({
29525
+ const styles$j = StyleSheet.create({
29528
29526
  singleSelectShort: {
29529
29527
  // Non-standard spacing, but it's the smallest we can go
29530
29528
  // without running into styling issues with the dropdown.
@@ -29541,16 +29539,16 @@ const LabeledRow = props => {
29541
29539
  style
29542
29540
  } = props;
29543
29541
  return /*#__PURE__*/React.createElement("label", {
29544
- className: css(styles$h.label)
29542
+ className: css(styles$i.label)
29545
29543
  }, /*#__PURE__*/React.createElement(View, {
29546
- style: [styles$h.row, style]
29544
+ style: [styles$i.row, style]
29547
29545
  }, labelSide === "start" || /*#__PURE__*/React.createElement(LabelSmall, {
29548
- style: styles$h.spaceEnd
29546
+ style: styles$i.spaceEnd
29549
29547
  }, label), children, labelSide === "end" && /*#__PURE__*/React.createElement(LabelSmall, {
29550
- style: styles$h.spaceStart
29548
+ style: styles$i.spaceStart
29551
29549
  }, label)));
29552
29550
  };
29553
- const styles$h = StyleSheet.create({
29551
+ const styles$i = StyleSheet.create({
29554
29552
  label: {
29555
29553
  width: "fit-content"
29556
29554
  },
@@ -29944,10 +29942,10 @@ class InteractiveGraphSettings extends React.Component {
29944
29942
  onChange: this.change
29945
29943
  }))), /*#__PURE__*/React.createElement(LabeledRow, {
29946
29944
  label: "Background image URL:",
29947
- style: styles$g.resetSpaceTop
29945
+ style: styles$h.resetSpaceTop
29948
29946
  }, /*#__PURE__*/React.createElement("input", {
29949
29947
  type: "text",
29950
- className: css(styles$g.backgroundUrlInput),
29948
+ className: css(styles$h.backgroundUrlInput),
29951
29949
  ref: this.bgUrlRef,
29952
29950
  value: this.state.backgroundImage.url || "",
29953
29951
  onChange: e => {
@@ -29961,24 +29959,24 @@ class InteractiveGraphSettings extends React.Component {
29961
29959
  onKeyPress: this.changeBackgroundUrl,
29962
29960
  onBlur: this.changeBackgroundUrl
29963
29961
  }), /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React.createElement(View, {
29964
- style: styles$g.rulerSection
29962
+ style: styles$h.rulerSection
29965
29963
  }, /*#__PURE__*/React.createElement(View, {
29966
- style: styles$g.checkboxRow
29964
+ style: styles$h.checkboxRow
29967
29965
  }, /*#__PURE__*/React.createElement(PropCheckBox$7, {
29968
29966
  label: "Show ruler",
29969
29967
  showRuler: this.props.showRuler,
29970
29968
  onChange: this.change,
29971
- style: styles$g.resetSpaceTop
29969
+ style: styles$h.resetSpaceTop
29972
29970
  }), /*#__PURE__*/React.createElement(PropCheckBox$7, {
29973
29971
  label: "Show protractor",
29974
29972
  showProtractor: this.props.showProtractor,
29975
29973
  onChange: this.change,
29976
- style: styles$g.resetSpaceTop
29974
+ style: styles$h.resetSpaceTop
29977
29975
  })), this.props.showRuler && /*#__PURE__*/React.createElement(View, {
29978
- style: styles$g.spaceTop
29976
+ style: styles$h.spaceTop
29979
29977
  }, /*#__PURE__*/React.createElement(LabeledRow, {
29980
29978
  label: "Ruler label:",
29981
- style: styles$g.resetSpaceTop
29979
+ style: styles$h.resetSpaceTop
29982
29980
  }, /*#__PURE__*/React.createElement(SingleSelect, {
29983
29981
  id: "ruler-label-select",
29984
29982
  selectedValue: this.props.rulerLabel,
@@ -29988,7 +29986,7 @@ class InteractiveGraphSettings extends React.Component {
29988
29986
  });
29989
29987
  },
29990
29988
  placeholder: "None",
29991
- style: styles$g.singleSelectShort
29989
+ style: styles$h.singleSelectShort
29992
29990
  }, /*#__PURE__*/React.createElement(OptionItem, {
29993
29991
  value: "",
29994
29992
  label: "None",
@@ -30029,7 +30027,7 @@ class InteractiveGraphSettings extends React.Component {
30029
30027
  });
30030
30028
  },
30031
30029
  placeholder: "10",
30032
- style: styles$g.singleSelectShort
30030
+ style: styles$h.singleSelectShort
30033
30031
  }, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React.createElement(OptionItem, {
30034
30032
  key: value,
30035
30033
  value: `${value}`,
@@ -30053,7 +30051,7 @@ InteractiveGraphSettings.defaultProps = {
30053
30051
  rulerLabel: "",
30054
30052
  rulerTicks: 10
30055
30053
  };
30056
- const styles$g = StyleSheet.create({
30054
+ const styles$h = StyleSheet.create({
30057
30055
  resetSpaceTop: {
30058
30056
  marginTop: 0
30059
30057
  },
@@ -30097,17 +30095,17 @@ const LockedFigureSelect = props => {
30097
30095
  onChange
30098
30096
  } = props;
30099
30097
  return /*#__PURE__*/React.createElement(View, {
30100
- style: styles$f.container
30098
+ style: styles$g.container
30101
30099
  }, /*#__PURE__*/React.createElement(ActionMenu, {
30102
- menuText: "Add element",
30103
- style: styles$f.addElementSelect
30100
+ menuText: "Add locked figure",
30101
+ style: styles$g.addElementSelect
30104
30102
  }, [/*#__PURE__*/React.createElement(ActionItem, {
30105
30103
  key: `${id}-point`,
30106
30104
  label: "Point",
30107
30105
  onClick: () => onChange("point")
30108
30106
  }, "Point")]));
30109
30107
  };
30110
- const styles$f = StyleSheet.create({
30108
+ const styles$g = StyleSheet.create({
30111
30109
  container: {
30112
30110
  marginTop: spacing.medium_16
30113
30111
  },
@@ -30168,21 +30166,98 @@ const defaultContext = {
30168
30166
  };
30169
30167
  const MediaLayoutContext = React.createContext(defaultContext);
30170
30168
  MediaLayoutContext.displayName = "MediaLayoutContext";
30169
+ StyleSheet.create({
30170
+ grow: {
30171
+ flexGrow: 1
30172
+ }
30173
+ });
30171
30174
 
30172
- class Spring extends React.Component {
30175
+ class Strut extends React.Component {
30173
30176
  render() {
30174
30177
  const {
30178
+ size,
30175
30179
  style
30176
30180
  } = this.props;
30177
30181
  return React.createElement(View, {
30178
30182
  "aria-hidden": "true",
30179
- style: [styles$e.grow, style]
30183
+ style: [strutStyle(size), style]
30180
30184
  });
30181
30185
  }
30182
30186
  }
30187
+ const strutStyle = size => {
30188
+ return {
30189
+ width: size,
30190
+ MsFlexBasis: size,
30191
+ MsFlexPreferredSize: size,
30192
+ WebkitFlexBasis: size,
30193
+ flexBasis: size,
30194
+ flexShrink: 0
30195
+ };
30196
+ };
30197
+
30198
+ const ColorCircle = props => {
30199
+ const {
30200
+ color: color$1,
30201
+ filled = true,
30202
+ decorative = false
30203
+ } = props;
30204
+ return /*#__PURE__*/React.createElement(View, {
30205
+ "aria-label":
30206
+ // Don't include an aria label for decorative circles.
30207
+ !decorative ? `Color: ${color$1}, ${filled ? "filled" : "open"}` : undefined,
30208
+ style: [styles$f.colorCircle, {
30209
+ border: `4px solid ${color[color$1]}`,
30210
+ backgroundColor: filled ? color[color$1] : color.white
30211
+ }]
30212
+ });
30213
+ };
30214
+ const styles$f = StyleSheet.create({
30215
+ colorCircle: {
30216
+ // Add a white outline so that the color circle is visible when
30217
+ // the dropdown option is highlighted with its blue background.
30218
+ outline: `2px solid ${color.offWhite}`,
30219
+ borderRadius: "50%",
30220
+ width: spacing.large_24,
30221
+ height: spacing.large_24
30222
+ }
30223
+ });
30224
+
30225
+ const ColorSelect = props => {
30226
+ const {
30227
+ id,
30228
+ selectedValue,
30229
+ onChange
30230
+ } = props;
30231
+ return /*#__PURE__*/React.createElement(View, {
30232
+ style: styles$e.row
30233
+ }, /*#__PURE__*/React.createElement(LabelMedium, {
30234
+ htmlFor: id,
30235
+ style: styles$e.label,
30236
+ tag: "label"
30237
+ }, "Color"), /*#__PURE__*/React.createElement(SingleSelect, {
30238
+ id: id,
30239
+ selectedValue: selectedValue,
30240
+ onChange: onChange
30241
+ // Placeholder is required, but never gets used.
30242
+ ,
30243
+ placeholder: ""
30244
+ }, lockedFigureColors.map(colorName => /*#__PURE__*/React.createElement(OptionItem, {
30245
+ key: colorName,
30246
+ value: colorName,
30247
+ label: colorName,
30248
+ leftAccessory: /*#__PURE__*/React.createElement(ColorCircle, {
30249
+ color: colorName,
30250
+ decorative: true
30251
+ })
30252
+ }, colorName))));
30253
+ };
30183
30254
  const styles$e = StyleSheet.create({
30184
- grow: {
30185
- flexGrow: 1
30255
+ row: {
30256
+ flexDirection: "row",
30257
+ alignItems: "center"
30258
+ },
30259
+ label: {
30260
+ marginInlineEnd: spacing.xSmall_8
30186
30261
  }
30187
30262
  });
30188
30263
 
@@ -30231,13 +30306,30 @@ function getValidNumberFromString(value) {
30231
30306
  // If the value is not a number, return 0.
30232
30307
  return isNaN(parsed) ? 0 : parsed;
30233
30308
  }
30234
- function getDefaultFigureForFigureType(type) {
30309
+ function getDefaultFigureForType(type) {
30235
30310
  switch (type) {
30236
30311
  case "point":
30237
30312
  return {
30238
30313
  type: "point",
30239
- coord: [0, 0]
30314
+ coord: [0, 0],
30315
+ color: "blue",
30316
+ filled: true
30240
30317
  };
30318
+ case "line":
30319
+ return {
30320
+ type: "line",
30321
+ kind: "line",
30322
+ points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
30323
+ coord: [2, 2]
30324
+ })],
30325
+ color: "blue",
30326
+ lineStyle: "solid",
30327
+ showArrows: false,
30328
+ showStartPoint: false,
30329
+ showEndPoint: false
30330
+ };
30331
+ default:
30332
+ throw new UnreachableCaseError(type);
30241
30333
  }
30242
30334
  }
30243
30335
 
@@ -30247,15 +30339,21 @@ function getDefaultFigureForFigureType(type) {
30247
30339
  *
30248
30340
  * Used in the interactive graph editor's locked figures section.
30249
30341
  */
30250
- const possibleColors = ["purple", "blue", "teal", "green", "gold", "red", "pink"];
30251
30342
  const LockedPointSettings = props => {
30252
30343
  const {
30253
30344
  coord,
30345
+ color: pointColor,
30346
+ filled = true,
30347
+ label,
30348
+ toggled = "true",
30254
30349
  style,
30255
- onChangeColor,
30256
- onChangeCoord,
30350
+ onChangeProps,
30351
+ onToggle,
30257
30352
  onRemove
30258
30353
  } = props;
30354
+
30355
+ // Keep track of the coordinates via state as the user is editing them,
30356
+ // before they are updated in the props on blur.
30259
30357
  const [coordState, setCoordState] = React.useState([
30260
30358
  // Using strings to make it easier to work with the text fields.
30261
30359
  coord[0].toString(), coord[1].toString()]);
@@ -30265,86 +30363,135 @@ const LockedPointSettings = props => {
30265
30363
  const ids = useUniqueIdWithMock();
30266
30364
  const xCoordId = ids.get("x-coord");
30267
30365
  const yCoordId = ids.get("y-coord");
30268
- const colorSelectId = ids.get("color-select");
30366
+ const colorSelectId = ids.get("point-color-select");
30367
+ const showPointToggleId = ids.get("show-point-toggle");
30269
30368
  function handleBlur() {
30270
30369
  const validCoord = [getValidNumberFromString(coordState[0]), getValidNumberFromString(coordState[1])];
30271
30370
 
30272
30371
  // Make the text field only show valid numbers after blur.
30273
30372
  setCoordState([validCoord[0].toString(), validCoord[1].toString()]);
30274
30373
  // Update the graph with the new coordinates.
30275
- onChangeCoord(validCoord);
30374
+ onChangeProps({
30375
+ coord: validCoord
30376
+ });
30276
30377
  }
30277
30378
  function handleCoordChange(newValue, coordIndex) {
30278
30379
  const newCoord = [...coordState];
30279
30380
  newCoord[coordIndex] = newValue;
30280
30381
  setCoordState(newCoord);
30281
30382
  }
30282
- return /*#__PURE__*/React.createElement(View, {
30283
- style: styles$d.container
30383
+ function handleColorChange(newValue) {
30384
+ onChangeProps({
30385
+ color: newValue
30386
+ });
30387
+ }
30388
+ return /*#__PURE__*/React.createElement(View
30389
+ // More specificity so that we can override the default
30390
+ // .heading > h2 > .header styles from the articles.less
30391
+ // file (which is imported in perseus-renderer.less).
30392
+ , {
30393
+ className: "locked-figure-accordion"
30394
+ }, /*#__PURE__*/React.createElement(AccordionSection, {
30395
+ style: [styles$d.container, style],
30396
+ headerStyle: styles$d.accordionHeader,
30397
+ header:
30398
+ /*#__PURE__*/
30399
+ // Summary: Point, coords, color (filled/open)
30400
+ React.createElement(View, {
30401
+ style: styles$d.row
30402
+ }, /*#__PURE__*/React.createElement(LabelLarge, null, `${label || "Point"} (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
30403
+ size: spacing.xSmall_8
30404
+ }), toggled && /*#__PURE__*/React.createElement(ColorCircle, {
30405
+ color: pointColor,
30406
+ filled: filled
30407
+ }))
30408
+ }, /*#__PURE__*/React.createElement(View, {
30409
+ style: styles$d.accordionPanel
30284
30410
  }, /*#__PURE__*/React.createElement(View, {
30285
30411
  style: styles$d.row
30286
- }, /*#__PURE__*/React.createElement(LabelLarge, null, "Point"), /*#__PURE__*/React.createElement(Spring, null), /*#__PURE__*/React.createElement(IconButton, {
30287
- icon: trashIcon,
30288
- "aria-label": `Delete locked point at ${coordState[0]}, ${coordState[1]}`,
30289
- onClick: onRemove
30290
- })), /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, {
30291
- style: styles$d.row
30412
+ }, /*#__PURE__*/React.createElement(View, {
30413
+ style: [styles$d.row, styles$d.spaceUnder]
30292
30414
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30293
30415
  htmlFor: xCoordId,
30294
30416
  style: styles$d.label,
30295
30417
  tag: "label"
30296
- }, "x Coordinate"), /*#__PURE__*/React.createElement(TextField, {
30418
+ }, "x Coord"), /*#__PURE__*/React.createElement(TextField, {
30297
30419
  id: xCoordId,
30420
+ type: "number",
30298
30421
  value: coordState[0],
30299
30422
  onChange: newValue => handleCoordChange(newValue, 0),
30300
30423
  onBlur: handleBlur,
30301
30424
  style: styles$d.textField
30302
- })), /*#__PURE__*/React.createElement(View, {
30303
- style: styles$d.row
30425
+ })), /*#__PURE__*/React.createElement(Strut, {
30426
+ size: spacing.medium_16
30427
+ }), /*#__PURE__*/React.createElement(View, {
30428
+ style: [styles$d.row, styles$d.spaceUnder]
30304
30429
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30305
30430
  htmlFor: yCoordId,
30306
30431
  style: styles$d.label,
30307
30432
  tag: "label"
30308
- }, "y Coordinate"), /*#__PURE__*/React.createElement(TextField, {
30433
+ }, "y Coord"), /*#__PURE__*/React.createElement(TextField, {
30309
30434
  id: yCoordId,
30435
+ type: "number",
30310
30436
  value: coordState[1],
30311
30437
  onChange: newValue => handleCoordChange(newValue, 1),
30312
30438
  onBlur: handleBlur,
30313
30439
  style: styles$d.textField
30314
- }))), /*#__PURE__*/React.createElement(View, {
30315
- style: styles$d.row
30316
- }, /*#__PURE__*/React.createElement(LabelMedium, {
30317
- htmlFor: colorSelectId,
30318
- style: styles$d.label,
30319
- tag: "label"
30320
- }, "Color"), /*#__PURE__*/React.createElement(SingleSelect, {
30440
+ }))), onToggle && /*#__PURE__*/React.createElement(View, {
30441
+ style: [styles$d.row, styles$d.spaceUnder]
30442
+ }, /*#__PURE__*/React.createElement(Switch, {
30443
+ id: showPointToggleId,
30444
+ checked: !!toggled,
30445
+ onChange: onToggle
30446
+ }), /*#__PURE__*/React.createElement(Strut, {
30447
+ size: spacing.small_12
30448
+ }), /*#__PURE__*/React.createElement(LabelMedium, {
30449
+ tag: "label",
30450
+ htmlFor: showPointToggleId
30451
+ }, "Show point on graph")), toggled && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
30321
30452
  id: colorSelectId,
30322
- selectedValue: (style == null ? void 0 : style.fill) || "blue",
30323
- onChange: onChangeColor
30324
- // Placeholder is required, but never gets used.
30325
- ,
30326
- placeholder: ""
30327
- }, possibleColors.map(colorName => /*#__PURE__*/React.createElement(OptionItem, {
30328
- key: colorName,
30329
- value: colorName,
30330
- label: colorName,
30331
- leftAccessory: /*#__PURE__*/React.createElement(View, {
30332
- style: [styles$d.colorCircle, {
30333
- backgroundColor: color[colorName]
30334
- }]
30335
- })
30336
- }, colorName)))));
30453
+ selectedValue: pointColor || "blue",
30454
+ onChange: handleColorChange
30455
+ }), /*#__PURE__*/React.createElement(Strut, {
30456
+ size: spacing.xSmall_8
30457
+ }), /*#__PURE__*/React.createElement(Checkbox$1, {
30458
+ label: "Open point",
30459
+ checked: !filled,
30460
+ onChange: newValue => {
30461
+ onChangeProps({
30462
+ filled: !newValue
30463
+ });
30464
+ },
30465
+ style: styles$d.spaceUnder
30466
+ })), onRemove && /*#__PURE__*/React.createElement(IconButton, {
30467
+ icon: trashIcon,
30468
+ "aria-label": `Delete locked point at ${coordState[0]}, ${coordState[1]}`,
30469
+ onClick: onRemove,
30470
+ style: styles$d.deleteButton
30471
+ }))));
30337
30472
  };
30338
30473
  const styles$d = StyleSheet.create({
30339
30474
  container: {
30340
30475
  backgroundColor: color.fadedBlue8,
30341
- marginBottom: spacing.xSmall_8,
30476
+ marginBottom: spacing.small_12
30477
+ },
30478
+ accordionHeader: {
30479
+ paddingTop: spacing.small_12,
30480
+ paddingBottom: spacing.small_12,
30481
+ paddingInlineStart: spacing.medium_16,
30482
+ // Fixed height so the addition of the color circle doesn't
30483
+ // change the height of the header when toggling.
30484
+ height: spacing.xxLarge_48
30485
+ },
30486
+ accordionPanel: {
30342
30487
  padding: spacing.medium_16,
30343
- borderRadius: spacing.xSmall_8
30488
+ paddingBottom: spacing.xSmall_8
30344
30489
  },
30345
30490
  row: {
30346
30491
  flexDirection: "row",
30347
- alignItems: "center",
30492
+ alignItems: "center"
30493
+ },
30494
+ spaceUnder: {
30348
30495
  marginBottom: spacing.xSmall_8
30349
30496
  },
30350
30497
  label: {
@@ -30353,13 +30500,10 @@ const styles$d = StyleSheet.create({
30353
30500
  textField: {
30354
30501
  width: spacing.xxxLarge_64
30355
30502
  },
30356
- colorCircle: {
30357
- // Add a white border so that the color circle is visible when
30358
- // the dropdown option is highlighted with its blue background.
30359
- border: `2px solid ${color.offWhite}`,
30360
- borderRadius: "50%",
30361
- width: spacing.large_24,
30362
- height: spacing.large_24
30503
+ deleteButton: {
30504
+ position: "absolute",
30505
+ top: spacing.small_12,
30506
+ right: spacing.small_12
30363
30507
  }
30364
30508
  });
30365
30509
 
@@ -30389,7 +30533,7 @@ const LockedFiguresSection = props => {
30389
30533
  function addLockedFigure(newFigure) {
30390
30534
  const lockedFigures = figures || [];
30391
30535
  const newProps = {
30392
- lockedFigures: [...lockedFigures, getDefaultFigureForFigureType(newFigure)]
30536
+ lockedFigures: [...lockedFigures, getDefaultFigureForType(newFigure)]
30393
30537
  };
30394
30538
  onChange(newProps);
30395
30539
  }
@@ -30399,36 +30543,31 @@ const LockedFiguresSection = props => {
30399
30543
  lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
30400
30544
  });
30401
30545
  }
30402
- function changeCoord(index, coord) {
30403
- const lockedFigures = figures || [];
30404
- const newProps = {
30405
- lockedFigures: [...lockedFigures.slice(0, index), _extends({}, lockedFigures[index], {
30406
- coord
30407
- }), ...lockedFigures.slice(index + 1)]
30408
- };
30409
- onChange(newProps);
30410
- }
30411
- function changeColor(index, colorName) {
30546
+ function changeProps(index,
30547
+ // Omit the type from the figure props so it doesn't think
30548
+ // we're trying to pass in the props for the wrong type.
30549
+ figureProps) {
30412
30550
  const lockedFigures = figures || [];
30413
- const newProps = {
30414
- lockedFigures: [...lockedFigures.slice(0, index), _extends({}, lockedFigures[index], {
30415
- style: _extends({}, lockedFigures[index].style, {
30416
- fill: colorName,
30417
- stroke: colorName
30418
- })
30419
- }), ...lockedFigures.slice(index + 1)]
30551
+ const newFigures = {
30552
+ lockedFigures: [...lockedFigures.slice(0, index), _extends({}, lockedFigures[index], figureProps), ...lockedFigures.slice(index + 1)]
30420
30553
  };
30421
- onChange(newProps);
30554
+ onChange(newFigures);
30422
30555
  }
30423
30556
  return /*#__PURE__*/React.createElement(View, {
30424
30557
  style: styles$c.container
30425
- }, figures == null ? void 0 : figures.map((figure, index) => /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
30426
- key: `${uniqueId}-locked-${figure}-${index}`
30427
- }, figure, {
30428
- onChangeColor: color => changeColor(index, color),
30429
- onChangeCoord: coord => changeCoord(index, coord),
30430
- onRemove: () => removeLockedFigure(index)
30431
- }))), /*#__PURE__*/React.createElement(LockedFigureSelect, {
30558
+ }, figures == null ? void 0 : figures.map((figure, index) => {
30559
+ // TODO(LEMS-1740): Remove this check when
30560
+ // locked lines are added to LockedFigureSettings.
30561
+ if (figure.type === "line") {
30562
+ return;
30563
+ }
30564
+ return /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
30565
+ key: `${uniqueId}-locked-${figure}-${index}`
30566
+ }, figure, {
30567
+ onChangeProps: newProps => changeProps(index, newProps),
30568
+ onRemove: () => removeLockedFigure(index)
30569
+ }));
30570
+ }), /*#__PURE__*/React.createElement(LockedFigureSelect, {
30432
30571
  id: `${uniqueId}-select`,
30433
30572
  onChange: addLockedFigure
30434
30573
  }));
@@ -30519,13 +30658,15 @@ class InteractiveGraphEditor extends React.Component {
30519
30658
  DeprecationMixin.UNSAFE_componentWillMount.call(this);
30520
30659
  }
30521
30660
  render() {
30522
- var _this$props$graph$typ, _this$props$graph, _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$apiOption;
30661
+ var _this$props$graph$typ, _this$props$graph, _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$apiOption, _this$props$apiOption2;
30523
30662
  let graph;
30524
30663
  let equationString;
30525
30664
  const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, interactiveSizes.defaultBoxSize);
30526
30665
  const snapStep = this.props.snapStep || Util.snapStepFromGridStep(gridStep);
30527
30666
  const sizeClass = containerSizeClass.SMALL;
30528
30667
  if (this.props.valid === true) {
30668
+ const correct = this.props.correct;
30669
+
30529
30670
  // TODO(aria): send these down all at once
30530
30671
  const graphProps = {
30531
30672
  ref: "graph",
@@ -30535,7 +30676,7 @@ class InteractiveGraphEditor extends React.Component {
30535
30676
  step: this.props.step,
30536
30677
  gridStep: gridStep,
30537
30678
  snapStep: snapStep,
30538
- graph: this.props.correct,
30679
+ graph: correct,
30539
30680
  backgroundImage: this.props.backgroundImage,
30540
30681
  markings: this.props.markings,
30541
30682
  showProtractor: this.props.showProtractor,
@@ -30559,6 +30700,10 @@ class InteractiveGraphEditor extends React.Component {
30559
30700
  });
30560
30701
  }
30561
30702
  };
30703
+
30704
+ // This is used to force a remount of the graph component
30705
+ // when there's a significant change
30706
+ const graphKey = `${correct.type}:${correct.numSegments || 0}`;
30562
30707
  graph =
30563
30708
  /*#__PURE__*/
30564
30709
  // There are a bunch of props that renderer.jsx passes to widgets via
@@ -30566,6 +30711,7 @@ class InteractiveGraphEditor extends React.Component {
30566
30711
  // bother passing.
30567
30712
  // @ts-expect-error - TS2769 - No overload matches this call.
30568
30713
  React.createElement(InteractiveGraph, _extends({}, graphProps, {
30714
+ key: graphKey,
30569
30715
  containerSizeClass: sizeClass,
30570
30716
  apiOptions: _extends({}, this.props.apiOptions, {
30571
30717
  isMobile: false
@@ -30761,9 +30907,9 @@ class InteractiveGraphEditor extends React.Component {
30761
30907
  borderWidth: 1
30762
30908
  }
30763
30909
  }, equationString), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), graph,
30764
- // Only show the "Add element" dropdown if the graph is
30910
+ // Only show the "Add locked figure" dropdown if the graph is
30765
30911
  // using Mafs.
30766
- this.props.graph && ((_this$props$apiOption = this.props.apiOptions) == null || (_this$props$apiOption = _this$props$apiOption.flags) == null || (_this$props$apiOption = _this$props$apiOption["mafs"]) == null ? void 0 : _this$props$apiOption[this.props.graph.type]) && /*#__PURE__*/React.createElement(LockedFiguresSection, {
30912
+ this.props.graph && ((_this$props$apiOption = this.props.apiOptions) == null || (_this$props$apiOption = _this$props$apiOption.flags) == null || (_this$props$apiOption = _this$props$apiOption.mafs) == null ? void 0 : _this$props$apiOption["interactive-graph-locked-features-m1"]) && ((_this$props$apiOption2 = this.props.apiOptions) == null || (_this$props$apiOption2 = _this$props$apiOption2.flags) == null || (_this$props$apiOption2 = _this$props$apiOption2.mafs) == null ? void 0 : _this$props$apiOption2[this.props.graph.type]) && /*#__PURE__*/React.createElement(LockedFiguresSection, {
30767
30913
  figures: this.props.lockedFigures,
30768
30914
  onChange: this.props.onChange
30769
30915
  }));
@@ -30911,7 +31057,7 @@ class FormWrappedTextField extends React.Component {
30911
31057
  className: css(inputBase),
30912
31058
  ref: forwardedRef,
30913
31059
  id: id,
30914
- "data-test-id": testId
31060
+ "data-testid": testId
30915
31061
  })), !leftSideIcon && wrappedIcon);
30916
31062
  }
30917
31063
  }
@@ -31043,7 +31189,7 @@ class Link extends React.Component {
31043
31189
  rel = "noopener noreferrer";
31044
31190
  }
31045
31191
  return /*#__PURE__*/React.createElement(element, _extends({
31046
- "data-test-id": testId
31192
+ "data-testid": testId
31047
31193
  }, otherProps, urlProp, {
31048
31194
  className: css(...delegatedStyles) + delegatedClassName,
31049
31195
  style: inlineStyles,
@@ -31362,7 +31508,7 @@ class Checkbox extends React.Component {
31362
31508
  }, handlers) => /*#__PURE__*/React.createElement("div", _extends({}, handlers, {
31363
31509
  className: css(styles$6.container, focused && styles$6.focused),
31364
31510
  style: style,
31365
- "data-test-id": dataTestId,
31511
+ "data-testid": dataTestId,
31366
31512
  "data-checked": checked
31367
31513
  }), /*#__PURE__*/React.createElement("svg", {
31368
31514
  className: css(styles$6.svg, (disabled || appearDisabled) && styles$6.disabled),
@@ -31609,7 +31755,7 @@ class Option extends React.Component {
31609
31755
  onKeyDown: event => this.handleKeyDown(event),
31610
31756
  "aria-disabled": disabled,
31611
31757
  "aria-label": ariaLabel,
31612
- "data-test-id": testId
31758
+ "data-testid": testId
31613
31759
  }, optionRenderer && optionRenderer(
31614
31760
  /*#__PURE__*/
31615
31761
  /**