@khanacademy/perseus-editor 14.5.0 → 14.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -27,6 +27,7 @@ import { SingleSelect, OptionItem, ActionMenu, ActionItem } from '@khanacademy/w
27
27
  import Banner from '@khanacademy/wonder-blocks-banner';
28
28
  import plusCircle from '@phosphor-icons/core/regular/plus-circle.svg';
29
29
  import { AccordionSection } from '@khanacademy/wonder-blocks-accordion';
30
+ import pencilCircle from '@phosphor-icons/core/regular/pencil-circle.svg';
30
31
  import IconButton from '@khanacademy/wonder-blocks-icon-button';
31
32
  import caretDoubleDownIcon from '@phosphor-icons/core/bold/caret-double-down-bold.svg';
32
33
  import caretDoubleUpIcon from '@phosphor-icons/core/bold/caret-double-up-bold.svg';
@@ -45,7 +46,7 @@ import arrowCounterClockwise from '@phosphor-icons/core/bold/arrow-counter-clock
45
46
 
46
47
  // This file is processed by a Rollup plugin (replace) to inject the production
47
48
  const libName = "@khanacademy/perseus-editor";
48
- const libVersion = "14.5.0";
49
+ const libVersion = "14.6.1";
49
50
  addLibraryVersionToPerseusDebug(libName, libVersion);
50
51
 
51
52
  function _extends() {
@@ -230,7 +231,7 @@ class SectionControlButton extends React.Component {
230
231
  role: "button",
231
232
  hideDefaultFocusRing: true,
232
233
  "aria-label": title,
233
- style: styles$T.button
234
+ style: styles$U.button
234
235
  }, ({
235
236
  hovered,
236
237
  focused,
@@ -238,7 +239,7 @@ class SectionControlButton extends React.Component {
238
239
  }) => /*#__PURE__*/React.createElement(InlineIcon$b, icon));
239
240
  }
240
241
  }
241
- const styles$T = StyleSheet.create({
242
+ const styles$U = StyleSheet.create({
242
243
  button: {
243
244
  backgroundColor: color.gold,
244
245
  margin: 2,
@@ -20629,11 +20630,11 @@ class Spring extends React.Component {
20629
20630
  } = this.props;
20630
20631
  return React.createElement(View, {
20631
20632
  "aria-hidden": "true",
20632
- style: [styles$S.grow, style]
20633
+ style: [styles$T.grow, style]
20633
20634
  });
20634
20635
  }
20635
20636
  }
20636
- const styles$S = StyleSheet.create({
20637
+ const styles$T = StyleSheet.create({
20637
20638
  grow: {
20638
20639
  flexGrow: 1
20639
20640
  }
@@ -20877,13 +20878,13 @@ class WidgetSelect extends React.Component {
20877
20878
  * that collapse a region.
20878
20879
  */
20879
20880
  function ToggleableCaret(props) {
20880
- const iconStyle = props.isExpanded ? styles$R.expanded : styles$R.collapsed;
20881
+ const iconStyle = props.isExpanded ? styles$S.expanded : styles$S.collapsed;
20881
20882
  return /*#__PURE__*/React.createElement(PhosphorIcon, {
20882
20883
  icon: caretRight,
20883
20884
  style: iconStyle
20884
20885
  });
20885
20886
  }
20886
- const styles$R = StyleSheet.create({
20887
+ const styles$S = StyleSheet.create({
20887
20888
  collapsed: {
20888
20889
  transition: ".15s"
20889
20890
  },
@@ -20916,16 +20917,16 @@ class TexErrorView extends React.Component {
20916
20917
  showErrors
20917
20918
  } = this.state;
20918
20919
  return /*#__PURE__*/React.createElement(View, {
20919
- style: styles$Q.errorContainer
20920
+ style: styles$R.errorContainer
20920
20921
  }, /*#__PURE__*/React.createElement(View, {
20921
- style: styles$Q.title,
20922
+ style: styles$R.title,
20922
20923
  onClick: this.handleToggleTexErrors
20923
20924
  }, /*#__PURE__*/React.createElement(ToggleableCaret, {
20924
20925
  isExpanded: showErrors
20925
20926
  }), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React.createElement(View, {
20926
- style: styles$Q.errorExplanation
20927
+ style: styles$R.errorExplanation
20927
20928
  }, "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, {
20928
- style: styles$Q.error,
20929
+ style: styles$R.error,
20929
20930
  key: index
20930
20931
  }, /*#__PURE__*/React.createElement(View, {
20931
20932
  style: {
@@ -20934,7 +20935,7 @@ class TexErrorView extends React.Component {
20934
20935
  }, e.math), /*#__PURE__*/React.createElement(View, null, e.message))));
20935
20936
  }
20936
20937
  }
20937
- const styles$Q = StyleSheet.create({
20938
+ const styles$R = StyleSheet.create({
20938
20939
  title: {
20939
20940
  backgroundColor: "#eee",
20940
20941
  fontSize: "1.25em",
@@ -23590,7 +23591,7 @@ class StructuredItemDiff extends React.Component {
23590
23591
 
23591
23592
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
23592
23593
  const {
23593
- InfoTip: InfoTip$m,
23594
+ InfoTip: InfoTip$n,
23594
23595
  InlineIcon: InlineIcon$7
23595
23596
  } = components;
23596
23597
  const {
@@ -23662,7 +23663,7 @@ class HintEditor extends React.Component {
23662
23663
  type: "button",
23663
23664
  className: this.props.isFirst ? "hidden" : "",
23664
23665
  onClick: _.partial(this.props.onMove, -1)
23665
- }, /*#__PURE__*/React.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$m, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23666
+ }, /*#__PURE__*/React.createElement(InlineIcon$7, iconCircleArrowUp)), " ", this.props.isLast && /*#__PURE__*/React.createElement(InfoTip$n, null, /*#__PURE__*/React.createElement("p", null, "The last hint is automatically bolded."))), /*#__PURE__*/React.createElement("input", {
23666
23667
  type: "checkbox"
23667
23668
  // @ts-expect-error - TS2322 - Type 'boolean | null | undefined' is not assignable to type 'boolean | undefined'.
23668
23669
  ,
@@ -23908,7 +23909,7 @@ CombinedHintsEditor.defaultProps = {
23908
23909
  };
23909
23910
 
23910
23911
  const {
23911
- InfoTip: InfoTip$l
23912
+ InfoTip: InfoTip$m
23912
23913
  } = components;
23913
23914
  class ItemExtrasEditor extends React.Component {
23914
23915
  constructor(...args) {
@@ -24047,17 +24048,17 @@ ItemExtrasEditor.defaultProps = {
24047
24048
  zTable: false
24048
24049
  };
24049
24050
  const ItemExtraCheckbox = props => /*#__PURE__*/React.createElement(View, {
24050
- style: [styles$P.checkbox, props.indent ? styles$P.indented : undefined]
24051
+ style: [styles$Q.checkbox, props.indent ? styles$Q.indented : undefined]
24051
24052
  }, /*#__PURE__*/React.createElement(Checkbox$1, {
24052
24053
  label: /*#__PURE__*/React.createElement(View, {
24053
24054
  style: {
24054
24055
  flexDirection: "row"
24055
24056
  }
24056
- }, props.label, " ", /*#__PURE__*/React.createElement(InfoTip$l, null, props.infoTip)),
24057
+ }, props.label, " ", /*#__PURE__*/React.createElement(InfoTip$m, null, props.infoTip)),
24057
24058
  checked: props.checked,
24058
24059
  onChange: newCheckedState => props.onChange(newCheckedState)
24059
24060
  }));
24060
- const styles$P = StyleSheet.create({
24061
+ const styles$Q = StyleSheet.create({
24061
24062
  indented: {
24062
24063
  marginInlineStart: spacing.large_24
24063
24064
  }
@@ -24719,7 +24720,7 @@ class SimpleButton extends React.Component {
24719
24720
  } = _this$props,
24720
24721
  otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$3);
24721
24722
  return /*#__PURE__*/React.createElement("div", _extends({
24722
- className: css(styles$O.baseButton, color === "green" && styles$O.green, color === "orange" && styles$O.orange),
24723
+ className: css(styles$P.baseButton, color === "green" && styles$P.green, color === "orange" && styles$P.orange),
24723
24724
  onClick: onClick
24724
24725
  }, otherProps), children);
24725
24726
  }
@@ -24734,7 +24735,7 @@ SimpleButton.defaultProps = {
24734
24735
  color: "green",
24735
24736
  onClick: () => {}
24736
24737
  };
24737
- const styles$O = StyleSheet.create({
24738
+ const styles$P = StyleSheet.create({
24738
24739
  baseButton: {
24739
24740
  top: "0",
24740
24741
  fontSize: "11px",
@@ -24954,23 +24955,23 @@ const LeafContainer = ({
24954
24955
  }) => {
24955
24956
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
24956
24957
  const previewHeading = hasPreviewHeading && /*#__PURE__*/React.createElement("div", {
24957
- className: css(styles$N.containerHeader)
24958
+ className: css(styles$O.containerHeader)
24958
24959
  }, /*#__PURE__*/React.createElement(Header, {
24959
24960
  depth: path.length,
24960
- className: css(styles$N.containerTitle)
24961
+ className: css(styles$O.containerTitle)
24961
24962
  }, capitalize(name)));
24962
24963
  return /*#__PURE__*/React.createElement("div", {
24963
- className: css(styles$N.container)
24964
+ className: css(styles$O.container)
24964
24965
  }, /*#__PURE__*/React.createElement("span", {
24965
- className: css(styles$N.row, styles$N.rowHeading)
24966
+ className: css(styles$O.row, styles$O.rowHeading)
24966
24967
  }, /*#__PURE__*/React.createElement("div", {
24967
- className: css(styles$N.columnLeft)
24968
+ className: css(styles$O.columnLeft)
24968
24969
  }, /*#__PURE__*/React.createElement("div", {
24969
- className: "pod-title " + css(styles$N.containerHeader)
24970
+ className: "pod-title " + css(styles$O.containerHeader)
24970
24971
  }, /*#__PURE__*/React.createElement("div", {
24971
- className: css(styles$N.containerTitle)
24972
+ className: css(styles$O.containerTitle)
24972
24973
  }, capitalize(name)), controls)), /*#__PURE__*/React.createElement("div", {
24973
- className: css(styles$N.columnRight)
24974
+ className: css(styles$O.columnRight)
24974
24975
  }, previewHeading)), children);
24975
24976
  };
24976
24977
  const ArrayContainer = props => {
@@ -24983,11 +24984,11 @@ const ArrayContainer = props => {
24983
24984
  actions
24984
24985
  } = props;
24985
24986
  return /*#__PURE__*/React.createElement("div", {
24986
- className: css(styles$N.container)
24987
+ className: css(styles$O.container)
24987
24988
  }, controls && /*#__PURE__*/React.createElement("div", {
24988
- className: css(styles$N.columnLeft, styles$N.containerHeader)
24989
+ className: css(styles$O.columnLeft, styles$O.containerHeader)
24989
24990
  }, controls), /*#__PURE__*/React.createElement("div", null, children), /*#__PURE__*/React.createElement("div", {
24990
- className: css(styles$N.columnLeft)
24991
+ className: css(styles$O.columnLeft)
24991
24992
  }, /*#__PURE__*/React.createElement("a", {
24992
24993
  href: "javascript:void 0",
24993
24994
  onClick: () => actions.addArrayElement(path, shape.elementShape)
@@ -25000,28 +25001,28 @@ const ObjectContainer = ({
25000
25001
  path
25001
25002
  }) => {
25002
25003
  const headingEditor = /*#__PURE__*/React.createElement("div", {
25003
- className: css(styles$N.containerHeader)
25004
+ className: css(styles$O.containerHeader)
25004
25005
  }, /*#__PURE__*/React.createElement(Header, {
25005
25006
  depth: path.length,
25006
- className: css(styles$N.containerTitle)
25007
+ className: css(styles$O.containerTitle)
25007
25008
  }, capitalize(name)), controls);
25008
25009
  const headingPreview = (name || controls) && /*#__PURE__*/React.createElement("div", {
25009
- className: css(styles$N.containerHeader, styles$N.previewCollectionHeader)
25010
+ className: css(styles$O.containerHeader, styles$O.previewCollectionHeader)
25010
25011
  }, /*#__PURE__*/React.createElement(Header, {
25011
25012
  depth: path.length,
25012
- className: css(styles$N.containerTitle)
25013
+ className: css(styles$O.containerTitle)
25013
25014
  }, capitalize(name)));
25014
25015
  const hasBothHeadings = headingEditor && headingPreview;
25015
25016
  return /*#__PURE__*/React.createElement("div", {
25016
- className: css(styles$N.container)
25017
+ className: css(styles$O.container)
25017
25018
  }, hasBothHeadings && /*#__PURE__*/React.createElement("span", {
25018
- className: css(styles$N.row)
25019
+ className: css(styles$O.row)
25019
25020
  }, /*#__PURE__*/React.createElement("div", {
25020
- className: css(styles$N.columnLeft)
25021
+ className: css(styles$O.columnLeft)
25021
25022
  }, headingEditor), /*#__PURE__*/React.createElement("div", {
25022
- className: css(styles$N.columnRight)
25023
+ className: css(styles$O.columnRight)
25023
25024
  }, headingPreview)), /*#__PURE__*/React.createElement("div", {
25024
- className: css(path.length > 0 && styles$N.contentIndent)
25025
+ className: css(path.length > 0 && styles$O.contentIndent)
25025
25026
  }, children));
25026
25027
  };
25027
25028
 
@@ -25144,11 +25145,11 @@ const ItemNodeContent = withStickiness(props => {
25144
25145
  className: "framework-perseus"
25145
25146
  }, lens(renderers).get(path));
25146
25147
  return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
25147
- className: css(styles$N.row)
25148
+ className: css(styles$O.row)
25148
25149
  }, /*#__PURE__*/React.createElement("div", {
25149
- className: css(styles$N.columnLeft)
25150
+ className: css(styles$O.columnLeft)
25150
25151
  }, /*#__PURE__*/React.createElement("div", {
25151
- className: css(sticky && styles$N.sticky)
25152
+ className: css(sticky && styles$O.sticky)
25152
25153
  },
25153
25154
  /*#__PURE__*/
25154
25155
  // @ts-expect-error - TS2769 - No overload matches this call.
@@ -25156,9 +25157,9 @@ const ItemNodeContent = withStickiness(props => {
25156
25157
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25157
25158
  apiOptions: apiOptions
25158
25159
  })))), /*#__PURE__*/React.createElement("div", {
25159
- className: css(styles$N.columnRight)
25160
+ className: css(styles$O.columnRight)
25160
25161
  }, /*#__PURE__*/React.createElement("div", {
25161
- className: css(sticky && styles$N.sticky)
25162
+ className: css(sticky && styles$O.sticky)
25162
25163
  }, preview))));
25163
25164
  });
25164
25165
  const HintNodeContent = withStickiness(props => {
@@ -25174,13 +25175,13 @@ const HintNodeContent = withStickiness(props => {
25174
25175
  className: "framework-perseus"
25175
25176
  }, lens(renderers).get(path));
25176
25177
  return /*#__PURE__*/React.createElement("div", {
25177
- className: css(styles$N.row)
25178
+ className: css(styles$O.row)
25178
25179
  }, /*#__PURE__*/React.createElement("div", {
25179
- className: css(styles$N.columnLeft)
25180
+ className: css(styles$O.columnLeft)
25180
25181
  }, /*#__PURE__*/React.createElement("div", {
25181
- className: css(sticky && styles$N.sticky)
25182
+ className: css(sticky && styles$O.sticky)
25182
25183
  }, /*#__PURE__*/React.createElement(HintEditor, _extends({}, data, {
25183
- className: css(styles$N.hintEditor),
25184
+ className: css(styles$O.hintEditor),
25184
25185
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25185
25186
  apiOptions: apiOptions,
25186
25187
  showTitle: false,
@@ -25195,9 +25196,9 @@ const HintNodeContent = withStickiness(props => {
25195
25196
  isFirst: true,
25196
25197
  isLast: true
25197
25198
  })))), /*#__PURE__*/React.createElement("div", {
25198
- className: css(styles$N.columnRight)
25199
+ className: css(styles$O.columnRight)
25199
25200
  }, /*#__PURE__*/React.createElement("div", {
25200
- className: css(sticky && styles$N.sticky)
25201
+ className: css(sticky && styles$O.sticky)
25201
25202
  }, preview)));
25202
25203
  });
25203
25204
  const TagsNodeContent = props => {
@@ -25214,9 +25215,9 @@ const TagsNodeContent = props => {
25214
25215
  return null;
25215
25216
  }
25216
25217
  return /*#__PURE__*/React.createElement("div", {
25217
- className: css(styles$N.columnLeft)
25218
+ className: css(styles$O.columnLeft)
25218
25219
  }, /*#__PURE__*/React.createElement("div", {
25219
- className: css(styles$N.tagsEditor)
25220
+ className: css(styles$O.tagsEditor)
25220
25221
  }, /*#__PURE__*/React.createElement(GroupMetadataEditor, {
25221
25222
  value: data,
25222
25223
  onChange: newVal => actions.setValueAtPath(path, newVal),
@@ -25247,23 +25248,23 @@ const ArrayNodeContent = props => {
25247
25248
  const subpath = path.concat(i);
25248
25249
  const controls = [i > 0 && /*#__PURE__*/React.createElement("div", {
25249
25250
  key: "moveArrayElementUp",
25250
- className: css(styles$N.control)
25251
+ className: css(styles$O.control)
25251
25252
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25252
25253
  color: "orange",
25253
25254
  title: "Move up",
25254
25255
  onClick: () => actions.moveArrayElementUp(subpath)
25255
25256
  }, /*#__PURE__*/React.createElement("div", {
25256
- className: css(styles$N.verticalFlip)
25257
+ className: css(styles$O.verticalFlip)
25257
25258
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React.createElement("div", {
25258
25259
  key: "moveArrayElementDown",
25259
- className: css(styles$N.control)
25260
+ className: css(styles$O.control)
25260
25261
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25261
25262
  color: "orange",
25262
25263
  title: "Move down",
25263
25264
  onClick: () => actions.moveArrayElementDown(subpath)
25264
25265
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React.createElement("div", {
25265
25266
  key: "removeArrayElement",
25266
- className: css(styles$N.control)
25267
+ className: css(styles$O.control)
25267
25268
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25268
25269
  color: "orange",
25269
25270
  title: "Delete",
@@ -25271,7 +25272,7 @@ const ArrayNodeContent = props => {
25271
25272
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconTrash$4)))];
25272
25273
  return /*#__PURE__*/React.createElement("div", {
25273
25274
  key: i,
25274
- className: css(styles$N.arrayElement, !elementIsLeaf && styles$N.arrayElementAndNotLeaf)
25275
+ className: css(styles$O.arrayElement, !elementIsLeaf && styles$O.arrayElementAndNotLeaf)
25275
25276
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25276
25277
  key: i,
25277
25278
  shape: shape.elementShape,
@@ -25297,7 +25298,7 @@ const ObjectNodeContent = props => {
25297
25298
  // made sense to the shape's author is the order in which we'll iterate :)
25298
25299
  const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React.createElement("div", {
25299
25300
  key: subkey,
25300
- className: css(styles$N.objectElement)
25301
+ className: css(styles$O.objectElement)
25301
25302
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25302
25303
  shape: shape.shape[subkey],
25303
25304
  data: data[subkey],
@@ -25464,7 +25465,7 @@ class MultiRendererEditor extends React.Component {
25464
25465
  }, this._renderContent());
25465
25466
  }
25466
25467
  }
25467
- const styles$N = StyleSheet.create({
25468
+ const styles$O = StyleSheet.create({
25468
25469
  // This is used in a number of places throughout this file.
25469
25470
  container: {},
25470
25471
  // eslint-disable-next-line react-native/no-unused-styles
@@ -25759,7 +25760,7 @@ class BlurInput extends React.Component {
25759
25760
  }
25760
25761
 
25761
25762
  const {
25762
- InfoTip: InfoTip$k
25763
+ InfoTip: InfoTip$l
25763
25764
  } = components;
25764
25765
  const DEFAULT_WIDTH = 400;
25765
25766
  const DEFAULT_HEIGHT = 400;
@@ -25923,7 +25924,7 @@ class CSProgramEditor extends React.Component {
25923
25924
  showEditor: value
25924
25925
  });
25925
25926
  }
25926
- }), /*#__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, {
25927
+ }), /*#__PURE__*/React.createElement(InfoTip$l, null, "If you show the editor, you should use the \"full-width\" alignment to make room for the width of the editor."), /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement(Checkbox$1, {
25927
25928
  label: "Show Buttons",
25928
25929
  checked: this.props.showButtons,
25929
25930
  onChange: value => {
@@ -25935,7 +25936,7 @@ class CSProgramEditor extends React.Component {
25935
25936
  name: "settings",
25936
25937
  pairs: this.props.settings,
25937
25938
  onChange: this._handleSettingsChange
25938
- }), /*#__PURE__*/React.createElement(InfoTip$k, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
25939
+ }), /*#__PURE__*/React.createElement(InfoTip$l, null, "Settings that you add here are available to the program as an object returned by ", /*#__PURE__*/React.createElement("code", null, "Program.settings()"))));
25939
25940
  }
25940
25941
  }
25941
25942
  CSProgramEditor.propTypes = _extends({}, Changeable.propTypes);
@@ -26021,7 +26022,7 @@ DeprecatedStandinEditor.widgetName = "deprecated-standin";
26021
26022
 
26022
26023
  /* eslint-disable @khanacademy/ts-no-error-suppressions */
26023
26024
  const {
26024
- InfoTip: InfoTip$j,
26025
+ InfoTip: InfoTip$k,
26025
26026
  InlineIcon: InlineIcon$5
26026
26027
  } = components;
26027
26028
  const {
@@ -26090,14 +26091,14 @@ class DropdownEditor extends React.Component {
26090
26091
  className: "perseus-widget-dropdown"
26091
26092
  }, /*#__PURE__*/React.createElement("div", {
26092
26093
  className: "dropdown-info"
26093
- }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26094
+ }, "Dropdown", /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "The drop down is useful for making inequalities in a custom format. We normally use the symbols ", "<", ",", " ", ">", ", \u2264, \u2265 (in that order) which you can copy into the choices. When possible, use the \"multiple choice\" answer type instead."))), /*#__PURE__*/React.createElement("div", {
26094
26095
  className: "dropdown-placeholder"
26095
26096
  }, /*#__PURE__*/React.createElement("input", {
26096
26097
  type: "text",
26097
26098
  placeholder: "Placeholder value",
26098
26099
  value: this.props.placeholder,
26099
26100
  onChange: this.onPlaceholderChange
26100
- }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React.createElement("div", {
26101
+ }), /*#__PURE__*/React.createElement(InfoTip$k, null, /*#__PURE__*/React.createElement("p", null, "This value will appear as the drop down default. It should give the user some indication of the values available in the drop down itself, e.g., Yes/No/Maybe."))), /*#__PURE__*/React.createElement("div", {
26101
26102
  className: "clearfix"
26102
26103
  }), /*#__PURE__*/React.createElement("ul", {
26103
26104
  className: "dropdown-choices"
@@ -26410,7 +26411,7 @@ const SortableItem = createReactClass({
26410
26411
  }
26411
26412
  return /*#__PURE__*/React.createElement("li", {
26412
26413
  draggable: this.props.draggable,
26413
- className: [dragState, css(styles$M.sortableListItem)].join(" "),
26414
+ className: [dragState, css(styles$N.sortableListItem)].join(" "),
26414
26415
  onDragStart: this.handleDragStart,
26415
26416
  onDrop: this.handleDrop,
26416
26417
  onDragEnter: this.handleDragEnter,
@@ -26418,14 +26419,14 @@ const SortableItem = createReactClass({
26418
26419
  }, this.props.component);
26419
26420
  }
26420
26421
  });
26421
- const styles$M = StyleSheet.create({
26422
+ const styles$N = StyleSheet.create({
26422
26423
  sortableListItem: {
26423
26424
  margin: "5px 0"
26424
26425
  }
26425
26426
  });
26426
26427
 
26427
26428
  const {
26428
- InfoTip: InfoTip$i
26429
+ InfoTip: InfoTip$j
26429
26430
  } = components;
26430
26431
 
26431
26432
  // types for iterables
@@ -26666,28 +26667,28 @@ class ExpressionEditor extends React.Component {
26666
26667
  onChange: this.handleToggleDiv
26667
26668
  }));
26668
26669
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(HeadingSmall, null, "Global Options"), /*#__PURE__*/React.createElement("div", {
26669
- className: css(styles$L.paddedY)
26670
+ className: css(styles$M.paddedY)
26670
26671
  }, /*#__PURE__*/React.createElement(LabeledTextField, {
26671
26672
  label: "Visible label",
26672
26673
  value: this.props.visibleLabel || "",
26673
26674
  onChange: this.change("visibleLabel")
26674
- }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."))), /*#__PURE__*/React.createElement("div", {
26675
- className: css(styles$L.paddedY)
26675
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "Optional visible text; strongly encouraged to help learners using dictation software, but can be omitted if the surrounding content provides enough context."))), /*#__PURE__*/React.createElement("div", {
26676
+ className: css(styles$M.paddedY)
26676
26677
  }, /*#__PURE__*/React.createElement(LabeledTextField, {
26677
26678
  label: "Aria label",
26678
26679
  value: this.props.ariaLabel || "",
26679
26680
  onChange: this.change("ariaLabel")
26680
- }), /*#__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", {
26681
+ }), /*#__PURE__*/React.createElement(InfoTip$j, 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", {
26681
26682
  href: "https://www.w3.org/WAI/tips/designing/#ensure-that-form-elements-include-clearly-associated-labels",
26682
26683
  target: "_blank"
26683
26684
  }, "this article.")))), /*#__PURE__*/React.createElement("div", {
26684
- className: css(styles$L.paddedY)
26685
+ className: css(styles$M.paddedY)
26685
26686
  }, /*#__PURE__*/React.createElement(LabeledTextField, {
26686
26687
  label: "Function variables",
26687
26688
  value: this.state.functionsInternal,
26688
26689
  onChange: this.handleFunctions
26689
- }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React.createElement("div", {
26690
- className: css(styles$L.paddedY)
26690
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "Single-letter variables listed here will be interpreted as functions. This let us know that f(x) means \"f of x\" and not \"f times x\"."))), /*#__PURE__*/React.createElement("div", {
26691
+ className: css(styles$M.paddedY)
26691
26692
  }, /*#__PURE__*/React.createElement(Checkbox$1, {
26692
26693
  label: "Use \xD7 instead of \u22C5 for multiplication",
26693
26694
  checked: this.props.times,
@@ -26696,8 +26697,8 @@ class ExpressionEditor extends React.Component {
26696
26697
  times: value
26697
26698
  });
26698
26699
  }
26699
- }), /*#__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", {
26700
- className: css(styles$L.paddedY)
26700
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "For pre-algebra problems this option displays multiplication as \\times instead of \\cdot in both the rendered output and the acceptable formats examples."))), /*#__PURE__*/React.createElement("div", {
26701
+ className: css(styles$M.paddedY)
26701
26702
  }, /*#__PURE__*/React.createElement(HeadingXSmall, null, "Button Sets"), buttonSetChoices), /*#__PURE__*/React.createElement(HeadingSmall, null, "Answers"), /*#__PURE__*/React.createElement("p", {
26702
26703
  style: {
26703
26704
  margin: "4px 0"
@@ -26768,18 +26769,18 @@ class AnswerOption extends React.Component {
26768
26769
  color: "destructive",
26769
26770
  light: true
26770
26771
  }, "Delete");
26771
- const answerStatusCss = css(styles$L.answerStatus, this.props.considered === "wrong" && styles$L.answerStatusWrong, this.props.considered === "correct" && styles$L.answerStatusCorrect, this.props.considered === "ungraded" && styles$L.answerStatusUngraded);
26772
+ const answerStatusCss = css(styles$M.answerStatus, this.props.considered === "wrong" && styles$M.answerStatusWrong, this.props.considered === "correct" && styles$M.answerStatusCorrect, this.props.considered === "ungraded" && styles$M.answerStatusUngraded);
26772
26773
  return /*#__PURE__*/React.createElement("div", {
26773
- className: css(styles$L.answerOption)
26774
+ className: css(styles$M.answerOption)
26774
26775
  }, /*#__PURE__*/React.createElement("div", {
26775
- className: css(styles$L.answerHandle)
26776
+ className: css(styles$M.answerHandle)
26776
26777
  }), /*#__PURE__*/React.createElement("div", {
26777
- className: css(styles$L.answerBody)
26778
+ className: css(styles$M.answerBody)
26778
26779
  }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
26779
26780
  onClick: this.toggleConsidered,
26780
26781
  className: answerStatusCss
26781
26782
  }, this.props.considered), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Expression, this.props.expressionProps))), /*#__PURE__*/React.createElement("div", {
26782
- className: css(styles$L.paddedY, styles$L.paddedX)
26783
+ className: css(styles$M.paddedY, styles$M.paddedX)
26783
26784
  }, /*#__PURE__*/React.createElement(Checkbox$1, {
26784
26785
  label: "Answer expression must have the same form.",
26785
26786
  checked: this.props.form,
@@ -26788,8 +26789,8 @@ class AnswerOption extends React.Component {
26788
26789
  form: value
26789
26790
  });
26790
26791
  }
26791
- }), /*#__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", {
26792
- className: css(styles$L.paddedY, styles$L.paddedX)
26792
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be in the same form. Commutativity and excess negative signs are ignored."))), /*#__PURE__*/React.createElement("div", {
26793
+ className: css(styles$M.paddedY, styles$M.paddedX)
26793
26794
  }, /*#__PURE__*/React.createElement(Checkbox$1, {
26794
26795
  label: "Answer expression must be fully expanded and simplified.",
26795
26796
  checked: this.props.simplify,
@@ -26798,12 +26799,12 @@ class AnswerOption extends React.Component {
26798
26799
  simplify: value
26799
26800
  });
26800
26801
  }
26801
- }), /*#__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", {
26802
- className: css(styles$L.buttonRow, styles$L.paddedY)
26802
+ }), /*#__PURE__*/React.createElement(InfoTip$j, null, /*#__PURE__*/React.createElement("p", null, "The student's answer must be fully expanded and simplified. Answering this equation (x^2+2x+1) with this factored equation (x+1)^2 will render this response \"Your answer is not fully expanded and simplified.\""))), /*#__PURE__*/React.createElement("div", {
26803
+ className: css(styles$M.buttonRow, styles$M.paddedY)
26803
26804
  }, removeButton)));
26804
26805
  }
26805
26806
  }
26806
- const styles$L = StyleSheet.create({
26807
+ const styles$M = StyleSheet.create({
26807
26808
  paddedX: {
26808
26809
  paddingLeft: spacing.xSmall_8,
26809
26810
  paddingRight: spacing.xSmall_8
@@ -26898,10 +26899,10 @@ class GradedGroupEditor extends React.Component {
26898
26899
  }, /*#__PURE__*/React.createElement("div", {
26899
26900
  className: "perseus-widget-row"
26900
26901
  }, /*#__PURE__*/React.createElement("label", {
26901
- className: css(styles$K.title)
26902
+ className: css(styles$L.title)
26902
26903
  }, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$5, {
26903
26904
  value: this.props.title,
26904
- className: css(styles$K.input)
26905
+ className: css(styles$L.input)
26905
26906
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
26906
26907
  ,
26907
26908
  onChange: this.change("title")
@@ -26926,7 +26927,7 @@ class GradedGroupEditor extends React.Component {
26926
26927
  }, /*#__PURE__*/React.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React.createElement("div", {
26927
26928
  className: "perseus-hint-editor"
26928
26929
  }, /*#__PURE__*/React.createElement("div", {
26929
- className: css(styles$K.hintsTitle)
26930
+ className: css(styles$L.hintsTitle)
26930
26931
  }, "Hint"), /*#__PURE__*/React.createElement(Editor, {
26931
26932
  ref: this.hintEditor,
26932
26933
  content: this.props.hint ? this.props.hint.content : "",
@@ -26963,7 +26964,7 @@ GradedGroupEditor.defaultProps = {
26963
26964
  images: {},
26964
26965
  hint: null
26965
26966
  };
26966
- const styles$K = StyleSheet.create({
26967
+ const styles$L = StyleSheet.create({
26967
26968
  title: {
26968
26969
  fontSize: 18,
26969
26970
  fontWeight: "bold"
@@ -27041,7 +27042,7 @@ const setArrayItem = (list, i, value) => [...list.slice(0, i), value, ...list.sl
27041
27042
 
27042
27043
  const {
27043
27044
  ButtonGroup: ButtonGroup$7,
27044
- InfoTip: InfoTip$h,
27045
+ InfoTip: InfoTip$i,
27045
27046
  RangeInput: RangeInput$6
27046
27047
  } = components;
27047
27048
  const defaultBackgroundImage$3 = {
@@ -27500,7 +27501,7 @@ const GraphSettings = createReactClass({
27500
27501
  },
27501
27502
  onKeyPress: this.changeBackgroundUrl,
27502
27503
  onBlur: this.changeBackgroundUrl
27503
- }), /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27504
+ }), /*#__PURE__*/React.createElement(InfoTip$i, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), _.contains(this.props.editableSettings, "measure") && /*#__PURE__*/React.createElement("div", {
27504
27505
  className: "misc-settings"
27505
27506
  }, /*#__PURE__*/React.createElement("div", {
27506
27507
  className: "perseus-widget-row"
@@ -27546,7 +27547,7 @@ const GraphSettings = createReactClass({
27546
27547
  });
27547
27548
 
27548
27549
  const {
27549
- InfoTip: InfoTip$g,
27550
+ InfoTip: InfoTip$h,
27550
27551
  MultiButtonGroup: MultiButtonGroup$1
27551
27552
  } = components;
27552
27553
  const {
@@ -27629,7 +27630,7 @@ class GrapherEditor extends React.Component {
27629
27630
  className: "perseus-error"
27630
27631
  }, this.props.graph.valid);
27631
27632
  }
27632
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$g, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27633
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, "Correct answer", " ", /*#__PURE__*/React.createElement(InfoTip$h, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer.")), " ", ": ", equationString), /*#__PURE__*/React.createElement(GraphSettings, {
27633
27634
  editableSettings: ["graph", "snap", "image"],
27634
27635
  box: getInteractiveBoxFromSizeClass$1(sizeClass),
27635
27636
  range: this.props.graph.range,
@@ -27879,7 +27880,7 @@ IframeEditor.defaultProps = {
27879
27880
 
27880
27881
  /* eslint-disable jsx-a11y/anchor-is-valid */
27881
27882
  const {
27882
- InfoTip: InfoTip$f,
27883
+ InfoTip: InfoTip$g,
27883
27884
  InlineIcon: InlineIcon$3,
27884
27885
  RangeInput: RangeInput$5
27885
27886
  } = components;
@@ -28069,7 +28070,7 @@ class ImageEditor extends React.Component {
28069
28070
  style: {
28070
28071
  width: "100%"
28071
28072
  }
28072
- }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$f, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28073
+ }))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Dimensions:"), /*#__PURE__*/React.createElement("p", null, backgroundImage.width, "x", backgroundImage.height))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("div", null, "Alt text:", /*#__PURE__*/React.createElement(InfoTip$g, null, "This is important for screenreaders. The content of this alt text will be formatted as markdown (tables, emphasis, etc. are supported).")), /*#__PURE__*/React.createElement(Editor, {
28073
28074
  apiOptions: this.props.apiOptions,
28074
28075
  content: this.props.alt,
28075
28076
  onChange: props => {
@@ -28093,7 +28094,7 @@ class ImageEditor extends React.Component {
28093
28094
  }, this.state.backgroundImageError);
28094
28095
  return /*#__PURE__*/React.createElement("div", {
28095
28096
  className: "perseus-image-editor"
28096
- }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$f, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28097
+ }, /*#__PURE__*/React.createElement("label", null, "Image url:", /*#__PURE__*/React.createElement(InfoTip$g, null, "Paste an image or graphie image URL."), this.state.backgroundImageError && backgroundImageErrorText, /*#__PURE__*/React.createElement(BlurInput, {
28097
28098
  value: backgroundImage.url || "",
28098
28099
  style: {
28099
28100
  width: 332
@@ -28115,7 +28116,7 @@ ImageEditor.defaultProps = {
28115
28116
  };
28116
28117
 
28117
28118
  const {
28118
- InfoTip: InfoTip$e
28119
+ InfoTip: InfoTip$f
28119
28120
  } = components;
28120
28121
  const answerTypes = {
28121
28122
  number: {
@@ -28201,7 +28202,7 @@ class InputNumberEditor extends React.Component {
28201
28202
  value: "optional"
28202
28203
  }, "will be accepted"), /*#__PURE__*/React.createElement("option", {
28203
28204
  value: "enforced"
28204
- }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28205
+ }, "will be marked wrong"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Normally select \"will not be graded\". This will give the user a message saying the answer is correct but not simplified. The user will then have to simplify it and re-enter, but will not be penalized. (5th grade and anything after)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be accepted\" only if the user is not expected to know how to simplify fractions yet. (Anything prior to 5th grade)"), /*#__PURE__*/React.createElement("p", null, "Select \"will be marked wrong\" only if we are specifically assessing the ability to simplify."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28205
28206
  type: "checkbox",
28206
28207
  checked: this.props.inexact,
28207
28208
  onChange: e => {
@@ -28237,7 +28238,7 @@ class InputNumberEditor extends React.Component {
28237
28238
  });
28238
28239
  },
28239
28240
  "aria-label": "Answer type"
28240
- }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28241
+ }, answerTypeOptions), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Use the default \"Numbers\" unless the answer must be in a specific form (e.g., question is about converting decimals to fractions)."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, "Width", " ", /*#__PURE__*/React.createElement("select", {
28241
28242
  value: this.props.size,
28242
28243
  onChange: e => {
28243
28244
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type '"small" | "normal" | undefined'.
@@ -28249,7 +28250,7 @@ class InputNumberEditor extends React.Component {
28249
28250
  value: "normal"
28250
28251
  }, "Normal (80px)"), /*#__PURE__*/React.createElement("option", {
28251
28252
  value: "small"
28252
- }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28253
+ }, "Small (40px)"))), /*#__PURE__*/React.createElement(InfoTip$f, null, /*#__PURE__*/React.createElement("p", null, "Use size \"Normal\" for all text boxes, unless there are multiple text boxes in one line and the answer area is too narrow to fit them."))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
28253
28254
  type: "checkbox",
28254
28255
  checked: this.props.rightAlign,
28255
28256
  onChange: e => {
@@ -28422,13 +28423,13 @@ function MathquillInput(props) {
28422
28423
  }
28423
28424
  });
28424
28425
  return /*#__PURE__*/React.createElement(View, {
28425
- style: styles$J.outerWrapper
28426
+ style: styles$K.outerWrapper
28426
28427
  }, /*#__PURE__*/React.createElement("span", {
28427
28428
  ref: mathFieldWrapperRef,
28428
28429
  className: "perseus-math-input mq-editable-field mq-math-mode"
28429
28430
  }));
28430
28431
  }
28431
- const styles$J = StyleSheet.create({
28432
+ const styles$K = StyleSheet.create({
28432
28433
  outerWrapper: {
28433
28434
  display: "inline-block",
28434
28435
  borderStyle: "solid",
@@ -29532,7 +29533,7 @@ const GraphPointsCountSelector = ({
29532
29533
  // Never uses placeholder, always has value
29533
29534
  ,
29534
29535
  placeholder: "",
29535
- style: styles$I.singleSelectShort
29536
+ style: styles$J.singleSelectShort
29536
29537
  }, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
29537
29538
  key: n,
29538
29539
  value: `${n}`,
@@ -29543,7 +29544,7 @@ const GraphPointsCountSelector = ({
29543
29544
  label: "unlimited"
29544
29545
  })]);
29545
29546
  };
29546
- const styles$I = StyleSheet.create({
29547
+ const styles$J = StyleSheet.create({
29547
29548
  singleSelectShort: {
29548
29549
  // Non-standard spacing, but it's the smallest we can go
29549
29550
  // without running into styling issues with the dropdown.
@@ -29556,7 +29557,7 @@ const GraphTypeSelector = props => {
29556
29557
  selectedValue: props.graphType,
29557
29558
  onChange: props.onChange,
29558
29559
  placeholder: "Select an answer type",
29559
- style: styles$H.singleSelectShort
29560
+ style: styles$I.singleSelectShort
29560
29561
  }, props.showNoneOption && /*#__PURE__*/React.createElement(OptionItem, {
29561
29562
  value: "none",
29562
29563
  label: "None"
@@ -29592,7 +29593,7 @@ const GraphTypeSelector = props => {
29592
29593
  label: "Angle"
29593
29594
  }));
29594
29595
  };
29595
- const styles$H = StyleSheet.create({
29596
+ const styles$I = StyleSheet.create({
29596
29597
  singleSelectShort: {
29597
29598
  // Non-standard spacing, but it's the smallest we can go
29598
29599
  // without running into styling issues with the dropdown.
@@ -29607,11 +29608,11 @@ function Heading({
29607
29608
  onToggle
29608
29609
  }) {
29609
29610
  return /*#__PURE__*/React.createElement(Clickable, {
29610
- style: [styles$G.container, !isCollapsible && styles$G.notClickable],
29611
+ style: [styles$H.container, !isCollapsible && styles$H.notClickable],
29611
29612
  disabled: !isCollapsible,
29612
29613
  onClick: () => isCollapsible && (onToggle == null ? void 0 : onToggle(!isOpen))
29613
29614
  }, () => /*#__PURE__*/React.createElement(View, {
29614
- style: styles$G.heading
29615
+ style: styles$H.heading
29615
29616
  }, /*#__PURE__*/React.createElement(LabelLarge, {
29616
29617
  style: {
29617
29618
  fontSize: 14,
@@ -29621,7 +29622,7 @@ function Heading({
29621
29622
  isExpanded: isOpen
29622
29623
  })));
29623
29624
  }
29624
- const styles$G = StyleSheet.create({
29625
+ const styles$H = StyleSheet.create({
29625
29626
  container: {
29626
29627
  marginTop: spacing.small_12,
29627
29628
  // NOTE(jeremy): This is the inverse of the @editorPadding CSS
@@ -29681,8 +29682,8 @@ function InteractiveGraphDescription(props) {
29681
29682
  isOpen: isOpen,
29682
29683
  onToggle: setIsOpen
29683
29684
  }), isOpen && /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(LabelXSmall, {
29684
- style: styles$F.caption
29685
- }, "Use these fields to describe the graph as a whole. These are used by screen readers to describe content to users who are visually impaired."), /*#__PURE__*/React.createElement(LabelLarge, {
29685
+ style: styles$G.caption
29686
+ }, "Use these fields to describe the graph as a whole. These are used by screen readers to describe content to users who may be visually impaired."), /*#__PURE__*/React.createElement(LabelLarge, {
29686
29687
  tag: "label"
29687
29688
  }, "Title", /*#__PURE__*/React.createElement(TextField, {
29688
29689
  value: ariaLabelValue,
@@ -29692,7 +29693,7 @@ function InteractiveGraphDescription(props) {
29692
29693
  // is an empty string.
29693
29694
  newValue || undefined
29694
29695
  }),
29695
- style: styles$F.spaceAbove
29696
+ style: styles$G.spaceAbove
29696
29697
  })), /*#__PURE__*/React.createElement(Strut, {
29697
29698
  size: spacing.small_12
29698
29699
  }), /*#__PURE__*/React.createElement(LabelLarge, {
@@ -29707,10 +29708,10 @@ function InteractiveGraphDescription(props) {
29707
29708
  // is an empty string.
29708
29709
  newValue || undefined
29709
29710
  }),
29710
- style: styles$F.spaceAbove
29711
+ style: styles$G.spaceAbove
29711
29712
  }))));
29712
29713
  }
29713
- const styles$F = StyleSheet.create({
29714
+ const styles$G = StyleSheet.create({
29714
29715
  caption: {
29715
29716
  color: color.offBlack64,
29716
29717
  paddingTop: spacing.xxSmall_6,
@@ -29730,16 +29731,16 @@ const LabeledRow = props => {
29730
29731
  style
29731
29732
  } = props;
29732
29733
  return /*#__PURE__*/React.createElement("label", {
29733
- className: css(styles$E.label)
29734
+ className: css(styles$F.label)
29734
29735
  }, /*#__PURE__*/React.createElement(View, {
29735
- style: [styles$E.row, style]
29736
+ style: [styles$F.row, style]
29736
29737
  }, labelSide === "start" || /*#__PURE__*/React.createElement(LabelSmall, {
29737
- style: styles$E.spaceEnd
29738
+ style: styles$F.spaceEnd
29738
29739
  }, label), children, labelSide === "end" && /*#__PURE__*/React.createElement(LabelSmall, {
29739
- style: styles$E.spaceStart
29740
+ style: styles$F.spaceStart
29740
29741
  }, label)));
29741
29742
  };
29742
- const styles$E = StyleSheet.create({
29743
+ const styles$F = StyleSheet.create({
29743
29744
  label: {
29744
29745
  width: "fit-content"
29745
29746
  },
@@ -29759,7 +29760,7 @@ const styles$E = StyleSheet.create({
29759
29760
 
29760
29761
  const {
29761
29762
  ButtonGroup: ButtonGroup$2,
29762
- InfoTip: InfoTip$d,
29763
+ InfoTip: InfoTip$e,
29763
29764
  RangeInput: RangeInput$4
29764
29765
  } = components;
29765
29766
  const defaultBackgroundImage$1 = {
@@ -30133,10 +30134,10 @@ class InteractiveGraphSettings extends React.Component {
30133
30134
  }
30134
30135
  }))), /*#__PURE__*/React.createElement(LabeledRow, {
30135
30136
  label: "Background image URL:",
30136
- style: styles$D.resetSpaceTop
30137
+ style: styles$E.resetSpaceTop
30137
30138
  }, /*#__PURE__*/React.createElement("input", {
30138
30139
  type: "text",
30139
- className: css(styles$D.backgroundUrlInput),
30140
+ className: css(styles$E.backgroundUrlInput),
30140
30141
  ref: this.bgUrlRef,
30141
30142
  value: this.state.backgroundImage.url || "",
30142
30143
  onChange: e => {
@@ -30149,10 +30150,10 @@ class InteractiveGraphSettings extends React.Component {
30149
30150
  },
30150
30151
  onKeyPress: this.changeBackgroundUrl,
30151
30152
  onBlur: this.changeBackgroundUrl
30152
- }), /*#__PURE__*/React.createElement(InfoTip$d, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React.createElement(View, {
30153
- style: styles$D.protractorSection
30153
+ }), /*#__PURE__*/React.createElement(InfoTip$e, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React.createElement(View, {
30154
+ style: styles$E.protractorSection
30154
30155
  }, /*#__PURE__*/React.createElement(View, {
30155
- style: styles$D.checkboxRow
30156
+ style: styles$E.checkboxRow
30156
30157
  }, /*#__PURE__*/React.createElement(Checkbox$1, {
30157
30158
  label: "Show protractor",
30158
30159
  checked: this.props.showProtractor,
@@ -30161,7 +30162,7 @@ class InteractiveGraphSettings extends React.Component {
30161
30162
  showProtractor: value
30162
30163
  });
30163
30164
  },
30164
- style: styles$D.resetSpaceTop
30165
+ style: styles$E.resetSpaceTop
30165
30166
  })), this.props.showProtractor && /*#__PURE__*/React.createElement(Banner, {
30166
30167
  layout: "floating",
30167
30168
  text: "The protractor is not accessible. Please consider an alternate approach.",
@@ -30182,7 +30183,7 @@ InteractiveGraphSettings.defaultProps = {
30182
30183
  showProtractor: false,
30183
30184
  showTooltips: false
30184
30185
  };
30185
- const styles$D = StyleSheet.create({
30186
+ const styles$E = StyleSheet.create({
30186
30187
  resetSpaceTop: {
30187
30188
  marginTop: 0
30188
30189
  },
@@ -30219,13 +30220,13 @@ const SegmentCountSelector = ({
30219
30220
  const num = +newValue;
30220
30221
  onChange(num);
30221
30222
  },
30222
- style: styles$C.singleSelectShort
30223
+ style: styles$D.singleSelectShort
30223
30224
  }, _.range(1, 7).map(n => /*#__PURE__*/React.createElement(OptionItem, {
30224
30225
  key: n,
30225
30226
  value: `${n}`,
30226
30227
  label: `${n} segment${n > 1 ? "s" : ""}`
30227
30228
  })));
30228
- const styles$C = StyleSheet.create({
30229
+ const styles$D = StyleSheet.create({
30229
30230
  singleSelectShort: {
30230
30231
  // Non-standard spacing, but it's the smallest we can go
30231
30232
  // without running into styling issues with the dropdown.
@@ -30250,17 +30251,17 @@ const LockedFigureSelect = props => {
30250
30251
  figureTypes.push("label");
30251
30252
  }
30252
30253
  return /*#__PURE__*/React.createElement(View, {
30253
- style: styles$B.container
30254
+ style: styles$C.container
30254
30255
  }, /*#__PURE__*/React.createElement(ActionMenu, {
30255
30256
  menuText: "Add locked figure",
30256
- style: styles$B.addElementSelect
30257
+ style: styles$C.addElementSelect
30257
30258
  }, figureTypes.map(figureType => /*#__PURE__*/React.createElement(ActionItem, {
30258
30259
  key: `${id}-${figureType}`,
30259
30260
  label: figureType,
30260
30261
  onClick: () => onChange(figureType)
30261
30262
  }))));
30262
30263
  };
30263
- const styles$B = StyleSheet.create({
30264
+ const styles$C = StyleSheet.create({
30264
30265
  container: {
30265
30266
  marginTop: spacing.xSmall_8
30266
30267
  },
@@ -30377,18 +30378,18 @@ const AngleInput = props => {
30377
30378
  }
30378
30379
  return /*#__PURE__*/React.createElement(LabelMedium, {
30379
30380
  tag: "label",
30380
- style: styles$A.row
30381
+ style: styles$B.row
30381
30382
  }, "angle (degrees)", /*#__PURE__*/React.createElement(Strut, {
30382
30383
  size: spacing.xxSmall_6
30383
30384
  }), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
30384
30385
  value: angleInput,
30385
30386
  onChange: handleAngleChange,
30386
- style: styles$A.textField
30387
+ style: styles$B.textField
30387
30388
  }), /*#__PURE__*/React.createElement(Strut, {
30388
30389
  size: spacing.xxSmall_6
30389
30390
  }));
30390
30391
  };
30391
- const styles$A = StyleSheet.create({
30392
+ const styles$B = StyleSheet.create({
30392
30393
  row: {
30393
30394
  display: "flex",
30394
30395
  flexDirection: "row",
@@ -30437,30 +30438,30 @@ const CoordinatePairInput = props => {
30437
30438
  onChange(newCoords);
30438
30439
  }
30439
30440
  return /*#__PURE__*/React.createElement(View, {
30440
- style: [styles$z.row, style]
30441
+ style: [styles$A.row, style]
30441
30442
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30442
30443
  tag: "label",
30443
- style: styles$z.row
30444
+ style: styles$A.row
30444
30445
  }, labels ? labels[0] : "x coord", /*#__PURE__*/React.createElement(Strut, {
30445
30446
  size: spacing.xxSmall_6
30446
30447
  }), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
30447
30448
  value: coordState[0],
30448
30449
  onChange: newValue => handleCoordChange(newValue, 0),
30449
- style: [styles$z.textField, error ? styles$z.errorField : undefined]
30450
+ style: [styles$A.textField, error ? styles$A.errorField : undefined]
30450
30451
  })), /*#__PURE__*/React.createElement(Strut, {
30451
30452
  size: spacing.medium_16
30452
30453
  }), /*#__PURE__*/React.createElement(LabelMedium, {
30453
30454
  tag: "label",
30454
- style: styles$z.row
30455
+ style: styles$A.row
30455
30456
  }, labels ? labels[1] : "y coord", /*#__PURE__*/React.createElement(Strut, {
30456
30457
  size: spacing.xxSmall_6
30457
30458
  }), /*#__PURE__*/React.createElement(ScrolllessNumberTextField, {
30458
30459
  value: coordState[1],
30459
30460
  onChange: newValue => handleCoordChange(newValue, 1),
30460
- style: [styles$z.textField, error ? styles$z.errorField : undefined]
30461
+ style: [styles$A.textField, error ? styles$A.errorField : undefined]
30461
30462
  })));
30462
30463
  };
30463
- const styles$z = StyleSheet.create({
30464
+ const styles$A = StyleSheet.create({
30464
30465
  row: {
30465
30466
  display: "flex",
30466
30467
  flexDirection: "row",
@@ -30493,14 +30494,14 @@ const PerseusEditorAccordion = props => {
30493
30494
  }, /*#__PURE__*/React.createElement(AccordionSection, {
30494
30495
  expanded: expanded,
30495
30496
  onToggle: onToggle,
30496
- style: [styles$y.container, containerStyle],
30497
- headerStyle: styles$y.accordionHeader,
30497
+ style: [styles$z.container, containerStyle],
30498
+ headerStyle: styles$z.accordionHeader,
30498
30499
  header: header
30499
30500
  }, /*#__PURE__*/React.createElement(View, {
30500
- style: [styles$y.accordionPanel, panelStyle]
30501
+ style: [styles$z.accordionPanel, panelStyle]
30501
30502
  }, children)));
30502
30503
  };
30503
- const styles$y = StyleSheet.create({
30504
+ const styles$z = StyleSheet.create({
30504
30505
  container: {
30505
30506
  backgroundColor: color.fadedBlue8,
30506
30507
  marginTop: spacing.xSmall_8
@@ -30531,13 +30532,13 @@ const ColorSwatch = props => {
30531
30532
  "aria-label":
30532
30533
  // Don't include an aria label for decorative circles.
30533
30534
  !decorative ? `${color$1}, ${filled ? "filled" : "open"}` : undefined,
30534
- style: [styles$x.colorSwatch, {
30535
+ style: [styles$y.colorSwatch, {
30535
30536
  border: `4px solid ${lockedFigureColors[color$1]}`,
30536
30537
  backgroundColor: filled ? lockedFigureColors[color$1] : color.white
30537
30538
  }]
30538
30539
  });
30539
30540
  };
30540
- const styles$x = StyleSheet.create({
30541
+ const styles$y = StyleSheet.create({
30541
30542
  colorSwatch: {
30542
30543
  // Add a white outline so that the color swatch is visible when
30543
30544
  // the dropdown option is highlighted with its blue background.
@@ -30556,10 +30557,10 @@ const ColorSelect = props => {
30556
30557
  onChange
30557
30558
  } = props;
30558
30559
  return /*#__PURE__*/React.createElement(View, {
30559
- style: [styles$w.row, style]
30560
+ style: [styles$x.row, style]
30560
30561
  }, /*#__PURE__*/React.createElement(LabelMedium, {
30561
30562
  tag: "label",
30562
- style: styles$w.row
30563
+ style: styles$x.row
30563
30564
  }, "color", /*#__PURE__*/React.createElement(Strut, {
30564
30565
  size: spacing.xxSmall_6
30565
30566
  }), /*#__PURE__*/React.createElement(SingleSelect, {
@@ -30578,7 +30579,7 @@ const ColorSelect = props => {
30578
30579
  })
30579
30580
  })))));
30580
30581
  };
30581
- const styles$w = StyleSheet.create({
30582
+ const styles$x = StyleSheet.create({
30582
30583
  row: {
30583
30584
  display: "flex",
30584
30585
  flexDirection: "row",
@@ -30597,17 +30598,17 @@ const EllipseSwatch = props => {
30597
30598
  } = props;
30598
30599
  return /*#__PURE__*/React.createElement(View, {
30599
30600
  "aria-label": `${color}, stroke ${strokeStyle}, fill ${fillStyle}`,
30600
- style: [styles$v.container, {
30601
+ style: [styles$w.container, {
30601
30602
  border: `4px ${strokeStyle} ${lockedFigureColors[color]}`
30602
30603
  }]
30603
30604
  }, /*#__PURE__*/React.createElement(View, {
30604
- style: [styles$v.innerCircle, {
30605
+ style: [styles$w.innerCircle, {
30605
30606
  backgroundColor: lockedFigureColors[color],
30606
30607
  opacity: fillStyle === "white" ? 0 : lockedFigureFillStyles[fillStyle]
30607
30608
  }]
30608
30609
  }));
30609
30610
  };
30610
- const styles$v = StyleSheet.create({
30611
+ const styles$w = StyleSheet.create({
30611
30612
  container: {
30612
30613
  // Add a white outline so that the color swatch is visible when
30613
30614
  // the dropdown option is highlighted with its blue background.
@@ -30633,7 +30634,7 @@ const LineStrokeSelect = props => {
30633
30634
  } = props;
30634
30635
  return /*#__PURE__*/React.createElement(LabelMedium, {
30635
30636
  tag: "label",
30636
- style: styles$u.lineStrokeSelect
30637
+ style: styles$v.lineStrokeSelect
30637
30638
  }, "stroke", /*#__PURE__*/React.createElement(Strut, {
30638
30639
  size: spacing.xxxSmall_4
30639
30640
  }), /*#__PURE__*/React.createElement(SingleSelect, {
@@ -30650,7 +30651,7 @@ const LineStrokeSelect = props => {
30650
30651
  label: "dashed"
30651
30652
  })));
30652
30653
  };
30653
- const styles$u = StyleSheet.create({
30654
+ const styles$v = StyleSheet.create({
30654
30655
  lineStrokeSelect: {
30655
30656
  display: "flex",
30656
30657
  flexDirection: "row",
@@ -30660,6 +30661,66 @@ const styles$u = StyleSheet.create({
30660
30661
  }
30661
30662
  });
30662
30663
 
30664
+ const {
30665
+ InfoTip: InfoTip$d
30666
+ } = components;
30667
+ function LockedFigureAria(props) {
30668
+ const {
30669
+ ariaLabel,
30670
+ prePopulatedAriaLabel,
30671
+ onChangeProps
30672
+ } = props;
30673
+ const id = React.useId();
30674
+ const ariaLabelId = `aria-label-${id}`;
30675
+ return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(Strut, {
30676
+ size: spacing.xSmall_8
30677
+ }), /*#__PURE__*/React.createElement(View, {
30678
+ style: styles$u.row
30679
+ }, /*#__PURE__*/React.createElement(LabelMedium, {
30680
+ tag: "label",
30681
+ htmlFor: ariaLabelId
30682
+ }, "Aria label"), /*#__PURE__*/React.createElement(Spring, null), /*#__PURE__*/React.createElement(InfoTip$d, null, "Aria label is used by screen readers to describe content to users who may be visually impaired. ", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("br", null), "Populating this field will make it so that users can use a screen reader to navigate to this point and hear the description.", /*#__PURE__*/React.createElement("br", null), /*#__PURE__*/React.createElement("br", null), "If you leave this field blank, the point will be hidden from screen readers. Users will not be able to navigate to this point using a screen reader.")), /*#__PURE__*/React.createElement(Strut, {
30683
+ size: spacing.xxSmall_6
30684
+ }), /*#__PURE__*/React.createElement(LabelXSmall, {
30685
+ style: styles$u.caption
30686
+ }, "The figure is hidden from screen readers if this field is left blank."), /*#__PURE__*/React.createElement(Strut, {
30687
+ size: spacing.xxSmall_6
30688
+ }), /*#__PURE__*/React.createElement(TextArea, {
30689
+ id: ariaLabelId,
30690
+ value: ariaLabel != null ? ariaLabel : "",
30691
+ onChange: newValue => {
30692
+ onChangeProps({
30693
+ // Save as undefined if the field is empty.
30694
+ ariaLabel: newValue || undefined
30695
+ });
30696
+ },
30697
+ placeholder: "Ex. Point at (x, y)",
30698
+ rows: 1,
30699
+ resizeType: "vertical"
30700
+ }), /*#__PURE__*/React.createElement(Button, {
30701
+ kind: "tertiary",
30702
+ startIcon: pencilCircle,
30703
+ style: styles$u.button,
30704
+ onClick: () => {
30705
+ onChangeProps({
30706
+ ariaLabel: prePopulatedAriaLabel
30707
+ });
30708
+ }
30709
+ }, "Auto-generate"));
30710
+ }
30711
+ const styles$u = StyleSheet.create({
30712
+ row: {
30713
+ flexDirection: "row",
30714
+ alignItems: "center"
30715
+ },
30716
+ button: {
30717
+ alignSelf: "start"
30718
+ },
30719
+ caption: {
30720
+ color: color.offBlack64
30721
+ }
30722
+ });
30723
+
30663
30724
  /**
30664
30725
  * The part of a locked figure settings panel that contains actions
30665
30726
  * for this panel and its associated locked figure, including
@@ -30779,7 +30840,7 @@ function LockedLabelSettings(props) {
30779
30840
  })
30780
30841
  })), /*#__PURE__*/React.createElement(View, {
30781
30842
  style: styles$s.row
30782
- }, onMove && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ColorSelect, {
30843
+ }, /*#__PURE__*/React.createElement(ColorSelect, {
30783
30844
  selectedValue: color$1,
30784
30845
  onChange: newColor => {
30785
30846
  onChangeProps({
@@ -30789,7 +30850,7 @@ function LockedLabelSettings(props) {
30789
30850
  style: styles$s.spaceUnder
30790
30851
  }), /*#__PURE__*/React.createElement(Strut, {
30791
30852
  size: spacing.medium_16
30792
- })), /*#__PURE__*/React.createElement(LabelMedium, {
30853
+ }), /*#__PURE__*/React.createElement(LabelMedium, {
30793
30854
  tag: "label",
30794
30855
  style: styles$s.row
30795
30856
  }, "size", /*#__PURE__*/React.createElement(Strut, {
@@ -30914,7 +30975,7 @@ const {
30914
30975
  InfoTip: InfoTip$c
30915
30976
  } = components;
30916
30977
  const LockedEllipseSettings = props => {
30917
- var _flags$mafs;
30978
+ var _flags$mafs, _flags$mafs2;
30918
30979
  const {
30919
30980
  flags,
30920
30981
  center,
@@ -30922,6 +30983,7 @@ const LockedEllipseSettings = props => {
30922
30983
  angle,
30923
30984
  color,
30924
30985
  labels,
30986
+ ariaLabel,
30925
30987
  fillStyle,
30926
30988
  strokeStyle,
30927
30989
  expanded,
@@ -30930,6 +30992,31 @@ const LockedEllipseSettings = props => {
30930
30992
  onMove,
30931
30993
  onRemove
30932
30994
  } = props;
30995
+ function getPrepopulatedAriaLabel() {
30996
+ const isCircle = radius[0] === radius[1];
30997
+ let str = "";
30998
+ if (isCircle) {
30999
+ str += `Circle with radius ${radius[0]}`;
31000
+ } else {
31001
+ str += `Ellipse with x radius ${radius[0]} and y radius ${radius[1]}`;
31002
+ }
31003
+ str += `, centered at (${center[0]}, ${center[1]})`;
31004
+ if (!isCircle && angle !== 0) {
31005
+ str += `, rotated by ${radianToDegree(angle)} degrees`;
31006
+ }
31007
+ if (labels && labels.length > 0) {
31008
+ str += ", with label";
31009
+ // Make it "with labels" instead of "with label" if there are
31010
+ // multiple labels.
31011
+ if (labels.length > 1) {
31012
+ str += "s";
31013
+ }
31014
+
31015
+ // Separate additional labels with commas.
31016
+ str += ` ${labels.map(l => l.text).join(", ")}`;
31017
+ }
31018
+ return str;
31019
+ }
30933
31020
  function handleCenterChange(newCoord) {
30934
31021
  const xOffset = newCoord[0] - center[0];
30935
31022
  const yOffset = newCoord[1] - center[1];
@@ -31039,7 +31126,23 @@ const LockedEllipseSettings = props => {
31039
31126
  onChange: value => onChangeProps({
31040
31127
  strokeStyle: value
31041
31128
  })
31042
- }), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-ellipse-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
31129
+ }), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-figures-aria"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
31130
+ size: spacing.small_12
31131
+ }), /*#__PURE__*/React.createElement(View, {
31132
+ style: styles$r.horizontalRule
31133
+ }), /*#__PURE__*/React.createElement(LockedFigureAria, {
31134
+ ariaLabel: ariaLabel,
31135
+ prePopulatedAriaLabel: getPrepopulatedAriaLabel(),
31136
+ onChangeProps: newProps => {
31137
+ onChangeProps(newProps);
31138
+ }
31139
+ })), (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-ellipse-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
31140
+ size: spacing.xxxSmall_4
31141
+ }), /*#__PURE__*/React.createElement(View, {
31142
+ style: styles$r.horizontalRule
31143
+ }), /*#__PURE__*/React.createElement(Strut, {
31144
+ size: spacing.small_12
31145
+ }), /*#__PURE__*/React.createElement(LabelMedium, null, "Visible labels"), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
31043
31146
  expanded: true,
31044
31147
  onChangeProps: newLabel => {
31045
31148
  handleLabelChange(newLabel, labelIndex);
@@ -31090,6 +31193,10 @@ const styles$r = StyleSheet.create({
31090
31193
  },
31091
31194
  labelContainer: {
31092
31195
  backgroundColor: color.white
31196
+ },
31197
+ horizontalRule: {
31198
+ height: 1,
31199
+ backgroundColor: color.offBlack16
31093
31200
  }
31094
31201
  });
31095
31202
 
@@ -31126,7 +31233,7 @@ const examples = {
31126
31233
  };
31127
31234
 
31128
31235
  const LockedFunctionSettings = props => {
31129
- var _flags$mafs;
31236
+ var _flags$mafs, _flags$mafs2;
31130
31237
  const {
31131
31238
  flags,
31132
31239
  color: lineColor,
@@ -31135,12 +31242,12 @@ const LockedFunctionSettings = props => {
31135
31242
  directionalAxis,
31136
31243
  domain,
31137
31244
  labels,
31245
+ ariaLabel,
31138
31246
  onChangeProps,
31139
31247
  onMove,
31140
31248
  onRemove
31141
31249
  } = props;
31142
31250
  const equationPrefix = directionalAxis === "x" ? "y=" : "x=";
31143
- const domainRangeText = directionalAxis === "x" ? "domain" : "range";
31144
31251
  const lineLabel = `Function (${equationPrefix}${equation})`;
31145
31252
 
31146
31253
  // Tracking the string value of domain/range constraints to handle interim state of
@@ -31152,6 +31259,27 @@ const LockedFunctionSettings = props => {
31152
31259
  // "useEffect" used to maintain parity between domain/range constraints and their string representation.
31153
31260
  setDomainEntries([domain && domain[0] !== -Infinity ? domain[0].toString() : "", domain && domain[1] !== Infinity ? domain[1].toString() : ""]);
31154
31261
  }, [domain]);
31262
+ function getPrepopulatedAriaLabel() {
31263
+ let str = `Function with equation ${equationPrefix}${equation}`;
31264
+
31265
+ // Add the domain/range constraints to the aria label
31266
+ // if they are not the default values.
31267
+ if (domain && !(domain[0] === -Infinity && domain[1] === Infinity)) {
31268
+ str += `, domain from ${domain[0]} to ${domain[1]}`;
31269
+ }
31270
+ if (labels && labels.length > 0) {
31271
+ str += ", with label";
31272
+ // Make it "with labels" instead of "with label" if there are
31273
+ // multiple labels.
31274
+ if (labels.length > 1) {
31275
+ str += "s";
31276
+ }
31277
+
31278
+ // Separate additional labels with commas.
31279
+ str += ` ${labels.map(l => l.text).join(", ")}`;
31280
+ }
31281
+ return str;
31282
+ }
31155
31283
 
31156
31284
  // Generic function for handling property changes (except for 'domain/range')
31157
31285
  function handlePropChange(property, newValue) {
@@ -31273,7 +31401,7 @@ const LockedFunctionSettings = props => {
31273
31401
  }, /*#__PURE__*/React.createElement(LabelMedium, {
31274
31402
  tag: "label",
31275
31403
  style: [styles$p.dropdownLabel, styles$p.domainMin]
31276
- }, `${domainRangeText} min`, /*#__PURE__*/React.createElement(Strut, {
31404
+ }, "domain min", /*#__PURE__*/React.createElement(Strut, {
31277
31405
  size: spacing.xxSmall_6
31278
31406
  }), /*#__PURE__*/React.createElement(TextField, {
31279
31407
  type: "number",
@@ -31286,7 +31414,7 @@ const LockedFunctionSettings = props => {
31286
31414
  size: spacing.medium_16
31287
31415
  }), /*#__PURE__*/React.createElement(LabelMedium, {
31288
31416
  tag: "label",
31289
- "aria-label": `${domainRangeText} max`,
31417
+ "aria-label": "domain max",
31290
31418
  style: [styles$p.dropdownLabel, styles$p.domainMax]
31291
31419
  }, "max", /*#__PURE__*/React.createElement(Strut, {
31292
31420
  size: spacing.xxSmall_6
@@ -31320,13 +31448,30 @@ const LockedFunctionSettings = props => {
31320
31448
  }))), exampleCategorySelected && /*#__PURE__*/React.createElement("ul", {
31321
31449
  className: css(styles$p.exampleContainer)
31322
31450
  }, exampleContent.map((example, index) => /*#__PURE__*/React.createElement(ExampleItem, {
31451
+ key: index,
31323
31452
  category: exampleCategory,
31324
31453
  example: example,
31325
31454
  index: index,
31326
31455
  pasteEquationFn: handlePropChange
31327
- })))), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-function-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
31456
+ })))), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-figures-aria"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
31457
+ size: spacing.small_12
31458
+ }), /*#__PURE__*/React.createElement(View, {
31459
+ style: styles$p.horizontalRule
31460
+ }), /*#__PURE__*/React.createElement(LockedFigureAria, {
31461
+ ariaLabel: ariaLabel,
31462
+ prePopulatedAriaLabel: getPrepopulatedAriaLabel(),
31463
+ onChangeProps: newProps => {
31464
+ onChangeProps(newProps);
31465
+ }
31466
+ })), (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-function-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
31467
+ size: spacing.xxxSmall_4
31468
+ }), /*#__PURE__*/React.createElement(View, {
31328
31469
  style: styles$p.horizontalRule
31329
- }), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
31470
+ }), /*#__PURE__*/React.createElement(Strut, {
31471
+ size: spacing.small_12
31472
+ }), /*#__PURE__*/React.createElement(LabelMedium, null, "Visible labels"), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({
31473
+ key: labelIndex
31474
+ }, label, {
31330
31475
  expanded: true,
31331
31476
  onChangeProps: newLabel => {
31332
31477
  handleLabelChange(newLabel, labelIndex);
@@ -31487,8 +31632,6 @@ const styles$p = StyleSheet.create({
31487
31632
  alignSelf: "start"
31488
31633
  },
31489
31634
  horizontalRule: {
31490
- marginTop: spacing.small_12,
31491
- marginBottom: spacing.xxxSmall_4,
31492
31635
  height: 1,
31493
31636
  backgroundColor: color.offBlack16
31494
31637
  },
@@ -31527,7 +31670,7 @@ const styles$o = StyleSheet.create({
31527
31670
  });
31528
31671
 
31529
31672
  const LockedPointSettings = props => {
31530
- var _flags$mafs, _flags$mafs2;
31673
+ var _flags$mafs, _flags$mafs2, _flags$mafs3;
31531
31674
  const {
31532
31675
  flags,
31533
31676
  headerLabel,
@@ -31535,6 +31678,7 @@ const LockedPointSettings = props => {
31535
31678
  color: pointColor,
31536
31679
  filled = true,
31537
31680
  labels,
31681
+ ariaLabel,
31538
31682
  onChangeProps,
31539
31683
  onMove,
31540
31684
  onRemove,
@@ -31545,6 +31689,31 @@ const LockedPointSettings = props => {
31545
31689
  onToggle
31546
31690
  } = props;
31547
31691
  const isDefiningPoint = !onMove && !onRemove;
31692
+
31693
+ /**
31694
+ * Get a prepopulated aria label for the point.
31695
+ *
31696
+ * If the point has no labels, the aria label will just be
31697
+ * "Point at (x, y)".
31698
+ *
31699
+ * If the point has labels, the aria label will be
31700
+ * "Point at (x, y) with label1, label2, label3".
31701
+ */
31702
+ function getPrepopulatedAriaLabel() {
31703
+ let str = `Point at (${coord[0]}, ${coord[1]})`;
31704
+ if (labels && labels.length > 0) {
31705
+ str += " with label";
31706
+ // Make it "with labels" instead of "with label" if there are
31707
+ // multiple labels.
31708
+ if (labels.length > 1) {
31709
+ str += "s";
31710
+ }
31711
+
31712
+ // Separate additional labels with commas.
31713
+ str += ` ${labels.map(l => l.text).join(", ")}`;
31714
+ }
31715
+ return str;
31716
+ }
31548
31717
  function handleColorChange(newValue) {
31549
31718
  const newProps = {
31550
31719
  color: newValue
@@ -31629,7 +31798,23 @@ const LockedPointSettings = props => {
31629
31798
  filled: !newValue
31630
31799
  });
31631
31800
  }
31632
- })), (!isDefiningPoint && (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-point-labels"]) || isDefiningPoint && (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-line-labels"])) && /*#__PURE__*/React.createElement(React.Fragment, null, labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
31801
+ })), !isDefiningPoint && (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-figures-aria"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
31802
+ size: spacing.small_12
31803
+ }), /*#__PURE__*/React.createElement(View, {
31804
+ style: styles$n.horizontalRule
31805
+ }), /*#__PURE__*/React.createElement(LockedFigureAria, {
31806
+ ariaLabel: ariaLabel,
31807
+ prePopulatedAriaLabel: getPrepopulatedAriaLabel(),
31808
+ onChangeProps: newProps => {
31809
+ onChangeProps(newProps);
31810
+ }
31811
+ })), (!isDefiningPoint && (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-point-labels"]) || isDefiningPoint && (flags == null || (_flags$mafs3 = flags["mafs"]) == null ? void 0 : _flags$mafs3["locked-line-labels"])) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
31812
+ size: spacing.xxxSmall_4
31813
+ }), /*#__PURE__*/React.createElement(View, {
31814
+ style: styles$n.horizontalRule
31815
+ }), /*#__PURE__*/React.createElement(Strut, {
31816
+ size: spacing.small_12
31817
+ }), /*#__PURE__*/React.createElement(LabelMedium, null, "Visible labels"), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
31633
31818
  containerStyle: !isDefiningPoint && styles$n.lockedPointLabelContainer,
31634
31819
  expanded: true,
31635
31820
  onChangeProps: newLabel => {
@@ -31691,12 +31876,16 @@ const styles$n = StyleSheet.create({
31691
31876
  },
31692
31877
  addButton: {
31693
31878
  alignSelf: "start"
31879
+ },
31880
+ horizontalRule: {
31881
+ height: 1,
31882
+ backgroundColor: color.offBlack16
31694
31883
  }
31695
31884
  });
31696
31885
 
31697
31886
  const lengthZeroStr = "The line cannot have length 0.";
31698
31887
  const LockedLineSettings = props => {
31699
- var _flags$mafs;
31888
+ var _flags$mafs, _flags$mafs2;
31700
31889
  const {
31701
31890
  flags,
31702
31891
  kind,
@@ -31706,6 +31895,7 @@ const LockedLineSettings = props => {
31706
31895
  showPoint1,
31707
31896
  showPoint2,
31708
31897
  labels,
31898
+ ariaLabel,
31709
31899
  onChangeProps,
31710
31900
  onMove,
31711
31901
  onRemove
@@ -31717,6 +31907,21 @@ const LockedLineSettings = props => {
31717
31907
 
31718
31908
  // Check if the line has length 0.
31719
31909
  const isInvalid = vector.equal(point1.coord, point2.coord);
31910
+ function getPrepopulatedAriaLabel() {
31911
+ let str = `${capitalizeKind} from (${point1.coord[0]}, ${point1.coord[1]}) to (${point2.coord[0]}, ${point2.coord[1]})`;
31912
+ if (labels && labels.length > 0) {
31913
+ str += " with label";
31914
+ // Make it "with labels" instead of "with label" if there are
31915
+ // multiple labels.
31916
+ if (labels.length > 1) {
31917
+ str += "s";
31918
+ }
31919
+
31920
+ // Separate additional labels with commas.
31921
+ str += ` ${labels.map(l => l.text).join(", ")}`;
31922
+ }
31923
+ return str;
31924
+ }
31720
31925
  function handleChangePoint(newPointProps, index) {
31721
31926
  const newPoints = [...points];
31722
31927
  newPoints[index] = _extends({}, points[index], newPointProps);
@@ -31845,9 +32050,23 @@ const LockedLineSettings = props => {
31845
32050
  showPoint2: newValue
31846
32051
  }),
31847
32052
  onChangeProps: newProps => handleChangePoint(newProps, 1)
31848
- })), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-line-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
32053
+ })), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-figures-aria"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
32054
+ size: spacing.small_12
32055
+ }), /*#__PURE__*/React.createElement(View, {
32056
+ style: styles$m.horizontalRule
32057
+ }), /*#__PURE__*/React.createElement(LockedFigureAria, {
32058
+ ariaLabel: ariaLabel,
32059
+ prePopulatedAriaLabel: getPrepopulatedAriaLabel(),
32060
+ onChangeProps: newProps => {
32061
+ onChangeProps(newProps);
32062
+ }
32063
+ })), (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-line-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
32064
+ size: spacing.xxxSmall_4
32065
+ }), /*#__PURE__*/React.createElement(View, {
31849
32066
  style: styles$m.horizontalRule
31850
- }), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
32067
+ }), /*#__PURE__*/React.createElement(Strut, {
32068
+ size: spacing.small_12
32069
+ }), /*#__PURE__*/React.createElement(LabelMedium, null, "Visible labels"), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
31851
32070
  expanded: true,
31852
32071
  onChangeProps: newLabel => {
31853
32072
  handleLabelChange(newLabel, labelIndex);
@@ -31897,8 +32116,6 @@ const styles$m = StyleSheet.create({
31897
32116
  alignSelf: "start"
31898
32117
  },
31899
32118
  horizontalRule: {
31900
- marginTop: spacing.small_12,
31901
- marginBottom: spacing.xxxSmall_4,
31902
32119
  height: 1,
31903
32120
  backgroundColor: color.offBlack16
31904
32121
  },
@@ -31943,47 +32160,106 @@ const styles$l = StyleSheet.create({
31943
32160
  });
31944
32161
 
31945
32162
  const LockedPolygonSettings = props => {
32163
+ var _flags$mafs, _flags$mafs2;
31946
32164
  const {
32165
+ flags,
31947
32166
  points,
31948
32167
  color,
31949
32168
  showVertices,
31950
32169
  fillStyle,
31951
32170
  strokeStyle,
32171
+ labels,
32172
+ ariaLabel,
31952
32173
  expanded,
31953
32174
  onToggle,
31954
32175
  onChangeProps,
31955
32176
  onMove,
31956
32177
  onRemove
31957
32178
  } = props;
32179
+ function getPrepopulatedAriaLabel() {
32180
+ let str = `Polygon with ${points.length} sides, vertices at `;
32181
+
32182
+ // Add the coordinates of each point to the aria label
32183
+ str += points.map(([x, y]) => `(${x}, ${y})`).join(", ");
32184
+ if (labels && labels.length > 0) {
32185
+ str += ", with label";
32186
+ // Make it "with labels" instead of "with label" if there are
32187
+ // multiple labels.
32188
+ if (labels.length > 1) {
32189
+ str += "s";
32190
+ }
32191
+
32192
+ // Separate additional labels with commas.
32193
+ str += ` ${labels.map(l => l.text).join(", ")}`;
32194
+ }
32195
+ return str;
32196
+ }
31958
32197
  function handleColorChange(newValue) {
31959
- onChangeProps({
32198
+ const newProps = {
31960
32199
  color: newValue
31961
- });
32200
+ };
32201
+
32202
+ // Update the color of the all labels to match the point
32203
+ newProps.labels = labels == null ? void 0 : labels.map(label => _extends({}, label, {
32204
+ color: newValue
32205
+ }));
32206
+ onChangeProps(newProps);
31962
32207
  }
31963
32208
  function handlePolygonMove(movement) {
31964
32209
  switch (movement) {
31965
32210
  case "up":
31966
32211
  onChangeProps({
31967
- points: points.map(([x, y]) => [x, y + 1])
32212
+ points: points.map(([x, y]) => [x, y + 1]),
32213
+ labels: labels == null ? void 0 : labels.map(label => _extends({}, label, {
32214
+ coord: [label.coord[0], label.coord[1] + 1]
32215
+ }))
31968
32216
  });
31969
32217
  break;
31970
32218
  case "down":
31971
32219
  onChangeProps({
31972
- points: points.map(([x, y]) => [x, y - 1])
32220
+ points: points.map(([x, y]) => [x, y - 1]),
32221
+ labels: labels == null ? void 0 : labels.map(label => _extends({}, label, {
32222
+ coord: [label.coord[0], label.coord[1] - 1]
32223
+ }))
31973
32224
  });
31974
32225
  break;
31975
32226
  case "left":
31976
32227
  onChangeProps({
31977
- points: points.map(([x, y]) => [x - 1, y])
32228
+ points: points.map(([x, y]) => [x - 1, y]),
32229
+ labels: labels == null ? void 0 : labels.map(label => _extends({}, label, {
32230
+ coord: [label.coord[0] - 1, label.coord[1]]
32231
+ }))
31978
32232
  });
31979
32233
  break;
31980
32234
  case "right":
31981
32235
  onChangeProps({
31982
- points: points.map(([x, y]) => [x + 1, y])
32236
+ points: points.map(([x, y]) => [x + 1, y]),
32237
+ labels: labels == null ? void 0 : labels.map(label => _extends({}, label, {
32238
+ coord: [label.coord[0] + 1, label.coord[1]]
32239
+ }))
31983
32240
  });
31984
32241
  break;
31985
32242
  }
31986
32243
  }
32244
+ function handleLabelChange(updatedLabel, labelIndex) {
32245
+ if (!labels) {
32246
+ return;
32247
+ }
32248
+ const updatedLabels = [...labels];
32249
+ updatedLabels[labelIndex] = _extends({}, labels[labelIndex], updatedLabel);
32250
+ onChangeProps({
32251
+ labels: updatedLabels
32252
+ });
32253
+ }
32254
+ function handleLabelRemove(labelIndex) {
32255
+ if (!labels) {
32256
+ return;
32257
+ }
32258
+ const updatedLabels = labels.filter((_, index) => index !== labelIndex);
32259
+ onChangeProps({
32260
+ labels: updatedLabels
32261
+ });
32262
+ }
31987
32263
  return /*#__PURE__*/React.createElement(PerseusEditorAccordion, {
31988
32264
  expanded: expanded,
31989
32265
  onToggle: onToggle,
@@ -32112,7 +32388,50 @@ const LockedPolygonSettings = props => {
32112
32388
  size: "small",
32113
32389
  icon: arrowFatRight,
32114
32390
  onClick: () => handlePolygonMove("right")
32115
- }))))), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
32391
+ }))))), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-figures-aria"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
32392
+ size: spacing.small_12
32393
+ }), /*#__PURE__*/React.createElement(View, {
32394
+ style: styles$k.horizontalRule
32395
+ }), /*#__PURE__*/React.createElement(LockedFigureAria, {
32396
+ ariaLabel: ariaLabel,
32397
+ prePopulatedAriaLabel: getPrepopulatedAriaLabel(),
32398
+ onChangeProps: newProps => {
32399
+ onChangeProps(newProps);
32400
+ }
32401
+ })), (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-polygon-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
32402
+ size: spacing.xxxSmall_4
32403
+ }), /*#__PURE__*/React.createElement(View, {
32404
+ style: styles$k.horizontalRule
32405
+ }), /*#__PURE__*/React.createElement(Strut, {
32406
+ size: spacing.small_12
32407
+ }), /*#__PURE__*/React.createElement(LabelMedium, null, "Visible labels"), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
32408
+ expanded: true,
32409
+ onChangeProps: newLabel => {
32410
+ handleLabelChange(newLabel, labelIndex);
32411
+ },
32412
+ onRemove: () => {
32413
+ handleLabelRemove(labelIndex);
32414
+ },
32415
+ containerStyle: styles$k.labelContainer
32416
+ }))), /*#__PURE__*/React.createElement(Button, {
32417
+ kind: "tertiary",
32418
+ startIcon: plusCircle,
32419
+ onClick: () => {
32420
+ var _labels$length;
32421
+ const newLabel = _extends({}, getDefaultFigureForType("label"), {
32422
+ coord: [points[0][0],
32423
+ // Additional vertical offset for each
32424
+ // label so they don't overlap.
32425
+ points[0][1] - ((_labels$length = labels == null ? void 0 : labels.length) != null ? _labels$length : 0)],
32426
+ // Default to the same color as the ellipse
32427
+ color: color
32428
+ });
32429
+ onChangeProps({
32430
+ labels: [...(labels != null ? labels : []), newLabel]
32431
+ });
32432
+ },
32433
+ style: styles$k.addButton
32434
+ }, "Add visible label")), /*#__PURE__*/React.createElement(LockedFigureSettingsActions, {
32116
32435
  figureType: props.type,
32117
32436
  onMove: onMove,
32118
32437
  onRemove: onRemove
@@ -32151,17 +32470,29 @@ const styles$k = StyleSheet.create({
32151
32470
  truncatedWidth: {
32152
32471
  // Allow truncation, stop bleeding over the edge.
32153
32472
  minWidth: 0
32473
+ },
32474
+ // Styles for the visible labels section
32475
+ addButton: {
32476
+ alignSelf: "start"
32477
+ },
32478
+ labelContainer: {
32479
+ backgroundColor: color.white
32480
+ },
32481
+ horizontalRule: {
32482
+ height: 1,
32483
+ backgroundColor: color.offBlack16
32154
32484
  }
32155
32485
  });
32156
32486
 
32157
32487
  const lengthErrorMessage = "The vector cannot have length 0.";
32158
32488
  const LockedVectorSettings = props => {
32159
- var _flags$mafs;
32489
+ var _flags$mafs, _flags$mafs2;
32160
32490
  const {
32161
32491
  flags,
32162
32492
  points,
32163
32493
  color: lineColor,
32164
32494
  labels,
32495
+ ariaLabel,
32165
32496
  onChangeProps,
32166
32497
  onMove,
32167
32498
  onRemove
@@ -32171,6 +32502,21 @@ const LockedVectorSettings = props => {
32171
32502
 
32172
32503
  // Check if the line has length 0.
32173
32504
  const isInvalid = vector.equal(tail, tip);
32505
+ function getPrepopulatedAriaLabel() {
32506
+ let str = `Vector from (${tail[0]}, ${tail[1]}) to (${tip[0]}, ${tip[1]})`;
32507
+ if (labels && labels.length > 0) {
32508
+ str += " with label";
32509
+ // Make it "with labels" instead of "with label" if there are
32510
+ // multiple labels.
32511
+ if (labels.length > 1) {
32512
+ str += "s";
32513
+ }
32514
+
32515
+ // Separate additional labels with commas.
32516
+ str += ` ${labels.map(l => l.text).join(", ")}`;
32517
+ }
32518
+ return str;
32519
+ }
32174
32520
  function handleChangePoint(newCoord, index) {
32175
32521
  if (typeof newCoord !== "undefined") {
32176
32522
  const newPoints = [...points];
@@ -32265,9 +32611,23 @@ const LockedVectorSettings = props => {
32265
32611
  onChange: newProps => {
32266
32612
  handleChangePoint(newProps, 1);
32267
32613
  }
32268
- })), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-vector-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(View, {
32614
+ })), (flags == null || (_flags$mafs = flags["mafs"]) == null ? void 0 : _flags$mafs["locked-figures-aria"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
32615
+ size: spacing.small_12
32616
+ }), /*#__PURE__*/React.createElement(View, {
32617
+ style: styles$j.horizontalRule
32618
+ }), /*#__PURE__*/React.createElement(LockedFigureAria, {
32619
+ ariaLabel: ariaLabel,
32620
+ prePopulatedAriaLabel: getPrepopulatedAriaLabel(),
32621
+ onChangeProps: newProps => {
32622
+ onChangeProps(newProps);
32623
+ }
32624
+ })), (flags == null || (_flags$mafs2 = flags["mafs"]) == null ? void 0 : _flags$mafs2["locked-vector-labels"]) && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Strut, {
32625
+ size: spacing.xxxSmall_4
32626
+ }), /*#__PURE__*/React.createElement(View, {
32269
32627
  style: styles$j.horizontalRule
32270
- }), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
32628
+ }), /*#__PURE__*/React.createElement(Strut, {
32629
+ size: spacing.small_12
32630
+ }), /*#__PURE__*/React.createElement(LabelMedium, null, "Visible labels"), labels == null ? void 0 : labels.map((label, labelIndex) => /*#__PURE__*/React.createElement(LockedLabelSettings, _extends({}, label, {
32271
32631
  expanded: true,
32272
32632
  onChangeProps: newLabel => {
32273
32633
  handleLabelChange(newLabel, labelIndex);
@@ -32324,8 +32684,6 @@ const styles$j = StyleSheet.create({
32324
32684
  alignSelf: "start"
32325
32685
  },
32326
32686
  horizontalRule: {
32327
- marginTop: spacing.small_12,
32328
- marginBottom: spacing.xxxSmall_4,
32329
32687
  height: 1,
32330
32688
  backgroundColor: color.offBlack16
32331
32689
  },