@khanacademy/perseus-editor 11.2.0 → 11.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { addLibraryVersionToPerseusDebug, PerseusError, Errors } from '@khanacademy/perseus-core';
2
- import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, 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, getQuadraticCoords, getSinusoidCoords, getCircleCoords, getLinearSystemCoords, getSegmentCoords, getLineCoords, lockedFigureColors, lockedFigureFillStyles, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, widgets } from '@khanacademy/perseus';
2
+ import { constants, components, Widgets, icons, WIDGET_PROP_DENYLIST, Util, Log, 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, getAngleCoords, getPolygonCoords, getPointCoords, getQuadraticCoords, getSinusoidCoords, getCircleCoords, getLinearSystemCoords, getSegmentCoords, getLineCoords, lockedFigureColors, lockedFigureFillStyles, InteractiveGraphWidget, globalStyles, globalConstants, MatrixWidget, PlotterWidget, plotterPlotTypes, BaseRadio, TableWidget, widgets } from '@khanacademy/perseus';
3
3
  import * as React from 'react';
4
- import { useRef, useEffect } from 'react';
4
+ import { useRef, useEffect, useState } from 'react';
5
5
  import _ from 'underscore';
6
6
  import createReactClass from 'create-react-class';
7
7
  import Clickable from '@khanacademy/wonder-blocks-clickable';
@@ -13,13 +13,13 @@ import { View, useUniqueIdWithMock } from '@khanacademy/wonder-blocks-core';
13
13
  import { PhosphorIcon } from '@khanacademy/wonder-blocks-icon';
14
14
  import caretRight from '@phosphor-icons/core/bold/caret-right-bold.svg';
15
15
  import classNames from 'classnames';
16
+ import { Checkbox as Checkbox$1, TextField } from '@khanacademy/wonder-blocks-form';
16
17
  import ReactDOM from 'react-dom';
17
18
  import { point, vector, number } from '@khanacademy/kmath';
18
19
  import * as KAS from '@khanacademy/kas';
19
20
  import { isTruthy, UnreachableCaseError } from '@khanacademy/wonder-stuff-core';
20
21
  import { useMathInputI18n, createMathField } from '@khanacademy/math-input';
21
22
  import { ActionMenu, ActionItem, SingleSelect, OptionItem } from '@khanacademy/wonder-blocks-dropdown';
22
- import { TextField, Checkbox as Checkbox$1 } from '@khanacademy/wonder-blocks-form';
23
23
  import { LabelSmall, LabelLarge, LabelMedium, LabelXSmall, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
24
24
  import Button from '@khanacademy/wonder-blocks-button';
25
25
  import { AccordionSection } from '@khanacademy/wonder-blocks-accordion';
@@ -37,7 +37,7 @@ import arrowCounterClockwise from '@phosphor-icons/core/bold/arrow-counter-clock
37
37
 
38
38
  // This file is processed by a Rollup plugin (replace) to inject the production
39
39
  const libName = "@khanacademy/perseus-editor";
40
- const libVersion = "11.2.0";
40
+ const libVersion = "11.3.0";
41
41
  addLibraryVersionToPerseusDebug(libName, libVersion);
42
42
 
43
43
  function _extends() {
@@ -227,7 +227,7 @@ class SectionControlButton extends React.Component {
227
227
  role: "button",
228
228
  hideDefaultFocusRing: true,
229
229
  "aria-label": title,
230
- style: styles$L.button
230
+ style: styles$P.button
231
231
  }, ({
232
232
  hovered,
233
233
  focused,
@@ -235,7 +235,7 @@ class SectionControlButton extends React.Component {
235
235
  }) => /*#__PURE__*/React.createElement(InlineIcon$a, icon));
236
236
  }
237
237
  }
238
- const styles$L = StyleSheet.create({
238
+ const styles$P = StyleSheet.create({
239
239
  button: {
240
240
  backgroundColor: color.gold,
241
241
  margin: 2,
@@ -20740,13 +20740,13 @@ class WidgetSelect extends React.Component {
20740
20740
  * that collapse a region.
20741
20741
  */
20742
20742
  function ToggleableCaret(props) {
20743
- const iconStyle = props.isExpanded ? styles$K.expanded : styles$K.collapsed;
20743
+ const iconStyle = props.isExpanded ? styles$O.expanded : styles$O.collapsed;
20744
20744
  return /*#__PURE__*/React.createElement(PhosphorIcon, {
20745
20745
  icon: caretRight,
20746
20746
  style: iconStyle
20747
20747
  });
20748
20748
  }
20749
- const styles$K = StyleSheet.create({
20749
+ const styles$O = StyleSheet.create({
20750
20750
  collapsed: {
20751
20751
  transition: ".15s"
20752
20752
  },
@@ -20779,16 +20779,16 @@ class TexErrorView extends React.Component {
20779
20779
  showErrors
20780
20780
  } = this.state;
20781
20781
  return /*#__PURE__*/React.createElement(View, {
20782
- style: styles$J.errorContainer
20782
+ style: styles$N.errorContainer
20783
20783
  }, /*#__PURE__*/React.createElement(View, {
20784
- style: styles$J.title,
20784
+ style: styles$N.title,
20785
20785
  onClick: this.handleToggleTexErrors
20786
20786
  }, /*#__PURE__*/React.createElement(ToggleableCaret, {
20787
20787
  isExpanded: showErrors
20788
20788
  }), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React.createElement(View, {
20789
- style: styles$J.errorExplanation
20789
+ style: styles$N.errorExplanation
20790
20790
  }, "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, {
20791
- style: styles$J.error,
20791
+ style: styles$N.error,
20792
20792
  key: index
20793
20793
  }, /*#__PURE__*/React.createElement(View, {
20794
20794
  style: {
@@ -20797,7 +20797,7 @@ class TexErrorView extends React.Component {
20797
20797
  }, e.math), /*#__PURE__*/React.createElement(View, null, e.message))));
20798
20798
  }
20799
20799
  }
20800
- const styles$J = StyleSheet.create({
20800
+ const styles$N = StyleSheet.create({
20801
20801
  title: {
20802
20802
  backgroundColor: "#eee",
20803
20803
  fontSize: "1.25em",
@@ -23638,12 +23638,10 @@ class CombinedHintsEditor extends React.Component {
23638
23638
  super(...args);
23639
23639
  this.handleHintChange = (i, newProps, cb, silent) => {
23640
23640
  // TODO(joel) - lens
23641
- const hints = _(this.props.hints).clone();
23641
+ const hints = [...this.props.hints];
23642
23642
  hints[i] = _.extend({}, this.serializeHint(i, {
23643
23643
  keepDeletedWidgets: true
23644
23644
  }), newProps);
23645
-
23646
- // @ts-expect-error - TS2740 - Type 'Hint' is missing the following properties from type 'readonly Hint[]': length, concat, join, slice, and 18 more.
23647
23645
  this.props.onChange({
23648
23646
  hints: hints
23649
23647
  }, cb, silent);
@@ -23653,21 +23651,16 @@ class CombinedHintsEditor extends React.Component {
23653
23651
  if (!confirm("Are you sure you want to delete this hint?")) {
23654
23652
  return;
23655
23653
  }
23656
- const hints = _(this.props.hints).clone();
23657
- // @ts-expect-error - TS2339 - Property 'splice' does not exist on type 'Hint'.
23654
+ const hints = [...this.props.hints];
23658
23655
  hints.splice(i, 1);
23659
- // @ts-expect-error - TS2322 - Type 'Hint' is not assignable to type 'readonly Hint[]'.
23660
23656
  this.props.onChange({
23661
23657
  hints: hints
23662
23658
  });
23663
23659
  };
23664
23660
  this.handleHintMove = (i, dir) => {
23665
- const hints = _(this.props.hints).clone();
23666
- // @ts-expect-error - TS2339 - Property 'splice' does not exist on type 'Hint'.
23661
+ const hints = [...this.props.hints];
23667
23662
  const hint = hints.splice(i, 1)[0];
23668
- // @ts-expect-error - TS2339 - Property 'splice' does not exist on type 'Hint'.
23669
23663
  hints.splice(i + dir, 0, hint);
23670
- // @ts-expect-error - TS2322 - Type 'Hint' is not assignable to type 'readonly Hint[]'.
23671
23664
  this.props.onChange({
23672
23665
  hints: hints
23673
23666
  }, () => {
@@ -23677,10 +23670,10 @@ class CombinedHintsEditor extends React.Component {
23677
23670
  });
23678
23671
  };
23679
23672
  this.addHint = () => {
23680
- const hints = _(this.props.hints).clone()
23681
- // @ts-expect-error - TS2339 - Property 'concat' does not exist on type 'Hint'.
23682
- .concat([{
23683
- content: ""
23673
+ const hints = this.props.hints.concat([{
23674
+ content: "",
23675
+ images: {},
23676
+ widgets: {}
23684
23677
  }]);
23685
23678
  this.props.onChange({
23686
23679
  hints: hints
@@ -23800,65 +23793,65 @@ class ItemExtrasEditor extends React.Component {
23800
23793
  }, /*#__PURE__*/React.createElement("div", {
23801
23794
  className: "perseus-answer-options"
23802
23795
  }, /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23803
- label: "Show calculator:",
23796
+ label: "Show calculator",
23804
23797
  infoTip: "Use the calculator when completing difficult calculations is NOT the intent of the question. DON\u2019T use the calculator when testing the student\u2019s ability to complete different types of computations.",
23805
23798
  checked: this.props.calculator,
23806
- onChange: e => {
23799
+ onChange: newCheckedState => {
23807
23800
  this.props.onChange({
23808
- calculator: e.target.checked
23801
+ calculator: newCheckedState
23809
23802
  });
23810
23803
  }
23811
23804
  }), /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23812
- label: "Show financial calculator:",
23805
+ label: "Show financial calculator",
23813
23806
  infoTip: "This provides the student with the ability to view a financial calculator, e.g., for answering financial questions. Once checked, requires at least one of the three options below to be checked.",
23814
23807
  checked: this.shouldShowFinancialCalculatorOptions(),
23815
- onChange: e => {
23808
+ onChange: newCheckedState => {
23816
23809
  // If the financial calculator is unchecked,
23817
23810
  // these need to be reset. All checked by
23818
23811
  // default.
23819
23812
  this.props.onChange({
23820
- financialCalculatorMonthlyPayment: e.target.checked,
23821
- financialCalculatorTotalAmount: e.target.checked,
23822
- financialCalculatorTimeToPayOff: e.target.checked
23813
+ financialCalculatorMonthlyPayment: newCheckedState,
23814
+ financialCalculatorTotalAmount: newCheckedState,
23815
+ financialCalculatorTimeToPayOff: newCheckedState
23823
23816
  });
23824
23817
  }
23825
23818
  }), this.shouldShowFinancialCalculatorOptions() && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23826
- label: "Include monthly payment:",
23819
+ label: "Include monthly payment",
23827
23820
  infoTip: "This provides the student with the ability to view a monthly payment calculator; e.g., given a loan amount, interest rate, and term, what is the monthly payment?",
23828
23821
  checked: this.props.financialCalculatorMonthlyPayment,
23829
- onChange: e => {
23822
+ onChange: newCheckedState => {
23830
23823
  this.props.onChange({
23831
- financialCalculatorMonthlyPayment: e.target.checked
23824
+ financialCalculatorMonthlyPayment: newCheckedState
23832
23825
  });
23833
23826
  },
23834
23827
  indent: true
23835
23828
  }), /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23836
- label: "Include total amount:",
23829
+ label: "Include total amount",
23837
23830
  infoTip: "This provides the student with the ability to view a total amount calculator; e.g., given a monthly payment, interest rate, and term, what is the total amount to be paid?",
23838
23831
  checked: this.props.financialCalculatorTotalAmount,
23839
- onChange: e => {
23832
+ onChange: newCheckedState => {
23840
23833
  this.props.onChange({
23841
- financialCalculatorTotalAmount: e.target.checked
23834
+ financialCalculatorTotalAmount: newCheckedState
23842
23835
  });
23843
23836
  },
23844
23837
  indent: true
23845
23838
  }), /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23846
- label: "Include time-to-pay-off:",
23839
+ label: "Include time-to-pay-off",
23847
23840
  infoTip: "This provides the student with the ability to view a time to pay off calculator; e.g., given a loan amount, interest rate, and monthly payment, how long will it take to pay off the loan?",
23848
23841
  checked: this.props.financialCalculatorTimeToPayOff,
23849
- onChange: e => {
23842
+ onChange: newCheckedState => {
23850
23843
  this.props.onChange({
23851
- financialCalculatorTimeToPayOff: e.target.checked
23844
+ financialCalculatorTimeToPayOff: newCheckedState
23852
23845
  });
23853
23846
  },
23854
23847
  indent: true
23855
23848
  })), /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23856
- label: "Show periodic table:",
23849
+ label: "Show periodic table",
23857
23850
  infoTip: "This provides the student with the ability to view a periodic table of the elements, e.g., for answering chemistry questions.",
23858
23851
  checked: this.props.periodicTable,
23859
- onChange: e => {
23852
+ onChange: newCheckedState => {
23860
23853
  this.props.onChange({
23861
- periodicTable: e.target.checked,
23854
+ periodicTable: newCheckedState,
23862
23855
  // If the periodic table is unchecked,
23863
23856
  // this needs to be reset. If table is
23864
23857
  // checked, it should already be false.
@@ -23866,40 +23859,40 @@ class ItemExtrasEditor extends React.Component {
23866
23859
  });
23867
23860
  }
23868
23861
  }), this.props.periodicTable && /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23869
- label: "Include key/legend with periodic table:",
23862
+ label: "Include key/legend with periodic table",
23870
23863
  infoTip: "Include a key for HS courses; omit for AP chemistry.",
23871
23864
  checked: this.props.periodicTableWithKey,
23872
- onChange: e => {
23865
+ onChange: newCheckedState => {
23873
23866
  this.props.onChange({
23874
- periodicTableWithKey: e.target.checked
23867
+ periodicTableWithKey: newCheckedState
23875
23868
  });
23876
23869
  },
23877
23870
  indent: true
23878
23871
  }), /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23879
- label: "Show z table (statistics):",
23872
+ label: "Show z table (statistics)",
23880
23873
  infoTip: "This provides the student with the ability to view a table of critical values for the z distribution, e.g. for answering statistics questions.",
23881
23874
  checked: this.props.zTable,
23882
- onChange: e => {
23875
+ onChange: newCheckedState => {
23883
23876
  this.props.onChange({
23884
- zTable: e.target.checked
23877
+ zTable: newCheckedState
23885
23878
  });
23886
23879
  }
23887
23880
  }), /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23888
- label: "Show t table (statistics):",
23881
+ label: "Show t table (statistics)",
23889
23882
  infoTip: "This provides the student with the ability to view a table of critical values for the Student's t distribution, e.g. for answering statistics questions.",
23890
23883
  checked: this.props.tTable,
23891
- onChange: e => {
23884
+ onChange: newCheckedState => {
23892
23885
  this.props.onChange({
23893
- tTable: e.target.checked
23886
+ tTable: newCheckedState
23894
23887
  });
23895
23888
  }
23896
23889
  }), /*#__PURE__*/React.createElement(ItemExtraCheckbox, {
23897
- label: "Show chi-squared table (statistics):",
23890
+ label: "Show chi-squared table (statistics)",
23898
23891
  infoTip: "This provides the student with the ability to view a table of critical values for the chi-squared distribution, e.g. for answering statistics questions.",
23899
23892
  checked: this.props.chi2Table,
23900
- onChange: e => {
23893
+ onChange: newCheckedState => {
23901
23894
  this.props.onChange({
23902
- chi2Table: e.target.checked
23895
+ chi2Table: newCheckedState
23903
23896
  });
23904
23897
  }
23905
23898
  })));
@@ -23916,15 +23909,22 @@ ItemExtrasEditor.defaultProps = {
23916
23909
  tTable: false,
23917
23910
  zTable: false
23918
23911
  };
23919
- const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement("div", {
23920
- style: {
23921
- marginLeft: props.indent ? "10px" : "0px"
23922
- }
23923
- }, /*#__PURE__*/React.createElement("label", null, props.label, /*#__PURE__*/React.createElement("input", {
23924
- type: "checkbox",
23912
+ const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement(View, {
23913
+ style: [styles$M.checkbox, props.indent ? styles$M.indented : undefined]
23914
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
23915
+ label: /*#__PURE__*/React.createElement(View, {
23916
+ style: {
23917
+ flexDirection: "row"
23918
+ }
23919
+ }, props.label, " ", /*#__PURE__*/React.createElement(InfoTip$l, null, props.infoTip)),
23925
23920
  checked: props.checked,
23926
- onChange: props.onChange
23927
- })), /*#__PURE__*/React.createElement(InfoTip$l, null, props.infoTip));
23921
+ onChange: newCheckedState => props.onChange(newCheckedState)
23922
+ }));
23923
+ const styles$M = StyleSheet.create({
23924
+ indented: {
23925
+ marginInlineStart: spacing.large_24
23926
+ }
23927
+ });
23928
23928
 
23929
23929
  const ITEM_DATA_VERSION = itemDataVersion;
23930
23930
  class ItemEditor extends React.Component {
@@ -24591,7 +24591,7 @@ class SimpleButton extends React.Component {
24591
24591
  } = _this$props,
24592
24592
  otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$3);
24593
24593
  return /*#__PURE__*/React.createElement("div", _extends({
24594
- className: css(styles$I.baseButton, color === "green" && styles$I.green, color === "orange" && styles$I.orange),
24594
+ className: css(styles$L.baseButton, color === "green" && styles$L.green, color === "orange" && styles$L.orange),
24595
24595
  onClick: onClick
24596
24596
  }, otherProps), children);
24597
24597
  }
@@ -24606,7 +24606,7 @@ SimpleButton.defaultProps = {
24606
24606
  color: "green",
24607
24607
  onClick: () => {}
24608
24608
  };
24609
- const styles$I = StyleSheet.create({
24609
+ const styles$L = StyleSheet.create({
24610
24610
  baseButton: {
24611
24611
  top: "0",
24612
24612
  fontSize: "11px",
@@ -24826,23 +24826,23 @@ const LeafContainer = ({
24826
24826
  }) => {
24827
24827
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
24828
24828
  const previewHeading = hasPreviewHeading && /*#__PURE__*/React.createElement("div", {
24829
- className: css(styles$H.containerHeader)
24829
+ className: css(styles$K.containerHeader)
24830
24830
  }, /*#__PURE__*/React.createElement(Header, {
24831
24831
  depth: path.length,
24832
- className: css(styles$H.containerTitle)
24832
+ className: css(styles$K.containerTitle)
24833
24833
  }, capitalize(name)));
24834
24834
  return /*#__PURE__*/React.createElement("div", {
24835
- className: css(styles$H.container)
24835
+ className: css(styles$K.container)
24836
24836
  }, /*#__PURE__*/React.createElement("span", {
24837
- className: css(styles$H.row, styles$H.rowHeading)
24837
+ className: css(styles$K.row, styles$K.rowHeading)
24838
24838
  }, /*#__PURE__*/React.createElement("div", {
24839
- className: css(styles$H.columnLeft)
24839
+ className: css(styles$K.columnLeft)
24840
24840
  }, /*#__PURE__*/React.createElement("div", {
24841
- className: "pod-title " + css(styles$H.containerHeader)
24841
+ className: "pod-title " + css(styles$K.containerHeader)
24842
24842
  }, /*#__PURE__*/React.createElement("div", {
24843
- className: css(styles$H.containerTitle)
24843
+ className: css(styles$K.containerTitle)
24844
24844
  }, capitalize(name)), controls)), /*#__PURE__*/React.createElement("div", {
24845
- className: css(styles$H.columnRight)
24845
+ className: css(styles$K.columnRight)
24846
24846
  }, previewHeading)), children);
24847
24847
  };
24848
24848
  const ArrayContainer = props => {
@@ -24855,11 +24855,11 @@ const ArrayContainer = props => {
24855
24855
  actions
24856
24856
  } = props;
24857
24857
  return /*#__PURE__*/React.createElement("div", {
24858
- className: css(styles$H.container)
24858
+ className: css(styles$K.container)
24859
24859
  }, controls && /*#__PURE__*/React.createElement("div", {
24860
- className: css(styles$H.columnLeft, styles$H.containerHeader)
24860
+ className: css(styles$K.columnLeft, styles$K.containerHeader)
24861
24861
  }, controls), /*#__PURE__*/React.createElement("div", null, children), /*#__PURE__*/React.createElement("div", {
24862
- className: css(styles$H.columnLeft)
24862
+ className: css(styles$K.columnLeft)
24863
24863
  }, /*#__PURE__*/React.createElement("a", {
24864
24864
  href: "javascript:void 0",
24865
24865
  onClick: () => actions.addArrayElement(path, shape.elementShape)
@@ -24872,28 +24872,28 @@ const ObjectContainer = ({
24872
24872
  path
24873
24873
  }) => {
24874
24874
  const headingEditor = /*#__PURE__*/React.createElement("div", {
24875
- className: css(styles$H.containerHeader)
24875
+ className: css(styles$K.containerHeader)
24876
24876
  }, /*#__PURE__*/React.createElement(Header, {
24877
24877
  depth: path.length,
24878
- className: css(styles$H.containerTitle)
24878
+ className: css(styles$K.containerTitle)
24879
24879
  }, capitalize(name)), controls);
24880
24880
  const headingPreview = (name || controls) && /*#__PURE__*/React.createElement("div", {
24881
- className: css(styles$H.containerHeader, styles$H.previewCollectionHeader)
24881
+ className: css(styles$K.containerHeader, styles$K.previewCollectionHeader)
24882
24882
  }, /*#__PURE__*/React.createElement(Header, {
24883
24883
  depth: path.length,
24884
- className: css(styles$H.containerTitle)
24884
+ className: css(styles$K.containerTitle)
24885
24885
  }, capitalize(name)));
24886
24886
  const hasBothHeadings = headingEditor && headingPreview;
24887
24887
  return /*#__PURE__*/React.createElement("div", {
24888
- className: css(styles$H.container)
24888
+ className: css(styles$K.container)
24889
24889
  }, hasBothHeadings && /*#__PURE__*/React.createElement("span", {
24890
- className: css(styles$H.row)
24890
+ className: css(styles$K.row)
24891
24891
  }, /*#__PURE__*/React.createElement("div", {
24892
- className: css(styles$H.columnLeft)
24892
+ className: css(styles$K.columnLeft)
24893
24893
  }, headingEditor), /*#__PURE__*/React.createElement("div", {
24894
- className: css(styles$H.columnRight)
24894
+ className: css(styles$K.columnRight)
24895
24895
  }, headingPreview)), /*#__PURE__*/React.createElement("div", {
24896
- className: css(path.length > 0 && styles$H.contentIndent)
24896
+ className: css(path.length > 0 && styles$K.contentIndent)
24897
24897
  }, children));
24898
24898
  };
24899
24899
 
@@ -25016,11 +25016,11 @@ const ItemNodeContent = withStickiness(props => {
25016
25016
  className: "framework-perseus"
25017
25017
  }, lens(renderers).get(path));
25018
25018
  return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
25019
- className: css(styles$H.row)
25019
+ className: css(styles$K.row)
25020
25020
  }, /*#__PURE__*/React.createElement("div", {
25021
- className: css(styles$H.columnLeft)
25021
+ className: css(styles$K.columnLeft)
25022
25022
  }, /*#__PURE__*/React.createElement("div", {
25023
- className: css(sticky && styles$H.sticky)
25023
+ className: css(sticky && styles$K.sticky)
25024
25024
  },
25025
25025
  /*#__PURE__*/
25026
25026
  // @ts-expect-error - TS2769 - No overload matches this call.
@@ -25028,9 +25028,9 @@ const ItemNodeContent = withStickiness(props => {
25028
25028
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25029
25029
  apiOptions: apiOptions
25030
25030
  })))), /*#__PURE__*/React.createElement("div", {
25031
- className: css(styles$H.columnRight)
25031
+ className: css(styles$K.columnRight)
25032
25032
  }, /*#__PURE__*/React.createElement("div", {
25033
- className: css(sticky && styles$H.sticky)
25033
+ className: css(sticky && styles$K.sticky)
25034
25034
  }, preview))));
25035
25035
  });
25036
25036
  const HintNodeContent = withStickiness(props => {
@@ -25046,13 +25046,13 @@ const HintNodeContent = withStickiness(props => {
25046
25046
  className: "framework-perseus"
25047
25047
  }, lens(renderers).get(path));
25048
25048
  return /*#__PURE__*/React.createElement("div", {
25049
- className: css(styles$H.row)
25049
+ className: css(styles$K.row)
25050
25050
  }, /*#__PURE__*/React.createElement("div", {
25051
- className: css(styles$H.columnLeft)
25051
+ className: css(styles$K.columnLeft)
25052
25052
  }, /*#__PURE__*/React.createElement("div", {
25053
- className: css(sticky && styles$H.sticky)
25053
+ className: css(sticky && styles$K.sticky)
25054
25054
  }, /*#__PURE__*/React.createElement(HintEditor, _extends({}, data, {
25055
- className: css(styles$H.hintEditor),
25055
+ className: css(styles$K.hintEditor),
25056
25056
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25057
25057
  apiOptions: apiOptions,
25058
25058
  showTitle: false,
@@ -25067,9 +25067,9 @@ const HintNodeContent = withStickiness(props => {
25067
25067
  isFirst: true,
25068
25068
  isLast: true
25069
25069
  })))), /*#__PURE__*/React.createElement("div", {
25070
- className: css(styles$H.columnRight)
25070
+ className: css(styles$K.columnRight)
25071
25071
  }, /*#__PURE__*/React.createElement("div", {
25072
- className: css(sticky && styles$H.sticky)
25072
+ className: css(sticky && styles$K.sticky)
25073
25073
  }, preview)));
25074
25074
  });
25075
25075
  const TagsNodeContent = props => {
@@ -25086,9 +25086,9 @@ const TagsNodeContent = props => {
25086
25086
  return null;
25087
25087
  }
25088
25088
  return /*#__PURE__*/React.createElement("div", {
25089
- className: css(styles$H.columnLeft)
25089
+ className: css(styles$K.columnLeft)
25090
25090
  }, /*#__PURE__*/React.createElement("div", {
25091
- className: css(styles$H.tagsEditor)
25091
+ className: css(styles$K.tagsEditor)
25092
25092
  }, /*#__PURE__*/React.createElement(GroupMetadataEditor, {
25093
25093
  value: data,
25094
25094
  onChange: newVal => actions.setValueAtPath(path, newVal),
@@ -25119,23 +25119,23 @@ const ArrayNodeContent = props => {
25119
25119
  const subpath = path.concat(i);
25120
25120
  const controls = [i > 0 && /*#__PURE__*/React.createElement("div", {
25121
25121
  key: "moveArrayElementUp",
25122
- className: css(styles$H.control)
25122
+ className: css(styles$K.control)
25123
25123
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25124
25124
  color: "orange",
25125
25125
  title: "Move up",
25126
25126
  onClick: () => actions.moveArrayElementUp(subpath)
25127
25127
  }, /*#__PURE__*/React.createElement("div", {
25128
- className: css(styles$H.verticalFlip)
25128
+ className: css(styles$K.verticalFlip)
25129
25129
  }, /*#__PURE__*/React.createElement(InlineIcon$5, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React.createElement("div", {
25130
25130
  key: "moveArrayElementDown",
25131
- className: css(styles$H.control)
25131
+ className: css(styles$K.control)
25132
25132
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25133
25133
  color: "orange",
25134
25134
  title: "Move down",
25135
25135
  onClick: () => actions.moveArrayElementDown(subpath)
25136
25136
  }, /*#__PURE__*/React.createElement(InlineIcon$5, iconChevronDown))), /*#__PURE__*/React.createElement("div", {
25137
25137
  key: "removeArrayElement",
25138
- className: css(styles$H.control)
25138
+ className: css(styles$K.control)
25139
25139
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25140
25140
  color: "orange",
25141
25141
  title: "Delete",
@@ -25143,7 +25143,7 @@ const ArrayNodeContent = props => {
25143
25143
  }, /*#__PURE__*/React.createElement(InlineIcon$5, iconTrash$4)))];
25144
25144
  return /*#__PURE__*/React.createElement("div", {
25145
25145
  key: i,
25146
- className: css(styles$H.arrayElement, !elementIsLeaf && styles$H.arrayElementAndNotLeaf)
25146
+ className: css(styles$K.arrayElement, !elementIsLeaf && styles$K.arrayElementAndNotLeaf)
25147
25147
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25148
25148
  key: i,
25149
25149
  shape: shape.elementShape,
@@ -25169,7 +25169,7 @@ const ObjectNodeContent = props => {
25169
25169
  // made sense to the shape's author is the order in which we'll iterate :)
25170
25170
  const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React.createElement("div", {
25171
25171
  key: subkey,
25172
- className: css(styles$H.objectElement)
25172
+ className: css(styles$K.objectElement)
25173
25173
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25174
25174
  shape: shape.shape[subkey],
25175
25175
  data: data[subkey],
@@ -25336,7 +25336,7 @@ class MultiRendererEditor extends React.Component {
25336
25336
  }, this._renderContent());
25337
25337
  }
25338
25338
  }
25339
- const styles$H = StyleSheet.create({
25339
+ const styles$K = StyleSheet.create({
25340
25340
  // This is used in a number of places throughout this file.
25341
25341
  container: {},
25342
25342
  // eslint-disable-next-line react-native/no-unused-styles
@@ -25500,7 +25500,6 @@ const StatefulEditorPage = createReactClass({
25500
25500
  });
25501
25501
 
25502
25502
  const {
25503
- PropCheckBox: PropCheckBox$c,
25504
25503
  TextListEditor: TextListEditor$4
25505
25504
  } = components;
25506
25505
  const Categorizer = Categorizer$1.widget;
@@ -25517,11 +25516,14 @@ class CategorizerEditor extends React.Component {
25517
25516
  render() {
25518
25517
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
25519
25518
  className: "perseus-widget-row"
25520
- }, /*#__PURE__*/React.createElement(PropCheckBox$c, {
25519
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
25521
25520
  label: "Randomize item order",
25522
- labelAlignment: "right",
25523
- randomizeItems: this.props.randomizeItems,
25524
- onChange: this.props.onChange
25521
+ checked: this.props.randomizeItems,
25522
+ onChange: value => {
25523
+ this.props.onChange({
25524
+ randomizeItems: value
25525
+ });
25526
+ }
25525
25527
  })), "Categories:", /*#__PURE__*/React.createElement(TextListEditor$4, {
25526
25528
  options: this.props.categories,
25527
25529
  onChange: cat => {
@@ -25629,8 +25631,7 @@ class BlurInput extends React.Component {
25629
25631
  }
25630
25632
 
25631
25633
  const {
25632
- InfoTip: InfoTip$k,
25633
- PropCheckBox: PropCheckBox$b
25634
+ InfoTip: InfoTip$k
25634
25635
  } = components;
25635
25636
  const DEFAULT_WIDTH = 400;
25636
25637
  const DEFAULT_HEIGHT = 400;
@@ -25786,14 +25787,22 @@ class CSProgramEditor extends React.Component {
25786
25787
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Url or Program ID:", " ", /*#__PURE__*/React.createElement(BlurInput, {
25787
25788
  value: this.props.programID,
25788
25789
  onChange: this._handleProgramIDChange
25789
- })), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$b, {
25790
+ })), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(Checkbox$1, {
25790
25791
  label: "Show Editor",
25791
- showEditor: this.props.showEditor,
25792
- onChange: this.props.onChange
25793
- }), /*#__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, {
25792
+ checked: this.props.showEditor,
25793
+ onChange: value => {
25794
+ this.props.onChange({
25795
+ showEditor: value
25796
+ });
25797
+ }
25798
+ }), /*#__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(Checkbox$1, {
25794
25799
  label: "Show Buttons",
25795
- showButtons: this.props.showButtons,
25796
- onChange: this.props.onChange
25800
+ checked: this.props.showButtons,
25801
+ onChange: value => {
25802
+ this.props.onChange({
25803
+ showButtons: value
25804
+ });
25805
+ }
25797
25806
  }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("label", null, "Settings:", /*#__PURE__*/React.createElement(PairsEditor$1, {
25798
25807
  name: "settings",
25799
25808
  pairs: this.props.settings,
@@ -26492,7 +26501,6 @@ const SortableItem = createReactClass({
26492
26501
 
26493
26502
  const {
26494
26503
  InfoTip: InfoTip$i,
26495
- PropCheckBox: PropCheckBox$a,
26496
26504
  TextInput: TextInput$7
26497
26505
  } = components;
26498
26506
 
@@ -26754,11 +26762,14 @@ class ExpressionEditor extends React.Component {
26754
26762
  })), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Label text that's read by screen readers. Highly recommend adding a label here to ensure your exercise is accessible. For more information on writting accessible labels, please see", " ", /*#__PURE__*/React.createElement("a", {
26755
26763
  href: "https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",
26756
26764
  target: "_blank"
26757
- }, "this article.")))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$a, {
26758
- times: this.props.times,
26759
- onChange: this.props.onChange,
26760
- labelAlignment: "right",
26761
- label: "Use \xD7 for rendering multiplication instead of a center dot."
26765
+ }, "this article.")))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Checkbox$1, {
26766
+ label: "Use \xD7 for rendering multiplication instead of a center dot.",
26767
+ checked: this.props.times,
26768
+ onChange: value => {
26769
+ this.props.onChange({
26770
+ times: value
26771
+ });
26772
+ }
26762
26773
  }), /*#__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", {
26763
26774
  type: "text",
26764
26775
  defaultValue: this.props.functions.join(" "),
@@ -26853,18 +26864,24 @@ class AnswerOption extends React.Component {
26853
26864
  className: "answer-expression"
26854
26865
  }, /*#__PURE__*/React.createElement(Expression, this.props.expressionProps))), /*#__PURE__*/React.createElement("div", {
26855
26866
  className: "answer-option"
26856
- }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
26857
- form: this.props.form,
26858
- onChange: this.props.onChange,
26859
- labelAlignment: "right",
26860
- label: "Answer expression must have the same form."
26867
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
26868
+ label: "Answer expression must have the same form.",
26869
+ checked: this.props.form,
26870
+ onChange: value => {
26871
+ this.props.onChange({
26872
+ form: value
26873
+ });
26874
+ }
26861
26875
  }), /*#__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", {
26862
26876
  className: "answer-option"
26863
- }, /*#__PURE__*/React.createElement(PropCheckBox$a, {
26864
- simplify: this.props.simplify,
26865
- onChange: this.props.onChange,
26866
- labelAlignment: "right",
26867
- label: "Answer expression must be fully expanded and simplified."
26877
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
26878
+ label: "Answer expression must be fully expanded and simplified.",
26879
+ checked: this.props.simplify,
26880
+ onChange: value => {
26881
+ this.props.onChange({
26882
+ simplify: value
26883
+ });
26884
+ }
26868
26885
  }), /*#__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", {
26869
26886
  className: "remove-container"
26870
26887
  }, removeButton)));
@@ -26922,10 +26939,10 @@ class GradedGroupEditor extends React.Component {
26922
26939
  }, /*#__PURE__*/React.createElement("div", {
26923
26940
  className: "perseus-widget-row"
26924
26941
  }, /*#__PURE__*/React.createElement("label", {
26925
- className: css(styles$G.title)
26942
+ className: css(styles$J.title)
26926
26943
  }, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
26927
26944
  value: this.props.title,
26928
- className: css(styles$G.input)
26945
+ className: css(styles$J.input)
26929
26946
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26930
26947
  ,
26931
26948
  onChange: this.change("title")
@@ -26950,7 +26967,7 @@ class GradedGroupEditor extends React.Component {
26950
26967
  }, /*#__PURE__*/React.createElement(InlineIcon$3, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React.createElement("div", {
26951
26968
  className: "perseus-hint-editor"
26952
26969
  }, /*#__PURE__*/React.createElement("div", {
26953
- className: css(styles$G.hintsTitle)
26970
+ className: css(styles$J.hintsTitle)
26954
26971
  }, "Hint"), /*#__PURE__*/React.createElement(Editor, {
26955
26972
  ref: this.hintEditor,
26956
26973
  content: this.props.hint ? this.props.hint.content : "",
@@ -26987,7 +27004,7 @@ GradedGroupEditor.defaultProps = {
26987
27004
  images: {},
26988
27005
  hint: null
26989
27006
  };
26990
- const styles$G = StyleSheet.create({
27007
+ const styles$J = StyleSheet.create({
26991
27008
  title: {
26992
27009
  fontSize: 18,
26993
27010
  fontWeight: "bold"
@@ -27066,7 +27083,6 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
27066
27083
  const {
27067
27084
  ButtonGroup: ButtonGroup$4,
27068
27085
  InfoTip: InfoTip$h,
27069
- PropCheckBox: PropCheckBox$9,
27070
27086
  RangeInput: RangeInput$6
27071
27087
  } = components;
27072
27088
  const defaultBackgroundImage$3 = {
@@ -27496,10 +27512,14 @@ const GraphSettings = createReactClass({
27496
27512
  onChange: this.change("markings")
27497
27513
  })), /*#__PURE__*/React.createElement("div", {
27498
27514
  className: "perseus-widget-left-col"
27499
- }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27515
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
27500
27516
  label: "Show tooltips",
27501
- showTooltips: this.props.showTooltips,
27502
- onChange: this.change
27517
+ checked: this.props.showTooltips,
27518
+ onChange: value => {
27519
+ this.change({
27520
+ showTooltips: value
27521
+ });
27522
+ }
27503
27523
  }))), _.contains(this.props.editableSettings, "image") && /*#__PURE__*/React.createElement("div", {
27504
27524
  className: "image-settings"
27505
27525
  }, /*#__PURE__*/React.createElement("div", null, "Background image:"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
@@ -27527,16 +27547,24 @@ const GraphSettings = createReactClass({
27527
27547
  className: "perseus-widget-row"
27528
27548
  }, /*#__PURE__*/React.createElement("div", {
27529
27549
  className: "perseus-widget-left-col"
27530
- }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27550
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
27531
27551
  label: "Show ruler",
27532
- showRuler: this.props.showRuler,
27533
- onChange: this.change
27552
+ checked: this.props.showRuler,
27553
+ onChange: value => {
27554
+ this.change({
27555
+ showRuler: value
27556
+ });
27557
+ }
27534
27558
  })), /*#__PURE__*/React.createElement("div", {
27535
27559
  className: "perseus-widget-right-col"
27536
- }, /*#__PURE__*/React.createElement(PropCheckBox$9, {
27560
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
27537
27561
  label: "Show protractor",
27538
- showProtractor: this.props.showProtractor,
27539
- onChange: this.change
27562
+ checked: this.props.showProtractor,
27563
+ onChange: value => {
27564
+ this.change({
27565
+ showProtractor: value
27566
+ });
27567
+ }
27540
27568
  }))), this.props.showRuler && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Ruler label:", " ", /*#__PURE__*/React.createElement("select", {
27541
27569
  onChange: this.changeRulerLabel,
27542
27570
  value: this.props.rulerLabel
@@ -27736,9 +27764,6 @@ GroupEditor.defaultProps = {
27736
27764
  metadata: undefined
27737
27765
  };
27738
27766
 
27739
- const {
27740
- PropCheckBox: PropCheckBox$8
27741
- } = components;
27742
27767
  /**
27743
27768
  * This is used for editing a name/value pair.
27744
27769
  */
@@ -27860,14 +27885,22 @@ class IframeEditor extends React.Component {
27860
27885
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
27861
27886
  ,
27862
27887
  onChange: this.change("height")
27863
- })), /*#__PURE__*/React.createElement(PropCheckBox$8, {
27888
+ })), /*#__PURE__*/React.createElement(Checkbox$1, {
27864
27889
  label: "Allow full screen",
27865
- allowFullScreen: this.props.allowFullScreen,
27866
- onChange: this.props.onChange
27867
- }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(PropCheckBox$8, {
27890
+ checked: this.props.allowFullScreen,
27891
+ onChange: value => {
27892
+ this.props.onChange({
27893
+ allowFullScreen: value
27894
+ });
27895
+ }
27896
+ }), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(Checkbox$1, {
27868
27897
  label: "Allow iframe content to redirect the page",
27869
- allowTopNavigation: this.props.allowTopNavigation,
27870
- onChange: this.props.onChange
27898
+ checked: this.props.allowTopNavigation,
27899
+ onChange: value => {
27900
+ this.props.onChange({
27901
+ allowTopNavigation: value
27902
+ });
27903
+ }
27871
27904
  }));
27872
27905
  }
27873
27906
  }
@@ -28326,13 +28359,13 @@ function MathquillInput(props) {
28326
28359
  }
28327
28360
  });
28328
28361
  return /*#__PURE__*/React.createElement(View, {
28329
- style: styles$F.outerWrapper
28362
+ style: styles$I.outerWrapper
28330
28363
  }, /*#__PURE__*/React.createElement("span", {
28331
28364
  ref: mathFieldWrapperRef,
28332
28365
  className: "perseus-math-input mq-editable-field mq-math-mode"
28333
28366
  }));
28334
28367
  }
28335
- const styles$F = StyleSheet.create({
28368
+ const styles$I = StyleSheet.create({
28336
28369
  outerWrapper: {
28337
28370
  display: "inline-block",
28338
28371
  borderStyle: "solid",
@@ -29378,16 +29411,16 @@ const LabeledRow = props => {
29378
29411
  style
29379
29412
  } = props;
29380
29413
  return /*#__PURE__*/React.createElement("label", {
29381
- className: css(styles$E.label)
29414
+ className: css(styles$H.label)
29382
29415
  }, /*#__PURE__*/React.createElement(View, {
29383
- style: [styles$E.row, style]
29416
+ style: [styles$H.row, style]
29384
29417
  }, labelSide === "start" || /*#__PURE__*/React.createElement(LabelSmall, {
29385
- style: styles$E.spaceEnd
29418
+ style: styles$H.spaceEnd
29386
29419
  }, label), children, labelSide === "end" && /*#__PURE__*/React.createElement(LabelSmall, {
29387
- style: styles$E.spaceStart
29420
+ style: styles$H.spaceStart
29388
29421
  }, label)));
29389
29422
  };
29390
- const styles$E = StyleSheet.create({
29423
+ const styles$H = StyleSheet.create({
29391
29424
  label: {
29392
29425
  width: "fit-content"
29393
29426
  },
@@ -29464,11 +29497,11 @@ class Spring extends React.Component {
29464
29497
  } = this.props;
29465
29498
  return React.createElement(View, {
29466
29499
  "aria-hidden": "true",
29467
- style: [styles$D.grow, style]
29500
+ style: [styles$G.grow, style]
29468
29501
  });
29469
29502
  }
29470
29503
  }
29471
- const styles$D = StyleSheet.create({
29504
+ const styles$G = StyleSheet.create({
29472
29505
  grow: {
29473
29506
  flexGrow: 1
29474
29507
  }
@@ -29504,11 +29537,11 @@ function Heading({
29504
29537
  onToggle
29505
29538
  }) {
29506
29539
  return /*#__PURE__*/React.createElement(Clickable, {
29507
- style: [styles$C.container, !isCollapsible && styles$C.notClickable],
29540
+ style: [styles$F.container, !isCollapsible && styles$F.notClickable],
29508
29541
  disabled: !isCollapsible,
29509
29542
  onClick: () => isCollapsible && (onToggle == null ? void 0 : onToggle(!isOpen))
29510
29543
  }, () => /*#__PURE__*/React.createElement(View, {
29511
- style: styles$C.heading
29544
+ style: styles$F.heading
29512
29545
  }, /*#__PURE__*/React.createElement(LabelLarge, {
29513
29546
  style: {
29514
29547
  fontSize: 14,
@@ -29518,7 +29551,7 @@ function Heading({
29518
29551
  isExpanded: isOpen
29519
29552
  })));
29520
29553
  }
29521
- const styles$C = StyleSheet.create({
29554
+ const styles$F = StyleSheet.create({
29522
29555
  container: {
29523
29556
  marginTop: spacing.small_12,
29524
29557
  // NOTE(jeremy): This is the inverse of the @editorPadding CSS
@@ -29679,6 +29712,22 @@ function getDefaultGraphStartCoords(graph, range, step) {
29679
29712
  return getQuadraticCoords(_extends({}, graph, {
29680
29713
  startCoords: undefined
29681
29714
  }), range, step);
29715
+ case "point":
29716
+ return getPointCoords(_extends({}, graph, {
29717
+ startCoords: undefined
29718
+ }), range, step);
29719
+ case "polygon":
29720
+ return getPolygonCoords(_extends({}, graph, {
29721
+ startCoords: undefined
29722
+ }), range, step);
29723
+ case "angle":
29724
+ return getAngleCoords({
29725
+ graph: _extends({}, graph, {
29726
+ startCoords: undefined
29727
+ }),
29728
+ range,
29729
+ step
29730
+ });
29682
29731
  default:
29683
29732
  return undefined;
29684
29733
  }
@@ -29710,6 +29759,36 @@ const getQuadraticEquation = startCoords => {
29710
29759
  const c = (p2[0] * p3[0] * (p2[0] - p3[0]) * p1[1] + p3[0] * p1[0] * (p3[0] - p1[0]) * p2[1] + p1[0] * p2[0] * (p1[0] - p2[0]) * p3[1]) / denom;
29711
29760
  return "y = " + a.toFixed(3) + "x^2 + " + b.toFixed(3) + "x + " + c.toFixed(3);
29712
29761
  };
29762
+ const shouldShowStartCoordsUI = (flags, graph) => {
29763
+ var _flags$mafs, _flags$mafs2, _flags$mafs3, _flags$mafs4, _flags$mafs5;
29764
+ // TODO(LEMS-2228): Remove flags once this is fully released
29765
+ const startCoordsUiPhase1Types = ["linear", "linear-system", "ray", "segment", "circle"];
29766
+ const startCoordsUiPhase2Types = ["sinusoid", "quadratic"];
29767
+ const startCoordsPhase1 = flags == null || (_flags$mafs = flags.mafs) == null ? void 0 : _flags$mafs["start-coords-ui-phase-1"];
29768
+ const startCoordsPhase2 = flags == null || (_flags$mafs2 = flags.mafs) == null ? void 0 : _flags$mafs2["start-coords-ui-phase-2"];
29769
+ const startCoordsPoint = flags == null || (_flags$mafs3 = flags.mafs) == null ? void 0 : _flags$mafs3["start-coords-ui-point"];
29770
+ const startCoordsPolygon = flags == null || (_flags$mafs4 = flags.mafs) == null ? void 0 : _flags$mafs4["start-coords-ui-polygon"];
29771
+ const startCoordsAngle = flags == null || (_flags$mafs5 = flags.mafs) == null ? void 0 : _flags$mafs5["start-coords-ui-angle"];
29772
+ if (startCoordsPhase1 && startCoordsUiPhase1Types.includes(graph.type)) {
29773
+ return true;
29774
+ }
29775
+ if (startCoordsPhase2 && startCoordsUiPhase2Types.includes(graph.type)) {
29776
+ return true;
29777
+ }
29778
+ if (startCoordsAngle && graph.type === "angle") {
29779
+ return true;
29780
+ }
29781
+ if (startCoordsPoint && graph.type === "point" && graph.numPoints !== "unlimited") {
29782
+ return true;
29783
+ }
29784
+ if (startCoordsPolygon && graph.type === "polygon" && graph.numSides !== "unlimited" && (
29785
+ // Pre-initialized graph with undefined snapTo value
29786
+ // initializes to snapTo="grid"
29787
+ graph.snapTo === "grid" || graph.snapTo === undefined)) {
29788
+ return true;
29789
+ }
29790
+ return false;
29791
+ };
29713
29792
 
29714
29793
  /**
29715
29794
  * Dropdown for selecting a locked figure to add to an interactive graph.
@@ -29726,17 +29805,17 @@ const LockedFigureSelect = props => {
29726
29805
  const figureTypes = ["point", "line", "vector", "ellipse", "polygon"];
29727
29806
  const figureTypesCurrent = props.showM2bFeatures ? [...figureTypes, "function"] : figureTypes;
29728
29807
  return /*#__PURE__*/React.createElement(View, {
29729
- style: styles$B.container
29808
+ style: styles$E.container
29730
29809
  }, /*#__PURE__*/React.createElement(ActionMenu, {
29731
29810
  menuText: "Add locked figure",
29732
- style: styles$B.addElementSelect
29811
+ style: styles$E.addElementSelect
29733
29812
  }, figureTypesCurrent.map(figureType => /*#__PURE__*/React.createElement(ActionItem, {
29734
29813
  key: `${id}-${figureType}`,
29735
29814
  label: figureType,
29736
29815
  onClick: () => onChange(figureType)
29737
29816
  }))));
29738
29817
  };
29739
- const styles$B = StyleSheet.create({
29818
+ const styles$E = StyleSheet.create({
29740
29819
  container: {
29741
29820
  marginTop: spacing.xSmall_8
29742
29821
  },
@@ -29746,6 +29825,45 @@ const styles$B = StyleSheet.create({
29746
29825
  }
29747
29826
  });
29748
29827
 
29828
+ /**
29829
+ * This is a custom text field of type="number" for use in Perseus Editors.
29830
+ *
29831
+ * This makes it so that the text field's input number updates on scroll
29832
+ * without scrolling the page.
29833
+ *
29834
+ * NOTE 1: Native HTML number inputs do not update the number value on scroll,
29835
+ * they only scroll the page. Inputs in React do NOT work this way (explanation
29836
+ * here: https://stackoverflow.com/a/68266494). By default, scrolling on a
29837
+ * focused number input in React causes BOTH the input value to change AND
29838
+ * the page to scroll. The behavior in this component is an improvement on
29839
+ * the React behavior, but it's the opposite of the native HTML behavior.
29840
+ *
29841
+ * NOTE 2: Firefox seems to have a custom override for this. Even with this
29842
+ * stopPropogation, Firefox matches the native HTML behavior.
29843
+ */
29844
+ const ScrolllessNumberTextField = props => {
29845
+ const inputRef = React.useRef(null);
29846
+ React.useEffect(() => {
29847
+ const ref = inputRef.current;
29848
+
29849
+ // stopPropogation makes it so that the page scroll event is not
29850
+ // triggered when the input is focused and the user scrolls.
29851
+ // The input value will still change on scroll.
29852
+ const ignoreScroll = e => {
29853
+ e.stopPropagation();
29854
+ };
29855
+ ref == null || ref.addEventListener("wheel", ignoreScroll);
29856
+ return () => {
29857
+ ref == null || ref.removeEventListener("wheel", ignoreScroll);
29858
+ };
29859
+ }, [inputRef]);
29860
+ return /*#__PURE__*/React.createElement(TextField, _extends({
29861
+ type: "number"
29862
+ }, props, {
29863
+ ref: inputRef
29864
+ }));
29865
+ };
29866
+
29749
29867
  const AngleInput = props => {
29750
29868
  const {
29751
29869
  angle,
@@ -29767,19 +29885,18 @@ const AngleInput = props => {
29767
29885
  }
29768
29886
  return /*#__PURE__*/React.createElement(LabelMedium, {
29769
29887
  tag: "label",
29770
- style: styles$A.row
29888
+ style: styles$D.row
29771
29889
  }, "angle (degrees)", /*#__PURE__*/React.createElement(Strut, {
29772
29890
  size: spacing.xxSmall_6
29773
- }), /*#__PURE__*/React.createElement(TextField, {
29774
- type: "number",
29891
+ }), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
29775
29892
  value: angleInput,
29776
29893
  onChange: handleAngleChange,
29777
- style: styles$A.textField
29894
+ style: styles$D.textField
29778
29895
  }), /*#__PURE__*/React.createElement(Strut, {
29779
29896
  size: spacing.xxSmall_6
29780
29897
  }));
29781
29898
  };
29782
- const styles$A = StyleSheet.create({
29899
+ const styles$D = StyleSheet.create({
29783
29900
  row: {
29784
29901
  display: "flex",
29785
29902
  flexDirection: "row",
@@ -29828,32 +29945,30 @@ const CoordinatePairInput = props => {
29828
29945
  onChange(newCoords);
29829
29946
  }
29830
29947
  return /*#__PURE__*/React.createElement(View, {
29831
- style: [styles$z.row, style]
29948
+ style: [styles$C.row, style]
29832
29949
  }, /*#__PURE__*/React.createElement(LabelMedium, {
29833
29950
  tag: "label",
29834
- style: styles$z.row
29951
+ style: styles$C.row
29835
29952
  }, labels ? labels[0] : "x coord", /*#__PURE__*/React.createElement(Strut, {
29836
29953
  size: spacing.xxSmall_6
29837
- }), /*#__PURE__*/React.createElement(TextField, {
29838
- type: "number",
29954
+ }), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
29839
29955
  value: coordState[0],
29840
29956
  onChange: newValue => handleCoordChange(newValue, 0),
29841
- style: [styles$z.textField, error ? styles$z.errorField : undefined]
29957
+ style: [styles$C.textField, error ? styles$C.errorField : undefined]
29842
29958
  })), /*#__PURE__*/React.createElement(Strut, {
29843
29959
  size: spacing.medium_16
29844
29960
  }), /*#__PURE__*/React.createElement(LabelMedium, {
29845
29961
  tag: "label",
29846
- style: styles$z.row
29962
+ style: styles$C.row
29847
29963
  }, labels ? labels[1] : "y coord", /*#__PURE__*/React.createElement(Strut, {
29848
29964
  size: spacing.xxSmall_6
29849
- }), /*#__PURE__*/React.createElement(TextField, {
29850
- type: "number",
29965
+ }), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
29851
29966
  value: coordState[1],
29852
29967
  onChange: newValue => handleCoordChange(newValue, 1),
29853
- style: [styles$z.textField, error ? styles$z.errorField : undefined]
29968
+ style: [styles$C.textField, error ? styles$C.errorField : undefined]
29854
29969
  })));
29855
29970
  };
29856
- const styles$z = StyleSheet.create({
29971
+ const styles$C = StyleSheet.create({
29857
29972
  row: {
29858
29973
  display: "flex",
29859
29974
  flexDirection: "row",
@@ -29886,14 +30001,14 @@ const PerseusEditorAccordion = props => {
29886
30001
  }, /*#__PURE__*/React.createElement(AccordionSection, {
29887
30002
  expanded: expanded,
29888
30003
  onToggle: onToggle,
29889
- style: [styles$y.container, containerStyle],
29890
- headerStyle: styles$y.accordionHeader,
30004
+ style: [styles$B.container, containerStyle],
30005
+ headerStyle: styles$B.accordionHeader,
29891
30006
  header: header
29892
30007
  }, /*#__PURE__*/React.createElement(View, {
29893
- style: [styles$y.accordionPanel, panelStyle]
30008
+ style: [styles$B.accordionPanel, panelStyle]
29894
30009
  }, children)));
29895
30010
  };
29896
- const styles$y = StyleSheet.create({
30011
+ const styles$B = StyleSheet.create({
29897
30012
  container: {
29898
30013
  backgroundColor: color.fadedBlue8,
29899
30014
  marginTop: spacing.xSmall_8
@@ -29924,13 +30039,13 @@ const ColorSwatch = props => {
29924
30039
  "aria-label":
29925
30040
  // Don't include an aria label for decorative circles.
29926
30041
  !decorative ? `${color$1}, ${filled ? "filled" : "open"}` : undefined,
29927
- style: [styles$x.colorSwatch, {
30042
+ style: [styles$A.colorSwatch, {
29928
30043
  border: `4px solid ${lockedFigureColors[color$1]}`,
29929
30044
  backgroundColor: filled ? lockedFigureColors[color$1] : color.white
29930
30045
  }]
29931
30046
  });
29932
30047
  };
29933
- const styles$x = StyleSheet.create({
30048
+ const styles$A = StyleSheet.create({
29934
30049
  colorSwatch: {
29935
30050
  // Add a white outline so that the color swatch is visible when
29936
30051
  // the dropdown option is highlighted with its blue background.
@@ -29949,10 +30064,10 @@ const ColorSelect = props => {
29949
30064
  onChange
29950
30065
  } = props;
29951
30066
  return /*#__PURE__*/React.createElement(View, {
29952
- style: [styles$w.row, style]
30067
+ style: [styles$z.row, style]
29953
30068
  }, /*#__PURE__*/React.createElement(LabelMedium, {
29954
30069
  tag: "label",
29955
- style: styles$w.row
30070
+ style: styles$z.row
29956
30071
  }, "color", /*#__PURE__*/React.createElement(Strut, {
29957
30072
  size: spacing.xxSmall_6
29958
30073
  }), /*#__PURE__*/React.createElement(SingleSelect, {
@@ -29971,11 +30086,14 @@ const ColorSelect = props => {
29971
30086
  })
29972
30087
  })))));
29973
30088
  };
29974
- const styles$w = StyleSheet.create({
30089
+ const styles$z = StyleSheet.create({
29975
30090
  row: {
29976
30091
  display: "flex",
29977
30092
  flexDirection: "row",
29978
- alignItems: "center"
30093
+ alignItems: "center",
30094
+ // Set minWidth to "auto" to prevent the component from bleeding
30095
+ // into the margins. (minWidth is 0 by default.)
30096
+ minWidth: "auto"
29979
30097
  }
29980
30098
  });
29981
30099
 
@@ -29987,17 +30105,17 @@ const EllipseSwatch = props => {
29987
30105
  } = props;
29988
30106
  return /*#__PURE__*/React.createElement(View, {
29989
30107
  "aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
29990
- style: [styles$v.container, {
30108
+ style: [styles$y.container, {
29991
30109
  border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
29992
30110
  }]
29993
30111
  }, /*#__PURE__*/React.createElement(View, {
29994
- style: [styles$v.innerCircle, {
30112
+ style: [styles$y.innerCircle, {
29995
30113
  backgroundColor: lockedFigureColors[color],
29996
- opacity: lockedFigureFillStyles[fillStyle]
30114
+ opacity: fillStyle === "white" ? 0 : lockedFigureFillStyles[fillStyle]
29997
30115
  }]
29998
30116
  }));
29999
30117
  };
30000
- const styles$v = StyleSheet.create({
30118
+ const styles$y = StyleSheet.create({
30001
30119
  container: {
30002
30120
  // Add a white outline so that the color swatch is visible when
30003
30121
  // the dropdown option is highlighted with its blue background.
@@ -30016,6 +30134,40 @@ const styles$v = StyleSheet.create({
30016
30134
  }
30017
30135
  });
30018
30136
 
30137
+ const LineStrokeSelect = props => {
30138
+ const {
30139
+ selectedValue,
30140
+ onChange
30141
+ } = props;
30142
+ return /*#__PURE__*/React.createElement(LabelMedium, {
30143
+ tag: "label",
30144
+ style: styles$x.lineStrokeSelect
30145
+ }, "stroke", /*#__PURE__*/React.createElement(Strut, {
30146
+ size: spacing.xxxSmall_4
30147
+ }), /*#__PURE__*/React.createElement(SingleSelect, {
30148
+ selectedValue: selectedValue,
30149
+ onChange: onChange
30150
+ // Placeholder is required, but never gets used.
30151
+ ,
30152
+ placeholder: ""
30153
+ }, /*#__PURE__*/React.createElement(OptionItem, {
30154
+ value: "solid",
30155
+ label: "solid"
30156
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30157
+ value: "dashed",
30158
+ label: "dashed"
30159
+ })));
30160
+ };
30161
+ const styles$x = StyleSheet.create({
30162
+ lineStrokeSelect: {
30163
+ display: "flex",
30164
+ flexDirection: "row",
30165
+ alignItems: "center",
30166
+ // Allow truncation, stop bleeding over the edge.
30167
+ minWidth: 0
30168
+ }
30169
+ });
30170
+
30019
30171
  /**
30020
30172
  * The part of a locked figure settings panel that contains actions
30021
30173
  * for this panel and its associated locked figure, including
@@ -30028,40 +30180,40 @@ const LockedFigureSettingsActions = props => {
30028
30180
  onRemove
30029
30181
  } = props;
30030
30182
  return /*#__PURE__*/React.createElement(View, {
30031
- style: styles$u.container
30183
+ style: styles$w.container
30032
30184
  }, /*#__PURE__*/React.createElement(Button, {
30033
30185
  startIcon: trashIcon,
30034
30186
  "aria-label": `Delete locked ${figureType}`,
30035
30187
  onClick: onRemove,
30036
30188
  kind: "tertiary",
30037
- style: styles$u.deleteButton
30189
+ style: styles$w.deleteButton
30038
30190
  }, "Delete"), /*#__PURE__*/React.createElement(Spring, null), /*#__PURE__*/React.createElement(IconButton, {
30039
30191
  icon: caretDoubleUpIcon,
30040
30192
  size: "small",
30041
30193
  "aria-label": `Move locked ${figureType} to the back`,
30042
30194
  onClick: () => onMove("back"),
30043
- style: styles$u.iconButton
30195
+ style: styles$w.iconButton
30044
30196
  }), /*#__PURE__*/React.createElement(IconButton, {
30045
30197
  icon: caretUpIcon,
30046
30198
  size: "small",
30047
30199
  "aria-label": `Move locked ${figureType} backward`,
30048
30200
  onClick: () => onMove("backward"),
30049
- style: styles$u.iconButton
30201
+ style: styles$w.iconButton
30050
30202
  }), /*#__PURE__*/React.createElement(IconButton, {
30051
30203
  icon: caretDownIcon,
30052
30204
  size: "small",
30053
30205
  "aria-label": `Move locked ${figureType} forward`,
30054
30206
  onClick: () => onMove("forward"),
30055
- style: styles$u.iconButton
30207
+ style: styles$w.iconButton
30056
30208
  }), /*#__PURE__*/React.createElement(IconButton, {
30057
30209
  icon: caretDoubleDownIcon,
30058
30210
  size: "small",
30059
30211
  "aria-label": `Move locked ${figureType} to the front`,
30060
30212
  onClick: () => onMove("front"),
30061
- style: styles$u.iconButton
30213
+ style: styles$w.iconButton
30062
30214
  }));
30063
30215
  };
30064
- const styles$u = StyleSheet.create({
30216
+ const styles$w = StyleSheet.create({
30065
30217
  container: {
30066
30218
  width: "100%",
30067
30219
  flexDirection: "row",
@@ -30108,7 +30260,7 @@ const LockedEllipseSettings = props => {
30108
30260
  /*#__PURE__*/
30109
30261
  // Summary: Ellipse, center, radius, color (opacity, dashed)
30110
30262
  React.createElement(View, {
30111
- style: styles$t.row
30263
+ style: styles$v.row
30112
30264
  }, /*#__PURE__*/React.createElement(LabelLarge, null, `Ellipse (${center[0]}, ${center[1]}), radius ${radius[0]}, ${radius[1]}`), /*#__PURE__*/React.createElement(Strut, {
30113
30265
  size: spacing.xSmall_8
30114
30266
  }), /*#__PURE__*/React.createElement(EllipseSwatch, {
@@ -30117,19 +30269,19 @@ const LockedEllipseSettings = props => {
30117
30269
  strokeStyle: strokeStyle
30118
30270
  }))
30119
30271
  }, /*#__PURE__*/React.createElement(View, {
30120
- style: styles$t.row
30272
+ style: styles$v.row
30121
30273
  }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
30122
30274
  coord: center,
30123
- style: styles$t.spaceUnder,
30275
+ style: styles$v.spaceUnder,
30124
30276
  onChange: newCoords => onChangeProps({
30125
30277
  center: newCoords
30126
30278
  })
30127
30279
  }), /*#__PURE__*/React.createElement(View, {
30128
- style: styles$t.spaceUnder
30280
+ style: styles$v.spaceUnder
30129
30281
  }, /*#__PURE__*/React.createElement(InfoTip$d, null, "The coordinates for the center of the ellipse."))), /*#__PURE__*/React.createElement(CoordinatePairInput, {
30130
30282
  coord: radius,
30131
30283
  labels: ["x radius", "y radius"],
30132
- style: styles$t.spaceUnder,
30284
+ style: styles$v.spaceUnder,
30133
30285
  onChange: newCoords => onChangeProps({
30134
30286
  radius: newCoords
30135
30287
  })
@@ -30141,7 +30293,7 @@ const LockedEllipseSettings = props => {
30141
30293
  }), /*#__PURE__*/React.createElement(Strut, {
30142
30294
  size: spacing.xSmall_8
30143
30295
  }), /*#__PURE__*/React.createElement(View, {
30144
- style: [styles$t.row, styles$t.spaceUnder]
30296
+ style: [styles$v.row, styles$v.spaceUnder]
30145
30297
  }, /*#__PURE__*/React.createElement(ColorSelect, {
30146
30298
  selectedValue: color,
30147
30299
  onChange: handleColorChange
@@ -30149,7 +30301,7 @@ const LockedEllipseSettings = props => {
30149
30301
  size: spacing.medium_16
30150
30302
  }), /*#__PURE__*/React.createElement(LabelMedium, {
30151
30303
  tag: "label",
30152
- style: styles$t.row
30304
+ style: [styles$v.row, styles$v.truncatedWidth]
30153
30305
  }, "fill", /*#__PURE__*/React.createElement(Strut, {
30154
30306
  size: spacing.xxSmall_6
30155
30307
  }), /*#__PURE__*/React.createElement(SingleSelect, {
@@ -30164,25 +30316,200 @@ const LockedEllipseSettings = props => {
30164
30316
  key: option,
30165
30317
  value: option,
30166
30318
  label: option
30167
- }))))), /*#__PURE__*/React.createElement(LabelMedium, {
30168
- tag: "label",
30169
- style: styles$t.row
30170
- }, "stroke", /*#__PURE__*/React.createElement(Strut, {
30171
- size: spacing.xxSmall_6
30172
- }), /*#__PURE__*/React.createElement(SingleSelect, {
30319
+ }))))), /*#__PURE__*/React.createElement(LineStrokeSelect, {
30173
30320
  selectedValue: strokeStyle,
30174
30321
  onChange: value => onChangeProps({
30175
30322
  strokeStyle: value
30176
30323
  })
30324
+ }), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
30325
+ figureType: props.type,
30326
+ onMove: onMove,
30327
+ onRemove: onRemove
30328
+ }));
30329
+ };
30330
+ const styles$v = StyleSheet.create({
30331
+ row: {
30332
+ display: "flex",
30333
+ flexDirection: "row",
30334
+ alignItems: "center"
30335
+ },
30336
+ spaceUnder: {
30337
+ marginBottom: spacing.xSmall_8
30338
+ },
30339
+ truncatedWidth: {
30340
+ // Allow truncation, stop bleeding over the edge.
30341
+ minWidth: 0
30342
+ }
30343
+ });
30344
+
30345
+ const LineSwatch = props => {
30346
+ const {
30347
+ color,
30348
+ lineStyle
30349
+ } = props;
30350
+ return /*#__PURE__*/React.createElement(View, {
30351
+ style: styles$u.container
30352
+ }, /*#__PURE__*/React.createElement(View, {
30353
+ "aria-label": `${color}, ${lineStyle}`,
30354
+ style: [styles$u.lineSwatch, {
30355
+ border: `5px ${lineStyle} ${lockedFigureColors[color]}`
30356
+ }]
30357
+ }));
30358
+ };
30359
+ const styles$u = StyleSheet.create({
30360
+ container: {
30361
+ backgroundColor: color.white,
30362
+ justifyContent: "center",
30363
+ padding: spacing.xSmall_8,
30364
+ borderRadius: spacing.xxxSmall_4
30365
+ },
30366
+ lineSwatch: {
30367
+ width: 40
30368
+ }
30369
+ });
30370
+
30371
+ /**
30372
+ * LockedFunctionSettings is a component that allows the user to edit the
30373
+ * settings of specifically a locked function on the graph.
30374
+ *
30375
+ * Used in the interactive graph editor's locked figures section.
30376
+ */
30377
+ const LockedFunctionSettings = props => {
30378
+ const {
30379
+ color: lineColor,
30380
+ strokeStyle,
30381
+ equation,
30382
+ directionalAxis,
30383
+ domain,
30384
+ onChangeProps,
30385
+ onMove,
30386
+ onRemove
30387
+ } = props;
30388
+ const equationPrefix = directionalAxis === "x" ? "y=" : "x=";
30389
+ const lineLabel = `Function (${equationPrefix}${equation})`;
30390
+
30391
+ // Tracking the string value of domain constraints to handle interim state of
30392
+ // entering a negative value, as well as representing Infinity as an empty string.
30393
+ // This variable is used when specifying the values of the input fields.
30394
+ const [domainEntries, setDomainEntries] = useState([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
30395
+ useEffect(() => {
30396
+ // "useEffect" used to maintain parity between domain constraints and their string representation.
30397
+ setDomainEntries([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
30398
+ }, [domain]);
30399
+
30400
+ // Generic function for handling property changes (except for 'domain')
30401
+ function handlePropChange(property, newValue) {
30402
+ const updatedProps = {};
30403
+ updatedProps[property] = newValue;
30404
+ onChangeProps(updatedProps);
30405
+ }
30406
+
30407
+ /*
30408
+ Reason for having a separate 'propChange' function for 'domain':
30409
+ Domain entries are optional. Their default value is +/- Infinity.
30410
+ Since input fields that are empty evaluate to zero, there needs to be
30411
+ dedicated code to convert empty to Infinity.
30412
+ */
30413
+ function handleDomainChange(limitIndex, newValueString) {
30414
+ const newDomainEntries = [...domainEntries];
30415
+ newDomainEntries[limitIndex] = newValueString;
30416
+ setDomainEntries(newDomainEntries);
30417
+ const newDomain = domain ? [...domain] : [-Infinity, Infinity];
30418
+ let newValue = parseFloat(newValueString);
30419
+ if (newValueString === "" && limitIndex === 0) {
30420
+ newValue = -Infinity;
30421
+ } else if (newValueString === "" && limitIndex === 1) {
30422
+ newValue = Infinity;
30423
+ }
30424
+ newDomain[limitIndex] = newValue;
30425
+ onChangeProps({
30426
+ domain: newDomain
30427
+ });
30428
+ }
30429
+ return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
30430
+ expanded: props.expanded,
30431
+ onToggle: props.onToggle,
30432
+ header: /*#__PURE__*/React.createElement(View, {
30433
+ style: styles$t.row
30434
+ }, /*#__PURE__*/React.createElement(LabelLarge, {
30435
+ style: styles$t.accordionHeader
30436
+ }, lineLabel), /*#__PURE__*/React.createElement(Strut, {
30437
+ size: spacing.xSmall_8
30438
+ }), /*#__PURE__*/React.createElement(LineSwatch, {
30439
+ color: lineColor,
30440
+ lineStyle: strokeStyle
30441
+ }))
30442
+ }, /*#__PURE__*/React.createElement(View, {
30443
+ style: [styles$t.row, styles$t.spaceUnder]
30444
+ }, /*#__PURE__*/React.createElement(ColorSelect, {
30445
+ selectedValue: lineColor,
30446
+ onChange: newValue => {
30447
+ handlePropChange("color", newValue);
30448
+ }
30449
+ }), /*#__PURE__*/React.createElement(Strut, {
30450
+ size: spacing.small_12
30451
+ }), /*#__PURE__*/React.createElement(LineStrokeSelect, {
30452
+ selectedValue: strokeStyle,
30453
+ onChange: newValue => {
30454
+ handlePropChange("strokeStyle", newValue);
30455
+ }
30456
+ })), /*#__PURE__*/React.createElement(View, {
30457
+ style: [styles$t.row, styles$t.rowSpace]
30458
+ }, /*#__PURE__*/React.createElement(SingleSelect, {
30459
+ selectedValue: directionalAxis,
30460
+ onChange: newValue => {
30461
+ handlePropChange("directionalAxis", newValue);
30462
+ },
30463
+ "aria-label": "equation prefix",
30464
+ style: styles$t.equationPrefix
30177
30465
  // Placeholder is required, but never gets used.
30178
30466
  ,
30179
30467
  placeholder: ""
30180
30468
  }, /*#__PURE__*/React.createElement(OptionItem, {
30181
- value: "solid",
30182
- label: "solid"
30469
+ value: "x",
30470
+ label: "y ="
30183
30471
  }), /*#__PURE__*/React.createElement(OptionItem, {
30184
- value: "dashed",
30185
- label: "dashed"
30472
+ value: "y",
30473
+ label: "x ="
30474
+ })), /*#__PURE__*/React.createElement(Strut, {
30475
+ size: spacing.xSmall_8
30476
+ }), /*#__PURE__*/React.createElement(TextField, {
30477
+ type: "text",
30478
+ "aria-label": "equation",
30479
+ value: equation,
30480
+ onChange: newValue => {
30481
+ handlePropChange("equation", newValue);
30482
+ },
30483
+ style: [styles$t.textField]
30484
+ })), /*#__PURE__*/React.createElement(View, {
30485
+ style: [styles$t.row, styles$t.rowSpace]
30486
+ }, /*#__PURE__*/React.createElement(LabelMedium, {
30487
+ tag: "label",
30488
+ style: styles$t.domainMin
30489
+ }, "domain min", /*#__PURE__*/React.createElement(Strut, {
30490
+ size: spacing.xxSmall_6
30491
+ }), /*#__PURE__*/React.createElement(TextField, {
30492
+ type: "number",
30493
+ style: styles$t.domainMinField,
30494
+ value: domainEntries[0],
30495
+ onChange: newValue => {
30496
+ handleDomainChange(0, newValue);
30497
+ }
30498
+ })), /*#__PURE__*/React.createElement(Strut, {
30499
+ size: spacing.medium_16
30500
+ }), /*#__PURE__*/React.createElement(LabelMedium, {
30501
+ tag: "label",
30502
+ "aria-label": "domain max",
30503
+ style: styles$t.domainMax
30504
+ }, "max", /*#__PURE__*/React.createElement(Strut, {
30505
+ size: spacing.xxSmall_6
30506
+ }), /*#__PURE__*/React.createElement(TextField, {
30507
+ type: "number",
30508
+ style: styles$t.domainMaxField,
30509
+ value: domainEntries[1],
30510
+ onChange: newValue => {
30511
+ handleDomainChange(1, newValue);
30512
+ }
30186
30513
  }))), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
30187
30514
  figureType: props.type,
30188
30515
  onMove: onMove,
@@ -30190,13 +30517,57 @@ const LockedEllipseSettings = props => {
30190
30517
  }));
30191
30518
  };
30192
30519
  const styles$t = StyleSheet.create({
30520
+ accordionHeader: {
30521
+ textOverflow: "ellipsis",
30522
+ // A maximum width needs to be specified in order for the ellipsis to work.
30523
+ // The 64px in the calculation accounts for the line swatch (56px) and the preceding strut (8px).
30524
+ // Margin and padding won't work here because they would create space between the header text and the swatch.
30525
+ maxWidth: "calc(100% - 64px)",
30526
+ overflow: "hidden",
30527
+ whiteSpace: "nowrap"
30528
+ },
30529
+ equationPrefix: {
30530
+ minWidth: "auto"
30531
+ },
30532
+ domainMin: {
30533
+ alignItems: "center",
30534
+ display: "flex",
30535
+ // The 'width' property is applied to the label, which wraps the text and the input field.
30536
+ // The width of the input fields (min/max) should be the same (to have a consistent look),
30537
+ // so the following calculation distributes the space accordingly.
30538
+ // For the "domain min" block, the text is 82.7px, and the strut is 6px (88.7px total).
30539
+ // The "domain max" block is 30.23px, and the strut is 6px (36.23px total).
30540
+ // The calculation takes the remain space after the text & struts (141px total) are removed,
30541
+ // and divides it between the two input fields equally.
30542
+ // The calculation reads: "Take 1/2 of the non-text space, and add the required space for this label's text"
30543
+ width: "calc(((100% - 141px) / 2) + 88.7px)",
30544
+ // @ts-expect-error // TS2353: textWrap does not exist in type CSSProperties
30545
+ textWrap: "nowrap"
30546
+ },
30547
+ domainMinField: {
30548
+ width: "calc(100% - 88.7px)" // make room for the label
30549
+ },
30550
+
30551
+ domainMax: {
30552
+ alignItems: "center",
30553
+ display: "flex",
30554
+ // See explanation for "domainMin" for the calculation below.
30555
+ width: "calc(((100% - 141px) / 2) + 36.2px)"
30556
+ },
30557
+ domainMaxField: {
30558
+ width: "calc(100% - 36.2px)" // make room for the label
30559
+ },
30560
+
30561
+ rowSpace: {
30562
+ marginTop: spacing.xSmall_8
30563
+ },
30193
30564
  row: {
30194
30565
  display: "flex",
30195
30566
  flexDirection: "row",
30196
30567
  alignItems: "center"
30197
30568
  },
30198
- spaceUnder: {
30199
- marginBottom: spacing.xSmall_8
30569
+ textField: {
30570
+ flexGrow: "1"
30200
30571
  }
30201
30572
  });
30202
30573
 
@@ -30318,32 +30689,6 @@ const styles$r = StyleSheet.create({
30318
30689
  }
30319
30690
  });
30320
30691
 
30321
- const LineSwatch = props => {
30322
- const {
30323
- color,
30324
- lineStyle
30325
- } = props;
30326
- return /*#__PURE__*/React.createElement(View, {
30327
- style: styles$q.container
30328
- }, /*#__PURE__*/React.createElement(View, {
30329
- "aria-label": `${color}, ${lineStyle}`,
30330
- style: [styles$q.lineSwatch, {
30331
- border: `5px ${lineStyle} ${lockedFigureColors[color]}`
30332
- }]
30333
- }));
30334
- };
30335
- const styles$q = StyleSheet.create({
30336
- container: {
30337
- backgroundColor: color.white,
30338
- justifyContent: "center",
30339
- padding: spacing.xSmall_8,
30340
- borderRadius: spacing.xxxSmall_4
30341
- },
30342
- lineSwatch: {
30343
- width: 40
30344
- }
30345
- });
30346
-
30347
30692
  const lengthZeroStr = "The line cannot have length 0.";
30348
30693
  const LockedLineSettings = props => {
30349
30694
  const {
@@ -30386,7 +30731,7 @@ const LockedLineSettings = props => {
30386
30731
  expanded: props.expanded,
30387
30732
  onToggle: props.onToggle,
30388
30733
  header: /*#__PURE__*/React.createElement(View, {
30389
- style: styles$p.row
30734
+ style: styles$q.row
30390
30735
  }, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
30391
30736
  size: spacing.xSmall_8
30392
30737
  }), /*#__PURE__*/React.createElement(LineSwatch, {
@@ -30395,7 +30740,7 @@ const LockedLineSettings = props => {
30395
30740
  }))
30396
30741
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30397
30742
  tag: "label",
30398
- style: [styles$p.row, styles$p.spaceUnder]
30743
+ style: [styles$q.row, styles$q.spaceUnder]
30399
30744
  }, "kind", /*#__PURE__*/React.createElement(Strut, {
30400
30745
  size: spacing.xxxSmall_4
30401
30746
  }), /*#__PURE__*/React.createElement(SingleSelect, {
@@ -30416,34 +30761,19 @@ const LockedLineSettings = props => {
30416
30761
  value: "segment",
30417
30762
  label: "segment"
30418
30763
  }))), /*#__PURE__*/React.createElement(View, {
30419
- style: styles$p.row
30764
+ style: styles$q.row
30420
30765
  }, /*#__PURE__*/React.createElement(ColorSelect, {
30421
30766
  selectedValue: lineColor,
30422
30767
  onChange: handleColorChange
30423
30768
  }), /*#__PURE__*/React.createElement(Strut, {
30424
30769
  size: spacing.small_12
30425
- }), /*#__PURE__*/React.createElement(LabelMedium, {
30426
- tag: "label",
30427
- style: styles$p.row
30428
- }, "style", /*#__PURE__*/React.createElement(Strut, {
30429
- size: spacing.xxxSmall_4
30430
- }), /*#__PURE__*/React.createElement(SingleSelect, {
30770
+ }), /*#__PURE__*/React.createElement(LineStrokeSelect, {
30431
30771
  selectedValue: lineStyle,
30432
30772
  onChange: value => onChangeProps({
30433
30773
  lineStyle: value
30434
30774
  })
30435
- // Placeholder is required, but never gets used.
30436
- ,
30437
- placeholder: "",
30438
- style: styles$p.selectMarginOffset
30439
- }, /*#__PURE__*/React.createElement(OptionItem, {
30440
- value: "solid",
30441
- label: "solid"
30442
- }), /*#__PURE__*/React.createElement(OptionItem, {
30443
- value: "dashed",
30444
- label: "dashed"
30445
- })))), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
30446
- style: styles$p.errorText
30775
+ })), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
30776
+ style: styles$q.errorText
30447
30777
  }, lengthZeroStr), /*#__PURE__*/React.createElement(DefiningPointSettings, _extends({
30448
30778
  label: "Point 1",
30449
30779
  showPoint: showPoint1,
@@ -30468,7 +30798,7 @@ const LockedLineSettings = props => {
30468
30798
  onRemove: onRemove
30469
30799
  }));
30470
30800
  };
30471
- const styles$p = StyleSheet.create({
30801
+ const styles$q = StyleSheet.create({
30472
30802
  row: {
30473
30803
  display: "flex",
30474
30804
  flexDirection: "row",
@@ -30477,10 +30807,6 @@ const styles$p = StyleSheet.create({
30477
30807
  spaceUnder: {
30478
30808
  marginBottom: spacing.xSmall_8
30479
30809
  },
30480
- selectMarginOffset: {
30481
- // Align with the point settings accordions.
30482
- marginInlineEnd: -spacing.xxxSmall_4
30483
- },
30484
30810
  errorText: {
30485
30811
  color: color.red
30486
30812
  }
@@ -30513,7 +30839,7 @@ const LockedPointSettings = props => {
30513
30839
  /*#__PURE__*/
30514
30840
  // Summary: Point, coords, color (filled/open)
30515
30841
  React.createElement(View, {
30516
- style: styles$o.row
30842
+ style: styles$p.row
30517
30843
  }, /*#__PURE__*/React.createElement(LabelLarge, null, `Point (${coord[0]}, ${coord[1]})`), /*#__PURE__*/React.createElement(Strut, {
30518
30844
  size: spacing.xSmall_8
30519
30845
  }), /*#__PURE__*/React.createElement(ColorSwatch, {
@@ -30522,7 +30848,7 @@ const LockedPointSettings = props => {
30522
30848
  }))
30523
30849
  }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
30524
30850
  coord: coord,
30525
- style: styles$o.spaceUnder,
30851
+ style: styles$p.spaceUnder,
30526
30852
  onChange: newCoord => {
30527
30853
  onChangeProps({
30528
30854
  coord: newCoord
@@ -30531,7 +30857,7 @@ const LockedPointSettings = props => {
30531
30857
  }), /*#__PURE__*/React.createElement(ColorSelect, {
30532
30858
  selectedValue: pointColor,
30533
30859
  onChange: handleColorChange,
30534
- style: styles$o.spaceUnder
30860
+ style: styles$p.spaceUnder
30535
30861
  }), /*#__PURE__*/React.createElement(LabeledSwitch, {
30536
30862
  label: "open point",
30537
30863
  checked: !filled,
@@ -30546,7 +30872,7 @@ const LockedPointSettings = props => {
30546
30872
  onRemove: onRemove
30547
30873
  }));
30548
30874
  };
30549
- const styles$o = StyleSheet.create({
30875
+ const styles$p = StyleSheet.create({
30550
30876
  row: {
30551
30877
  flexDirection: "row",
30552
30878
  alignItems: "center"
@@ -30564,17 +30890,17 @@ const PolygonSwatch = props => {
30564
30890
  } = props;
30565
30891
  return /*#__PURE__*/React.createElement(View, {
30566
30892
  "aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
30567
- style: [styles$n.container, {
30893
+ style: [styles$o.container, {
30568
30894
  border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
30569
30895
  }]
30570
30896
  }, /*#__PURE__*/React.createElement(View, {
30571
- style: [styles$n.innerSquare, {
30897
+ style: [styles$o.innerSquare, {
30572
30898
  backgroundColor: lockedFigureColors[color],
30573
- opacity: lockedFigureFillStyles[fillStyle]
30899
+ opacity: fillStyle === "white" ? 0 : lockedFigureFillStyles[fillStyle]
30574
30900
  }]
30575
30901
  }));
30576
30902
  };
30577
- const styles$n = StyleSheet.create({
30903
+ const styles$o = StyleSheet.create({
30578
30904
  container: {
30579
30905
  // Add a white outline so that the color swatch is visible when
30580
30906
  // the dropdown option is highlighted with its blue background.
@@ -30616,7 +30942,7 @@ const LockedPolygonSettings = props => {
30616
30942
  /*#__PURE__*/
30617
30943
  // Summary: Polygon, number of sides, style swatch
30618
30944
  React.createElement(View, {
30619
- style: styles$m.row
30945
+ style: styles$n.row
30620
30946
  }, /*#__PURE__*/React.createElement(LabelLarge, null, `Polygon, ${points.length} sides`), /*#__PURE__*/React.createElement(Strut, {
30621
30947
  size: spacing.xSmall_8
30622
30948
  }), /*#__PURE__*/React.createElement(PolygonSwatch, {
@@ -30625,7 +30951,7 @@ const LockedPolygonSettings = props => {
30625
30951
  strokeStyle: strokeStyle
30626
30952
  }))
30627
30953
  }, /*#__PURE__*/React.createElement(View, {
30628
- style: [styles$m.row, styles$m.spaceUnder]
30954
+ style: [styles$n.row, styles$n.spaceUnder]
30629
30955
  }, /*#__PURE__*/React.createElement(ColorSelect, {
30630
30956
  selectedValue: color,
30631
30957
  onChange: handleColorChange
@@ -30633,7 +30959,7 @@ const LockedPolygonSettings = props => {
30633
30959
  size: spacing.medium_16
30634
30960
  }), /*#__PURE__*/React.createElement(LabelMedium, {
30635
30961
  tag: "label",
30636
- style: styles$m.row
30962
+ style: [styles$n.row, styles$n.truncatedWidth]
30637
30963
  }, "fill", /*#__PURE__*/React.createElement(Strut, {
30638
30964
  size: spacing.xxSmall_6
30639
30965
  }), /*#__PURE__*/React.createElement(SingleSelect, {
@@ -30648,42 +30974,28 @@ const LockedPolygonSettings = props => {
30648
30974
  key: option,
30649
30975
  value: option,
30650
30976
  label: option
30651
- }))))), /*#__PURE__*/React.createElement(LabelMedium, {
30652
- tag: "label",
30653
- style: [styles$m.row, styles$m.spaceUnder]
30654
- }, "stroke", /*#__PURE__*/React.createElement(Strut, {
30655
- size: spacing.xxSmall_6
30656
- }), /*#__PURE__*/React.createElement(SingleSelect, {
30977
+ }))))), /*#__PURE__*/React.createElement(LineStrokeSelect, {
30657
30978
  selectedValue: strokeStyle,
30658
30979
  onChange: value => onChangeProps({
30659
30980
  strokeStyle: value
30660
30981
  })
30661
- // Placeholder is required, but never gets used.
30662
- ,
30663
- placeholder: ""
30664
- }, /*#__PURE__*/React.createElement(OptionItem, {
30665
- value: "solid",
30666
- label: "solid"
30667
- }), /*#__PURE__*/React.createElement(OptionItem, {
30668
- value: "dashed",
30669
- label: "dashed"
30670
- }))), /*#__PURE__*/React.createElement(LabeledSwitch, {
30982
+ }), /*#__PURE__*/React.createElement(LabeledSwitch, {
30671
30983
  label: "show vertices",
30672
30984
  checked: showVertices,
30673
30985
  onChange: newValue => onChangeProps({
30674
30986
  showVertices: newValue
30675
30987
  }),
30676
- style: styles$m.spaceUnder
30988
+ style: styles$n.spaceUnder
30677
30989
  }), /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
30678
30990
  header: /*#__PURE__*/React.createElement(LabelLarge, null, "Points"),
30679
30991
  expanded: true,
30680
- containerStyle: styles$m.pointAccordionContainer,
30681
- panelStyle: styles$m.pointAccordionPanel
30992
+ containerStyle: styles$n.pointAccordionContainer,
30993
+ panelStyle: styles$n.pointAccordionPanel
30682
30994
  }, points.map((point, index) => {
30683
30995
  const pointLabel = String.fromCharCode(65 + index);
30684
30996
  return /*#__PURE__*/React.createElement(View, {
30685
- key: `locked-polygon-point-${point[0]}-${point[1]}-index-${index}`,
30686
- style: [styles$m.row, styles$m.spaceUnder]
30997
+ key: `locked-polygon-point-index-${index}`,
30998
+ style: [styles$n.row, styles$n.spaceUnder]
30687
30999
  }, /*#__PURE__*/React.createElement(LabelLarge, null, `${pointLabel}:`), /*#__PURE__*/React.createElement(Strut, {
30688
31000
  size: spacing.medium_16
30689
31001
  }), /*#__PURE__*/React.createElement(CoordinatePairInput, {
@@ -30711,7 +31023,7 @@ const LockedPolygonSettings = props => {
30711
31023
  points: newPoints
30712
31024
  });
30713
31025
  },
30714
- style: styles$m.icon
31026
+ style: styles$n.icon
30715
31027
  }));
30716
31028
  }), /*#__PURE__*/React.createElement(Button, {
30717
31029
  kind: "tertiary",
@@ -30727,7 +31039,7 @@ const LockedPolygonSettings = props => {
30727
31039
  onRemove: onRemove
30728
31040
  }));
30729
31041
  };
30730
- const styles$m = StyleSheet.create({
31042
+ const styles$n = StyleSheet.create({
30731
31043
  row: {
30732
31044
  display: "flex",
30733
31045
  flexDirection: "row",
@@ -30744,6 +31056,10 @@ const styles$m = StyleSheet.create({
30744
31056
  },
30745
31057
  spaceUnder: {
30746
31058
  marginBottom: spacing.xSmall_8
31059
+ },
31060
+ truncatedWidth: {
31061
+ // Allow truncation, stop bleeding over the edge.
31062
+ minWidth: 0
30747
31063
  }
30748
31064
  });
30749
31065
 
@@ -30785,7 +31101,7 @@ const LockedVectorSettings = props => {
30785
31101
  expanded: props.expanded,
30786
31102
  onToggle: props.onToggle,
30787
31103
  header: /*#__PURE__*/React.createElement(View, {
30788
- style: styles$l.row
31104
+ style: styles$m.row
30789
31105
  }, /*#__PURE__*/React.createElement(LabelLarge, null, lineLabel), /*#__PURE__*/React.createElement(Strut, {
30790
31106
  size: spacing.xSmall_8
30791
31107
  }), /*#__PURE__*/React.createElement(LineSwatch, {
@@ -30793,19 +31109,19 @@ const LockedVectorSettings = props => {
30793
31109
  lineStyle: "solid"
30794
31110
  }))
30795
31111
  }, /*#__PURE__*/React.createElement(View, {
30796
- style: [styles$l.row, styles$l.spaceUnder]
31112
+ style: [styles$m.row, styles$m.spaceUnder]
30797
31113
  }, /*#__PURE__*/React.createElement(ColorSelect, {
30798
31114
  selectedValue: lineColor,
30799
31115
  onChange: handleColorChange
30800
31116
  })), isInvalid && /*#__PURE__*/React.createElement(LabelMedium, {
30801
- style: styles$l.errorText
31117
+ style: styles$m.errorText
30802
31118
  }, lengthErrorMessage), /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
30803
31119
  expanded: true // Initial state is expanded
30804
31120
  ,
30805
- containerStyle: styles$l.container,
30806
- panelStyle: styles$l.accordionPanel,
31121
+ containerStyle: styles$m.container,
31122
+ panelStyle: styles$m.accordionPanel,
30807
31123
  header: /*#__PURE__*/React.createElement(View, {
30808
- style: styles$l.row
31124
+ style: styles$m.row
30809
31125
  }, /*#__PURE__*/React.createElement(LabelLarge, null, `Tail (${tail[0]}, ${tail[1]})`))
30810
31126
  }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
30811
31127
  coord: tail,
@@ -30816,10 +31132,10 @@ const LockedVectorSettings = props => {
30816
31132
  })), /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
30817
31133
  expanded: true // Initial state is expanded
30818
31134
  ,
30819
- containerStyle: styles$l.container,
30820
- panelStyle: styles$l.accordionPanel,
31135
+ containerStyle: styles$m.container,
31136
+ panelStyle: styles$m.accordionPanel,
30821
31137
  header: /*#__PURE__*/React.createElement(View, {
30822
- style: styles$l.row
31138
+ style: styles$m.row
30823
31139
  }, /*#__PURE__*/React.createElement(LabelLarge, null, `Tip (${tip[0]}, ${tip[1]})`))
30824
31140
  }, /*#__PURE__*/React.createElement(CoordinatePairInput, {
30825
31141
  coord: tip,
@@ -30833,7 +31149,7 @@ const LockedVectorSettings = props => {
30833
31149
  onRemove: onRemove
30834
31150
  }));
30835
31151
  };
30836
- const styles$l = StyleSheet.create({
31152
+ const styles$m = StyleSheet.create({
30837
31153
  accordionPanel: {
30838
31154
  paddingBottom: spacing.medium_16
30839
31155
  },
@@ -30875,6 +31191,11 @@ const LockedFigureSettings = props => {
30875
31191
  return /*#__PURE__*/React.createElement(LockedEllipseSettings, props);
30876
31192
  case "polygon":
30877
31193
  return /*#__PURE__*/React.createElement(LockedPolygonSettings, props);
31194
+ case "function":
31195
+ if (props.showM2bFeatures) {
31196
+ return /*#__PURE__*/React.createElement(LockedFunctionSettings, props);
31197
+ }
31198
+ break;
30878
31199
  }
30879
31200
  return null;
30880
31201
  };
@@ -30978,12 +31299,6 @@ const LockedFiguresSection = props => {
30978
31299
  onToggle: () => setIsExpanded(!isExpanded),
30979
31300
  isCollapsible: true
30980
31301
  }), isExpanded && /*#__PURE__*/React.createElement(View, null, figures == null ? void 0 : figures.map((figure, index) => {
30981
- if (figure.type === "function") {
30982
- // TODO(LEMS-1947): Add locked function settings.
30983
- // Remove this block once function locked figure settings are
30984
- // implemented.
30985
- return;
30986
- }
30987
31302
  return /*#__PURE__*/React.createElement(LockedFigureSettings, _extends({
30988
31303
  key: `${uniqueId}-locked-${figure}-${index}`,
30989
31304
  showM2bFeatures: props.showM2bFeatures,
@@ -30999,7 +31314,7 @@ const LockedFiguresSection = props => {
30999
31314
  onRemove: () => removeLockedFigure(index)
31000
31315
  }));
31001
31316
  }), /*#__PURE__*/React.createElement(View, {
31002
- style: styles$k.buttonContainer
31317
+ style: styles$l.buttonContainer
31003
31318
  }, /*#__PURE__*/React.createElement(LockedFigureSelect, {
31004
31319
  showM2bFeatures: props.showM2bFeatures,
31005
31320
  id: `${uniqueId}-select`,
@@ -31009,10 +31324,10 @@ const LockedFiguresSection = props => {
31009
31324
  }), showExpandButton && /*#__PURE__*/React.createElement(Button, {
31010
31325
  kind: "secondary",
31011
31326
  onClick: () => toggleExpanded(allCollapsed),
31012
- style: styles$k.button
31327
+ style: styles$l.button
31013
31328
  }, buttonLabel))));
31014
31329
  };
31015
- const styles$k = StyleSheet.create({
31330
+ const styles$l = StyleSheet.create({
31016
31331
  buttonContainer: {
31017
31332
  flexDirection: "row",
31018
31333
  alignItems: "center"
@@ -31047,7 +31362,7 @@ const GraphPointsCountSelector = ({
31047
31362
  // Never uses placeholder, always has value
31048
31363
  ,
31049
31364
  placeholder: "",
31050
- style: styles$j.singleSelectShort
31365
+ style: styles$k.singleSelectShort
31051
31366
  }, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
31052
31367
  key: n,
31053
31368
  value: `${n}`,
@@ -31058,7 +31373,7 @@ const GraphPointsCountSelector = ({
31058
31373
  label: "unlimited"
31059
31374
  })]);
31060
31375
  };
31061
- const styles$j = StyleSheet.create({
31376
+ const styles$k = StyleSheet.create({
31062
31377
  singleSelectShort: {
31063
31378
  // Non-standard spacing, but it's the smallest we can go
31064
31379
  // without running into styling issues with the dropdown.
@@ -31071,7 +31386,7 @@ const GraphTypeSelector = props => {
31071
31386
  selectedValue: props.graphType,
31072
31387
  onChange: props.onChange,
31073
31388
  placeholder: "Select a graph type",
31074
- style: styles$i.singleSelectShort
31389
+ style: styles$j.singleSelectShort
31075
31390
  }, /*#__PURE__*/React.createElement(OptionItem, {
31076
31391
  value: "linear",
31077
31392
  label: "Linear function"
@@ -31104,7 +31419,7 @@ const GraphTypeSelector = props => {
31104
31419
  label: "Angle"
31105
31420
  }));
31106
31421
  };
31107
- const styles$i = StyleSheet.create({
31422
+ const styles$j = StyleSheet.create({
31108
31423
  singleSelectShort: {
31109
31424
  // Non-standard spacing, but it's the smallest we can go
31110
31425
  // without running into styling issues with the dropdown.
@@ -31138,7 +31453,6 @@ function InteractiveGraphCorrectAnswer(props) {
31138
31453
  const {
31139
31454
  ButtonGroup: ButtonGroup$2,
31140
31455
  InfoTip: InfoTip$c,
31141
- PropCheckBox: PropCheckBox$7,
31142
31456
  RangeInput: RangeInput$4
31143
31457
  } = components;
31144
31458
  const defaultBackgroundImage$1 = {
@@ -31502,16 +31816,20 @@ class InteractiveGraphSettings extends React.Component {
31502
31816
  onChange: this.change("markings")
31503
31817
  }))), /*#__PURE__*/React.createElement("div", {
31504
31818
  className: "perseus-widget-left-col"
31505
- }, /*#__PURE__*/React.createElement(PropCheckBox$7, {
31819
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
31506
31820
  label: "Show tooltips",
31507
- showTooltips: this.props.showTooltips,
31508
- onChange: this.change
31821
+ checked: this.props.showTooltips,
31822
+ onChange: value => {
31823
+ this.change({
31824
+ showTooltips: value
31825
+ });
31826
+ }
31509
31827
  }))), /*#__PURE__*/React.createElement(LabeledRow, {
31510
31828
  label: "Background image URL:",
31511
- style: styles$h.resetSpaceTop
31829
+ style: styles$i.resetSpaceTop
31512
31830
  }, /*#__PURE__*/React.createElement("input", {
31513
31831
  type: "text",
31514
- className: css(styles$h.backgroundUrlInput),
31832
+ className: css(styles$i.backgroundUrlInput),
31515
31833
  ref: this.bgUrlRef,
31516
31834
  value: this.state.backgroundImage.url || "",
31517
31835
  onChange: e => {
@@ -31525,14 +31843,18 @@ class InteractiveGraphSettings extends React.Component {
31525
31843
  onKeyPress: this.changeBackgroundUrl,
31526
31844
  onBlur: this.changeBackgroundUrl
31527
31845
  }), /*#__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, {
31528
- style: styles$h.protractorSection
31846
+ style: styles$i.protractorSection
31529
31847
  }, /*#__PURE__*/React.createElement(View, {
31530
- style: styles$h.checkboxRow
31531
- }, /*#__PURE__*/React.createElement(PropCheckBox$7, {
31848
+ style: styles$i.checkboxRow
31849
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
31532
31850
  label: "Show protractor",
31533
- showProtractor: this.props.showProtractor,
31534
- onChange: this.change,
31535
- style: styles$h.resetSpaceTop
31851
+ checked: this.props.showProtractor,
31852
+ onChange: value => {
31853
+ this.change({
31854
+ showProtractor: value
31855
+ });
31856
+ },
31857
+ style: styles$i.resetSpaceTop
31536
31858
  })), this.props.showProtractor && /*#__PURE__*/React.createElement(Banner, {
31537
31859
  layout: "floating",
31538
31860
  text: "The protractor is not accessible. Please consider an alternate approach.",
@@ -31553,7 +31875,7 @@ InteractiveGraphSettings.defaultProps = {
31553
31875
  showProtractor: false,
31554
31876
  showTooltips: false
31555
31877
  };
31556
- const styles$h = StyleSheet.create({
31878
+ const styles$i = StyleSheet.create({
31557
31879
  resetSpaceTop: {
31558
31880
  marginTop: 0
31559
31881
  },
@@ -31590,13 +31912,13 @@ const SegmentCountSelector = ({
31590
31912
  const num = +newValue;
31591
31913
  onChange(num);
31592
31914
  },
31593
- style: styles$g.singleSelectShort
31915
+ style: styles$h.singleSelectShort
31594
31916
  }, _.range(1, 7).map(n => /*#__PURE__*/React.createElement(OptionItem, {
31595
31917
  key: n,
31596
31918
  value: `${n}`,
31597
31919
  label: `${n} segment${n > 1 ? "s" : ""}`
31598
31920
  })));
31599
- const styles$g = StyleSheet.create({
31921
+ const styles$h = StyleSheet.create({
31600
31922
  singleSelectShort: {
31601
31923
  // Non-standard spacing, but it's the smallest we can go
31602
31924
  // without running into styling issues with the dropdown.
@@ -31604,15 +31926,26 @@ const styles$g = StyleSheet.create({
31604
31926
  }
31605
31927
  });
31606
31928
 
31929
+ const StartCoordsAngle = props => {
31930
+ const {
31931
+ startCoords
31932
+ } = props;
31933
+ return /*#__PURE__*/React.createElement(View, null, "WIP", /*#__PURE__*/React.createElement("br", null), " Start coords:", startCoords.map((coord, index) => {
31934
+ return /*#__PURE__*/React.createElement(View, {
31935
+ key: index
31936
+ }, `Point ${index + 1}: (${coord[0]}, ${coord[1]})`);
31937
+ }));
31938
+ };
31939
+
31607
31940
  const StartCoordsCircle = props => {
31608
31941
  const {
31609
31942
  startCoords,
31610
31943
  onChange
31611
31944
  } = props;
31612
31945
  return /*#__PURE__*/React.createElement(View, {
31613
- style: styles$f.tile
31946
+ style: styles$g.tile
31614
31947
  }, /*#__PURE__*/React.createElement(View, {
31615
- style: styles$f.row
31948
+ style: styles$g.row
31616
31949
  }, /*#__PURE__*/React.createElement(LabelLarge, null, "Center:"), /*#__PURE__*/React.createElement(Strut, {
31617
31950
  size: spacing.small_12
31618
31951
  }), /*#__PURE__*/React.createElement(CoordinatePairInput, {
@@ -31625,22 +31958,21 @@ const StartCoordsCircle = props => {
31625
31958
  })), /*#__PURE__*/React.createElement(Strut, {
31626
31959
  size: spacing.small_12
31627
31960
  }), /*#__PURE__*/React.createElement(View, {
31628
- style: styles$f.row
31961
+ style: styles$g.row
31629
31962
  }, /*#__PURE__*/React.createElement(LabelLarge, null, "Radius:"), /*#__PURE__*/React.createElement(Strut, {
31630
31963
  size: spacing.small_12
31631
- }), /*#__PURE__*/React.createElement(TextField, {
31964
+ }), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
31632
31965
  value: startCoords.radius.toString(),
31633
- type: "number",
31634
31966
  onChange: value => {
31635
31967
  onChange({
31636
31968
  center: startCoords.center,
31637
31969
  radius: parseFloat(value)
31638
31970
  });
31639
31971
  },
31640
- style: styles$f.textField
31972
+ style: styles$g.textField
31641
31973
  })));
31642
31974
  };
31643
- const styles$f = StyleSheet.create({
31975
+ const styles$g = StyleSheet.create({
31644
31976
  tile: {
31645
31977
  backgroundColor: color.fadedBlue8,
31646
31978
  marginTop: spacing.xSmall_8,
@@ -31662,7 +31994,7 @@ const StartCoordsLine = props => {
31662
31994
  onChange
31663
31995
  } = props;
31664
31996
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
31665
- style: styles$e.tile
31997
+ style: styles$f.tile
31666
31998
  }, /*#__PURE__*/React.createElement(LabelLarge, null, "Point 1:"), /*#__PURE__*/React.createElement(Strut, {
31667
31999
  size: spacing.small_12
31668
32000
  }), /*#__PURE__*/React.createElement(CoordinatePairInput, {
@@ -31670,7 +32002,7 @@ const StartCoordsLine = props => {
31670
32002
  labels: ["x", "y"],
31671
32003
  onChange: value => onChange([value, startCoords[1]])
31672
32004
  })), /*#__PURE__*/React.createElement(View, {
31673
- style: styles$e.tile
32005
+ style: styles$f.tile
31674
32006
  }, /*#__PURE__*/React.createElement(LabelLarge, null, "Point 2:"), /*#__PURE__*/React.createElement(Strut, {
31675
32007
  size: spacing.small_12
31676
32008
  }), /*#__PURE__*/React.createElement(CoordinatePairInput, {
@@ -31679,7 +32011,7 @@ const StartCoordsLine = props => {
31679
32011
  onChange: value => onChange([startCoords[0], value])
31680
32012
  })));
31681
32013
  };
31682
- const styles$e = StyleSheet.create({
32014
+ const styles$f = StyleSheet.create({
31683
32015
  tile: {
31684
32016
  backgroundColor: color.fadedBlue8,
31685
32017
  marginTop: spacing.xSmall_8,
@@ -31702,7 +32034,7 @@ const StartCoordsMultiline = props => {
31702
32034
  header: /*#__PURE__*/React.createElement(LabelLarge, null, `${graphName} ${i + 1}`),
31703
32035
  expanded: true
31704
32036
  }, /*#__PURE__*/React.createElement(View, {
31705
- style: styles$d.nestedTile
32037
+ style: styles$e.nestedTile
31706
32038
  }, /*#__PURE__*/React.createElement(LabelLarge, null, "Point 1:"), /*#__PURE__*/React.createElement(Strut, {
31707
32039
  size: spacing.small_12
31708
32040
  }), /*#__PURE__*/React.createElement(CoordinatePairInput, {
@@ -31714,7 +32046,7 @@ const StartCoordsMultiline = props => {
31714
32046
  onChange(newCoords);
31715
32047
  }
31716
32048
  })), /*#__PURE__*/React.createElement(View, {
31717
- style: styles$d.nestedTile
32049
+ style: styles$e.nestedTile
31718
32050
  }, /*#__PURE__*/React.createElement(LabelLarge, null, "Point 2:"), /*#__PURE__*/React.createElement(Strut, {
31719
32051
  size: spacing.small_12
31720
32052
  }), /*#__PURE__*/React.createElement(CoordinatePairInput, {
@@ -31727,7 +32059,7 @@ const StartCoordsMultiline = props => {
31727
32059
  }
31728
32060
  })))));
31729
32061
  };
31730
- const styles$d = StyleSheet.create({
32062
+ const styles$e = StyleSheet.create({
31731
32063
  nestedTile: {
31732
32064
  paddingBottom: spacing.small_12,
31733
32065
  flexDirection: "row",
@@ -31735,6 +32067,39 @@ const styles$d = StyleSheet.create({
31735
32067
  }
31736
32068
  });
31737
32069
 
32070
+ const StartCoordsPoint = props => {
32071
+ const {
32072
+ startCoords,
32073
+ onChange
32074
+ } = props;
32075
+ return /*#__PURE__*/React.createElement(React.Fragment, null, startCoords.map((coord, index) => {
32076
+ return /*#__PURE__*/React.createElement(View, {
32077
+ key: index,
32078
+ style: styles$d.tile
32079
+ }, /*#__PURE__*/React.createElement(LabelLarge, null, `Point ${index + 1}:`), /*#__PURE__*/React.createElement(Strut, {
32080
+ size: spacing.small_12
32081
+ }), /*#__PURE__*/React.createElement(CoordinatePairInput, {
32082
+ coord: coord,
32083
+ labels: ["x", "y"],
32084
+ onChange: newCoord => {
32085
+ const newStartCoords = [...startCoords];
32086
+ newStartCoords[index] = newCoord;
32087
+ onChange(newStartCoords);
32088
+ }
32089
+ }));
32090
+ }));
32091
+ };
32092
+ const styles$d = StyleSheet.create({
32093
+ tile: {
32094
+ backgroundColor: color.fadedBlue8,
32095
+ marginTop: spacing.xSmall_8,
32096
+ padding: spacing.small_12,
32097
+ borderRadius: spacing.xSmall_8,
32098
+ flexDirection: "row",
32099
+ alignItems: "center"
32100
+ }
32101
+ });
32102
+
31738
32103
  const StartCoordsQuadratic = props => {
31739
32104
  const {
31740
32105
  startCoords,
@@ -31893,6 +32258,24 @@ const StartCoordsSettingsInner = props => {
31893
32258
  startCoords: quadraticCoords,
31894
32259
  onChange: onChange
31895
32260
  });
32261
+ // Graphs with startCoords of type ReadonlyArray<Coord>
32262
+ case "point":
32263
+ case "polygon":
32264
+ const pointCoords = type === "point" ? getPointCoords(props, range, step) : getPolygonCoords(props, range, step);
32265
+ return /*#__PURE__*/React.createElement(StartCoordsPoint, {
32266
+ startCoords: pointCoords,
32267
+ onChange: onChange
32268
+ });
32269
+ case "angle":
32270
+ const angleCoords = getAngleCoords({
32271
+ graph: props,
32272
+ range,
32273
+ step
32274
+ });
32275
+ return /*#__PURE__*/React.createElement(StartCoordsAngle, {
32276
+ startCoords: angleCoords,
32277
+ onChange: onChange
32278
+ });
31896
32279
  default:
31897
32280
  return null;
31898
32281
  }
@@ -31947,10 +32330,6 @@ const POLYGON_SIDES = _.map(_.range(3, 13), function (value) {
31947
32330
  label: `${value} sides`
31948
32331
  });
31949
32332
  });
31950
-
31951
- // TODO(LEMS-2228): Remove flags once this is fully released
31952
- const startCoordsUiPhase1Types = ["linear", "linear-system", "ray", "segment", "circle"];
31953
- const startCoordsUiPhase2Types = ["sinusoid", "quadratic"];
31954
32333
  /**
31955
32334
  * An editor for the InteractiveGraph widget, which allows the user to
31956
32335
  * specify the graph's properties and the correct answer.
@@ -32002,7 +32381,7 @@ class InteractiveGraphEditor extends React.Component {
32002
32381
  DeprecationMixin.UNSAFE_componentWillMount.call(this);
32003
32382
  }
32004
32383
  render() {
32005
- var _this$props$apiOption, _this$props$apiOption2, _this$props$graph$typ, _this$props$graph2, _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$graph5, _this$props$apiOption3, _this$props$apiOption4;
32384
+ var _this$props$graph$typ, _this$props$graph2, _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$graph5, _this$props$apiOption, _this$props$apiOption2;
32006
32385
  let graph;
32007
32386
  let equationString;
32008
32387
  const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, interactiveSizes.defaultBoxSize);
@@ -32063,9 +32442,6 @@ class InteractiveGraphEditor extends React.Component {
32063
32442
  className: "perseus-error"
32064
32443
  }, this.props.valid);
32065
32444
  }
32066
- const startCoordsPhase1 = (_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["start-coords-ui-phase-1"];
32067
- const startCoordsPhase2 = (_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["start-coords-ui-phase-2"];
32068
- const displayStartCoordsUI = this.props.graph && (startCoordsPhase1 && startCoordsUiPhase1Types.includes(this.props.graph.type) || startCoordsPhase2 && startCoordsUiPhase2Types.includes(this.props.graph.type));
32069
32445
  return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(LabeledRow, {
32070
32446
  label: "Type of Graph:"
32071
32447
  }, /*#__PURE__*/React.createElement(GraphTypeSelector, {
@@ -32136,7 +32512,8 @@ class InteractiveGraphEditor extends React.Component {
32136
32512
  coords: null
32137
32513
  });
32138
32514
  this.props.onChange({
32139
- correct: graph
32515
+ correct: graph,
32516
+ graph: graph
32140
32517
  });
32141
32518
  },
32142
32519
  style: styles$a.singleSelectShort
@@ -32208,7 +32585,7 @@ class InteractiveGraphEditor extends React.Component {
32208
32585
  }
32209
32586
  })), ((_this$props$graph5 = this.props.graph) == null ? void 0 : _this$props$graph5.type) &&
32210
32587
  // TODO(LEMS-2228): Remove flags once this is fully released
32211
- displayStartCoordsUI && /*#__PURE__*/React.createElement(StartCoordsSettings, _extends({}, this.props.graph, {
32588
+ shouldShowStartCoordsUI(this.props.apiOptions.flags, this.props.graph) && /*#__PURE__*/React.createElement(StartCoordsSettings, _extends({}, this.props.graph, {
32212
32589
  range: this.props.range,
32213
32590
  step: this.props.step,
32214
32591
  onChange: this.changeStartCoords
@@ -32264,8 +32641,8 @@ class InteractiveGraphEditor extends React.Component {
32264
32641
  })), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position."))),
32265
32642
  // Only show the "Add locked figure" dropdown if the graph
32266
32643
  // is using Mafs.
32267
- this.props.graph && ((_this$props$apiOption3 = this.props.apiOptions) == null || (_this$props$apiOption3 = _this$props$apiOption3.flags) == null || (_this$props$apiOption3 = _this$props$apiOption3.mafs) == null ? void 0 : _this$props$apiOption3[this.props.graph.type]) && /*#__PURE__*/React.createElement(LockedFiguresSection, {
32268
- showM2bFeatures: (_this$props$apiOption4 = this.props.apiOptions) == null || (_this$props$apiOption4 = _this$props$apiOption4.flags) == null || (_this$props$apiOption4 = _this$props$apiOption4.mafs) == null ? void 0 : _this$props$apiOption4["interactive-graph-locked-features-m2b"],
32644
+ 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, {
32645
+ showM2bFeatures: (_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-m2b"],
32269
32646
  figures: this.props.lockedFigures,
32270
32647
  onChange: this.props.onChange
32271
32648
  }));
@@ -33784,7 +34161,6 @@ const styles = StyleSheet.create({
33784
34161
  /* eslint-disable react/forbid-prop-types, react/sort-comp */
33785
34162
  const {
33786
34163
  InfoTip: InfoTip$a,
33787
- PropCheckBox: PropCheckBox$6,
33788
34164
  TextListEditor: TextListEditor$3
33789
34165
  } = components;
33790
34166
  class MatcherEditor extends React.Component {
@@ -33840,14 +34216,22 @@ class MatcherEditor extends React.Component {
33840
34216
  // eslint-disable-next-line react/jsx-no-bind
33841
34217
  ,
33842
34218
  onChange: this.onLabelChange.bind(this, 1)
33843
- })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$6, {
34219
+ })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Checkbox$1, {
33844
34220
  label: "Order of the matched pairs matters:",
33845
- orderMatters: this.props.orderMatters,
33846
- onChange: this.props.onChange
33847
- }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."), /*#__PURE__*/React.createElement("p", null, "If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox$6, {
34221
+ checked: this.props.orderMatters,
34222
+ onChange: value => {
34223
+ this.props.onChange({
34224
+ orderMatters: value
34225
+ });
34226
+ }
34227
+ }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "With this option enabled, only the order provided above will be treated as correct. This is useful when ordering is significant, such as in the context of a proof."), /*#__PURE__*/React.createElement("p", null, "If disabled, pairwise matching is sufficient. To make this clear, the left column becomes fixed in the provided order and only the cards in the right column can be moved."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Checkbox$1, {
33848
34228
  label: "Padding:",
33849
- padding: this.props.padding,
33850
- onChange: this.props.onChange
34229
+ checked: this.props.padding,
34230
+ onChange: value => {
34231
+ this.props.onChange({
34232
+ padding: value
34233
+ });
34234
+ }
33851
34235
  }), /*#__PURE__*/React.createElement(InfoTip$a, null, /*#__PURE__*/React.createElement("p", null, "Padding is good for text, but not needed for images."))));
33852
34236
  }
33853
34237
  }
@@ -33993,7 +34377,6 @@ MatrixEditor.defaultProps = {
33993
34377
  const {
33994
34378
  InfoTip: InfoTip$9,
33995
34379
  NumberInput: NumberInput$7,
33996
- PropCheckBox: PropCheckBox$5,
33997
34380
  RangeInput: RangeInput$2
33998
34381
  } = components;
33999
34382
  const defaultImage = {
@@ -34074,16 +34457,24 @@ class MeasurerEditor extends React.Component {
34074
34457
  className: "perseus-widget-row"
34075
34458
  }, /*#__PURE__*/React.createElement("div", {
34076
34459
  className: "perseus-widget-left-col"
34077
- }, /*#__PURE__*/React.createElement(PropCheckBox$5, {
34460
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
34078
34461
  label: "Show ruler",
34079
- showRuler: this.props.showRuler,
34080
- onChange: this.props.onChange
34462
+ checked: this.props.showRuler,
34463
+ onChange: value => {
34464
+ this.props.onChange({
34465
+ showRuler: value
34466
+ });
34467
+ }
34081
34468
  })), /*#__PURE__*/React.createElement("div", {
34082
34469
  className: "perseus-widget-right-col"
34083
- }, /*#__PURE__*/React.createElement(PropCheckBox$5, {
34470
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
34084
34471
  label: "Show protractor",
34085
- showProtractor: this.props.showProtractor,
34086
- onChange: this.props.onChange
34472
+ checked: this.props.showProtractor,
34473
+ onChange: value => {
34474
+ this.props.onChange({
34475
+ showProtractor: value
34476
+ });
34477
+ }
34087
34478
  }))), this.props.showRuler && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Ruler label:", " ", /*#__PURE__*/React.createElement("select", {
34088
34479
  onChange: e =>
34089
34480
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 2.
@@ -34195,7 +34586,6 @@ const {
34195
34586
  ButtonGroup: ButtonGroup$1,
34196
34587
  InfoTip: InfoTip$8,
34197
34588
  NumberInput: NumberInput$5,
34198
- PropCheckBox: PropCheckBox$4,
34199
34589
  RangeInput: RangeInput$1
34200
34590
  } = components;
34201
34591
  const bound = (x, gt, lt) => Math.min(Math.max(x, gt), lt);
@@ -34406,22 +34796,34 @@ class NumberLineEditor extends React.Component {
34406
34796
  className: "perseus-widget-row"
34407
34797
  }, !this.props.static && /*#__PURE__*/React.createElement("div", {
34408
34798
  className: "perseus-widget-left-col"
34409
- }, /*#__PURE__*/React.createElement(PropCheckBox$4, {
34799
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
34410
34800
  label: "Show tick controller",
34411
- isTickCtrl: this.props.isTickCtrl,
34412
- onChange: this.props.onChange
34801
+ checked: this.props.isTickCtrl,
34802
+ onChange: value => {
34803
+ this.props.onChange({
34804
+ isTickCtrl: value
34805
+ });
34806
+ }
34413
34807
  })), /*#__PURE__*/React.createElement("div", {
34414
34808
  className: "perseus-widget-right-col"
34415
- }, /*#__PURE__*/React.createElement(PropCheckBox$4, {
34809
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
34416
34810
  label: "Show label ticks",
34417
- labelTicks: this.props.labelTicks,
34418
- onChange: this.props.onChange
34811
+ checked: this.props.labelTicks,
34812
+ onChange: value => {
34813
+ this.props.onChange({
34814
+ labelTicks: value
34815
+ });
34816
+ }
34419
34817
  }))), /*#__PURE__*/React.createElement("div", {
34420
34818
  className: "perseus-widget-row"
34421
- }, !this.props.static && /*#__PURE__*/React.createElement(PropCheckBox$4, {
34819
+ }, !this.props.static && /*#__PURE__*/React.createElement(Checkbox$1, {
34422
34820
  label: "Show tooltips",
34423
- showTooltips: this.props.showTooltips,
34424
- onChange: this.props.onChange
34821
+ checked: this.props.showTooltips,
34822
+ onChange: value => {
34823
+ this.props.onChange({
34824
+ showTooltips: value
34825
+ });
34826
+ }
34425
34827
  })), /*#__PURE__*/React.createElement("div", {
34426
34828
  className: "perseus-widget-row"
34427
34829
  }, isTickCtrl && /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("label", null, "Start num divisions at", " ", /*#__PURE__*/React.createElement(NumberInput$5, {
@@ -34504,7 +34906,6 @@ const {
34504
34906
  InlineIcon: InlineIcon$1,
34505
34907
  MultiButtonGroup,
34506
34908
  NumberInput: NumberInput$4,
34507
- PropCheckBox: PropCheckBox$3,
34508
34909
  TextInput: TextInput$3
34509
34910
  } = components;
34510
34911
  const {
@@ -34676,12 +35077,14 @@ class NumericInputEditor extends React.Component {
34676
35077
  onChange: this.updateAnswer(i, "answerForms") || (() => {})
34677
35078
  }), /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "Formats will be autoselected for you based on the given answer; to show no suggested formats and accept all types, simply have a decimal/integer be the answer. Values with \u03C0 will have format \"pi\", and values that are fractions will have some subset (mixed will be \"mixed\" and \"proper\"; improper/proper will both be \"improper\" and \"proper\"). If you would like to specify that it is only a proper fraction (or only a mixed/improper fraction), deselect the other format. Except for specific cases, you should not need to change the autoselected formats."), /*#__PURE__*/React.createElement("p", null, "To restrict the answer to ", /*#__PURE__*/React.createElement("em", null, "only"), " an improper fraction (i.e. 7/4), select the improper fraction and toggle \"strict\" to true. This ", /*#__PURE__*/React.createElement("b", null, "will not"), " ", "accept 1.75 as an answer.", " "), /*#__PURE__*/React.createElement("p", null, "Unless you are testing that specific skill, please do not restrict the answer format."))), /*#__PURE__*/React.createElement("div", {
34678
35079
  className: "perseus-widget-row"
34679
- }, /*#__PURE__*/React.createElement(PropCheckBox$3, {
35080
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
34680
35081
  label: "Strictly match only these formats",
34681
- strict: answers[i]["strict"]
34682
- // eslint-disable-next-line react/jsx-no-bind
34683
- ,
34684
- onChange: this.updateAnswer.bind(this, i)
35082
+ checked: answers[i]["strict"],
35083
+ onChange: value => {
35084
+ this.updateAnswer.bind(this, i)({
35085
+ strict: value
35086
+ });
35087
+ }
34685
35088
  })));
34686
35089
  const maxError = i => /*#__PURE__*/React.createElement("div", {
34687
35090
  className: "perseus-widget-row"
@@ -34707,10 +35110,14 @@ class NumericInputEditor extends React.Component {
34707
35110
  }), /*#__PURE__*/React.createElement(InfoTip$7, 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.")));
34708
35111
  const rightAlign = /*#__PURE__*/React.createElement("div", {
34709
35112
  className: "perseus-widget-row"
34710
- }, /*#__PURE__*/React.createElement(PropCheckBox$3, {
35113
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
34711
35114
  label: "Right alignment",
34712
- rightAlign: this.props.rightAlign,
34713
- onChange: this.props.onChange
35115
+ checked: this.props.rightAlign,
35116
+ onChange: value => {
35117
+ this.props.onChange({
35118
+ rightAlign: value
35119
+ });
35120
+ }
34714
35121
  }));
34715
35122
  const labelText = /*#__PURE__*/React.createElement("div", {
34716
35123
  className: "perseus-widget-row"
@@ -34720,10 +35127,14 @@ class NumericInputEditor extends React.Component {
34720
35127
  })), /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "Text to describe this input. This will be shown to users using screenreaders.")));
34721
35128
  const coefficientCheck = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
34722
35129
  className: "perseus-widget-row"
34723
- }, /*#__PURE__*/React.createElement(PropCheckBox$3, {
35130
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
34724
35131
  label: "Coefficient",
34725
- coefficient: this.props.coefficient,
34726
- onChange: this.props.onChange
35132
+ checked: this.props.coefficient,
35133
+ onChange: value => {
35134
+ this.props.onChange({
35135
+ coefficient: value
35136
+ });
35137
+ }
34727
35138
  }), /*#__PURE__*/React.createElement(InfoTip$7, null, /*#__PURE__*/React.createElement("p", null, "A coefficient style number allows the student to use - for -1 and an empty string to mean 1."))));
34728
35139
  const addAnswerButton = /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("a", {
34729
35140
  href: "#",
@@ -34987,8 +35398,7 @@ OrdererEditor.defaultProps = {
34987
35398
  };
34988
35399
 
34989
35400
  const {
34990
- InfoTip: InfoTip$5,
34991
- PropCheckBox: PropCheckBox$2
35401
+ InfoTip: InfoTip$5
34992
35402
  } = components;
34993
35403
  class PassageEditor extends React.Component {
34994
35404
  constructor(..._args) {
@@ -35036,11 +35446,14 @@ class PassageEditor extends React.Component {
35036
35446
  className: "perseus-widget-passage-editor"
35037
35447
  }, /*#__PURE__*/React.createElement("div", {
35038
35448
  className: "perseus-widget-row"
35039
- }, /*#__PURE__*/React.createElement(PropCheckBox$2, {
35449
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
35040
35450
  label: "Show line numbers",
35041
- labelAlignment: "right",
35042
- showLineNumbers: this.props.showLineNumbers,
35043
- onChange: this.props.onChange
35451
+ checked: this.props.showLineNumbers,
35452
+ onChange: value => {
35453
+ this.props.onChange({
35454
+ showLineNumbers: value
35455
+ });
35456
+ }
35044
35457
  })), /*#__PURE__*/React.createElement("div", null, "Passage title:", /*#__PURE__*/React.createElement(InfoTip$5, null, /*#__PURE__*/React.createElement("p", null, "An optional title that will appear directly above the passage in the same font style. (E.g. Passage 1)")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("input", {
35045
35458
  type: "text",
35046
35459
  defaultValue: this.props.passageTitle,
@@ -35511,8 +35924,7 @@ PythonProgramEditor.defaultProps = {
35511
35924
  };
35512
35925
 
35513
35926
  const {
35514
- InlineIcon,
35515
- PropCheckBox: PropCheckBox$1
35927
+ InlineIcon
35516
35928
  } = components;
35517
35929
  const {
35518
35930
  iconPlus,
@@ -35701,25 +36113,34 @@ class RadioEditor extends React.Component {
35701
36113
  target: "_blank"
35702
36114
  }, "Multiple choice style guide"), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("div", {
35703
36115
  className: "perseus-widget-left-col"
35704
- }, /*#__PURE__*/React.createElement(PropCheckBox$1, {
36116
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
35705
36117
  label: "Multiple selections",
35706
- labelAlignment: "right",
35707
- multipleSelect: this.props.multipleSelect,
35708
- onChange: this.onMultipleSelectChange
36118
+ checked: this.props.multipleSelect,
36119
+ onChange: value => {
36120
+ this.onMultipleSelectChange({
36121
+ multipleSelect: value
36122
+ });
36123
+ }
35709
36124
  })), /*#__PURE__*/React.createElement("div", {
35710
36125
  className: "perseus-widget-right-col"
35711
- }, /*#__PURE__*/React.createElement(PropCheckBox$1, {
36126
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
35712
36127
  label: "Randomize order",
35713
- labelAlignment: "right",
35714
- randomize: this.props.randomize,
35715
- onChange: this.props.onChange
36128
+ checked: this.props.randomize,
36129
+ onChange: value => {
36130
+ this.props.onChange({
36131
+ randomize: value
36132
+ });
36133
+ }
35716
36134
  })), this.props.multipleSelect && /*#__PURE__*/React.createElement("div", {
35717
36135
  className: "perseus-widget-left-col"
35718
- }, /*#__PURE__*/React.createElement(PropCheckBox$1, {
36136
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
35719
36137
  label: "Specify number correct",
35720
- labelAlignment: "right",
35721
- countChoices: this.props.countChoices,
35722
- onChange: this.onCountChoicesChange
36138
+ checked: this.props.countChoices,
36139
+ onChange: value => {
36140
+ this.onCountChoicesChange({
36141
+ countChoices: value
36142
+ });
36143
+ }
35723
36144
  }))), /*#__PURE__*/React.createElement(BaseRadio, {
35724
36145
  multipleSelect: this.props.multipleSelect,
35725
36146
  countChoices: this.props.countChoices,
@@ -35856,7 +36277,6 @@ SimpleMarkdownTesterEditor.defaultProps = {
35856
36277
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
35857
36278
  const {
35858
36279
  InfoTip: InfoTip$2,
35859
- PropCheckBox,
35860
36280
  TextListEditor
35861
36281
  } = components;
35862
36282
  const HORIZONTAL = "horizontal";
@@ -35894,10 +36314,14 @@ class SorterEditor extends React.Component {
35894
36314
  value: HORIZONTAL
35895
36315
  }, "Horizontal"), /*#__PURE__*/React.createElement("option", {
35896
36316
  value: VERTICAL
35897
- }, "Vertical"))), /*#__PURE__*/React.createElement(InfoTip$2, null, /*#__PURE__*/React.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text and larger images."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(PropCheckBox, {
36317
+ }, "Vertical"))), /*#__PURE__*/React.createElement(InfoTip$2, null, /*#__PURE__*/React.createElement("p", null, "Use the horizontal layout for short text and small images. The vertical layout is best for longer text and larger images."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Checkbox$1, {
35898
36318
  label: "Padding:",
35899
- padding: this.props.padding,
35900
- onChange: this.props.onChange
36319
+ checked: this.props.padding,
36320
+ onChange: value => {
36321
+ this.props.onChange({
36322
+ padding: value
36323
+ });
36324
+ }
35901
36325
  }), /*#__PURE__*/React.createElement(InfoTip$2, null, /*#__PURE__*/React.createElement("p", null, "Padding is good for text, but not needed for images."))));
35902
36326
  }
35903
36327
  }