@khanacademy/perseus-editor 5.0.3 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -26,6 +26,8 @@ var wonderBlocksForm = require('@khanacademy/wonder-blocks-form');
26
26
  var Spacing = require('@khanacademy/wonder-blocks-spacing');
27
27
  var wonderBlocksTypography = require('@khanacademy/wonder-blocks-typography');
28
28
  var wonderBlocksTokens = require('@khanacademy/wonder-blocks-tokens');
29
+ var IconButton = require('@khanacademy/wonder-blocks-icon-button');
30
+ var trashIcon = require('@phosphor-icons/core/bold/trash-bold.svg');
29
31
  var Button = require('@khanacademy/wonder-blocks-button');
30
32
  var i18n$1 = require('@khanacademy/wonder-blocks-i18n');
31
33
 
@@ -61,12 +63,14 @@ var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
61
63
  var ReactDOM__default = /*#__PURE__*/_interopDefaultLegacy(ReactDOM);
62
64
  var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
63
65
  var Spacing__default = /*#__PURE__*/_interopDefaultLegacy(Spacing);
66
+ var IconButton__default = /*#__PURE__*/_interopDefaultLegacy(IconButton);
67
+ var trashIcon__default = /*#__PURE__*/_interopDefaultLegacy(trashIcon);
64
68
  var Button__default = /*#__PURE__*/_interopDefaultLegacy(Button);
65
69
  var i18n__namespace = /*#__PURE__*/_interopNamespace(i18n$1);
66
70
 
67
71
  // This file is processed by a Rollup plugin (replace) to inject the production
68
72
  const libName = "@khanacademy/perseus-editor";
69
- const libVersion = "5.0.3";
73
+ const libVersion = "5.1.1";
70
74
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
71
75
 
72
76
  function _extends() {
@@ -260,13 +264,13 @@ class SectionControlButton extends React__namespace.Component {
260
264
  role: "button",
261
265
  hideDefaultFocusRing: true,
262
266
  "aria-label": title,
263
- style: styles$m.button
267
+ style: styles$q.button
264
268
  }, _ref => {
265
269
  return /*#__PURE__*/React__namespace.createElement(InlineIcon$b, icon);
266
270
  });
267
271
  }
268
272
  }
269
- const styles$m = aphrodite.StyleSheet.create({
273
+ const styles$q = aphrodite.StyleSheet.create({
270
274
  button: {
271
275
  backgroundColor: Color__default["default"].gold,
272
276
  margin: 2,
@@ -20784,19 +20788,19 @@ class TexErrorView extends React__namespace.Component {
20784
20788
  const {
20785
20789
  showErrors
20786
20790
  } = this.state;
20787
- const iconStyle = showErrors ? styles$l.iconExpanded : styles$l.iconCollapsed;
20791
+ const iconStyle = showErrors ? styles$p.iconExpanded : styles$p.iconCollapsed;
20788
20792
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20789
- style: styles$l.errorContainer
20793
+ style: styles$p.errorContainer
20790
20794
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20791
- style: styles$l.title,
20795
+ style: styles$p.title,
20792
20796
  onClick: this.handleToggleTexErrors
20793
20797
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksIcon.PhosphorIcon, {
20794
20798
  icon: caretRight__default["default"],
20795
20799
  style: iconStyle
20796
20800
  }), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20797
- style: styles$l.errorExplanation
20801
+ style: styles$p.errorExplanation
20798
20802
  }, "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__namespace.createElement(wonderBlocksCore.View, {
20799
- style: styles$l.error,
20803
+ style: styles$p.error,
20800
20804
  key: index
20801
20805
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
20802
20806
  style: {
@@ -20805,7 +20809,7 @@ class TexErrorView extends React__namespace.Component {
20805
20809
  }, e.math), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, e.message))));
20806
20810
  }
20807
20811
  }
20808
- const styles$l = aphrodite.StyleSheet.create({
20812
+ const styles$p = aphrodite.StyleSheet.create({
20809
20813
  title: {
20810
20814
  backgroundColor: "#eee",
20811
20815
  fontSize: "1.25em",
@@ -24583,12 +24587,12 @@ class SimpleButton extends React__namespace.Component {
24583
24587
  ...otherProps
24584
24588
  } = this.props;
24585
24589
  return /*#__PURE__*/React__namespace.createElement("div", _extends({
24586
- className: aphrodite.css(styles$k.baseButton, color === "green" && styles$k.green, color === "orange" && styles$k.orange),
24590
+ className: aphrodite.css(styles$o.baseButton, color === "green" && styles$o.green, color === "orange" && styles$o.orange),
24587
24591
  onClick: onClick
24588
24592
  }, otherProps), children);
24589
24593
  }
24590
24594
  }
24591
- const styles$k = aphrodite.StyleSheet.create({
24595
+ const styles$o = aphrodite.StyleSheet.create({
24592
24596
  baseButton: {
24593
24597
  top: "0",
24594
24598
  fontSize: "11px",
@@ -24801,23 +24805,23 @@ const LeafContainer = _ref2 => {
24801
24805
  } = _ref2;
24802
24806
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
24803
24807
  const previewHeading = hasPreviewHeading && /*#__PURE__*/React__namespace.createElement("div", {
24804
- className: aphrodite.css(styles$j.containerHeader)
24808
+ className: aphrodite.css(styles$n.containerHeader)
24805
24809
  }, /*#__PURE__*/React__namespace.createElement(Header, {
24806
24810
  depth: path.length,
24807
- className: aphrodite.css(styles$j.containerTitle)
24811
+ className: aphrodite.css(styles$n.containerTitle)
24808
24812
  }, capitalize(name)));
24809
24813
  return /*#__PURE__*/React__namespace.createElement("div", {
24810
- className: aphrodite.css(styles$j.container)
24814
+ className: aphrodite.css(styles$n.container)
24811
24815
  }, /*#__PURE__*/React__namespace.createElement("span", {
24812
- className: aphrodite.css(styles$j.row, styles$j.rowHeading)
24816
+ className: aphrodite.css(styles$n.row, styles$n.rowHeading)
24813
24817
  }, /*#__PURE__*/React__namespace.createElement("div", {
24814
- className: aphrodite.css(styles$j.columnLeft)
24818
+ className: aphrodite.css(styles$n.columnLeft)
24815
24819
  }, /*#__PURE__*/React__namespace.createElement("div", {
24816
- className: "pod-title " + aphrodite.css(styles$j.containerHeader)
24820
+ className: "pod-title " + aphrodite.css(styles$n.containerHeader)
24817
24821
  }, /*#__PURE__*/React__namespace.createElement("div", {
24818
- className: aphrodite.css(styles$j.containerTitle)
24822
+ className: aphrodite.css(styles$n.containerTitle)
24819
24823
  }, capitalize(name)), controls)), /*#__PURE__*/React__namespace.createElement("div", {
24820
- className: aphrodite.css(styles$j.columnRight)
24824
+ className: aphrodite.css(styles$n.columnRight)
24821
24825
  }, previewHeading)), children);
24822
24826
  };
24823
24827
  const ArrayContainer = props => {
@@ -24830,11 +24834,11 @@ const ArrayContainer = props => {
24830
24834
  actions
24831
24835
  } = props;
24832
24836
  return /*#__PURE__*/React__namespace.createElement("div", {
24833
- className: aphrodite.css(styles$j.container)
24837
+ className: aphrodite.css(styles$n.container)
24834
24838
  }, controls && /*#__PURE__*/React__namespace.createElement("div", {
24835
- className: aphrodite.css(styles$j.columnLeft, styles$j.containerHeader)
24839
+ className: aphrodite.css(styles$n.columnLeft, styles$n.containerHeader)
24836
24840
  }, controls), /*#__PURE__*/React__namespace.createElement("div", null, children), /*#__PURE__*/React__namespace.createElement("div", {
24837
- className: aphrodite.css(styles$j.columnLeft)
24841
+ className: aphrodite.css(styles$n.columnLeft)
24838
24842
  }, /*#__PURE__*/React__namespace.createElement("a", {
24839
24843
  href: "javascript:void 0",
24840
24844
  onClick: () => actions.addArrayElement(path, shape.elementShape)
@@ -24848,28 +24852,28 @@ const ObjectContainer = _ref3 => {
24848
24852
  path
24849
24853
  } = _ref3;
24850
24854
  const headingEditor = /*#__PURE__*/React__namespace.createElement("div", {
24851
- className: aphrodite.css(styles$j.containerHeader)
24855
+ className: aphrodite.css(styles$n.containerHeader)
24852
24856
  }, /*#__PURE__*/React__namespace.createElement(Header, {
24853
24857
  depth: path.length,
24854
- className: aphrodite.css(styles$j.containerTitle)
24858
+ className: aphrodite.css(styles$n.containerTitle)
24855
24859
  }, capitalize(name)), controls);
24856
24860
  const headingPreview = (name || controls) && /*#__PURE__*/React__namespace.createElement("div", {
24857
- className: aphrodite.css(styles$j.containerHeader, styles$j.previewCollectionHeader)
24861
+ className: aphrodite.css(styles$n.containerHeader, styles$n.previewCollectionHeader)
24858
24862
  }, /*#__PURE__*/React__namespace.createElement(Header, {
24859
24863
  depth: path.length,
24860
- className: aphrodite.css(styles$j.containerTitle)
24864
+ className: aphrodite.css(styles$n.containerTitle)
24861
24865
  }, capitalize(name)));
24862
24866
  const hasBothHeadings = headingEditor && headingPreview;
24863
24867
  return /*#__PURE__*/React__namespace.createElement("div", {
24864
- className: aphrodite.css(styles$j.container)
24868
+ className: aphrodite.css(styles$n.container)
24865
24869
  }, hasBothHeadings && /*#__PURE__*/React__namespace.createElement("span", {
24866
- className: aphrodite.css(styles$j.row)
24870
+ className: aphrodite.css(styles$n.row)
24867
24871
  }, /*#__PURE__*/React__namespace.createElement("div", {
24868
- className: aphrodite.css(styles$j.columnLeft)
24872
+ className: aphrodite.css(styles$n.columnLeft)
24869
24873
  }, headingEditor), /*#__PURE__*/React__namespace.createElement("div", {
24870
- className: aphrodite.css(styles$j.columnRight)
24874
+ className: aphrodite.css(styles$n.columnRight)
24871
24875
  }, headingPreview)), /*#__PURE__*/React__namespace.createElement("div", {
24872
- className: aphrodite.css(path.length > 0 && styles$j.contentIndent)
24876
+ className: aphrodite.css(path.length > 0 && styles$n.contentIndent)
24873
24877
  }, children));
24874
24878
  };
24875
24879
 
@@ -24989,11 +24993,11 @@ const ItemNodeContent = withStickiness(props => {
24989
24993
  className: "framework-perseus"
24990
24994
  }, lens(renderers).get(path));
24991
24995
  return /*#__PURE__*/React__namespace.createElement("span", null, /*#__PURE__*/React__namespace.createElement("div", {
24992
- className: aphrodite.css(styles$j.row)
24996
+ className: aphrodite.css(styles$n.row)
24993
24997
  }, /*#__PURE__*/React__namespace.createElement("div", {
24994
- className: aphrodite.css(styles$j.columnLeft)
24998
+ className: aphrodite.css(styles$n.columnLeft)
24995
24999
  }, /*#__PURE__*/React__namespace.createElement("div", {
24996
- className: aphrodite.css(sticky && styles$j.sticky)
25000
+ className: aphrodite.css(sticky && styles$n.sticky)
24997
25001
  },
24998
25002
  /*#__PURE__*/
24999
25003
  // @ts-expect-error - TS2769 - No overload matches this call.
@@ -25001,9 +25005,9 @@ const ItemNodeContent = withStickiness(props => {
25001
25005
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25002
25006
  apiOptions: apiOptions
25003
25007
  })))), /*#__PURE__*/React__namespace.createElement("div", {
25004
- className: aphrodite.css(styles$j.columnRight)
25008
+ className: aphrodite.css(styles$n.columnRight)
25005
25009
  }, /*#__PURE__*/React__namespace.createElement("div", {
25006
- className: aphrodite.css(sticky && styles$j.sticky)
25010
+ className: aphrodite.css(sticky && styles$n.sticky)
25007
25011
  }, preview))));
25008
25012
  });
25009
25013
  const HintNodeContent = withStickiness(props => {
@@ -25019,13 +25023,13 @@ const HintNodeContent = withStickiness(props => {
25019
25023
  className: "framework-perseus"
25020
25024
  }, lens(renderers).get(path));
25021
25025
  return /*#__PURE__*/React__namespace.createElement("div", {
25022
- className: aphrodite.css(styles$j.row)
25026
+ className: aphrodite.css(styles$n.row)
25023
25027
  }, /*#__PURE__*/React__namespace.createElement("div", {
25024
- className: aphrodite.css(styles$j.columnLeft)
25028
+ className: aphrodite.css(styles$n.columnLeft)
25025
25029
  }, /*#__PURE__*/React__namespace.createElement("div", {
25026
- className: aphrodite.css(sticky && styles$j.sticky)
25030
+ className: aphrodite.css(sticky && styles$n.sticky)
25027
25031
  }, /*#__PURE__*/React__namespace.createElement(HintEditor, _extends({}, data, {
25028
- className: aphrodite.css(styles$j.hintEditor),
25032
+ className: aphrodite.css(styles$n.hintEditor),
25029
25033
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25030
25034
  apiOptions: apiOptions,
25031
25035
  showTitle: false,
@@ -25040,9 +25044,9 @@ const HintNodeContent = withStickiness(props => {
25040
25044
  isFirst: true,
25041
25045
  isLast: true
25042
25046
  })))), /*#__PURE__*/React__namespace.createElement("div", {
25043
- className: aphrodite.css(styles$j.columnRight)
25047
+ className: aphrodite.css(styles$n.columnRight)
25044
25048
  }, /*#__PURE__*/React__namespace.createElement("div", {
25045
- className: aphrodite.css(sticky && styles$j.sticky)
25049
+ className: aphrodite.css(sticky && styles$n.sticky)
25046
25050
  }, preview)));
25047
25051
  });
25048
25052
  const TagsNodeContent = props => {
@@ -25059,9 +25063,9 @@ const TagsNodeContent = props => {
25059
25063
  return null;
25060
25064
  }
25061
25065
  return /*#__PURE__*/React__namespace.createElement("div", {
25062
- className: aphrodite.css(styles$j.columnLeft)
25066
+ className: aphrodite.css(styles$n.columnLeft)
25063
25067
  }, /*#__PURE__*/React__namespace.createElement("div", {
25064
- className: aphrodite.css(styles$j.tagsEditor)
25068
+ className: aphrodite.css(styles$n.tagsEditor)
25065
25069
  }, /*#__PURE__*/React__namespace.createElement(GroupMetadataEditor, {
25066
25070
  value: data,
25067
25071
  onChange: newVal => actions.setValueAtPath(path, newVal),
@@ -25092,23 +25096,23 @@ const ArrayNodeContent = props => {
25092
25096
  const subpath = path.concat(i);
25093
25097
  const controls = [i > 0 && /*#__PURE__*/React__namespace.createElement("div", {
25094
25098
  key: "moveArrayElementUp",
25095
- className: aphrodite.css(styles$j.control)
25099
+ className: aphrodite.css(styles$n.control)
25096
25100
  }, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
25097
25101
  color: "orange",
25098
25102
  title: "Move up",
25099
25103
  onClick: () => actions.moveArrayElementUp(subpath)
25100
25104
  }, /*#__PURE__*/React__namespace.createElement("div", {
25101
- className: aphrodite.css(styles$j.verticalFlip)
25105
+ className: aphrodite.css(styles$n.verticalFlip)
25102
25106
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React__namespace.createElement("div", {
25103
25107
  key: "moveArrayElementDown",
25104
- className: aphrodite.css(styles$j.control)
25108
+ className: aphrodite.css(styles$n.control)
25105
25109
  }, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
25106
25110
  color: "orange",
25107
25111
  title: "Move down",
25108
25112
  onClick: () => actions.moveArrayElementDown(subpath)
25109
25113
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React__namespace.createElement("div", {
25110
25114
  key: "removeArrayElement",
25111
- className: aphrodite.css(styles$j.control)
25115
+ className: aphrodite.css(styles$n.control)
25112
25116
  }, /*#__PURE__*/React__namespace.createElement(SimpleButton, {
25113
25117
  color: "orange",
25114
25118
  title: "Delete",
@@ -25116,7 +25120,7 @@ const ArrayNodeContent = props => {
25116
25120
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon$6, iconTrash$4)))];
25117
25121
  return /*#__PURE__*/React__namespace.createElement("div", {
25118
25122
  key: i,
25119
- className: aphrodite.css(styles$j.arrayElement, !elementIsLeaf && styles$j.arrayElementAndNotLeaf)
25123
+ className: aphrodite.css(styles$n.arrayElement, !elementIsLeaf && styles$n.arrayElementAndNotLeaf)
25120
25124
  }, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
25121
25125
  key: i,
25122
25126
  shape: shape.elementShape,
@@ -25142,7 +25146,7 @@ const ObjectNodeContent = props => {
25142
25146
  // made sense to the shape's author is the order in which we'll iterate :)
25143
25147
  const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React__namespace.createElement("div", {
25144
25148
  key: subkey,
25145
- className: aphrodite.css(styles$j.objectElement)
25149
+ className: aphrodite.css(styles$n.objectElement)
25146
25150
  }, /*#__PURE__*/React__namespace.createElement(NodeContainer, _extends({}, otherProps, {
25147
25151
  shape: shape.shape[subkey],
25148
25152
  data: data[subkey],
@@ -25311,7 +25315,7 @@ class MultiRendererEditor extends React__namespace.Component {
25311
25315
  }, this._renderContent());
25312
25316
  }
25313
25317
  }
25314
- const styles$j = aphrodite.StyleSheet.create({
25318
+ const styles$n = aphrodite.StyleSheet.create({
25315
25319
  // This is used in a number of places throughout this file.
25316
25320
  container: {},
25317
25321
  // eslint-disable-next-line react-native/no-unused-styles
@@ -25463,47 +25467,47 @@ const StatefulArticleEditor = createReactClass__default["default"]({
25463
25467
  screen
25464
25468
  } = this.state;
25465
25469
  return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("div", {
25466
- style: styles$i.controlBar
25470
+ style: styles$m.controlBar
25467
25471
  }, /*#__PURE__*/React__namespace.createElement("span", {
25468
- style: styles$i.controls
25472
+ style: styles$m.controls
25469
25473
  }, "Mode:", " ", /*#__PURE__*/React__namespace.createElement("span", {
25470
25474
  onClick: () => this.setState({
25471
25475
  mode: "edit"
25472
25476
  }),
25473
- style: mode === "edit" ? styles$i.controlSelected : styles$i.control
25477
+ style: mode === "edit" ? styles$m.controlSelected : styles$m.control
25474
25478
  }, "EDIT"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
25475
25479
  onClick: () => this.setState({
25476
25480
  mode: "preview"
25477
25481
  }),
25478
- style: mode === "preview" ? styles$i.controlSelected : styles$i.control
25482
+ style: mode === "preview" ? styles$m.controlSelected : styles$m.control
25479
25483
  }, "PREVIEW"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
25480
25484
  onClick: () => this.setState({
25481
25485
  mode: "json"
25482
25486
  }),
25483
- style: mode === "json" ? styles$i.controlSelected : styles$i.control
25487
+ style: mode === "json" ? styles$m.controlSelected : styles$m.control
25484
25488
  }, "JSON")), /*#__PURE__*/React__namespace.createElement("span", {
25485
- style: styles$i.controls
25489
+ style: styles$m.controls
25486
25490
  }, "Screen:", " ", /*#__PURE__*/React__namespace.createElement("span", {
25487
25491
  onClick: () => this.setState({
25488
25492
  screen: "phone"
25489
25493
  }),
25490
- style: screen === "phone" ? styles$i.controlSelected : styles$i.control
25494
+ style: screen === "phone" ? styles$m.controlSelected : styles$m.control
25491
25495
  }, "PHONE"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
25492
25496
  onClick: () => this.setState({
25493
25497
  screen: "tablet"
25494
25498
  }),
25495
- style: screen === "tablet" ? styles$i.controlSelected : styles$i.control
25499
+ style: screen === "tablet" ? styles$m.controlSelected : styles$m.control
25496
25500
  }, "TABLET"), " | ", /*#__PURE__*/React__namespace.createElement("span", {
25497
25501
  onClick: () => this.setState({
25498
25502
  screen: "desktop"
25499
25503
  }),
25500
- style: screen === "desktop" ? styles$i.controlSelected : styles$i.control
25504
+ style: screen === "desktop" ? styles$m.controlSelected : styles$m.control
25501
25505
  }, "DESKTOP"))), /*#__PURE__*/React__namespace.createElement("div", {
25502
- style: styles$i.editor
25506
+ style: styles$m.editor
25503
25507
  }, /*#__PURE__*/React__namespace.createElement(ArticleEditor, this.state)));
25504
25508
  }
25505
25509
  });
25506
- const styles$i = {
25510
+ const styles$m = {
25507
25511
  controlBar: {
25508
25512
  marginBottom: 25,
25509
25513
  marginTop: 5
@@ -27041,10 +27045,10 @@ class GradedGroupEditor extends React__namespace.Component {
27041
27045
  }, /*#__PURE__*/React__namespace.createElement("div", {
27042
27046
  className: "perseus-widget-row"
27043
27047
  }, /*#__PURE__*/React__namespace.createElement("label", {
27044
- className: aphrodite.css(styles$h.title)
27048
+ className: aphrodite.css(styles$l.title)
27045
27049
  }, "Title:", " ", /*#__PURE__*/React__namespace.createElement(TextInput$6, {
27046
27050
  value: this.props.title,
27047
- className: aphrodite.css(styles$h.input)
27051
+ className: aphrodite.css(styles$l.input)
27048
27052
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
27049
27053
  ,
27050
27054
  onChange: this.change("title")
@@ -27069,7 +27073,7 @@ class GradedGroupEditor extends React__namespace.Component {
27069
27073
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React__namespace.createElement("div", {
27070
27074
  className: "perseus-hint-editor"
27071
27075
  }, /*#__PURE__*/React__namespace.createElement("div", {
27072
- className: aphrodite.css(styles$h.hintsTitle)
27076
+ className: aphrodite.css(styles$l.hintsTitle)
27073
27077
  }, "Hint"), /*#__PURE__*/React__namespace.createElement(Editor, {
27074
27078
  ref: this.hintEditor,
27075
27079
  content: this.props.hint ? this.props.hint.content : "",
@@ -27101,7 +27105,7 @@ class GradedGroupEditor extends React__namespace.Component {
27101
27105
  };
27102
27106
  };
27103
27107
  }
27104
- const styles$h = aphrodite.StyleSheet.create({
27108
+ const styles$l = aphrodite.StyleSheet.create({
27105
27109
  title: {
27106
27110
  fontSize: 18,
27107
27111
  fontWeight: "bold"
@@ -28464,13 +28468,13 @@ function MathquillInput(props) {
28464
28468
  }
28465
28469
  });
28466
28470
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
28467
- style: styles$g.outerWrapper
28471
+ style: styles$k.outerWrapper
28468
28472
  }, /*#__PURE__*/React__namespace.createElement("span", {
28469
28473
  ref: mathFieldWrapperRef,
28470
28474
  className: "perseus-math-input mq-editable-field mq-math-mode"
28471
28475
  }));
28472
28476
  }
28473
- const styles$g = aphrodite.StyleSheet.create({
28477
+ const styles$k = aphrodite.StyleSheet.create({
28474
28478
  outerWrapper: {
28475
28479
  display: "inline-block",
28476
28480
  borderStyle: "solid",
@@ -29556,7 +29560,7 @@ const GraphPointsCountSelector = _ref => {
29556
29560
  // Never uses placeholder, always has value
29557
29561
  ,
29558
29562
  placeholder: "",
29559
- style: styles$f.singleSelectShort
29563
+ style: styles$j.singleSelectShort
29560
29564
  }, [...[...Array(7).keys()].map(n => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
29561
29565
  key: n,
29562
29566
  value: `${n}`,
@@ -29566,7 +29570,7 @@ const GraphPointsCountSelector = _ref => {
29566
29570
  label: "unlimited"
29567
29571
  })]);
29568
29572
  };
29569
- const styles$f = aphrodite.StyleSheet.create({
29573
+ const styles$j = aphrodite.StyleSheet.create({
29570
29574
  singleSelectShort: {
29571
29575
  // Non-standard spacing, but it's the smallest we can go
29572
29576
  // without running into styling issues with the dropdown.
@@ -29579,7 +29583,7 @@ const GraphTypeSelector = props => {
29579
29583
  selectedValue: props.graphType,
29580
29584
  onChange: props.onChange,
29581
29585
  placeholder: "Select a graph type",
29582
- style: styles$e.singleSelectShort
29586
+ style: styles$i.singleSelectShort
29583
29587
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
29584
29588
  value: "linear",
29585
29589
  label: "Linear function"
@@ -29612,7 +29616,7 @@ const GraphTypeSelector = props => {
29612
29616
  label: "Angle"
29613
29617
  }));
29614
29618
  };
29615
- const styles$e = aphrodite.StyleSheet.create({
29619
+ const styles$i = aphrodite.StyleSheet.create({
29616
29620
  singleSelectShort: {
29617
29621
  // Non-standard spacing, but it's the smallest we can go
29618
29622
  // without running into styling issues with the dropdown.
@@ -29628,19 +29632,25 @@ const LabeledRow = props => {
29628
29632
  labelSide = "left",
29629
29633
  style
29630
29634
  } = props;
29631
- return /*#__PURE__*/React__namespace.createElement("label", null, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29632
- style: [styles$d.row, style]
29635
+ return /*#__PURE__*/React__namespace.createElement("label", {
29636
+ className: aphrodite.css(styles$h.label)
29637
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
29638
+ style: [styles$h.row, style]
29633
29639
  }, labelSide === "start" || /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
29634
- style: styles$d.spaceEnd
29640
+ style: styles$h.spaceEnd
29635
29641
  }, label), children, labelSide === "end" && /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelSmall, {
29636
- style: styles$d.spaceStart
29642
+ style: styles$h.spaceStart
29637
29643
  }, label)));
29638
29644
  };
29639
- const styles$d = aphrodite.StyleSheet.create({
29645
+ const styles$h = aphrodite.StyleSheet.create({
29646
+ label: {
29647
+ width: "fit-content"
29648
+ },
29640
29649
  row: {
29641
29650
  flexDirection: "row",
29642
29651
  marginTop: wonderBlocksTokens.spacing.xSmall_8,
29643
- alignItems: "center"
29652
+ alignItems: "center",
29653
+ width: "fit-content"
29644
29654
  },
29645
29655
  spaceStart: {
29646
29656
  marginInlineStart: wonderBlocksTokens.spacing.xSmall_8
@@ -30054,10 +30064,10 @@ class InteractiveGraphSettings extends React__namespace.Component {
30054
30064
  onChange: this.change
30055
30065
  }))), /*#__PURE__*/React__namespace.createElement(LabeledRow, {
30056
30066
  label: "Background image URL:",
30057
- style: styles$c.resetSpaceTop
30067
+ style: styles$g.resetSpaceTop
30058
30068
  }, /*#__PURE__*/React__namespace.createElement("input", {
30059
30069
  type: "text",
30060
- className: aphrodite.css(styles$c.backgroundUrlInput),
30070
+ className: aphrodite.css(styles$g.backgroundUrlInput),
30061
30071
  ref: this.bgUrlRef,
30062
30072
  value: this.state.backgroundImage.url || "",
30063
30073
  onChange: e => {
@@ -30073,24 +30083,24 @@ class InteractiveGraphSettings extends React__namespace.Component {
30073
30083
  onKeyPress: this.changeBackgroundUrl,
30074
30084
  onBlur: this.changeBackgroundUrl
30075
30085
  }), /*#__PURE__*/React__namespace.createElement(InfoTip$c, null, /*#__PURE__*/React__namespace.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30076
- style: styles$c.rulerSection
30086
+ style: styles$g.rulerSection
30077
30087
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30078
- style: styles$c.checkboxRow
30088
+ style: styles$g.checkboxRow
30079
30089
  }, /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
30080
30090
  label: "Show ruler",
30081
30091
  showRuler: this.props.showRuler,
30082
30092
  onChange: this.change,
30083
- style: styles$c.resetSpaceTop
30093
+ style: styles$g.resetSpaceTop
30084
30094
  }), /*#__PURE__*/React__namespace.createElement(PropCheckBox$7, {
30085
30095
  label: "Show protractor",
30086
30096
  showProtractor: this.props.showProtractor,
30087
30097
  onChange: this.change,
30088
- style: styles$c.resetSpaceTop
30098
+ style: styles$g.resetSpaceTop
30089
30099
  })), this.props.showRuler && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30090
- style: styles$c.spaceTop
30100
+ style: styles$g.spaceTop
30091
30101
  }, /*#__PURE__*/React__namespace.createElement(LabeledRow, {
30092
30102
  label: "Ruler label:",
30093
- style: styles$c.resetSpaceTop
30103
+ style: styles$g.resetSpaceTop
30094
30104
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.SingleSelect, {
30095
30105
  id: "ruler-label-select",
30096
30106
  selectedValue: this.props.rulerLabel,
@@ -30100,7 +30110,7 @@ class InteractiveGraphSettings extends React__namespace.Component {
30100
30110
  });
30101
30111
  },
30102
30112
  placeholder: "None",
30103
- style: styles$c.singleSelectShort
30113
+ style: styles$g.singleSelectShort
30104
30114
  }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
30105
30115
  value: "",
30106
30116
  label: "None",
@@ -30141,7 +30151,7 @@ class InteractiveGraphSettings extends React__namespace.Component {
30141
30151
  });
30142
30152
  },
30143
30153
  placeholder: "10",
30144
- style: styles$c.singleSelectShort
30154
+ style: styles$g.singleSelectShort
30145
30155
  }, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.OptionItem, {
30146
30156
  key: value,
30147
30157
  value: `${value}`,
@@ -30149,7 +30159,7 @@ class InteractiveGraphSettings extends React__namespace.Component {
30149
30159
  })))))));
30150
30160
  }
30151
30161
  }
30152
- const styles$c = aphrodite.StyleSheet.create({
30162
+ const styles$g = aphrodite.StyleSheet.create({
30153
30163
  resetSpaceTop: {
30154
30164
  marginTop: 0
30155
30165
  },
@@ -30180,6 +30190,315 @@ const styles$c = aphrodite.StyleSheet.create({
30180
30190
  }
30181
30191
  });
30182
30192
 
30193
+ /**
30194
+ * Dropdown for selecting a locked figure to add to an interactive graph.
30195
+ * Locked figures are elements (points, segmeents, etc.) that are not
30196
+ * interactive, just present in the graph's background.
30197
+ *
30198
+ * Used in the interactive graph editor's locked figures section.
30199
+ */
30200
+ const LockedFigureSelect = props => {
30201
+ const {
30202
+ id,
30203
+ onChange
30204
+ } = props;
30205
+ return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30206
+ style: styles$f.container
30207
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionMenu, {
30208
+ menuText: "Add element",
30209
+ style: styles$f.addElementSelect
30210
+ }, [/*#__PURE__*/React__namespace.createElement(wonderBlocksDropdown.ActionItem, {
30211
+ key: `${id}-point`,
30212
+ label: "Point",
30213
+ onClick: () => onChange("point")
30214
+ }, "Point")]));
30215
+ };
30216
+ const styles$f = aphrodite.StyleSheet.create({
30217
+ container: {
30218
+ marginTop: wonderBlocksTokens.spacing.medium_16
30219
+ },
30220
+ addElementSelect: {
30221
+ backgroundColor: wonderBlocksTokens.color.fadedBlue16,
30222
+ borderRadius: wonderBlocksTokens.spacing.xxxSmall_4
30223
+ }
30224
+ });
30225
+
30226
+ const mediaDefaultSpecLargeMarginWidth = wonderBlocksTokens.spacing.large_24;
30227
+ const MEDIA_DEFAULT_SPEC = {
30228
+ small: {
30229
+ query: "(max-width: 767px)",
30230
+ totalColumns: 4,
30231
+ gutterWidth: wonderBlocksTokens.spacing.medium_16,
30232
+ marginWidth: wonderBlocksTokens.spacing.medium_16
30233
+ },
30234
+ medium: {
30235
+ query: "(min-width: 768px) and (max-width: 1023px)",
30236
+ totalColumns: 8,
30237
+ gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
30238
+ marginWidth: wonderBlocksTokens.spacing.large_24
30239
+ },
30240
+ large: {
30241
+ query: "(min-width: 1024px)",
30242
+ totalColumns: 12,
30243
+ gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
30244
+ marginWidth: mediaDefaultSpecLargeMarginWidth,
30245
+ maxWidth: 1120 + mediaDefaultSpecLargeMarginWidth * 2
30246
+ }
30247
+ };
30248
+ ({
30249
+ large: {
30250
+ query: "(min-width: 1px)",
30251
+ totalColumns: 12,
30252
+ gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
30253
+ marginWidth: wonderBlocksTokens.spacing.medium_16
30254
+ }
30255
+ });
30256
+ ({
30257
+ small: {
30258
+ query: "(max-width: 767px)",
30259
+ totalColumns: 4,
30260
+ gutterWidth: wonderBlocksTokens.spacing.medium_16,
30261
+ marginWidth: wonderBlocksTokens.spacing.medium_16
30262
+ },
30263
+ large: {
30264
+ query: "(min-width: 768px)",
30265
+ totalColumns: 12,
30266
+ gutterWidth: wonderBlocksTokens.spacing.xLarge_32,
30267
+ marginWidth: wonderBlocksTokens.spacing.xxLarge_48
30268
+ }
30269
+ });
30270
+
30271
+ const defaultContext = {
30272
+ ssrSize: "large",
30273
+ mediaSpec: MEDIA_DEFAULT_SPEC
30274
+ };
30275
+ const MediaLayoutContext = React__namespace.createContext(defaultContext);
30276
+ MediaLayoutContext.displayName = "MediaLayoutContext";
30277
+
30278
+ class Spring extends React__namespace.Component {
30279
+ render() {
30280
+ const {
30281
+ style
30282
+ } = this.props;
30283
+ return React__namespace.createElement(wonderBlocksCore.View, {
30284
+ "aria-hidden": "true",
30285
+ style: [styles$e.grow, style]
30286
+ });
30287
+ }
30288
+ }
30289
+ const styles$e = aphrodite.StyleSheet.create({
30290
+ grow: {
30291
+ flexGrow: 1
30292
+ }
30293
+ });
30294
+
30295
+ function focusWithChromeStickyFocusBugWorkaround(element) {
30296
+ // NOTE(marksandstrom) Chrome sticky focus bug.
30297
+ //
30298
+ // There is a bug in Chrome related to sticky positioning and
30299
+ // focus: When a child of an element with sticky positioning is
30300
+ // focused with the focus() method, the scrollable area
30301
+ // containing that element will scroll to the top (even though
30302
+ // the element is already visble on the page). For a dropdown
30303
+ // this means that the area will be scrolled to the top when
30304
+ // the user interacts with the dropdown (since we actively
30305
+ // manage dropdown header and option focus for keyboard users).
30306
+ //
30307
+ // To work around this bug the `preventScroll` focus option is
30308
+ // used.
30309
+ //
30310
+ // Using `focusOptions` is an experimental browser feature
30311
+ // "that should not be used in production code". However, since
30312
+ // Chrome is the only browser we support that exhibits this
30313
+ // buggy behavior and using `focusOptions` works around the
30314
+ // bug, it is perfectly reasonable to use the feature in this
30315
+ // case. We are not relying on the effect of the
30316
+ // `preventScroll` option otherwise.
30317
+ //
30318
+ // focusOptions documentation:
30319
+ //
30320
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
30321
+ //
30322
+ // Note that there could be cases where we want default focus() behavior.
30323
+ // One that comes to mind is a dropdown with a long list of options that
30324
+ // might be rendered off screen when opened. With this workaround the
30325
+ // selected option would not be scrolled into view if the option is near
30326
+ // the end of the list. We're not aware of any uses of the dropdown where
30327
+ // this is an issue, however, so there isn't currently a way to out of the
30328
+ // `preventScroll` behavior.
30329
+
30330
+ // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
30331
+ element.focus({
30332
+ preventScroll: true
30333
+ });
30334
+ }
30335
+ function getValidNumberFromString(value) {
30336
+ const parsed = parseInt(value);
30337
+ // If the value is not a number, return 0.
30338
+ return isNaN(parsed) ? 0 : parsed;
30339
+ }
30340
+ function getDefaultFigureForFigureType(type) {
30341
+ switch (type) {
30342
+ case "point":
30343
+ return {
30344
+ type: "point",
30345
+ coord: [0, 0]
30346
+ };
30347
+ }
30348
+ }
30349
+
30350
+ /**
30351
+ * LockedPointSettings is a component that allows the user to edit the
30352
+ * settings of specifically a locked point on the graph.
30353
+ *
30354
+ * Used in the interactive graph editor's locked figures section.
30355
+ */
30356
+ const LockedPointSettings = props => {
30357
+ const {
30358
+ coord,
30359
+ onRemove,
30360
+ onChangeCoord
30361
+ } = props;
30362
+ const [coordState, setCoordState] = React__namespace.useState([
30363
+ // Using strings to make it easier to work with the text fields.
30364
+ coord[0].toString(), coord[1].toString()]);
30365
+
30366
+ // Generate unique IDs so that the programmatic labels can be associated
30367
+ // with their respective text fields.
30368
+ const ids = wonderBlocksCore.useUniqueIdWithMock();
30369
+ const xCoordId = ids.get("x-coord");
30370
+ const yCoordId = ids.get("y-coord");
30371
+ function handleBlur() {
30372
+ const validCoord = [getValidNumberFromString(coordState[0]), getValidNumberFromString(coordState[1])];
30373
+
30374
+ // Make the text field only show valid numbers after blur.
30375
+ setCoordState([validCoord[0].toString(), validCoord[1].toString()]);
30376
+ // Update the graph with the new coordinates.
30377
+ onChangeCoord(validCoord);
30378
+ }
30379
+ function handleChange(newValue, coordIndex) {
30380
+ const newCoord = [...coordState];
30381
+ newCoord[coordIndex] = newValue;
30382
+ setCoordState(newCoord);
30383
+ }
30384
+ return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30385
+ style: styles$d.container
30386
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30387
+ style: styles$d.row
30388
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelLarge, null, "Point"), /*#__PURE__*/React__namespace.createElement(Spring, null), /*#__PURE__*/React__namespace.createElement(IconButton__default["default"], {
30389
+ icon: trashIcon__default["default"],
30390
+ "aria-label": `Delete locked point at ${coordState[0]}, ${coordState[1]}`,
30391
+ onClick: onRemove
30392
+ })), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30393
+ style: styles$d.row
30394
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30395
+ htmlFor: xCoordId,
30396
+ style: styles$d.label,
30397
+ tag: "label"
30398
+ }, "x Coordinate"), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
30399
+ id: xCoordId,
30400
+ value: coordState[0],
30401
+ onChange: newValue => handleChange(newValue, 0),
30402
+ onBlur: handleBlur,
30403
+ style: styles$d.textField
30404
+ })), /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30405
+ style: styles$d.row
30406
+ }, /*#__PURE__*/React__namespace.createElement(wonderBlocksTypography.LabelMedium, {
30407
+ htmlFor: yCoordId,
30408
+ style: styles$d.label,
30409
+ tag: "label"
30410
+ }, "y Coordinate"), /*#__PURE__*/React__namespace.createElement(wonderBlocksForm.TextField, {
30411
+ id: yCoordId,
30412
+ value: coordState[1],
30413
+ onChange: newValue => handleChange(newValue, 1),
30414
+ onBlur: handleBlur,
30415
+ style: styles$d.textField
30416
+ }))));
30417
+ };
30418
+ const styles$d = aphrodite.StyleSheet.create({
30419
+ container: {
30420
+ backgroundColor: wonderBlocksTokens.color.fadedBlue8,
30421
+ marginBottom: wonderBlocksTokens.spacing.xSmall_8,
30422
+ padding: wonderBlocksTokens.spacing.medium_16,
30423
+ borderRadius: wonderBlocksTokens.spacing.xSmall_8
30424
+ },
30425
+ row: {
30426
+ flexDirection: "row",
30427
+ alignItems: "center",
30428
+ marginBottom: wonderBlocksTokens.spacing.xSmall_8
30429
+ },
30430
+ label: {
30431
+ marginInlineEnd: wonderBlocksTokens.spacing.xSmall_8
30432
+ },
30433
+ textField: {
30434
+ width: wonderBlocksTokens.spacing.xxxLarge_64
30435
+ }
30436
+ });
30437
+
30438
+ /**
30439
+ * LockedFigureSettings takes in a figure and renders the
30440
+ * respective settings for that figure type.
30441
+ *
30442
+ * Used in the interactive graph editor's locked figures section.
30443
+ */
30444
+
30445
+ // Union this type with other locked figure types when they are added.
30446
+
30447
+ const LockedFigureSettings = props => {
30448
+ switch (props.type) {
30449
+ case "point":
30450
+ return /*#__PURE__*/React__namespace.createElement(LockedPointSettings, props);
30451
+ }
30452
+ return null;
30453
+ };
30454
+
30455
+ const LockedFiguresSection = props => {
30456
+ const uniqueId = wonderBlocksCore.useUniqueIdWithMock().get("locked-figures-section");
30457
+ const {
30458
+ figures,
30459
+ onChange
30460
+ } = props;
30461
+ function addLockedFigure(newFigure) {
30462
+ const lockedFigures = figures || [];
30463
+ const newProps = {
30464
+ lockedFigures: [...lockedFigures, getDefaultFigureForFigureType(newFigure)]
30465
+ };
30466
+ onChange(newProps);
30467
+ }
30468
+ function removeLockedFigure(index) {
30469
+ const lockedFigures = figures || [];
30470
+ onChange({
30471
+ lockedFigures: [...lockedFigures.slice(0, index), ...lockedFigures.slice(index + 1)]
30472
+ });
30473
+ }
30474
+ function changeCoord(index, coord) {
30475
+ const lockedFigures = figures || [];
30476
+ const newProps = {
30477
+ lockedFigures: [...lockedFigures.slice(0, index), {
30478
+ ...lockedFigures[index],
30479
+ coord
30480
+ }, ...lockedFigures.slice(index + 1)]
30481
+ };
30482
+ onChange(newProps);
30483
+ }
30484
+ return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
30485
+ style: styles$c.container
30486
+ }, figures?.map((figure, index) => /*#__PURE__*/React__namespace.createElement(LockedFigureSettings, _extends({
30487
+ key: `${uniqueId}-locked-${figure}-${index}`
30488
+ }, figure, {
30489
+ onRemove: () => removeLockedFigure(index),
30490
+ onChangeCoord: coord => changeCoord(index, coord)
30491
+ }))), /*#__PURE__*/React__namespace.createElement(LockedFigureSelect, {
30492
+ id: `${uniqueId}-select`,
30493
+ onChange: addLockedFigure
30494
+ }));
30495
+ };
30496
+ const styles$c = aphrodite.StyleSheet.create({
30497
+ container: {
30498
+ paddingTop: wonderBlocksTokens.spacing.large_24
30499
+ }
30500
+ });
30501
+
30183
30502
  const SegmentCountSelector = _ref => {
30184
30503
  let {
30185
30504
  numSegments = 1,
@@ -30288,6 +30607,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
30288
30607
  showTooltips: this.props.showTooltips,
30289
30608
  rulerLabel: this.props.rulerLabel,
30290
30609
  rulerTicks: this.props.rulerTicks,
30610
+ lockedFigures: this.props.lockedFigures,
30291
30611
  trackInteraction: function () {},
30292
30612
  onChange: newProps => {
30293
30613
  let correct = this.props.correct;
@@ -30508,7 +30828,13 @@ class InteractiveGraphEditor extends React__namespace.Component {
30508
30828
  borderStyle: "solid",
30509
30829
  borderWidth: 1
30510
30830
  }
30511
- }, equationString), /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), graph);
30831
+ }, equationString), /*#__PURE__*/React__namespace.createElement(InfoTip$b, null, /*#__PURE__*/React__namespace.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), graph,
30832
+ // Only show the "Add element" dropdown if the graph is
30833
+ // using Mafs.
30834
+ this.props.graph && this.props.apiOptions?.flags?.["mafs"]?.[this.props.graph.type] && /*#__PURE__*/React__namespace.createElement(LockedFiguresSection, {
30835
+ figures: this.props.lockedFigures,
30836
+ onChange: this.props.onChange
30837
+ }));
30512
30838
  }
30513
30839
  changeMatchType = newValue => {
30514
30840
  const correct = {
@@ -30520,7 +30846,7 @@ class InteractiveGraphEditor extends React__namespace.Component {
30520
30846
  });
30521
30847
  };
30522
30848
  serialize() {
30523
- const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showRuler", "showTooltips", "rulerLabel", "rulerTicks", "range", "gridStep", "snapStep");
30849
+ const json = ___default["default"].pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showRuler", "showTooltips", "rulerLabel", "rulerTicks", "range", "gridStep", "snapStep", "lockedFigures");
30524
30850
 
30525
30851
  // eslint-disable-next-line react/no-string-refs
30526
30852
  const graph = this.refs.graph;
@@ -31296,47 +31622,6 @@ const styles$5 = aphrodite.StyleSheet.create({
31296
31622
  }
31297
31623
  });
31298
31624
 
31299
- function focusWithChromeStickyFocusBugWorkaround(element) {
31300
- // NOTE(marksandstrom) Chrome sticky focus bug.
31301
- //
31302
- // There is a bug in Chrome related to sticky positioning and
31303
- // focus: When a child of an element with sticky positioning is
31304
- // focused with the focus() method, the scrollable area
31305
- // containing that element will scroll to the top (even though
31306
- // the element is already visble on the page). For a dropdown
31307
- // this means that the area will be scrolled to the top when
31308
- // the user interacts with the dropdown (since we actively
31309
- // manage dropdown header and option focus for keyboard users).
31310
- //
31311
- // To work around this bug the `preventScroll` focus option is
31312
- // used.
31313
- //
31314
- // Using `focusOptions` is an experimental browser feature
31315
- // "that should not be used in production code". However, since
31316
- // Chrome is the only browser we support that exhibits this
31317
- // buggy behavior and using `focusOptions` works around the
31318
- // bug, it is perfectly reasonable to use the feature in this
31319
- // case. We are not relying on the effect of the
31320
- // `preventScroll` option otherwise.
31321
- //
31322
- // focusOptions documentation:
31323
- //
31324
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
31325
- //
31326
- // Note that there could be cases where we want default focus() behavior.
31327
- // One that comes to mind is a dropdown with a long list of options that
31328
- // might be rendered off screen when opened. With this workaround the
31329
- // selected option would not be scrolled into view if the option is near
31330
- // the end of the list. We're not aware of any uses of the dropdown where
31331
- // this is an issue, however, so there isn't currently a way to out of the
31332
- // `preventScroll` behavior.
31333
-
31334
- // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
31335
- element.focus({
31336
- preventScroll: true
31337
- });
31338
- }
31339
-
31340
31625
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
31341
31626
  const {
31342
31627
  Icon