@khanacademy/perseus-editor 6.9.0 → 6.11.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, lockedEllipseFillStyles, 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, lockedFigureFillStyles, 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';
@@ -23,13 +23,13 @@ import { TextField, Checkbox as Checkbox$1 } from '@khanacademy/wonder-blocks-fo
23
23
  import { LabelSmall, LabelMedium, LabelLarge, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
24
24
  import Banner from '@khanacademy/wonder-blocks-banner';
25
25
  import Button from '@khanacademy/wonder-blocks-button';
26
- import Switch from '@khanacademy/wonder-blocks-switch';
27
26
  import { AccordionSection } from '@khanacademy/wonder-blocks-accordion';
28
27
  import trashIcon from '@phosphor-icons/core/bold/trash-bold.svg';
28
+ import Switch from '@khanacademy/wonder-blocks-switch';
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.9.0";
32
+ const libVersion = "6.11.0";
33
33
  addLibraryVersionToPerseusDebug(libName, libVersion);
34
34
 
35
35
  function _extends() {
@@ -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$n,
23448
+ InfoTip: InfoTip$m,
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$n, 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$m, 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$m
23773
+ InfoTip: InfoTip$l
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$m, null, props.infoTip));
23919
+ })), /*#__PURE__*/React.createElement(InfoTip$l, null, props.infoTip));
23920
23920
 
23921
23921
  const ITEM_DATA_VERSION = itemDataVersion;
23922
23922
  class ItemEditor extends React.Component {
@@ -25731,7 +25731,7 @@ class BlurInput extends React.Component {
25731
25731
  }
25732
25732
 
25733
25733
  const {
25734
- InfoTip: InfoTip$l,
25734
+ InfoTip: InfoTip$k,
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$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, {
25895
+ }), /*#__PURE__*/React.createElement(InfoTip$k, 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$l, 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$k, 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$k,
25989
+ InfoTip: InfoTip$j,
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$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", {
26058
+ }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$j, 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$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", {
26065
+ }), /*#__PURE__*/React.createElement(InfoTip$j, 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$j,
26596
+ InfoTip: InfoTip$i,
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$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", {
26850
+ }), /*#__PURE__*/React.createElement(InfoTip$i, 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$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", {
26854
+ })), /*#__PURE__*/React.createElement(InfoTip$i, 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$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", {
26949
+ }), /*#__PURE__*/React.createElement(InfoTip$i, 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$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", {
26956
+ }), /*#__PURE__*/React.createElement(InfoTip$i, 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
  }
@@ -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$i,
27156
+ InfoTip: InfoTip$h,
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$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", {
27612
+ }), /*#__PURE__*/React.createElement(InfoTip$h, 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$h,
27650
+ InfoTip: InfoTip$g,
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$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, {
27733
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$g, 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$g,
27978
+ InfoTip: InfoTip$f,
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$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, {
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$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
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$g, 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$f, 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$f
28215
+ InfoTip: InfoTip$e
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$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", {
28301
+ }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$e, 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$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", {
28337
+ }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$e, 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$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", {
28349
+ }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$e, 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 => {
@@ -29584,7 +29584,7 @@ const styles$t = StyleSheet.create({
29584
29584
 
29585
29585
  const {
29586
29586
  ButtonGroup: ButtonGroup$2,
29587
- InfoTip: InfoTip$e,
29587
+ InfoTip: InfoTip$d,
29588
29588
  PropCheckBox: PropCheckBox$7,
29589
29589
  RangeInput: RangeInput$4
29590
29590
  } = components;
@@ -30006,7 +30006,7 @@ class InteractiveGraphSettings extends React.Component {
30006
30006
  },
30007
30007
  onKeyPress: this.changeBackgroundUrl,
30008
30008
  onBlur: this.changeBackgroundUrl
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, {
30009
+ }), /*#__PURE__*/React.createElement(InfoTip$d, 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
30010
  style: styles$s.rulerSection
30011
30011
  }, /*#__PURE__*/React.createElement(View, {
30012
30012
  style: styles$s.checkboxRow
@@ -30249,79 +30249,145 @@ const styles$r = StyleSheet.create({
30249
30249
  }
30250
30250
  });
30251
30251
 
30252
- const {
30253
- InfoTip: InfoTip$d
30254
- } = components;
30255
- const degreeToRadian = degrees => {
30252
+ function focusWithChromeStickyFocusBugWorkaround(element) {
30253
+ // NOTE(marksandstrom) Chrome sticky focus bug.
30254
+ //
30255
+ // There is a bug in Chrome related to sticky positioning and
30256
+ // focus: When a child of an element with sticky positioning is
30257
+ // focused with the focus() method, the scrollable area
30258
+ // containing that element will scroll to the top (even though
30259
+ // the element is already visble on the page). For a dropdown
30260
+ // this means that the area will be scrolled to the top when
30261
+ // the user interacts with the dropdown (since we actively
30262
+ // manage dropdown header and option focus for keyboard users).
30263
+ //
30264
+ // To work around this bug the `preventScroll` focus option is
30265
+ // used.
30266
+ //
30267
+ // Using `focusOptions` is an experimental browser feature
30268
+ // "that should not be used in production code". However, since
30269
+ // Chrome is the only browser we support that exhibits this
30270
+ // buggy behavior and using `focusOptions` works around the
30271
+ // bug, it is perfectly reasonable to use the feature in this
30272
+ // case. We are not relying on the effect of the
30273
+ // `preventScroll` option otherwise.
30274
+ //
30275
+ // focusOptions documentation:
30276
+ //
30277
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
30278
+ //
30279
+ // Note that there could be cases where we want default focus() behavior.
30280
+ // One that comes to mind is a dropdown with a long list of options that
30281
+ // might be rendered off screen when opened. With this workaround the
30282
+ // selected option would not be scrolled into view if the option is near
30283
+ // the end of the list. We're not aware of any uses of the dropdown where
30284
+ // this is an issue, however, so there isn't currently a way to out of the
30285
+ // `preventScroll` behavior.
30286
+
30287
+ // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
30288
+ element.focus({
30289
+ preventScroll: true
30290
+ });
30291
+ }
30292
+ const DEFAULT_COLOR = "grayH";
30293
+ function getDefaultFigureForType(type) {
30294
+ switch (type) {
30295
+ case "point":
30296
+ return {
30297
+ type: "point",
30298
+ coord: [0, 0],
30299
+ color: DEFAULT_COLOR,
30300
+ filled: true
30301
+ };
30302
+ case "line":
30303
+ return {
30304
+ type: "line",
30305
+ kind: "line",
30306
+ points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
30307
+ coord: [2, 2]
30308
+ })],
30309
+ color: DEFAULT_COLOR,
30310
+ lineStyle: "solid",
30311
+ showPoint1: false,
30312
+ showPoint2: false
30313
+ };
30314
+ case "vector":
30315
+ return {
30316
+ type: "vector",
30317
+ points: [[0, 0], [2, 2]],
30318
+ color: DEFAULT_COLOR
30319
+ };
30320
+ case "ellipse":
30321
+ return {
30322
+ type: "ellipse",
30323
+ center: [0, 0],
30324
+ radius: [1, 1],
30325
+ angle: 0,
30326
+ color: DEFAULT_COLOR,
30327
+ fillStyle: "none",
30328
+ strokeStyle: "solid"
30329
+ };
30330
+ case "polygon":
30331
+ return {
30332
+ type: "polygon",
30333
+ points: [[0, 2], [-1, 0], [1, 0]],
30334
+ color: DEFAULT_COLOR,
30335
+ showVertices: false,
30336
+ fillStyle: "none",
30337
+ strokeStyle: "solid"
30338
+ };
30339
+ default:
30340
+ throw new UnreachableCaseError(type);
30341
+ }
30342
+ }
30343
+ function degreeToRadian(degrees) {
30256
30344
  return degrees / 180 * Math.PI;
30257
- };
30345
+ }
30346
+ function radianToDegree(radians) {
30347
+ return radians / Math.PI * 180;
30348
+ }
30349
+
30258
30350
  const AngleInput = props => {
30259
30351
  const {
30260
30352
  angle,
30261
30353
  onChange
30262
30354
  } = props;
30263
- const [angleInput, setAngleInput] = React.useState(angle.toString());
30264
- const [isInDegrees, setIsInDegrees] = React.useState(false);
30265
- function handleAngleChange(newValue, useDegrees = isInDegrees) {
30355
+ const [angleInput, setAngleInput] = React.useState(radianToDegree(angle).toString());
30356
+ function handleAngleChange(newValue) {
30266
30357
  // Update the local state (update the input field value).
30267
30358
  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.
30359
+
30360
+ // If the new value is not a number, don't update the props.
30361
+ // If it's empty, keep the props the same value instead of setting to 0.
30362
+ if (isNaN(+newValue) || newValue === "") {
30280
30363
  return;
30281
30364
  }
30282
- }
30283
- function handleAngleTypeChange() {
30284
- // Change the angle based on the new angle type.
30285
- handleAngleChange(angleInput, !isInDegrees);
30286
30365
 
30287
- // Update the angle to the new type.
30288
- setIsInDegrees(usingDegrees => !usingDegrees);
30366
+ // Update the graph.
30367
+ onChange(degreeToRadian(newValue));
30289
30368
  }
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, {
30369
+ return /*#__PURE__*/React.createElement(LabelMedium, {
30370
+ tag: "label",
30295
30371
  style: styles$q.row
30296
- }, "angle", /*#__PURE__*/React.createElement(Strut, {
30372
+ }, "angle (degrees)", /*#__PURE__*/React.createElement(Strut, {
30297
30373
  size: spacing.xxSmall_6
30298
30374
  }), /*#__PURE__*/React.createElement(TextField, {
30299
- id: "",
30375
+ type: "number",
30300
30376
  value: angleInput,
30301
30377
  onChange: handleAngleChange,
30302
30378
  style: styles$q.textField
30303
- }))), /*#__PURE__*/React.createElement(Strut, {
30379
+ }), /*#__PURE__*/React.createElement(Strut, {
30304
30380
  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\").")));
30381
+ }));
30313
30382
  };
30314
30383
  const styles$q = StyleSheet.create({
30315
30384
  row: {
30385
+ display: "flex",
30316
30386
  flexDirection: "row",
30317
30387
  alignItems: "center"
30318
30388
  },
30319
- switch: {
30320
- marginLeft: spacing.xxSmall_6,
30321
- marginRight: spacing.xxSmall_6
30322
- },
30323
30389
  textField: {
30324
- maxWidth: spacing.xxxLarge_64
30390
+ width: spacing.xxxLarge_64
30325
30391
  }
30326
30392
  });
30327
30393
 
@@ -30359,16 +30425,14 @@ const ColorSelect = props => {
30359
30425
  style,
30360
30426
  onChange
30361
30427
  } = props;
30362
- const ids = useUniqueIdWithMock();
30363
- const id = ids.get("color-select");
30364
30428
  return /*#__PURE__*/React.createElement(View, {
30365
30429
  style: [styles$o.row, style]
30366
30430
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30367
- htmlFor: id,
30368
- style: styles$o.label,
30369
- tag: "label"
30370
- }, "color"), /*#__PURE__*/React.createElement(SingleSelect, {
30371
- id: id,
30431
+ tag: "label",
30432
+ style: styles$o.row
30433
+ }, "color", /*#__PURE__*/React.createElement(Strut, {
30434
+ size: spacing.xxSmall_6
30435
+ }), /*#__PURE__*/React.createElement(SingleSelect, {
30372
30436
  selectedValue: selectedValue,
30373
30437
  onChange: onChange
30374
30438
  // Placeholder is required, but never gets used.
@@ -30382,15 +30446,13 @@ const ColorSelect = props => {
30382
30446
  color: colorName,
30383
30447
  decorative: true
30384
30448
  })
30385
- }, colorName))));
30449
+ }, colorName)))));
30386
30450
  };
30387
30451
  const styles$o = StyleSheet.create({
30388
30452
  row: {
30453
+ display: "flex",
30389
30454
  flexDirection: "row",
30390
30455
  alignItems: "center"
30391
- },
30392
- label: {
30393
- marginInlineEnd: spacing.xxxSmall_4
30394
30456
  }
30395
30457
  });
30396
30458
 
@@ -30407,12 +30469,6 @@ const CoordinatePairInput = props => {
30407
30469
  const [coordState, setCoordState] = React.useState([
30408
30470
  // Using strings to make it easier to work with the text fields.
30409
30471
  coord[0].toString(), coord[1].toString()]);
30410
-
30411
- // Generate unique IDs so that the programmatic labels can be associated
30412
- // with their respective text fields.
30413
- const ids = useUniqueIdWithMock();
30414
- const xCoordId = ids.get("x-coord");
30415
- const yCoordId = ids.get("y-coord");
30416
30472
  function handleCoordChange(newValue, coordIndex) {
30417
30473
  // Update the local state (update the input field value).
30418
30474
  const newCoordState = [...coordState];
@@ -30433,40 +30489,38 @@ const CoordinatePairInput = props => {
30433
30489
  return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(View, {
30434
30490
  style: [styles$n.row, styles$n.spaceUnder]
30435
30491
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30436
- htmlFor: xCoordId,
30437
- style: styles$n.label,
30438
- tag: "label"
30439
- }, labels ? labels[0] : "x coord"), /*#__PURE__*/React.createElement(TextField, {
30440
- id: xCoordId,
30492
+ tag: "label",
30493
+ style: styles$n.row
30494
+ }, labels ? labels[0] : "x coord", /*#__PURE__*/React.createElement(Strut, {
30495
+ size: spacing.xxSmall_6
30496
+ }), /*#__PURE__*/React.createElement(TextField, {
30441
30497
  type: "number",
30442
30498
  value: coordState[0],
30443
30499
  onChange: newValue => handleCoordChange(newValue, 0),
30444
30500
  style: [styles$n.textField, error ? styles$n.errorField : undefined]
30445
- }), /*#__PURE__*/React.createElement(Strut, {
30501
+ })), /*#__PURE__*/React.createElement(Strut, {
30446
30502
  size: spacing.medium_16
30447
30503
  }), /*#__PURE__*/React.createElement(LabelMedium, {
30448
- htmlFor: yCoordId,
30449
- style: styles$n.label,
30450
- tag: "label"
30451
- }, labels ? labels[1] : "y coord"), /*#__PURE__*/React.createElement(TextField, {
30452
- id: yCoordId,
30504
+ tag: "label",
30505
+ style: styles$n.row
30506
+ }, labels ? labels[1] : "y coord", /*#__PURE__*/React.createElement(Strut, {
30507
+ size: spacing.xxSmall_6
30508
+ }), /*#__PURE__*/React.createElement(TextField, {
30453
30509
  type: "number",
30454
30510
  value: coordState[1],
30455
30511
  onChange: newValue => handleCoordChange(newValue, 1),
30456
30512
  style: [styles$n.textField, error ? styles$n.errorField : undefined]
30457
- })));
30513
+ }))));
30458
30514
  };
30459
30515
  const styles$n = StyleSheet.create({
30460
30516
  row: {
30517
+ display: "flex",
30461
30518
  flexDirection: "row",
30462
30519
  alignItems: "center"
30463
30520
  },
30464
30521
  spaceUnder: {
30465
30522
  marginBottom: spacing.xSmall_8
30466
30523
  },
30467
- label: {
30468
- marginInlineEnd: spacing.xxSmall_6
30469
- },
30470
30524
  textField: {
30471
30525
  width: spacing.xxxLarge_64
30472
30526
  },
@@ -30490,7 +30544,7 @@ const EllipseSwatch = props => {
30490
30544
  }, /*#__PURE__*/React.createElement(View, {
30491
30545
  style: [styles$m.innerCircle, {
30492
30546
  backgroundColor: lockedFigureColors[color],
30493
- opacity: lockedEllipseFillStyles[fillStyle]
30547
+ opacity: lockedFigureFillStyles[fillStyle]
30494
30548
  }]
30495
30549
  }));
30496
30550
  };
@@ -30608,9 +30662,6 @@ const LockedEllipseSettings = props => {
30608
30662
  onChangeProps,
30609
30663
  onRemove
30610
30664
  } = props;
30611
- const ids = useUniqueIdWithMock();
30612
- const strokeSelectId = ids.get("stroke-style-select");
30613
- const fillSelectId = ids.get("fill-style-select");
30614
30665
  function handleColorChange(newValue) {
30615
30666
  onChangeProps({
30616
30667
  color: newValue
@@ -30662,10 +30713,10 @@ const LockedEllipseSettings = props => {
30662
30713
  size: spacing.medium_16
30663
30714
  }), /*#__PURE__*/React.createElement(LabelMedium, {
30664
30715
  tag: "label",
30665
- htmlFor: fillSelectId,
30666
- style: styles$j.label
30667
- }, "fill"), /*#__PURE__*/React.createElement(SingleSelect, {
30668
- id: fillSelectId,
30716
+ style: styles$j.row
30717
+ }, "fill", /*#__PURE__*/React.createElement(Strut, {
30718
+ size: spacing.xxSmall_6
30719
+ }), /*#__PURE__*/React.createElement(SingleSelect, {
30669
30720
  selectedValue: fillStyle,
30670
30721
  onChange: value => onChangeProps({
30671
30722
  fillStyle: value
@@ -30673,18 +30724,16 @@ const LockedEllipseSettings = props => {
30673
30724
  // Placeholder is required, but never gets used.
30674
30725
  ,
30675
30726
  placeholder: ""
30676
- }, Object.keys(lockedEllipseFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
30727
+ }, Object.keys(lockedFigureFillStyles).map(option => /*#__PURE__*/React.createElement(OptionItem, {
30677
30728
  key: option,
30678
30729
  value: option,
30679
30730
  label: option
30680
- }, option)))), /*#__PURE__*/React.createElement(View, {
30681
- style: styles$j.row
30682
- }, /*#__PURE__*/React.createElement(LabelMedium, {
30731
+ }, option))))), /*#__PURE__*/React.createElement(LabelMedium, {
30683
30732
  tag: "label",
30684
- htmlFor: strokeSelectId,
30685
- style: styles$j.label
30686
- }, "stroke"), /*#__PURE__*/React.createElement(SingleSelect, {
30687
- id: strokeSelectId,
30733
+ style: styles$j.row
30734
+ }, "stroke", /*#__PURE__*/React.createElement(Strut, {
30735
+ size: spacing.xxSmall_6
30736
+ }), /*#__PURE__*/React.createElement(SingleSelect, {
30688
30737
  selectedValue: strokeStyle,
30689
30738
  onChange: value => onChangeProps({
30690
30739
  strokeStyle: value
@@ -30705,12 +30754,10 @@ const LockedEllipseSettings = props => {
30705
30754
  };
30706
30755
  const styles$j = StyleSheet.create({
30707
30756
  row: {
30757
+ display: "flex",
30708
30758
  flexDirection: "row",
30709
30759
  alignItems: "center"
30710
30760
  },
30711
- label: {
30712
- marginInlineEnd: spacing.xxSmall_6
30713
- },
30714
30761
  spaceUnder: {
30715
30762
  marginBottom: spacing.xSmall_8
30716
30763
  }
@@ -30870,12 +30917,6 @@ const LockedLineSettings = props => {
30870
30917
  onRemove
30871
30918
  } = props;
30872
30919
  const [point1, point2] = points;
30873
-
30874
- // Generate unique IDs so that the programmatic labels can be associated
30875
- // with their respective text fields.
30876
- const ids = useUniqueIdWithMock();
30877
- const kindSelectId = ids.get("line-kind-select");
30878
- const styleSelectId = ids.get("line-style-select");
30879
30920
  const capitalizeKind = kind.charAt(0).toUpperCase() + kind.slice(1);
30880
30921
  const lineLabel = `${capitalizeKind} (${point1.coord[0]},
30881
30922
  ${point1.coord[1]}), (${point2.coord[0]}, ${point2.coord[1]})`;
@@ -30911,14 +30952,12 @@ const LockedLineSettings = props => {
30911
30952
  color: lineColor,
30912
30953
  lineStyle: lineStyle
30913
30954
  }))
30914
- }, /*#__PURE__*/React.createElement(View, {
30915
- style: [styles$f.row, styles$f.spaceUnder]
30916
30955
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30917
- htmlFor: kindSelectId,
30918
- style: styles$f.label,
30919
- tag: "label"
30920
- }, "kind"), /*#__PURE__*/React.createElement(SingleSelect, {
30921
- id: kindSelectId,
30956
+ tag: "label",
30957
+ style: [styles$f.row, styles$f.spaceUnder]
30958
+ }, "kind", /*#__PURE__*/React.createElement(Strut, {
30959
+ size: spacing.xxxSmall_4
30960
+ }), /*#__PURE__*/React.createElement(SingleSelect, {
30922
30961
  selectedValue: kind,
30923
30962
  onChange: value => onChangeProps({
30924
30963
  kind: value
@@ -30936,20 +30975,18 @@ const LockedLineSettings = props => {
30936
30975
  value: "segment",
30937
30976
  label: "segment"
30938
30977
  }))), /*#__PURE__*/React.createElement(View, {
30939
- style: [styles$f.row, styles$f.spaceUnder]
30978
+ style: styles$f.row
30940
30979
  }, /*#__PURE__*/React.createElement(ColorSelect, {
30941
30980
  selectedValue: lineColor,
30942
30981
  onChange: handleColorChange
30943
30982
  }), /*#__PURE__*/React.createElement(Strut, {
30944
30983
  size: spacing.small_12
30945
- }), /*#__PURE__*/React.createElement(View, {
30984
+ }), /*#__PURE__*/React.createElement(LabelMedium, {
30985
+ tag: "label",
30946
30986
  style: styles$f.row
30947
- }, /*#__PURE__*/React.createElement(LabelMedium, {
30948
- htmlFor: styleSelectId,
30949
- style: styles$f.label,
30950
- tag: "label"
30951
- }, "style"), /*#__PURE__*/React.createElement(SingleSelect, {
30952
- id: styleSelectId,
30987
+ }, "style", /*#__PURE__*/React.createElement(Strut, {
30988
+ size: spacing.xxxSmall_4
30989
+ }), /*#__PURE__*/React.createElement(SingleSelect, {
30953
30990
  selectedValue: lineStyle,
30954
30991
  onChange: value => onChangeProps({
30955
30992
  lineStyle: value
@@ -30993,15 +31030,13 @@ const LockedLineSettings = props => {
30993
31030
  };
30994
31031
  const styles$f = StyleSheet.create({
30995
31032
  row: {
31033
+ display: "flex",
30996
31034
  flexDirection: "row",
30997
31035
  alignItems: "center"
30998
31036
  },
30999
31037
  spaceUnder: {
31000
31038
  marginBottom: spacing.xSmall_8
31001
31039
  },
31002
- label: {
31003
- marginInlineEnd: spacing.xxxSmall_4
31004
- },
31005
31040
  selectMarginOffset: {
31006
31041
  // Align with the point settings accordions.
31007
31042
  marginInlineEnd: -spacing.xxxSmall_4
@@ -31214,89 +31249,6 @@ const LockedFigureSettings = props => {
31214
31249
  return null;
31215
31250
  };
31216
31251
 
31217
- function focusWithChromeStickyFocusBugWorkaround(element) {
31218
- // NOTE(marksandstrom) Chrome sticky focus bug.
31219
- //
31220
- // There is a bug in Chrome related to sticky positioning and
31221
- // focus: When a child of an element with sticky positioning is
31222
- // focused with the focus() method, the scrollable area
31223
- // containing that element will scroll to the top (even though
31224
- // the element is already visble on the page). For a dropdown
31225
- // this means that the area will be scrolled to the top when
31226
- // the user interacts with the dropdown (since we actively
31227
- // manage dropdown header and option focus for keyboard users).
31228
- //
31229
- // To work around this bug the `preventScroll` focus option is
31230
- // used.
31231
- //
31232
- // Using `focusOptions` is an experimental browser feature
31233
- // "that should not be used in production code". However, since
31234
- // Chrome is the only browser we support that exhibits this
31235
- // buggy behavior and using `focusOptions` works around the
31236
- // bug, it is perfectly reasonable to use the feature in this
31237
- // case. We are not relying on the effect of the
31238
- // `preventScroll` option otherwise.
31239
- //
31240
- // focusOptions documentation:
31241
- //
31242
- // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus
31243
- //
31244
- // Note that there could be cases where we want default focus() behavior.
31245
- // One that comes to mind is a dropdown with a long list of options that
31246
- // might be rendered off screen when opened. With this workaround the
31247
- // selected option would not be scrolled into view if the option is near
31248
- // the end of the list. We're not aware of any uses of the dropdown where
31249
- // this is an issue, however, so there isn't currently a way to out of the
31250
- // `preventScroll` behavior.
31251
-
31252
- // @ts-expect-error - TS2339 - Property 'focus' does not exist on type 'Element'.
31253
- element.focus({
31254
- preventScroll: true
31255
- });
31256
- }
31257
- const DEFAULT_COLOR = "grayH";
31258
- function getDefaultFigureForType(type) {
31259
- switch (type) {
31260
- case "point":
31261
- return {
31262
- type: "point",
31263
- coord: [0, 0],
31264
- color: DEFAULT_COLOR,
31265
- filled: true
31266
- };
31267
- case "line":
31268
- return {
31269
- type: "line",
31270
- kind: "line",
31271
- points: [getDefaultFigureForType("point"), _extends({}, getDefaultFigureForType("point"), {
31272
- coord: [2, 2]
31273
- })],
31274
- color: DEFAULT_COLOR,
31275
- lineStyle: "solid",
31276
- showPoint1: false,
31277
- showPoint2: false
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
- };
31295
- default:
31296
- throw new UnreachableCaseError(type);
31297
- }
31298
- }
31299
-
31300
31252
  const LockedFiguresSection = props => {
31301
31253
  var _props$figures;
31302
31254
  // Keep track of all figures' accordions' expanded states for the
@@ -31347,6 +31299,12 @@ const LockedFiguresSection = props => {
31347
31299
  const buttonLabel = allCollapsed ? "Expand all" : "Collapse all";
31348
31300
  const showExpandButton = !!(figures != null && figures.length);
31349
31301
  return /*#__PURE__*/React.createElement(View, null, figures == null ? void 0 : figures.map((figure, index) => {
31302
+ if (figure.type === "polygon") {
31303
+ // TODO(LEMS-1943): Implement locked polygon settings.
31304
+ // Remove this block once locked polygon settings are
31305
+ // implemented.
31306
+ return;
31307
+ }
31350
31308
  return /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
31351
31309
  key: `${uniqueId}-locked-${figure}-${index}`,
31352
31310
  showM2Features: props.showM2Features,
@@ -31476,6 +31434,15 @@ class InteractiveGraphEditor extends React.Component {
31476
31434
  UNSAFE_componentWillMount() {
31477
31435
  DeprecationMixin.UNSAFE_componentWillMount.call(this);
31478
31436
  }
31437
+ static buildGraphKey(correct) {
31438
+ const testGraphKey = [];
31439
+ for (const key in correct) {
31440
+ if (correct[key]) {
31441
+ typeof correct[key] === "number" || typeof correct[key] === "string" || typeof correct[key] === "boolean" ? testGraphKey.push(correct[key]) : testGraphKey.push(0);
31442
+ }
31443
+ }
31444
+ return testGraphKey.join(":");
31445
+ }
31479
31446
  render() {
31480
31447
  var _this$props$graph$typ, _this$props$graph, _this$props$correct, _this$props$correct2, _this$props$correct3, _this$props$correct4, _this$props$correct5, _this$props$correct6, _this$props$correct7, _this$props$correct8, _this$props$correct9, _this$props$correct10, _this$props$correct11, _this$props$apiOption, _this$props$apiOption2;
31481
31448
  let graph;
@@ -31519,10 +31486,9 @@ class InteractiveGraphEditor extends React.Component {
31519
31486
  });
31520
31487
  }
31521
31488
  };
31522
-
31523
31489
  // This is used to force a remount of the graph component
31524
31490
  // when there's a significant change
31525
- const graphKey = `${correct.type}:${correct.numSegments || 0}`;
31491
+ const graphKey = InteractiveGraphEditor.buildGraphKey(correct);
31526
31492
  graph =
31527
31493
  /*#__PURE__*/
31528
31494
  // There are a bunch of props that renderer.jsx passes to widgets via