@khanacademy/perseus-editor 6.6.0 → 6.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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, PerseusI18nContext, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, lockedFigureColors, 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, PerseusI18nContext, KhanColors, ColorPicker, DashPicker, ArrowPicker, ElementContainer, lockedFigureColors, lockedEllipseFillStyles, 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';
@@ -29,7 +29,7 @@ import trashIcon from '@phosphor-icons/core/bold/trash-bold.svg';
29
29
 
30
30
  // This file is processed by a Rollup plugin (replace) to inject the production
31
31
  const libName = "@khanacademy/perseus-editor";
32
- const libVersion = "6.6.0";
32
+ const libVersion = "6.9.0";
33
33
  addLibraryVersionToPerseusDebug(libName, libVersion);
34
34
 
35
35
  function _extends() {
@@ -219,7 +219,7 @@ class SectionControlButton extends React.Component {
219
219
  role: "button",
220
220
  hideDefaultFocusRing: true,
221
221
  "aria-label": title,
222
- style: styles$z.button
222
+ style: styles$D.button
223
223
  }, ({
224
224
  hovered,
225
225
  focused,
@@ -227,7 +227,7 @@ class SectionControlButton extends React.Component {
227
227
  }) => /*#__PURE__*/React.createElement(InlineIcon$b, icon));
228
228
  }
229
229
  }
230
- const styles$z = StyleSheet.create({
230
+ const styles$D = StyleSheet.create({
231
231
  button: {
232
232
  backgroundColor: color.gold,
233
233
  margin: 2,
@@ -20732,13 +20732,13 @@ class WidgetSelect extends React.Component {
20732
20732
  * that collapse a region.
20733
20733
  */
20734
20734
  function ToggleableCaret(props) {
20735
- const iconStyle = props.isExpanded ? styles$y.expanded : styles$y.collapsed;
20735
+ const iconStyle = props.isExpanded ? styles$C.expanded : styles$C.collapsed;
20736
20736
  return /*#__PURE__*/React.createElement(PhosphorIcon, {
20737
20737
  icon: caretRight,
20738
20738
  style: iconStyle
20739
20739
  });
20740
20740
  }
20741
- const styles$y = StyleSheet.create({
20741
+ const styles$C = StyleSheet.create({
20742
20742
  collapsed: {
20743
20743
  transition: ".15s"
20744
20744
  },
@@ -20771,16 +20771,16 @@ class TexErrorView extends React.Component {
20771
20771
  showErrors
20772
20772
  } = this.state;
20773
20773
  return /*#__PURE__*/React.createElement(View, {
20774
- style: styles$x.errorContainer
20774
+ style: styles$B.errorContainer
20775
20775
  }, /*#__PURE__*/React.createElement(View, {
20776
- style: styles$x.title,
20776
+ style: styles$B.title,
20777
20777
  onClick: this.handleToggleTexErrors
20778
20778
  }, /*#__PURE__*/React.createElement(ToggleableCaret, {
20779
20779
  isExpanded: showErrors
20780
20780
  }), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React.createElement(View, {
20781
- style: styles$x.errorExplanation
20781
+ style: styles$B.errorExplanation
20782
20782
  }, "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, {
20783
- style: styles$x.error,
20783
+ style: styles$B.error,
20784
20784
  key: index
20785
20785
  }, /*#__PURE__*/React.createElement(View, {
20786
20786
  style: {
@@ -20789,7 +20789,7 @@ class TexErrorView extends React.Component {
20789
20789
  }, e.math), /*#__PURE__*/React.createElement(View, null, e.message))));
20790
20790
  }
20791
20791
  }
20792
- const styles$x = StyleSheet.create({
20792
+ const styles$B = StyleSheet.create({
20793
20793
  title: {
20794
20794
  backgroundColor: "#eee",
20795
20795
  fontSize: "1.25em",
@@ -23445,7 +23445,7 @@ class StructuredItemDiff extends React.Component {
23445
23445
 
23446
23446
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
23447
23447
  const {
23448
- InfoTip: InfoTip$l,
23448
+ InfoTip: InfoTip$n,
23449
23449
  InlineIcon: InlineIcon$7
23450
23450
  } = components;
23451
23451
  const {
@@ -23517,7 +23517,7 @@ class HintEditor extends React.Component {
23517
23517
  type: "button",
23518
23518
  className: this.props.isFirst ? "hidden" : "",
23519
23519
  onClick: _.partial(this.props.onMove, -1)
23520
- }, /*#__PURE__*/React.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$l, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23520
+ }, /*#__PURE__*/React.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$n, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23521
23521
  type: "checkbox"
23522
23522
  // @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
23523
23523
  ,
@@ -23770,7 +23770,7 @@ CombinedHintsEditor.defaultProps = {
23770
23770
  };
23771
23771
 
23772
23772
  const {
23773
- InfoTip: InfoTip$k
23773
+ InfoTip: InfoTip$m
23774
23774
  } = components;
23775
23775
  class ItemExtrasEditor extends React.Component {
23776
23776
  constructor(...args) {
@@ -23916,7 +23916,7 @@ const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement("div", {
23916
23916
  type: "checkbox",
23917
23917
  checked: props.checked,
23918
23918
  onChange: props.onChange
23919
- })), /*#__PURE__*/React.createElement(InfoTip$k, null, props.infoTip));
23919
+ })), /*#__PURE__*/React.createElement(InfoTip$m, null, props.infoTip));
23920
23920
 
23921
23921
  const ITEM_DATA_VERSION = itemDataVersion;
23922
23922
  class ItemEditor extends React.Component {
@@ -24583,7 +24583,7 @@ class SimpleButton extends React.Component {
24583
24583
  } = _this$props,
24584
24584
  otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$3);
24585
24585
  return /*#__PURE__*/React.createElement("div", _extends({
24586
- className: css(styles$w.baseButton, color === "green" && styles$w.green, color === "orange" && styles$w.orange),
24586
+ className: css(styles$A.baseButton, color === "green" && styles$A.green, color === "orange" && styles$A.orange),
24587
24587
  onClick: onClick
24588
24588
  }, otherProps), children);
24589
24589
  }
@@ -24598,7 +24598,7 @@ SimpleButton.defaultProps = {
24598
24598
  color: "green",
24599
24599
  onClick: () => {}
24600
24600
  };
24601
- const styles$w = StyleSheet.create({
24601
+ const styles$A = StyleSheet.create({
24602
24602
  baseButton: {
24603
24603
  top: "0",
24604
24604
  fontSize: "11px",
@@ -24818,23 +24818,23 @@ const LeafContainer = ({
24818
24818
  }) => {
24819
24819
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
24820
24820
  const previewHeading = hasPreviewHeading && /*#__PURE__*/React.createElement("div", {
24821
- className: css(styles$v.containerHeader)
24821
+ className: css(styles$z.containerHeader)
24822
24822
  }, /*#__PURE__*/React.createElement(Header, {
24823
24823
  depth: path.length,
24824
- className: css(styles$v.containerTitle)
24824
+ className: css(styles$z.containerTitle)
24825
24825
  }, capitalize(name)));
24826
24826
  return /*#__PURE__*/React.createElement("div", {
24827
- className: css(styles$v.container)
24827
+ className: css(styles$z.container)
24828
24828
  }, /*#__PURE__*/React.createElement("span", {
24829
- className: css(styles$v.row, styles$v.rowHeading)
24829
+ className: css(styles$z.row, styles$z.rowHeading)
24830
24830
  }, /*#__PURE__*/React.createElement("div", {
24831
- className: css(styles$v.columnLeft)
24831
+ className: css(styles$z.columnLeft)
24832
24832
  }, /*#__PURE__*/React.createElement("div", {
24833
- className: "pod-title " + css(styles$v.containerHeader)
24833
+ className: "pod-title " + css(styles$z.containerHeader)
24834
24834
  }, /*#__PURE__*/React.createElement("div", {
24835
- className: css(styles$v.containerTitle)
24835
+ className: css(styles$z.containerTitle)
24836
24836
  }, capitalize(name)), controls)), /*#__PURE__*/React.createElement("div", {
24837
- className: css(styles$v.columnRight)
24837
+ className: css(styles$z.columnRight)
24838
24838
  }, previewHeading)), children);
24839
24839
  };
24840
24840
  const ArrayContainer = props => {
@@ -24847,11 +24847,11 @@ const ArrayContainer = props => {
24847
24847
  actions
24848
24848
  } = props;
24849
24849
  return /*#__PURE__*/React.createElement("div", {
24850
- className: css(styles$v.container)
24850
+ className: css(styles$z.container)
24851
24851
  }, controls && /*#__PURE__*/React.createElement("div", {
24852
- className: css(styles$v.columnLeft, styles$v.containerHeader)
24852
+ className: css(styles$z.columnLeft, styles$z.containerHeader)
24853
24853
  }, controls), /*#__PURE__*/React.createElement("div", null, children), /*#__PURE__*/React.createElement("div", {
24854
- className: css(styles$v.columnLeft)
24854
+ className: css(styles$z.columnLeft)
24855
24855
  }, /*#__PURE__*/React.createElement("a", {
24856
24856
  href: "javascript:void 0",
24857
24857
  onClick: () => actions.addArrayElement(path, shape.elementShape)
@@ -24864,28 +24864,28 @@ const ObjectContainer = ({
24864
24864
  path
24865
24865
  }) => {
24866
24866
  const headingEditor = /*#__PURE__*/React.createElement("div", {
24867
- className: css(styles$v.containerHeader)
24867
+ className: css(styles$z.containerHeader)
24868
24868
  }, /*#__PURE__*/React.createElement(Header, {
24869
24869
  depth: path.length,
24870
- className: css(styles$v.containerTitle)
24870
+ className: css(styles$z.containerTitle)
24871
24871
  }, capitalize(name)), controls);
24872
24872
  const headingPreview = (name || controls) && /*#__PURE__*/React.createElement("div", {
24873
- className: css(styles$v.containerHeader, styles$v.previewCollectionHeader)
24873
+ className: css(styles$z.containerHeader, styles$z.previewCollectionHeader)
24874
24874
  }, /*#__PURE__*/React.createElement(Header, {
24875
24875
  depth: path.length,
24876
- className: css(styles$v.containerTitle)
24876
+ className: css(styles$z.containerTitle)
24877
24877
  }, capitalize(name)));
24878
24878
  const hasBothHeadings = headingEditor && headingPreview;
24879
24879
  return /*#__PURE__*/React.createElement("div", {
24880
- className: css(styles$v.container)
24880
+ className: css(styles$z.container)
24881
24881
  }, hasBothHeadings && /*#__PURE__*/React.createElement("span", {
24882
- className: css(styles$v.row)
24882
+ className: css(styles$z.row)
24883
24883
  }, /*#__PURE__*/React.createElement("div", {
24884
- className: css(styles$v.columnLeft)
24884
+ className: css(styles$z.columnLeft)
24885
24885
  }, headingEditor), /*#__PURE__*/React.createElement("div", {
24886
- className: css(styles$v.columnRight)
24886
+ className: css(styles$z.columnRight)
24887
24887
  }, headingPreview)), /*#__PURE__*/React.createElement("div", {
24888
- className: css(path.length > 0 && styles$v.contentIndent)
24888
+ className: css(path.length > 0 && styles$z.contentIndent)
24889
24889
  }, children));
24890
24890
  };
24891
24891
 
@@ -25008,11 +25008,11 @@ const ItemNodeContent = withStickiness(props => {
25008
25008
  className: "framework-perseus"
25009
25009
  }, lens(renderers).get(path));
25010
25010
  return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
25011
- className: css(styles$v.row)
25011
+ className: css(styles$z.row)
25012
25012
  }, /*#__PURE__*/React.createElement("div", {
25013
- className: css(styles$v.columnLeft)
25013
+ className: css(styles$z.columnLeft)
25014
25014
  }, /*#__PURE__*/React.createElement("div", {
25015
- className: css(sticky && styles$v.sticky)
25015
+ className: css(sticky && styles$z.sticky)
25016
25016
  },
25017
25017
  /*#__PURE__*/
25018
25018
  // @ts-expect-error - TS2769 - No overload matches this call.
@@ -25020,9 +25020,9 @@ const ItemNodeContent = withStickiness(props => {
25020
25020
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25021
25021
  apiOptions: apiOptions
25022
25022
  })))), /*#__PURE__*/React.createElement("div", {
25023
- className: css(styles$v.columnRight)
25023
+ className: css(styles$z.columnRight)
25024
25024
  }, /*#__PURE__*/React.createElement("div", {
25025
- className: css(sticky && styles$v.sticky)
25025
+ className: css(sticky && styles$z.sticky)
25026
25026
  }, preview))));
25027
25027
  });
25028
25028
  const HintNodeContent = withStickiness(props => {
@@ -25038,13 +25038,13 @@ const HintNodeContent = withStickiness(props => {
25038
25038
  className: "framework-perseus"
25039
25039
  }, lens(renderers).get(path));
25040
25040
  return /*#__PURE__*/React.createElement("div", {
25041
- className: css(styles$v.row)
25041
+ className: css(styles$z.row)
25042
25042
  }, /*#__PURE__*/React.createElement("div", {
25043
- className: css(styles$v.columnLeft)
25043
+ className: css(styles$z.columnLeft)
25044
25044
  }, /*#__PURE__*/React.createElement("div", {
25045
- className: css(sticky && styles$v.sticky)
25045
+ className: css(sticky && styles$z.sticky)
25046
25046
  }, /*#__PURE__*/React.createElement(HintEditor, _extends({}, data, {
25047
- className: css(styles$v.hintEditor),
25047
+ className: css(styles$z.hintEditor),
25048
25048
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25049
25049
  apiOptions: apiOptions,
25050
25050
  showTitle: false,
@@ -25059,9 +25059,9 @@ const HintNodeContent = withStickiness(props => {
25059
25059
  isFirst: true,
25060
25060
  isLast: true
25061
25061
  })))), /*#__PURE__*/React.createElement("div", {
25062
- className: css(styles$v.columnRight)
25062
+ className: css(styles$z.columnRight)
25063
25063
  }, /*#__PURE__*/React.createElement("div", {
25064
- className: css(sticky && styles$v.sticky)
25064
+ className: css(sticky && styles$z.sticky)
25065
25065
  }, preview)));
25066
25066
  });
25067
25067
  const TagsNodeContent = props => {
@@ -25078,9 +25078,9 @@ const TagsNodeContent = props => {
25078
25078
  return null;
25079
25079
  }
25080
25080
  return /*#__PURE__*/React.createElement("div", {
25081
- className: css(styles$v.columnLeft)
25081
+ className: css(styles$z.columnLeft)
25082
25082
  }, /*#__PURE__*/React.createElement("div", {
25083
- className: css(styles$v.tagsEditor)
25083
+ className: css(styles$z.tagsEditor)
25084
25084
  }, /*#__PURE__*/React.createElement(GroupMetadataEditor, {
25085
25085
  value: data,
25086
25086
  onChange: newVal => actions.setValueAtPath(path, newVal),
@@ -25111,23 +25111,23 @@ const ArrayNodeContent = props => {
25111
25111
  const subpath = path.concat(i);
25112
25112
  const controls = [i > 0 && /*#__PURE__*/React.createElement("div", {
25113
25113
  key: "moveArrayElementUp",
25114
- className: css(styles$v.control)
25114
+ className: css(styles$z.control)
25115
25115
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25116
25116
  color: "orange",
25117
25117
  title: "Move up",
25118
25118
  onClick: () => actions.moveArrayElementUp(subpath)
25119
25119
  }, /*#__PURE__*/React.createElement("div", {
25120
- className: css(styles$v.verticalFlip)
25120
+ className: css(styles$z.verticalFlip)
25121
25121
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React.createElement("div", {
25122
25122
  key: "moveArrayElementDown",
25123
- className: css(styles$v.control)
25123
+ className: css(styles$z.control)
25124
25124
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25125
25125
  color: "orange",
25126
25126
  title: "Move down",
25127
25127
  onClick: () => actions.moveArrayElementDown(subpath)
25128
25128
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React.createElement("div", {
25129
25129
  key: "removeArrayElement",
25130
- className: css(styles$v.control)
25130
+ className: css(styles$z.control)
25131
25131
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25132
25132
  color: "orange",
25133
25133
  title: "Delete",
@@ -25135,7 +25135,7 @@ const ArrayNodeContent = props => {
25135
25135
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconTrash$4)))];
25136
25136
  return /*#__PURE__*/React.createElement("div", {
25137
25137
  key: i,
25138
- className: css(styles$v.arrayElement, !elementIsLeaf && styles$v.arrayElementAndNotLeaf)
25138
+ className: css(styles$z.arrayElement, !elementIsLeaf && styles$z.arrayElementAndNotLeaf)
25139
25139
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25140
25140
  key: i,
25141
25141
  shape: shape.elementShape,
@@ -25161,7 +25161,7 @@ const ObjectNodeContent = props => {
25161
25161
  // made sense to the shape's author is the order in which we'll iterate :)
25162
25162
  const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React.createElement("div", {
25163
25163
  key: subkey,
25164
- className: css(styles$v.objectElement)
25164
+ className: css(styles$z.objectElement)
25165
25165
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25166
25166
  shape: shape.shape[subkey],
25167
25167
  data: data[subkey],
@@ -25328,7 +25328,7 @@ class MultiRendererEditor extends React.Component {
25328
25328
  }, this._renderContent());
25329
25329
  }
25330
25330
  }
25331
- const styles$v = StyleSheet.create({
25331
+ const styles$z = StyleSheet.create({
25332
25332
  // This is used in a number of places throughout this file.
25333
25333
  container: {},
25334
25334
  // eslint-disable-next-line react-native/no-unused-styles
@@ -25480,47 +25480,47 @@ const StatefulArticleEditor = createReactClass({
25480
25480
  screen
25481
25481
  } = this.state;
25482
25482
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
25483
- style: styles$u.controlBar
25483
+ style: styles$y.controlBar
25484
25484
  }, /*#__PURE__*/React.createElement("span", {
25485
- style: styles$u.controls
25485
+ style: styles$y.controls
25486
25486
  }, "Mode:", " ", /*#__PURE__*/React.createElement("span", {
25487
25487
  onClick: () => this.setState({
25488
25488
  mode: "edit"
25489
25489
  }),
25490
- style: mode === "edit" ? styles$u.controlSelected : styles$u.control
25490
+ style: mode === "edit" ? styles$y.controlSelected : styles$y.control
25491
25491
  }, "EDIT"), " | ", /*#__PURE__*/React.createElement("span", {
25492
25492
  onClick: () => this.setState({
25493
25493
  mode: "preview"
25494
25494
  }),
25495
- style: mode === "preview" ? styles$u.controlSelected : styles$u.control
25495
+ style: mode === "preview" ? styles$y.controlSelected : styles$y.control
25496
25496
  }, "PREVIEW"), " | ", /*#__PURE__*/React.createElement("span", {
25497
25497
  onClick: () => this.setState({
25498
25498
  mode: "json"
25499
25499
  }),
25500
- style: mode === "json" ? styles$u.controlSelected : styles$u.control
25500
+ style: mode === "json" ? styles$y.controlSelected : styles$y.control
25501
25501
  }, "JSON")), /*#__PURE__*/React.createElement("span", {
25502
- style: styles$u.controls
25502
+ style: styles$y.controls
25503
25503
  }, "Screen:", " ", /*#__PURE__*/React.createElement("span", {
25504
25504
  onClick: () => this.setState({
25505
25505
  screen: "phone"
25506
25506
  }),
25507
- style: screen === "phone" ? styles$u.controlSelected : styles$u.control
25507
+ style: screen === "phone" ? styles$y.controlSelected : styles$y.control
25508
25508
  }, "PHONE"), " | ", /*#__PURE__*/React.createElement("span", {
25509
25509
  onClick: () => this.setState({
25510
25510
  screen: "tablet"
25511
25511
  }),
25512
- style: screen === "tablet" ? styles$u.controlSelected : styles$u.control
25512
+ style: screen === "tablet" ? styles$y.controlSelected : styles$y.control
25513
25513
  }, "TABLET"), " | ", /*#__PURE__*/React.createElement("span", {
25514
25514
  onClick: () => this.setState({
25515
25515
  screen: "desktop"
25516
25516
  }),
25517
- style: screen === "desktop" ? styles$u.controlSelected : styles$u.control
25517
+ style: screen === "desktop" ? styles$y.controlSelected : styles$y.control
25518
25518
  }, "DESKTOP"))), /*#__PURE__*/React.createElement("div", {
25519
- style: styles$u.editor
25519
+ style: styles$y.editor
25520
25520
  }, /*#__PURE__*/React.createElement(ArticleEditor, this.state)));
25521
25521
  }
25522
25522
  });
25523
- const styles$u = {
25523
+ const styles$y = {
25524
25524
  controlBar: {
25525
25525
  marginBottom: 25,
25526
25526
  marginTop: 5
@@ -25731,7 +25731,7 @@ class BlurInput extends React.Component {
25731
25731
  }
25732
25732
 
25733
25733
  const {
25734
- InfoTip: InfoTip$j,
25734
+ InfoTip: InfoTip$l,
25735
25735
  PropCheckBox: PropCheckBox$b
25736
25736
  } = components;
25737
25737
  const DEFAULT_WIDTH = 400;
@@ -25892,7 +25892,7 @@ class CSProgramEditor extends React.Component {
25892
25892
  label: "Show Editor",
25893
25893
  showEditor: this.props.showEditor,
25894
25894
  onChange: this.props.onChange
25895
- }), /*#__PURE__*/React.createElement(InfoTip$j, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
25895
+ }), /*#__PURE__*/React.createElement(InfoTip$l, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
25896
25896
  label: "Show Buttons",
25897
25897
  showButtons: this.props.showButtons,
25898
25898
  onChange: this.props.onChange
@@ -25900,7 +25900,7 @@ class CSProgramEditor extends React.Component {
25900
25900
  name: "settings",
25901
25901
  pairs: this.props.settings,
25902
25902
  onChange: this._handleSettingsChange
25903
- }), /*#__PURE__*/React.createElement(InfoTip$j, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
25903
+ }), /*#__PURE__*/React.createElement(InfoTip$l, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
25904
25904
  }
25905
25905
  }
25906
25906
  CSProgramEditor.propTypes = _extends({}, Changeable.propTypes);
@@ -25986,7 +25986,7 @@ DeprecatedStandinEditor.widgetName = "deprecated-standin";
25986
25986
 
25987
25987
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
25988
25988
  const {
25989
- InfoTip: InfoTip$i,
25989
+ InfoTip: InfoTip$k,
25990
25990
  InlineIcon: InlineIcon$5
25991
25991
  } = components;
25992
25992
  const {
@@ -26055,14 +26055,14 @@ class DropdownEditor extends React.Component {
26055
26055
  className: "perseus-widget-dropdown"
26056
26056
  }, /*#__PURE__*/React.createElement("div", {
26057
26057
  className: "dropdown-info"
26058
- }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26058
+ }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26059
26059
  className: "dropdown-placeholder"
26060
26060
  }, /*#__PURE__*/React.createElement("input", {
26061
26061
  type: "text",
26062
26062
  placeholder: "Placeholder value",
26063
26063
  value: this.props.placeholder,
26064
26064
  onChange: this.onPlaceholderChange
26065
- }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React.createElement("div", {
26065
+ }), /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React.createElement("div", {
26066
26066
  className: "clearfix"
26067
26067
  }), /*#__PURE__*/React.createElement("ul", {
26068
26068
  className: "dropdown-choices"
@@ -26593,7 +26593,7 @@ const SortableItem = createReactClass({
26593
26593
  });
26594
26594
 
26595
26595
  const {
26596
- InfoTip: InfoTip$h,
26596
+ InfoTip: InfoTip$j,
26597
26597
  PropCheckBox: PropCheckBox$a
26598
26598
  } = components;
26599
26599
 
@@ -26847,11 +26847,11 @@ class ExpressionEditor extends React.Component {
26847
26847
  onChange: this.props.onChange,
26848
26848
  labelAlignment: "right",
26849
26849
  label: "Use \xD7 for rendering multiplication instead of a center dot."
26850
- }), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Function variables: ", /*#__PURE__*/React.createElement("input", {
26850
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Function variables: ", /*#__PURE__*/React.createElement("input", {
26851
26851
  type: "text",
26852
26852
  defaultValue: this.props.functions.join(" "),
26853
26853
  onChange: this.handleFunctions
26854
- })), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React.createElement("h3", {
26854
+ })), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Button sets:"), buttonSetChoices), /*#__PURE__*/React.createElement("h3", {
26855
26855
  className: "expression-editor-h3"
26856
26856
  }, "Answers"), /*#__PURE__*/React.createElement("p", {
26857
26857
  style: {
@@ -26946,14 +26946,14 @@ class AnswerOption extends React.Component {
26946
26946
  onChange: this.props.onChange,
26947
26947
  labelAlignment: "right",
26948
26948
  label: "Answer expression must have the same form."
26949
- }), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
26949
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
26950
26950
  className: "answer-option"
26951
26951
  }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
26952
26952
  simplify: this.props.simplify,
26953
26953
  onChange: this.props.onChange,
26954
26954
  labelAlignment: "right",
26955
26955
  label: "Answer expression must be fully expanded and simplified."
26956
- }), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React.createElement("div", {
26956
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React.createElement("div", {
26957
26957
  className: "remove-container"
26958
26958
  }, removeButton)));
26959
26959
  }
@@ -27010,10 +27010,10 @@ class GradedGroupEditor extends React.Component {
27010
27010
  }, /*#__PURE__*/React.createElement("div", {
27011
27011
  className: "perseus-widget-row"
27012
27012
  }, /*#__PURE__*/React.createElement("label", {
27013
- className: css(styles$t.title)
27013
+ className: css(styles$x.title)
27014
27014
  }, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
27015
27015
  value: this.props.title,
27016
- className: css(styles$t.input)
27016
+ className: css(styles$x.input)
27017
27017
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
27018
27018
  ,
27019
27019
  onChange: this.change("title")
@@ -27038,7 +27038,7 @@ class GradedGroupEditor extends React.Component {
27038
27038
  }, /*#__PURE__*/React.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React.createElement("div", {
27039
27039
  className: "perseus-hint-editor"
27040
27040
  }, /*#__PURE__*/React.createElement("div", {
27041
- className: css(styles$t.hintsTitle)
27041
+ className: css(styles$x.hintsTitle)
27042
27042
  }, "Hint"), /*#__PURE__*/React.createElement(Editor, {
27043
27043
  ref: this.hintEditor,
27044
27044
  content: this.props.hint ? this.props.hint.content : "",
@@ -27075,7 +27075,7 @@ GradedGroupEditor.defaultProps = {
27075
27075
  images: {},
27076
27076
  hint: null
27077
27077
  };
27078
- const styles$t = StyleSheet.create({
27078
+ const styles$x = StyleSheet.create({
27079
27079
  title: {
27080
27080
  fontSize: 18,
27081
27081
  fontWeight: "bold"
@@ -27153,7 +27153,7 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
27153
27153
 
27154
27154
  const {
27155
27155
  ButtonGroup: ButtonGroup$4,
27156
- InfoTip: InfoTip$g,
27156
+ InfoTip: InfoTip$i,
27157
27157
  PropCheckBox: PropCheckBox$9,
27158
27158
  RangeInput: RangeInput$6
27159
27159
  } = components;
@@ -27609,7 +27609,7 @@ const GraphSettings = createReactClass({
27609
27609
  },
27610
27610
  onKeyPress: this.changeBackgroundUrl,
27611
27611
  onBlur: this.changeBackgroundUrl
27612
- }), /*#__PURE__*/React.createElement(InfoTip$g, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27612
+ }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27613
27613
  className: "misc-settings"
27614
27614
  }, /*#__PURE__*/React.createElement("div", {
27615
27615
  className: "perseus-widget-row"
@@ -27647,7 +27647,7 @@ const GraphSettings = createReactClass({
27647
27647
  });
27648
27648
 
27649
27649
  const {
27650
- InfoTip: InfoTip$f,
27650
+ InfoTip: InfoTip$h,
27651
27651
  MultiButtonGroup: MultiButtonGroup$1
27652
27652
  } = components;
27653
27653
  const {
@@ -27730,7 +27730,7 @@ class GrapherEditor extends React.Component {
27730
27730
  className: "perseus-error"
27731
27731
  }, this.props.graph.valid);
27732
27732
  }
27733
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$f, 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.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27733
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$h, 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.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27734
27734
  editableSettings: ["graph", "snap", "image"],
27735
27735
  box: getInteractiveBoxFromSizeClass$1(sizeClass),
27736
27736
  range: this.props.graph.range,
@@ -27975,7 +27975,7 @@ IframeEditor.defaultProps = {
27975
27975
 
27976
27976
  /* eslint-disable jsx-a11y/anchor-is-valid, react/sort-comp */
27977
27977
  const {
27978
- InfoTip: InfoTip$e,
27978
+ InfoTip: InfoTip$g,
27979
27979
  InlineIcon: InlineIcon$3,
27980
27980
  RangeInput: RangeInput$5
27981
27981
  } = components;
@@ -28024,7 +28024,7 @@ class ImageEditor extends React.Component {
28024
28024
  style: {
28025
28025
  width: "100%"
28026
28026
  }
28027
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$e, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28027
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$g, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28028
28028
  apiOptions: this.props.apiOptions,
28029
28029
  content: this.props.alt,
28030
28030
  onChange: props => {
@@ -28048,7 +28048,7 @@ class ImageEditor extends React.Component {
28048
28048
  }, this.state.backgroundImageError);
28049
28049
  return /*#__PURE__*/React.createElement("div", {
28050
28050
  className: "perseus-image-editor"
28051
- }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$e, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28051
+ }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$g, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28052
28052
  value: backgroundImage.url || "",
28053
28053
  style: {
28054
28054
  width: 332
@@ -28212,7 +28212,7 @@ ImageEditor.defaultProps = {
28212
28212
 
28213
28213
  /* eslint-disable react/sort-comp */
28214
28214
  const {
28215
- InfoTip: InfoTip$d
28215
+ InfoTip: InfoTip$f
28216
28216
  } = components;
28217
28217
  const answerTypes = {
28218
28218
  number: {
@@ -28298,7 +28298,7 @@ class InputNumberEditor extends React.Component {
28298
28298
  value: "optional"
28299
28299
  }, "will be accepted"), /*#__PURE__*/React.createElement("option", {
28300
28300
  value: "enforced"
28301
- }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28301
+ }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28302
28302
  type: "checkbox",
28303
28303
  checked: this.props.inexact,
28304
28304
  onChange: e => {
@@ -28334,7 +28334,7 @@ class InputNumberEditor extends React.Component {
28334
28334
  });
28335
28335
  },
28336
28336
  "aria-label": "Answer type"
28337
- }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28337
+ }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28338
28338
  value: this.props.size,
28339
28339
  onChange: e => {
28340
28340
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"small" | "normal" | undefined'.
@@ -28346,7 +28346,7 @@ class InputNumberEditor extends React.Component {
28346
28346
  value: "normal"
28347
28347
  }, "Normal (80px)"), /*#__PURE__*/React.createElement("option", {
28348
28348
  value: "small"
28349
- }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28349
+ }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28350
28350
  type: "checkbox",
28351
28351
  checked: this.props.rightAlign,
28352
28352
  onChange: e => {
@@ -28414,13 +28414,13 @@ function MathquillInput(props) {
28414
28414
  }
28415
28415
  });
28416
28416
  return /*#__PURE__*/React.createElement(View, {
28417
- style: styles$s.outerWrapper
28417
+ style: styles$w.outerWrapper
28418
28418
  }, /*#__PURE__*/React.createElement("span", {
28419
28419
  ref: mathFieldWrapperRef,
28420
28420
  className: "perseus-math-input mq-editable-field mq-math-mode"
28421
28421
  }));
28422
28422
  }
28423
- const styles$s = StyleSheet.create({
28423
+ const styles$w = StyleSheet.create({
28424
28424
  outerWrapper: {
28425
28425
  display: "inline-block",
28426
28426
  borderStyle: "solid",
@@ -29481,7 +29481,7 @@ const GraphPointsCountSelector = ({
29481
29481
  // Never uses placeholder, always has value
29482
29482
  ,
29483
29483
  placeholder: "",
29484
- style: styles$r.singleSelectShort
29484
+ style: styles$v.singleSelectShort
29485
29485
  }, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
29486
29486
  key: n,
29487
29487
  value: `${n}`,
@@ -29492,7 +29492,7 @@ const GraphPointsCountSelector = ({
29492
29492
  label: "unlimited"
29493
29493
  })]);
29494
29494
  };
29495
- const styles$r = StyleSheet.create({
29495
+ const styles$v = StyleSheet.create({
29496
29496
  singleSelectShort: {
29497
29497
  // Non-standard spacing, but it's the smallest we can go
29498
29498
  // without running into styling issues with the dropdown.
@@ -29505,7 +29505,7 @@ const GraphTypeSelector = props => {
29505
29505
  selectedValue: props.graphType,
29506
29506
  onChange: props.onChange,
29507
29507
  placeholder: "Select a graph type",
29508
- style: styles$q.singleSelectShort
29508
+ style: styles$u.singleSelectShort
29509
29509
  }, /*#__PURE__*/React.createElement(OptionItem, {
29510
29510
  value: "linear",
29511
29511
  label: "Linear function"
@@ -29538,7 +29538,7 @@ const GraphTypeSelector = props => {
29538
29538
  label: "Angle"
29539
29539
  }));
29540
29540
  };
29541
- const styles$q = StyleSheet.create({
29541
+ const styles$u = StyleSheet.create({
29542
29542
  singleSelectShort: {
29543
29543
  // Non-standard spacing, but it's the smallest we can go
29544
29544
  // without running into styling issues with the dropdown.
@@ -29555,16 +29555,16 @@ const LabeledRow = props => {
29555
29555
  style
29556
29556
  } = props;
29557
29557
  return /*#__PURE__*/React.createElement("label", {
29558
- className: css(styles$p.label)
29558
+ className: css(styles$t.label)
29559
29559
  }, /*#__PURE__*/React.createElement(View, {
29560
- style: [styles$p.row, style]
29560
+ style: [styles$t.row, style]
29561
29561
  }, labelSide === "start" || /*#__PURE__*/React.createElement(LabelSmall, {
29562
- style: styles$p.spaceEnd
29562
+ style: styles$t.spaceEnd
29563
29563
  }, label), children, labelSide === "end" && /*#__PURE__*/React.createElement(LabelSmall, {
29564
- style: styles$p.spaceStart
29564
+ style: styles$t.spaceStart
29565
29565
  }, label)));
29566
29566
  };
29567
- const styles$p = StyleSheet.create({
29567
+ const styles$t = StyleSheet.create({
29568
29568
  label: {
29569
29569
  width: "fit-content"
29570
29570
  },
@@ -29584,7 +29584,7 @@ const styles$p = StyleSheet.create({
29584
29584
 
29585
29585
  const {
29586
29586
  ButtonGroup: ButtonGroup$2,
29587
- InfoTip: InfoTip$c,
29587
+ InfoTip: InfoTip$e,
29588
29588
  PropCheckBox: PropCheckBox$7,
29589
29589
  RangeInput: RangeInput$4
29590
29590
  } = components;
@@ -29990,10 +29990,10 @@ class InteractiveGraphSettings extends React.Component {
29990
29990
  onChange: this.change
29991
29991
  }))), /*#__PURE__*/React.createElement(LabeledRow, {
29992
29992
  label: "Background image URL:",
29993
- style: styles$o.resetSpaceTop
29993
+ style: styles$s.resetSpaceTop
29994
29994
  }, /*#__PURE__*/React.createElement("input", {
29995
29995
  type: "text",
29996
- className: css(styles$o.backgroundUrlInput),
29996
+ className: css(styles$s.backgroundUrlInput),
29997
29997
  ref: this.bgUrlRef,
29998
29998
  value: this.state.backgroundImage.url || "",
29999
29999
  onChange: e => {
@@ -30006,29 +30006,29 @@ class InteractiveGraphSettings extends React.Component {
30006
30006
  },
30007
30007
  onKeyPress: this.changeBackgroundUrl,
30008
30008
  onBlur: this.changeBackgroundUrl
30009
- }), /*#__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, {
30010
- style: styles$o.rulerSection
30009
+ }), /*#__PURE__*/React.createElement(InfoTip$e, 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, {
30010
+ style: styles$s.rulerSection
30011
30011
  }, /*#__PURE__*/React.createElement(View, {
30012
- style: styles$o.checkboxRow
30012
+ style: styles$s.checkboxRow
30013
30013
  }, /*#__PURE__*/React.createElement(PropCheckBox$7, {
30014
30014
  label: "Show ruler",
30015
30015
  showRuler: this.props.showRuler,
30016
30016
  onChange: this.change,
30017
- style: styles$o.resetSpaceTop
30017
+ style: styles$s.resetSpaceTop
30018
30018
  }), /*#__PURE__*/React.createElement(PropCheckBox$7, {
30019
30019
  label: "Show protractor",
30020
30020
  showProtractor: this.props.showProtractor,
30021
30021
  onChange: this.change,
30022
- style: styles$o.resetSpaceTop
30022
+ style: styles$s.resetSpaceTop
30023
30023
  })), (this.props.showRuler || this.props.showProtractor) && /*#__PURE__*/React.createElement(Banner, {
30024
30024
  layout: "floating",
30025
30025
  text: "The ruler and protractor are not accessible. Please consider an alternate approach.",
30026
30026
  kind: "warning"
30027
30027
  }), this.props.showRuler && /*#__PURE__*/React.createElement(View, {
30028
- style: styles$o.spaceTop
30028
+ style: styles$s.spaceTop
30029
30029
  }, /*#__PURE__*/React.createElement(LabeledRow, {
30030
30030
  label: "Ruler label:",
30031
- style: styles$o.resetSpaceTop
30031
+ style: styles$s.resetSpaceTop
30032
30032
  }, /*#__PURE__*/React.createElement(SingleSelect, {
30033
30033
  id: "ruler-label-select",
30034
30034
  selectedValue: this.props.rulerLabel,
@@ -30038,7 +30038,7 @@ class InteractiveGraphSettings extends React.Component {
30038
30038
  });
30039
30039
  },
30040
30040
  placeholder: "None",
30041
- style: styles$o.singleSelectShort
30041
+ style: styles$s.singleSelectShort
30042
30042
  }, /*#__PURE__*/React.createElement(OptionItem, {
30043
30043
  value: "",
30044
30044
  label: "None",
@@ -30079,7 +30079,7 @@ class InteractiveGraphSettings extends React.Component {
30079
30079
  });
30080
30080
  },
30081
30081
  placeholder: "10",
30082
- style: styles$o.singleSelectShort
30082
+ style: styles$s.singleSelectShort
30083
30083
  }, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React.createElement(OptionItem, {
30084
30084
  key: value,
30085
30085
  value: `${value}`,
@@ -30103,7 +30103,7 @@ InteractiveGraphSettings.defaultProps = {
30103
30103
  rulerLabel: "",
30104
30104
  rulerTicks: 10
30105
30105
  };
30106
- const styles$o = StyleSheet.create({
30106
+ const styles$s = StyleSheet.create({
30107
30107
  resetSpaceTop: {
30108
30108
  marginTop: 0
30109
30109
  },
@@ -30227,22 +30227,19 @@ const LockedFigureSelect = props => {
30227
30227
  id,
30228
30228
  onChange
30229
30229
  } = props;
30230
+ const figureTypes = props.showM2Features ? ["point", "line", "ellipse", "vector"] : ["point", "line"];
30230
30231
  return /*#__PURE__*/React.createElement(View, {
30231
- style: styles$n.container
30232
+ style: styles$r.container
30232
30233
  }, /*#__PURE__*/React.createElement(ActionMenu, {
30233
30234
  menuText: "Add locked figure",
30234
- style: styles$n.addElementSelect
30235
- }, [/*#__PURE__*/React.createElement(ActionItem, {
30236
- key: `${id}-point`,
30237
- label: "Point",
30238
- onClick: () => onChange("point")
30239
- }, "Point"), /*#__PURE__*/React.createElement(ActionItem, {
30240
- key: `${id}-line`,
30241
- label: "Line",
30242
- onClick: () => onChange("line")
30243
- }, "Line")]));
30235
+ style: styles$r.addElementSelect
30236
+ }, figureTypes.map(figureType => /*#__PURE__*/React.createElement(ActionItem, {
30237
+ key: `${id}-${figureType}`,
30238
+ label: figureType,
30239
+ onClick: () => onChange(figureType)
30240
+ }, figureType))));
30244
30241
  };
30245
- const styles$n = StyleSheet.create({
30242
+ const styles$r = StyleSheet.create({
30246
30243
  container: {
30247
30244
  marginTop: spacing.xSmall_8
30248
30245
  },
@@ -30252,6 +30249,82 @@ const styles$n = StyleSheet.create({
30252
30249
  }
30253
30250
  });
30254
30251
 
30252
+ const {
30253
+ InfoTip: InfoTip$d
30254
+ } = components;
30255
+ const degreeToRadian = degrees => {
30256
+ return degrees / 180 * Math.PI;
30257
+ };
30258
+ const AngleInput = props => {
30259
+ const {
30260
+ angle,
30261
+ onChange
30262
+ } = props;
30263
+ const [angleInput, setAngleInput] = React.useState(angle.toString());
30264
+ const [isInDegrees, setIsInDegrees] = React.useState(false);
30265
+ function handleAngleChange(newValue, useDegrees = isInDegrees) {
30266
+ // Update the local state (update the input field value).
30267
+ setAngleInput(newValue);
30268
+ try {
30269
+ // If the new value is a valid expression, update the props.
30270
+ // Save the angle in radians.
30271
+ const evaluatedAngle = KAS.parse(newValue).expr.eval();
30272
+ if (useDegrees) {
30273
+ onChange(degreeToRadian(evaluatedAngle));
30274
+ } else {
30275
+ onChange(evaluatedAngle);
30276
+ }
30277
+ } catch (e) {
30278
+ // The user likely has not finished typing the expression.
30279
+ // Do nothing.
30280
+ return;
30281
+ }
30282
+ }
30283
+ function handleAngleTypeChange() {
30284
+ // Change the angle based on the new angle type.
30285
+ handleAngleChange(angleInput, !isInDegrees);
30286
+
30287
+ // Update the angle to the new type.
30288
+ setIsInDegrees(usingDegrees => !usingDegrees);
30289
+ }
30290
+ return /*#__PURE__*/React.createElement(View, {
30291
+ style: [styles$q.row, styles$q.spaceUnder]
30292
+ }, /*#__PURE__*/React.createElement(LabelMedium, {
30293
+ tag: "label"
30294
+ }, /*#__PURE__*/React.createElement(View, {
30295
+ style: styles$q.row
30296
+ }, "angle", /*#__PURE__*/React.createElement(Strut, {
30297
+ size: spacing.xxSmall_6
30298
+ }), /*#__PURE__*/React.createElement(TextField, {
30299
+ id: "",
30300
+ value: angleInput,
30301
+ onChange: handleAngleChange,
30302
+ style: styles$q.textField
30303
+ }))), /*#__PURE__*/React.createElement(Strut, {
30304
+ size: spacing.xxSmall_6
30305
+ }), /*#__PURE__*/React.createElement(View, {
30306
+ style: styles$q.row
30307
+ }, /*#__PURE__*/React.createElement(LabelSmall, null, "radians"), /*#__PURE__*/React.createElement(View, {
30308
+ style: styles$q.switch
30309
+ }, /*#__PURE__*/React.createElement(Switch, {
30310
+ onChange: handleAngleTypeChange,
30311
+ checked: isInDegrees
30312
+ })), /*#__PURE__*/React.createElement(LabelSmall, null, "degrees")), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "The angle of rotation for the ellipse (if the x radius and y radius are different)."), /*#__PURE__*/React.createElement("p", null, "Expressions will be evaluted (e.g. \"pi/2\" or \"5pi/4\").")));
30313
+ };
30314
+ const styles$q = StyleSheet.create({
30315
+ row: {
30316
+ flexDirection: "row",
30317
+ alignItems: "center"
30318
+ },
30319
+ switch: {
30320
+ marginLeft: spacing.xxSmall_6,
30321
+ marginRight: spacing.xxSmall_6
30322
+ },
30323
+ textField: {
30324
+ maxWidth: spacing.xxxLarge_64
30325
+ }
30326
+ });
30327
+
30255
30328
  const ColorSwatch = props => {
30256
30329
  const {
30257
30330
  color: color$1,
@@ -30262,13 +30335,13 @@ const ColorSwatch = props => {
30262
30335
  "aria-label":
30263
30336
  // Don't include an aria label for decorative circles.
30264
30337
  !decorative ? `${color$1}, ${filled ? "filled" : "open"}` : undefined,
30265
- style: [styles$m.colorSwatch, {
30338
+ style: [styles$p.colorSwatch, {
30266
30339
  border: `4px solid ${lockedFigureColors[color$1]}`,
30267
30340
  backgroundColor: filled ? lockedFigureColors[color$1] : color.white
30268
30341
  }]
30269
30342
  });
30270
30343
  };
30271
- const styles$m = StyleSheet.create({
30344
+ const styles$p = StyleSheet.create({
30272
30345
  colorSwatch: {
30273
30346
  // Add a white outline so that the color swatch is visible when
30274
30347
  // the dropdown option is highlighted with its blue background.
@@ -30289,10 +30362,10 @@ const ColorSelect = props => {
30289
30362
  const ids = useUniqueIdWithMock();
30290
30363
  const id = ids.get("color-select");
30291
30364
  return /*#__PURE__*/React.createElement(View, {
30292
- style: [styles$l.row, style]
30365
+ style: [styles$o.row, style]
30293
30366
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30294
30367
  htmlFor: id,
30295
- style: styles$l.label,
30368
+ style: styles$o.label,
30296
30369
  tag: "label"
30297
30370
  }, "color"), /*#__PURE__*/React.createElement(SingleSelect, {
30298
30371
  id: id,
@@ -30311,7 +30384,7 @@ const ColorSelect = props => {
30311
30384
  })
30312
30385
  }, colorName))));
30313
30386
  };
30314
- const styles$l = StyleSheet.create({
30387
+ const styles$o = StyleSheet.create({
30315
30388
  row: {
30316
30389
  flexDirection: "row",
30317
30390
  alignItems: "center"
@@ -30324,8 +30397,9 @@ const styles$l = StyleSheet.create({
30324
30397
  const CoordinatePairInput = props => {
30325
30398
  const {
30326
30399
  coord,
30400
+ labels,
30327
30401
  error,
30328
- onChangeProps
30402
+ onChange
30329
30403
  } = props;
30330
30404
 
30331
30405
  // Keep track of the coordinates via state as the user is editing them,
@@ -30354,37 +30428,35 @@ const CoordinatePairInput = props => {
30354
30428
  // Update the props (update the graph).
30355
30429
  const newCoords = [...coord];
30356
30430
  newCoords[coordIndex] = +newValue;
30357
- onChangeProps({
30358
- coord: newCoords
30359
- });
30431
+ onChange(newCoords);
30360
30432
  }
30361
30433
  return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, {
30362
- style: [styles$k.row, styles$k.spaceUnder]
30434
+ style: [styles$n.row, styles$n.spaceUnder]
30363
30435
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30364
30436
  htmlFor: xCoordId,
30365
- style: styles$k.label,
30437
+ style: styles$n.label,
30366
30438
  tag: "label"
30367
- }, "x coord"), /*#__PURE__*/React.createElement(TextField, {
30439
+ }, labels ? labels[0] : "x coord"), /*#__PURE__*/React.createElement(TextField, {
30368
30440
  id: xCoordId,
30369
30441
  type: "number",
30370
30442
  value: coordState[0],
30371
30443
  onChange: newValue => handleCoordChange(newValue, 0),
30372
- style: [styles$k.textField, error ? styles$k.errorField : undefined]
30444
+ style: [styles$n.textField, error ? styles$n.errorField : undefined]
30373
30445
  }), /*#__PURE__*/React.createElement(Strut, {
30374
30446
  size: spacing.medium_16
30375
30447
  }), /*#__PURE__*/React.createElement(LabelMedium, {
30376
30448
  htmlFor: yCoordId,
30377
- style: styles$k.label,
30449
+ style: styles$n.label,
30378
30450
  tag: "label"
30379
- }, "y coord"), /*#__PURE__*/React.createElement(TextField, {
30451
+ }, labels ? labels[1] : "y coord"), /*#__PURE__*/React.createElement(TextField, {
30380
30452
  id: yCoordId,
30381
30453
  type: "number",
30382
30454
  value: coordState[1],
30383
30455
  onChange: newValue => handleCoordChange(newValue, 1),
30384
- style: [styles$k.textField, error ? styles$k.errorField : undefined]
30456
+ style: [styles$n.textField, error ? styles$n.errorField : undefined]
30385
30457
  })));
30386
30458
  };
30387
- const styles$k = StyleSheet.create({
30459
+ const styles$n = StyleSheet.create({
30388
30460
  row: {
30389
30461
  flexDirection: "row",
30390
30462
  alignItems: "center"
@@ -30404,32 +30476,40 @@ const styles$k = StyleSheet.create({
30404
30476
  }
30405
30477
  });
30406
30478
 
30407
- const LabeledSwitch = props => {
30479
+ const EllipseSwatch = props => {
30408
30480
  const {
30409
- checked,
30410
- label,
30411
- style,
30412
- onChange
30481
+ color,
30482
+ fillStyle,
30483
+ strokeStyle
30413
30484
  } = props;
30414
- const ids = useUniqueIdWithMock();
30415
- const switchId = ids.get("switch");
30416
30485
  return /*#__PURE__*/React.createElement(View, {
30417
- style: [styles$j.row, style]
30418
- }, /*#__PURE__*/React.createElement(Switch, {
30419
- id: switchId,
30420
- checked: checked,
30421
- onChange: onChange
30422
- }), /*#__PURE__*/React.createElement(Strut, {
30423
- size: spacing.xSmall_8
30424
- }), /*#__PURE__*/React.createElement(LabelMedium, {
30425
- tag: "label",
30426
- htmlFor: switchId
30427
- }, label));
30486
+ "aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
30487
+ style: [styles$m.container, {
30488
+ border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
30489
+ }]
30490
+ }, /*#__PURE__*/React.createElement(View, {
30491
+ style: [styles$m.innerCircle, {
30492
+ backgroundColor: lockedFigureColors[color],
30493
+ opacity: lockedEllipseFillStyles[fillStyle]
30494
+ }]
30495
+ }));
30428
30496
  };
30429
- const styles$j = StyleSheet.create({
30430
- row: {
30431
- flexDirection: "row",
30432
- alignItems: "center"
30497
+ const styles$m = StyleSheet.create({
30498
+ container: {
30499
+ // Add a white outline so that the color swatch is visible when
30500
+ // the dropdown option is highlighted with its blue background.
30501
+ outline: `2px solid ${color.offWhite}`,
30502
+ borderRadius: "50%",
30503
+ width: spacing.xLarge_32,
30504
+ height: spacing.large_24,
30505
+ backgroundColor: color.white,
30506
+ alignItems: "center",
30507
+ justifyContent: "center"
30508
+ },
30509
+ innerCircle: {
30510
+ width: 28,
30511
+ height: 20,
30512
+ borderRadius: "50%"
30433
30513
  }
30434
30514
  });
30435
30515
 
@@ -30451,14 +30531,14 @@ const LockedFigureSettingsAccordion = props => {
30451
30531
  }, /*#__PURE__*/React.createElement(AccordionSection, {
30452
30532
  expanded: expanded,
30453
30533
  onToggle: onToggle,
30454
- style: [styles$i.container, containerStyle],
30455
- headerStyle: styles$i.accordionHeader,
30534
+ style: [styles$l.container, containerStyle],
30535
+ headerStyle: styles$l.accordionHeader,
30456
30536
  header: header
30457
30537
  }, /*#__PURE__*/React.createElement(View, {
30458
- style: [styles$i.accordionPanel, panelStyle]
30538
+ style: [styles$l.accordionPanel, panelStyle]
30459
30539
  }, children)));
30460
30540
  };
30461
- const styles$i = StyleSheet.create({
30541
+ const styles$l = StyleSheet.create({
30462
30542
  container: {
30463
30543
  backgroundColor: color.fadedBlue8,
30464
30544
  marginTop: spacing.xSmall_8
@@ -30479,6 +30559,192 @@ const styles$i = StyleSheet.create({
30479
30559
  }
30480
30560
  });
30481
30561
 
30562
+ /**
30563
+ * The part of a locked figure settings panel that contains actions
30564
+ * for this panel and its associated locked figure, including
30565
+ * the delete button.
30566
+ */
30567
+ const LockedFigureSettingsActions = props => {
30568
+ const {
30569
+ onRemove,
30570
+ figureAriaLabel
30571
+ } = props;
30572
+ return /*#__PURE__*/React.createElement(View, {
30573
+ style: styles$k.container
30574
+ }, /*#__PURE__*/React.createElement(Button, {
30575
+ startIcon: trashIcon,
30576
+ "aria-label": `Delete ${figureAriaLabel}`,
30577
+ onClick: onRemove,
30578
+ kind: "tertiary",
30579
+ style: styles$k.deleteButton
30580
+ }, "Delete"));
30581
+ };
30582
+ const styles$k = StyleSheet.create({
30583
+ container: {
30584
+ width: "100%",
30585
+ flexDirection: "row",
30586
+ alignItems: "center",
30587
+ marginTop: spacing.xxxSmall_4
30588
+ },
30589
+ deleteButton: {
30590
+ // Line up the delete icon with the rest of the content.
30591
+ marginInlineStart: -spacing.xxxSmall_4
30592
+ }
30593
+ });
30594
+
30595
+ const {
30596
+ InfoTip: InfoTip$c
30597
+ } = components;
30598
+ const LockedEllipseSettings = props => {
30599
+ const {
30600
+ center,
30601
+ radius,
30602
+ angle,
30603
+ color,
30604
+ fillStyle,
30605
+ strokeStyle,
30606
+ expanded,
30607
+ onToggle,
30608
+ onChangeProps,
30609
+ onRemove
30610
+ } = props;
30611
+ const ids = useUniqueIdWithMock();
30612
+ const strokeSelectId = ids.get("stroke-style-select");
30613
+ const fillSelectId = ids.get("fill-style-select");
30614
+ function handleColorChange(newValue) {
30615
+ onChangeProps({
30616
+ color: newValue
30617
+ });
30618
+ }
30619
+ return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
30620
+ expanded: expanded,
30621
+ onToggle: onToggle,
30622
+ header:
30623
+ /*#__PURE__*/
30624
+ // Summary: Ellipse, center, radius, color (opacity, dashed)
30625
+ React.createElement(View, {
30626
+ style: styles$j.row
30627
+ }, /*#__PURE__*/React.createElement(LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React.createElement(Strut, {
30628
+ size: spacing.xSmall_8
30629
+ }), /*#__PURE__*/React.createElement(EllipseSwatch, {
30630
+ color: props.color,
30631
+ fillStyle: fillStyle,
30632
+ strokeStyle: strokeStyle
30633
+ }))
30634
+ }, /*#__PURE__*/React.createElement(View, {
30635
+ style: styles$j.row
30636
+ }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
30637
+ coord: center,
30638
+ onChange: newCoords => onChangeProps({
30639
+ center: newCoords
30640
+ })
30641
+ }), /*#__PURE__*/React.createElement(View, {
30642
+ style: styles$j.spaceUnder
30643
+ }, /*#__PURE__*/React.createElement(InfoTip$c, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React.createElement(CoordinatePairInput, {
30644
+ coord: radius,
30645
+ labels: ["x radius", "y radius"],
30646
+ onChange: newCoords => onChangeProps({
30647
+ radius: newCoords
30648
+ })
30649
+ }), /*#__PURE__*/React.createElement(AngleInput, {
30650
+ angle: angle,
30651
+ onChange: newAngle => onChangeProps({
30652
+ angle: newAngle
30653
+ })
30654
+ }), /*#__PURE__*/React.createElement(Strut, {
30655
+ size: spacing.xSmall_8
30656
+ }), /*#__PURE__*/React.createElement(View, {
30657
+ style: [styles$j.row, styles$j.spaceUnder]
30658
+ }, /*#__PURE__*/React.createElement(ColorSelect, {
30659
+ selectedValue: color,
30660
+ onChange: handleColorChange
30661
+ }), /*#__PURE__*/React.createElement(Strut, {
30662
+ size: spacing.medium_16
30663
+ }), /*#__PURE__*/React.createElement(LabelMedium, {
30664
+ tag: "label",
30665
+ htmlFor: fillSelectId,
30666
+ style: styles$j.label
30667
+ }, "fill"), /*#__PURE__*/React.createElement(SingleSelect, {
30668
+ id: fillSelectId,
30669
+ selectedValue: fillStyle,
30670
+ onChange: value => onChangeProps({
30671
+ fillStyle: value
30672
+ })
30673
+ // Placeholder is required, but never gets used.
30674
+ ,
30675
+ placeholder: ""
30676
+ }, Object.keys(lockedEllipseFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
30677
+ key: option,
30678
+ value: option,
30679
+ label: option
30680
+ }, option)))), /*#__PURE__*/React.createElement(View, {
30681
+ style: styles$j.row
30682
+ }, /*#__PURE__*/React.createElement(LabelMedium, {
30683
+ tag: "label",
30684
+ htmlFor: strokeSelectId,
30685
+ style: styles$j.label
30686
+ }, "stroke"), /*#__PURE__*/React.createElement(SingleSelect, {
30687
+ id: strokeSelectId,
30688
+ selectedValue: strokeStyle,
30689
+ onChange: value => onChangeProps({
30690
+ strokeStyle: value
30691
+ })
30692
+ // Placeholder is required, but never gets used.
30693
+ ,
30694
+ placeholder: ""
30695
+ }, /*#__PURE__*/React.createElement(OptionItem, {
30696
+ value: "solid",
30697
+ label: "solid"
30698
+ }, "solid"), /*#__PURE__*/React.createElement(OptionItem, {
30699
+ value: "dashed",
30700
+ label: "dashed"
30701
+ }, "dashed"))), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
30702
+ onRemove: onRemove,
30703
+ figureAriaLabel: `locked ellipse at ${center[0]}, ${center[1]}`
30704
+ }));
30705
+ };
30706
+ const styles$j = StyleSheet.create({
30707
+ row: {
30708
+ flexDirection: "row",
30709
+ alignItems: "center"
30710
+ },
30711
+ label: {
30712
+ marginInlineEnd: spacing.xxSmall_6
30713
+ },
30714
+ spaceUnder: {
30715
+ marginBottom: spacing.xSmall_8
30716
+ }
30717
+ });
30718
+
30719
+ const LabeledSwitch = props => {
30720
+ const {
30721
+ checked,
30722
+ label,
30723
+ style,
30724
+ onChange
30725
+ } = props;
30726
+ const ids = useUniqueIdWithMock();
30727
+ const switchId = ids.get("switch");
30728
+ return /*#__PURE__*/React.createElement(View, {
30729
+ style: [styles$i.row, style]
30730
+ }, /*#__PURE__*/React.createElement(Switch, {
30731
+ id: switchId,
30732
+ checked: checked,
30733
+ onChange: onChange
30734
+ }), /*#__PURE__*/React.createElement(Strut, {
30735
+ size: spacing.xSmall_8
30736
+ }), /*#__PURE__*/React.createElement(LabelMedium, {
30737
+ tag: "label",
30738
+ htmlFor: switchId
30739
+ }, label));
30740
+ };
30741
+ const styles$i = StyleSheet.create({
30742
+ row: {
30743
+ flexDirection: "row",
30744
+ alignItems: "center"
30745
+ }
30746
+ });
30747
+
30482
30748
  /**
30483
30749
  * DefiningPointSettings is a component that allows the user to edit the
30484
30750
  * settings of a point that defines a locked figure (ex. line) on the graph.
@@ -30520,7 +30786,11 @@ const DefiningPointSettings = props => {
30520
30786
  }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
30521
30787
  coord: coord,
30522
30788
  error: !!error,
30523
- onChangeProps: onChangeProps
30789
+ onChange: newCoords => {
30790
+ onChangeProps({
30791
+ coord: newCoords
30792
+ });
30793
+ }
30524
30794
  }), onTogglePoint && /*#__PURE__*/React.createElement(LabeledSwitch, {
30525
30795
  label: "show point on graph",
30526
30796
  checked: !!showPoint,
@@ -30587,39 +30857,6 @@ const styles$g = StyleSheet.create({
30587
30857
  }
30588
30858
  });
30589
30859
 
30590
- /**
30591
- * The part of a locked figure settings panel that contains actions
30592
- * for this panel and its associated locked figure, including
30593
- * the delete button.
30594
- */
30595
- const LockedFigureSettingsActions = props => {
30596
- const {
30597
- onRemove,
30598
- figureAriaLabel
30599
- } = props;
30600
- return /*#__PURE__*/React.createElement(View, {
30601
- style: styles$f.container
30602
- }, /*#__PURE__*/React.createElement(Button, {
30603
- startIcon: trashIcon,
30604
- "aria-label": `Delete ${figureAriaLabel}`,
30605
- onClick: onRemove,
30606
- kind: "tertiary",
30607
- style: styles$f.deleteButton
30608
- }, "Delete"));
30609
- };
30610
- const styles$f = StyleSheet.create({
30611
- container: {
30612
- width: "100%",
30613
- flexDirection: "row",
30614
- alignItems: "center",
30615
- marginTop: spacing.xxxSmall_4
30616
- },
30617
- deleteButton: {
30618
- // Line up the delete icon with the rest of the content.
30619
- marginInlineStart: -spacing.xxxSmall_4
30620
- }
30621
- });
30622
-
30623
30860
  const lengthZeroStr = "The line cannot have length 0.";
30624
30861
  const LockedLineSettings = props => {
30625
30862
  const {
@@ -30667,7 +30904,7 @@ const LockedLineSettings = props => {
30667
30904
  expanded: props.expanded,
30668
30905
  onToggle: props.onToggle,
30669
30906
  header: /*#__PURE__*/React.createElement(View, {
30670
- style: styles$e.row
30907
+ style: styles$f.row
30671
30908
  }, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
30672
30909
  size: spacing.xSmall_8
30673
30910
  }), /*#__PURE__*/React.createElement(LineSwatch, {
@@ -30675,10 +30912,10 @@ const LockedLineSettings = props => {
30675
30912
  lineStyle: lineStyle
30676
30913
  }))
30677
30914
  }, /*#__PURE__*/React.createElement(View, {
30678
- style: [styles$e.row, styles$e.spaceUnder]
30915
+ style: [styles$f.row, styles$f.spaceUnder]
30679
30916
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30680
30917
  htmlFor: kindSelectId,
30681
- style: styles$e.label,
30918
+ style: styles$f.label,
30682
30919
  tag: "label"
30683
30920
  }, "kind"), /*#__PURE__*/React.createElement(SingleSelect, {
30684
30921
  id: kindSelectId,
@@ -30699,17 +30936,17 @@ const LockedLineSettings = props => {
30699
30936
  value: "segment",
30700
30937
  label: "segment"
30701
30938
  }))), /*#__PURE__*/React.createElement(View, {
30702
- style: [styles$e.row, styles$e.spaceUnder]
30939
+ style: [styles$f.row, styles$f.spaceUnder]
30703
30940
  }, /*#__PURE__*/React.createElement(ColorSelect, {
30704
30941
  selectedValue: lineColor,
30705
30942
  onChange: handleColorChange
30706
30943
  }), /*#__PURE__*/React.createElement(Strut, {
30707
30944
  size: spacing.small_12
30708
30945
  }), /*#__PURE__*/React.createElement(View, {
30709
- style: styles$e.row
30946
+ style: styles$f.row
30710
30947
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30711
30948
  htmlFor: styleSelectId,
30712
- style: styles$e.label,
30949
+ style: styles$f.label,
30713
30950
  tag: "label"
30714
30951
  }, "style"), /*#__PURE__*/React.createElement(SingleSelect, {
30715
30952
  id: styleSelectId,
@@ -30720,7 +30957,7 @@ const LockedLineSettings = props => {
30720
30957
  // Placeholder is required, but never gets used.
30721
30958
  ,
30722
30959
  placeholder: "",
30723
- style: styles$e.selectMarginOffset
30960
+ style: styles$f.selectMarginOffset
30724
30961
  }, /*#__PURE__*/React.createElement(OptionItem, {
30725
30962
  value: "solid",
30726
30963
  label: "solid"
@@ -30728,7 +30965,7 @@ const LockedLineSettings = props => {
30728
30965
  value: "dashed",
30729
30966
  label: "dashed"
30730
30967
  })))), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
30731
- style: styles$e.errorText
30968
+ style: styles$f.errorText
30732
30969
  }, lengthZeroStr), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
30733
30970
  label: "Point 1",
30734
30971
  showPoint: showPoint1,
@@ -30754,7 +30991,7 @@ const LockedLineSettings = props => {
30754
30991
  ${point2.coord[0]}, ${point2.coord[1]}.`
30755
30992
  }));
30756
30993
  };
30757
- const styles$e = StyleSheet.create({
30994
+ const styles$f = StyleSheet.create({
30758
30995
  row: {
30759
30996
  flexDirection: "row",
30760
30997
  alignItems: "center"
@@ -30800,7 +31037,7 @@ const LockedPointSettings = props => {
30800
31037
  /*#__PURE__*/
30801
31038
  // Summary: Point, coords, color (filled/open)
30802
31039
  React.createElement(View, {
30803
- style: styles$d.row
31040
+ style: styles$e.row
30804
31041
  }, /*#__PURE__*/React.createElement(LabelLarge, null, `Point (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
30805
31042
  size: spacing.xSmall_8
30806
31043
  }), /*#__PURE__*/React.createElement(ColorSwatch, {
@@ -30809,11 +31046,15 @@ const LockedPointSettings = props => {
30809
31046
  }))
30810
31047
  }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
30811
31048
  coord: coord,
30812
- onChangeProps: onChangeProps
31049
+ onChange: newCoord => {
31050
+ onChangeProps({
31051
+ coord: newCoord
31052
+ });
31053
+ }
30813
31054
  }), /*#__PURE__*/React.createElement(ColorSelect, {
30814
31055
  selectedValue: pointColor,
30815
31056
  onChange: handleColorChange,
30816
- style: styles$d.spaceUnder
31057
+ style: styles$e.spaceUnder
30817
31058
  }), /*#__PURE__*/React.createElement(LabeledSwitch, {
30818
31059
  label: "open point",
30819
31060
  checked: !filled,
@@ -30827,7 +31068,7 @@ const LockedPointSettings = props => {
30827
31068
  figureAriaLabel: `locked point at ${coord[0]}, ${coord[1]}`
30828
31069
  }));
30829
31070
  };
30830
- const styles$d = StyleSheet.create({
31071
+ const styles$e = StyleSheet.create({
30831
31072
  row: {
30832
31073
  flexDirection: "row",
30833
31074
  alignItems: "center"
@@ -30837,6 +31078,113 @@ const styles$d = StyleSheet.create({
30837
31078
  }
30838
31079
  });
30839
31080
 
31081
+ /**
31082
+ * LockedVectorSettings is a component that allows the user to edit the
31083
+ * settings of specifically a locked vector on the graph.
31084
+ *
31085
+ * Used in the interactive graph editor's locked figures section.
31086
+ */
31087
+ const lengthErrorMessage = "The vector cannot have length 0.";
31088
+ const LockedVectorSettings = props => {
31089
+ const {
31090
+ points,
31091
+ color: lineColor,
31092
+ onChangeProps,
31093
+ onRemove
31094
+ } = props;
31095
+ const [tail, tip] = points;
31096
+ const lineLabel = `Vector (${tail[0]}, ${tail[1]}), (${tip[0]}, ${tip[1]})`;
31097
+
31098
+ // Check if the line has length 0.
31099
+ const isInvalid = vector.equal(tail, tip);
31100
+ function handleChangePoint(newCoord, index) {
31101
+ if (typeof newCoord !== "undefined") {
31102
+ const newPoints = [...points];
31103
+ newPoints[index] = [...newCoord];
31104
+ onChangeProps({
31105
+ points: newPoints
31106
+ });
31107
+ }
31108
+ }
31109
+ function handleColorChange(newColor) {
31110
+ onChangeProps({
31111
+ color: newColor
31112
+ });
31113
+ }
31114
+ return /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
31115
+ expanded: props.expanded,
31116
+ onToggle: props.onToggle,
31117
+ header: /*#__PURE__*/React.createElement(View, {
31118
+ style: styles$d.row
31119
+ }, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
31120
+ size: spacing.xSmall_8
31121
+ }), /*#__PURE__*/React.createElement(LineSwatch, {
31122
+ color: lineColor,
31123
+ lineStyle: "solid"
31124
+ }))
31125
+ }, /*#__PURE__*/React.createElement(View, {
31126
+ style: [styles$d.row, styles$d.spaceUnder]
31127
+ }, /*#__PURE__*/React.createElement(ColorSelect, {
31128
+ selectedValue: lineColor,
31129
+ onChange: handleColorChange
31130
+ })), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
31131
+ style: styles$d.errorText
31132
+ }, lengthErrorMessage), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
31133
+ expanded: true // Initial state is expanded
31134
+ ,
31135
+ containerStyle: styles$d.container,
31136
+ panelStyle: styles$d.accordionPanel,
31137
+ header: /*#__PURE__*/React.createElement(View, {
31138
+ style: styles$d.row
31139
+ }, /*#__PURE__*/React.createElement(LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
31140
+ }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
31141
+ coord: tail,
31142
+ error: isInvalid,
31143
+ onChange: newProps => {
31144
+ handleChangePoint(newProps, 0);
31145
+ }
31146
+ })), /*#__PURE__*/React.createElement(LockedFigureSettingsAccordion, {
31147
+ expanded: true // Initial state is expanded
31148
+ ,
31149
+ containerStyle: styles$d.container,
31150
+ panelStyle: styles$d.accordionPanel,
31151
+ header: /*#__PURE__*/React.createElement(View, {
31152
+ style: styles$d.row
31153
+ }, /*#__PURE__*/React.createElement(LabelLarge, null, `Tip (${tip[0]}, ${tip[1]})`))
31154
+ }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
31155
+ coord: tip,
31156
+ error: isInvalid,
31157
+ onChange: newProps => {
31158
+ handleChangePoint(newProps, 1);
31159
+ }
31160
+ })), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
31161
+ onRemove: onRemove,
31162
+ figureAriaLabel: `locked vector defined by starting point
31163
+ ${tail[0]}, ${tail[1]} and extending to
31164
+ ${tip[0]}, ${tip[1]}.`
31165
+ }));
31166
+ };
31167
+ const styles$d = StyleSheet.create({
31168
+ accordionPanel: {
31169
+ paddingBottom: spacing.medium_16
31170
+ },
31171
+ container: {
31172
+ marginTop: spacing.xSmall_8,
31173
+ marginBottom: 0,
31174
+ marginLeft: -spacing.xxxSmall_4,
31175
+ marginRight: -spacing.xxxSmall_4,
31176
+ backgroundColor: color.white
31177
+ },
31178
+ errorText: {
31179
+ color: color.red,
31180
+ marginTop: spacing.xSmall_8
31181
+ },
31182
+ row: {
31183
+ flexDirection: "row",
31184
+ alignItems: "center"
31185
+ }
31186
+ });
31187
+
30840
31188
  /**
30841
31189
  * LockedFigureSettings takes in a figure and renders the
30842
31190
  * respective settings for that figure type.
@@ -30852,6 +31200,16 @@ const LockedFigureSettings = props => {
30852
31200
  return /*#__PURE__*/React.createElement(LockedPointSettings, props);
30853
31201
  case "line":
30854
31202
  return /*#__PURE__*/React.createElement(LockedLineSettings, props);
31203
+ case "ellipse":
31204
+ if (props.showM2Features) {
31205
+ return /*#__PURE__*/React.createElement(LockedEllipseSettings, props);
31206
+ }
31207
+ break;
31208
+ case "vector":
31209
+ if (props.showM2Features) {
31210
+ return /*#__PURE__*/React.createElement(LockedVectorSettings, props);
31211
+ }
31212
+ break;
30855
31213
  }
30856
31214
  return null;
30857
31215
  };
@@ -30918,6 +31276,22 @@ function getDefaultFigureForType(type) {
30918
31276
  showPoint1: false,
30919
31277
  showPoint2: false
30920
31278
  };
31279
+ case "ellipse":
31280
+ return {
31281
+ type: "ellipse",
31282
+ center: [0, 0],
31283
+ radius: [1, 1],
31284
+ angle: 0,
31285
+ color: DEFAULT_COLOR,
31286
+ fillStyle: "none",
31287
+ strokeStyle: "solid"
31288
+ };
31289
+ case "vector":
31290
+ return {
31291
+ type: "vector",
31292
+ points: [[0, 0], [2, 2]],
31293
+ color: DEFAULT_COLOR
31294
+ };
30921
31295
  default:
30922
31296
  throw new UnreachableCaseError(type);
30923
31297
  }
@@ -30972,20 +31346,24 @@ const LockedFiguresSection = props => {
30972
31346
  const allCollapsed = expandedStates.every(value => !value);
30973
31347
  const buttonLabel = allCollapsed ? "Expand all" : "Collapse all";
30974
31348
  const showExpandButton = !!(figures != null && figures.length);
30975
- return /*#__PURE__*/React.createElement(View, null, figures == null ? void 0 : figures.map((figure, index) => /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
30976
- expanded: expandedStates[index],
30977
- onToggle: newValue => {
30978
- const newExpanded = [...expandedStates];
30979
- newExpanded[index] = newValue;
30980
- setExpandedStates(newExpanded);
30981
- },
30982
- key: `${uniqueId}-locked-${figure}-${index}`
30983
- }, figure, {
30984
- onChangeProps: newProps => changeProps(index, newProps),
30985
- onRemove: () => removeLockedFigure(index)
30986
- }))), /*#__PURE__*/React.createElement(View, {
31349
+ return /*#__PURE__*/React.createElement(View, null, figures == null ? void 0 : figures.map((figure, index) => {
31350
+ return /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
31351
+ key: `${uniqueId}-locked-${figure}-${index}`,
31352
+ showM2Features: props.showM2Features,
31353
+ expanded: expandedStates[index],
31354
+ onToggle: newValue => {
31355
+ const newExpanded = [...expandedStates];
31356
+ newExpanded[index] = newValue;
31357
+ setExpandedStates(newExpanded);
31358
+ }
31359
+ }, figure, {
31360
+ onChangeProps: newProps => changeProps(index, newProps),
31361
+ onRemove: () => removeLockedFigure(index)
31362
+ }));
31363
+ }), /*#__PURE__*/React.createElement(View, {
30987
31364
  style: styles$c.buttonContainer
30988
31365
  }, /*#__PURE__*/React.createElement(LockedFigureSelect, {
31366
+ showM2Features: props.showM2Features,
30989
31367
  id: `${uniqueId}-select`,
30990
31368
  onChange: addLockedFigure
30991
31369
  }), /*#__PURE__*/React.createElement(Strut, {
@@ -31350,7 +31728,8 @@ class InteractiveGraphEditor extends React.Component {
31350
31728
  }, 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,
31351
31729
  // Only show the "Add locked figure" dropdown if the graph
31352
31730
  // is using Mafs.
31353
- 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, {
31731
+ 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, {
31732
+ showM2Features: (_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["interactive-graph-locked-features-m2"],
31354
31733
  figures: this.props.lockedFigures,
31355
31734
  onChange: this.props.onChange
31356
31735
  }));