@khanacademy/perseus-editor 5.0.2 → 5.0.3

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
@@ -18,26 +18,31 @@ import { point, number } from '@khanacademy/kmath';
18
18
  import * as KAS from '@khanacademy/kas';
19
19
  import { isTruthy } from '@khanacademy/wonder-stuff-core';
20
20
  import { createMathField } from '@khanacademy/math-input';
21
+ import { SingleSelect, OptionItem } from '@khanacademy/wonder-blocks-dropdown';
22
+ import { Checkbox as Checkbox$1 } from '@khanacademy/wonder-blocks-form';
21
23
  import Spacing from '@khanacademy/wonder-blocks-spacing';
22
- import * as Typography from '@khanacademy/wonder-blocks-typography';
24
+ import { LabelSmall, BodyMonospace } from '@khanacademy/wonder-blocks-typography';
25
+ import { spacing, color } from '@khanacademy/wonder-blocks-tokens';
23
26
  import Button from '@khanacademy/wonder-blocks-button';
24
27
  import * as i18n$1 from '@khanacademy/wonder-blocks-i18n';
25
28
 
26
29
  // This file is processed by a Rollup plugin (replace) to inject the production
27
30
  const libName = "@khanacademy/perseus-editor";
28
- const libVersion = "5.0.2";
31
+ const libVersion = "5.0.3";
29
32
  addLibraryVersionToPerseusDebug(libName, libVersion);
30
33
 
31
34
  function _extends() {
32
35
  _extends = Object.assign ? Object.assign.bind() : function (target) {
33
36
  for (var i = 1; i < arguments.length; i++) {
34
37
  var source = arguments[i];
38
+
35
39
  for (var key in source) {
36
40
  if (Object.prototype.hasOwnProperty.call(source, key)) {
37
41
  target[key] = source[key];
38
42
  }
39
43
  }
40
44
  }
45
+
41
46
  return target;
42
47
  };
43
48
  return _extends.apply(this, arguments);
@@ -219,7 +224,7 @@ class SectionControlButton extends React.Component {
219
224
  role: "button",
220
225
  hideDefaultFocusRing: true,
221
226
  "aria-label": title,
222
- style: styles$g.button
227
+ style: styles$m.button
223
228
  }, ({
224
229
  hovered,
225
230
  focused,
@@ -227,7 +232,7 @@ class SectionControlButton extends React.Component {
227
232
  }) => /*#__PURE__*/React.createElement(InlineIcon$b, icon));
228
233
  }
229
234
  }
230
- const styles$g = StyleSheet.create({
235
+ const styles$m = StyleSheet.create({
231
236
  button: {
232
237
  backgroundColor: Color.gold,
233
238
  margin: 2,
@@ -20749,19 +20754,19 @@ class TexErrorView extends React.Component {
20749
20754
  const {
20750
20755
  showErrors
20751
20756
  } = this.state;
20752
- const iconStyle = showErrors ? styles$f.iconExpanded : styles$f.iconCollapsed;
20757
+ const iconStyle = showErrors ? styles$l.iconExpanded : styles$l.iconCollapsed;
20753
20758
  return /*#__PURE__*/React.createElement(View, {
20754
- style: styles$f.errorContainer
20759
+ style: styles$l.errorContainer
20755
20760
  }, /*#__PURE__*/React.createElement(View, {
20756
- style: styles$f.title,
20761
+ style: styles$l.title,
20757
20762
  onClick: this.handleToggleTexErrors
20758
20763
  }, /*#__PURE__*/React.createElement(PhosphorIcon, {
20759
20764
  icon: caretRight,
20760
20765
  style: iconStyle
20761
20766
  }), "\xA0 TeX Errors (", errorList.length, ")"), showErrors && /*#__PURE__*/React.createElement(View, {
20762
- style: styles$f.errorExplanation
20767
+ style: styles$l.errorExplanation
20763
20768
  }, "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, {
20764
- style: styles$f.error,
20769
+ style: styles$l.error,
20765
20770
  key: index
20766
20771
  }, /*#__PURE__*/React.createElement(View, {
20767
20772
  style: {
@@ -20770,7 +20775,7 @@ class TexErrorView extends React.Component {
20770
20775
  }, e.math), /*#__PURE__*/React.createElement(View, null, e.message))));
20771
20776
  }
20772
20777
  }
20773
- const styles$f = StyleSheet.create({
20778
+ const styles$l = StyleSheet.create({
20774
20779
  title: {
20775
20780
  backgroundColor: "#eee",
20776
20781
  fontSize: "1.25em",
@@ -24363,11 +24368,13 @@ function _objectWithoutPropertiesLoose(source, excluded) {
24363
24368
  var target = {};
24364
24369
  var sourceKeys = Object.keys(source);
24365
24370
  var key, i;
24371
+
24366
24372
  for (i = 0; i < sourceKeys.length; i++) {
24367
24373
  key = sourceKeys[i];
24368
24374
  if (excluded.indexOf(key) >= 0) continue;
24369
24375
  target[key] = source[key];
24370
24376
  }
24377
+
24371
24378
  return target;
24372
24379
  }
24373
24380
 
@@ -24599,7 +24606,7 @@ class SimpleButton extends React.Component {
24599
24606
  } = _this$props,
24600
24607
  otherProps = _objectWithoutPropertiesLoose(_this$props, _excluded$3);
24601
24608
  return /*#__PURE__*/React.createElement("div", _extends({
24602
- className: css(styles$e.baseButton, color === "green" && styles$e.green, color === "orange" && styles$e.orange),
24609
+ className: css(styles$k.baseButton, color === "green" && styles$k.green, color === "orange" && styles$k.orange),
24603
24610
  onClick: onClick
24604
24611
  }, otherProps), children);
24605
24612
  }
@@ -24614,7 +24621,7 @@ SimpleButton.defaultProps = {
24614
24621
  color: "green",
24615
24622
  onClick: () => {}
24616
24623
  };
24617
- const styles$e = StyleSheet.create({
24624
+ const styles$k = StyleSheet.create({
24618
24625
  baseButton: {
24619
24626
  top: "0",
24620
24627
  fontSize: "11px",
@@ -24834,23 +24841,23 @@ const LeafContainer = ({
24834
24841
  }) => {
24835
24842
  const hasPreviewHeading = shape.type === "content" || shape.type === "hint";
24836
24843
  const previewHeading = hasPreviewHeading && /*#__PURE__*/React.createElement("div", {
24837
- className: css(styles$d.containerHeader)
24844
+ className: css(styles$j.containerHeader)
24838
24845
  }, /*#__PURE__*/React.createElement(Header, {
24839
24846
  depth: path.length,
24840
- className: css(styles$d.containerTitle)
24847
+ className: css(styles$j.containerTitle)
24841
24848
  }, capitalize(name)));
24842
24849
  return /*#__PURE__*/React.createElement("div", {
24843
- className: css(styles$d.container)
24850
+ className: css(styles$j.container)
24844
24851
  }, /*#__PURE__*/React.createElement("span", {
24845
- className: css(styles$d.row, styles$d.rowHeading)
24852
+ className: css(styles$j.row, styles$j.rowHeading)
24846
24853
  }, /*#__PURE__*/React.createElement("div", {
24847
- className: css(styles$d.columnLeft)
24854
+ className: css(styles$j.columnLeft)
24848
24855
  }, /*#__PURE__*/React.createElement("div", {
24849
- className: "pod-title " + css(styles$d.containerHeader)
24856
+ className: "pod-title " + css(styles$j.containerHeader)
24850
24857
  }, /*#__PURE__*/React.createElement("div", {
24851
- className: css(styles$d.containerTitle)
24858
+ className: css(styles$j.containerTitle)
24852
24859
  }, capitalize(name)), controls)), /*#__PURE__*/React.createElement("div", {
24853
- className: css(styles$d.columnRight)
24860
+ className: css(styles$j.columnRight)
24854
24861
  }, previewHeading)), children);
24855
24862
  };
24856
24863
  const ArrayContainer = props => {
@@ -24863,11 +24870,11 @@ const ArrayContainer = props => {
24863
24870
  actions
24864
24871
  } = props;
24865
24872
  return /*#__PURE__*/React.createElement("div", {
24866
- className: css(styles$d.container)
24873
+ className: css(styles$j.container)
24867
24874
  }, controls && /*#__PURE__*/React.createElement("div", {
24868
- className: css(styles$d.columnLeft, styles$d.containerHeader)
24875
+ className: css(styles$j.columnLeft, styles$j.containerHeader)
24869
24876
  }, controls), /*#__PURE__*/React.createElement("div", null, children), /*#__PURE__*/React.createElement("div", {
24870
- className: css(styles$d.columnLeft)
24877
+ className: css(styles$j.columnLeft)
24871
24878
  }, /*#__PURE__*/React.createElement("a", {
24872
24879
  href: "javascript:void 0",
24873
24880
  onClick: () => actions.addArrayElement(path, shape.elementShape)
@@ -24880,28 +24887,28 @@ const ObjectContainer = ({
24880
24887
  path
24881
24888
  }) => {
24882
24889
  const headingEditor = /*#__PURE__*/React.createElement("div", {
24883
- className: css(styles$d.containerHeader)
24890
+ className: css(styles$j.containerHeader)
24884
24891
  }, /*#__PURE__*/React.createElement(Header, {
24885
24892
  depth: path.length,
24886
- className: css(styles$d.containerTitle)
24893
+ className: css(styles$j.containerTitle)
24887
24894
  }, capitalize(name)), controls);
24888
24895
  const headingPreview = (name || controls) && /*#__PURE__*/React.createElement("div", {
24889
- className: css(styles$d.containerHeader, styles$d.previewCollectionHeader)
24896
+ className: css(styles$j.containerHeader, styles$j.previewCollectionHeader)
24890
24897
  }, /*#__PURE__*/React.createElement(Header, {
24891
24898
  depth: path.length,
24892
- className: css(styles$d.containerTitle)
24899
+ className: css(styles$j.containerTitle)
24893
24900
  }, capitalize(name)));
24894
24901
  const hasBothHeadings = headingEditor && headingPreview;
24895
24902
  return /*#__PURE__*/React.createElement("div", {
24896
- className: css(styles$d.container)
24903
+ className: css(styles$j.container)
24897
24904
  }, hasBothHeadings && /*#__PURE__*/React.createElement("span", {
24898
- className: css(styles$d.row)
24905
+ className: css(styles$j.row)
24899
24906
  }, /*#__PURE__*/React.createElement("div", {
24900
- className: css(styles$d.columnLeft)
24907
+ className: css(styles$j.columnLeft)
24901
24908
  }, headingEditor), /*#__PURE__*/React.createElement("div", {
24902
- className: css(styles$d.columnRight)
24909
+ className: css(styles$j.columnRight)
24903
24910
  }, headingPreview)), /*#__PURE__*/React.createElement("div", {
24904
- className: css(path.length > 0 && styles$d.contentIndent)
24911
+ className: css(path.length > 0 && styles$j.contentIndent)
24905
24912
  }, children));
24906
24913
  };
24907
24914
 
@@ -25024,11 +25031,11 @@ const ItemNodeContent = withStickiness(props => {
25024
25031
  className: "framework-perseus"
25025
25032
  }, lens(renderers).get(path));
25026
25033
  return /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement("div", {
25027
- className: css(styles$d.row)
25034
+ className: css(styles$j.row)
25028
25035
  }, /*#__PURE__*/React.createElement("div", {
25029
- className: css(styles$d.columnLeft)
25036
+ className: css(styles$j.columnLeft)
25030
25037
  }, /*#__PURE__*/React.createElement("div", {
25031
- className: css(sticky && styles$d.sticky)
25038
+ className: css(sticky && styles$j.sticky)
25032
25039
  },
25033
25040
  /*#__PURE__*/
25034
25041
  // @ts-expect-error - TS2769 - No overload matches this call.
@@ -25036,9 +25043,9 @@ const ItemNodeContent = withStickiness(props => {
25036
25043
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25037
25044
  apiOptions: apiOptions
25038
25045
  })))), /*#__PURE__*/React.createElement("div", {
25039
- className: css(styles$d.columnRight)
25046
+ className: css(styles$j.columnRight)
25040
25047
  }, /*#__PURE__*/React.createElement("div", {
25041
- className: css(sticky && styles$d.sticky)
25048
+ className: css(sticky && styles$j.sticky)
25042
25049
  }, preview))));
25043
25050
  });
25044
25051
  const HintNodeContent = withStickiness(props => {
@@ -25054,13 +25061,13 @@ const HintNodeContent = withStickiness(props => {
25054
25061
  className: "framework-perseus"
25055
25062
  }, lens(renderers).get(path));
25056
25063
  return /*#__PURE__*/React.createElement("div", {
25057
- className: css(styles$d.row)
25064
+ className: css(styles$j.row)
25058
25065
  }, /*#__PURE__*/React.createElement("div", {
25059
- className: css(styles$d.columnLeft)
25066
+ className: css(styles$j.columnLeft)
25060
25067
  }, /*#__PURE__*/React.createElement("div", {
25061
- className: css(sticky && styles$d.sticky)
25068
+ className: css(sticky && styles$j.sticky)
25062
25069
  }, /*#__PURE__*/React.createElement(HintEditor, _extends({}, data, {
25063
- className: css(styles$d.hintEditor),
25070
+ className: css(styles$j.hintEditor),
25064
25071
  onChange: newVal => actions.mergeValueAtPath(path, newVal),
25065
25072
  apiOptions: apiOptions,
25066
25073
  showTitle: false,
@@ -25075,9 +25082,9 @@ const HintNodeContent = withStickiness(props => {
25075
25082
  isFirst: true,
25076
25083
  isLast: true
25077
25084
  })))), /*#__PURE__*/React.createElement("div", {
25078
- className: css(styles$d.columnRight)
25085
+ className: css(styles$j.columnRight)
25079
25086
  }, /*#__PURE__*/React.createElement("div", {
25080
- className: css(sticky && styles$d.sticky)
25087
+ className: css(sticky && styles$j.sticky)
25081
25088
  }, preview)));
25082
25089
  });
25083
25090
  const TagsNodeContent = props => {
@@ -25094,9 +25101,9 @@ const TagsNodeContent = props => {
25094
25101
  return null;
25095
25102
  }
25096
25103
  return /*#__PURE__*/React.createElement("div", {
25097
- className: css(styles$d.columnLeft)
25104
+ className: css(styles$j.columnLeft)
25098
25105
  }, /*#__PURE__*/React.createElement("div", {
25099
- className: css(styles$d.tagsEditor)
25106
+ className: css(styles$j.tagsEditor)
25100
25107
  }, /*#__PURE__*/React.createElement(GroupMetadataEditor, {
25101
25108
  value: data,
25102
25109
  onChange: newVal => actions.setValueAtPath(path, newVal),
@@ -25127,23 +25134,23 @@ const ArrayNodeContent = props => {
25127
25134
  const subpath = path.concat(i);
25128
25135
  const controls = [i > 0 && /*#__PURE__*/React.createElement("div", {
25129
25136
  key: "moveArrayElementUp",
25130
- className: css(styles$d.control)
25137
+ className: css(styles$j.control)
25131
25138
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25132
25139
  color: "orange",
25133
25140
  title: "Move up",
25134
25141
  onClick: () => actions.moveArrayElementUp(subpath)
25135
25142
  }, /*#__PURE__*/React.createElement("div", {
25136
- className: css(styles$d.verticalFlip)
25143
+ className: css(styles$j.verticalFlip)
25137
25144
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown)))), i < data.length - 1 && /*#__PURE__*/React.createElement("div", {
25138
25145
  key: "moveArrayElementDown",
25139
- className: css(styles$d.control)
25146
+ className: css(styles$j.control)
25140
25147
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25141
25148
  color: "orange",
25142
25149
  title: "Move down",
25143
25150
  onClick: () => actions.moveArrayElementDown(subpath)
25144
25151
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconChevronDown))), /*#__PURE__*/React.createElement("div", {
25145
25152
  key: "removeArrayElement",
25146
- className: css(styles$d.control)
25153
+ className: css(styles$j.control)
25147
25154
  }, /*#__PURE__*/React.createElement(SimpleButton, {
25148
25155
  color: "orange",
25149
25156
  title: "Delete",
@@ -25151,7 +25158,7 @@ const ArrayNodeContent = props => {
25151
25158
  }, /*#__PURE__*/React.createElement(InlineIcon$6, iconTrash$4)))];
25152
25159
  return /*#__PURE__*/React.createElement("div", {
25153
25160
  key: i,
25154
- className: css(styles$d.arrayElement, !elementIsLeaf && styles$d.arrayElementAndNotLeaf)
25161
+ className: css(styles$j.arrayElement, !elementIsLeaf && styles$j.arrayElementAndNotLeaf)
25155
25162
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25156
25163
  key: i,
25157
25164
  shape: shape.elementShape,
@@ -25177,7 +25184,7 @@ const ObjectNodeContent = props => {
25177
25184
  // made sense to the shape's author is the order in which we'll iterate :)
25178
25185
  const children = Object.keys(shape.shape).map(subkey => /*#__PURE__*/React.createElement("div", {
25179
25186
  key: subkey,
25180
- className: css(styles$d.objectElement)
25187
+ className: css(styles$j.objectElement)
25181
25188
  }, /*#__PURE__*/React.createElement(NodeContainer, _extends({}, otherProps, {
25182
25189
  shape: shape.shape[subkey],
25183
25190
  data: data[subkey],
@@ -25344,7 +25351,7 @@ class MultiRendererEditor extends React.Component {
25344
25351
  }, this._renderContent());
25345
25352
  }
25346
25353
  }
25347
- const styles$d = StyleSheet.create({
25354
+ const styles$j = StyleSheet.create({
25348
25355
  // This is used in a number of places throughout this file.
25349
25356
  container: {},
25350
25357
  // eslint-disable-next-line react-native/no-unused-styles
@@ -25496,47 +25503,47 @@ const StatefulArticleEditor = createReactClass({
25496
25503
  screen
25497
25504
  } = this.state;
25498
25505
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
25499
- style: styles$c.controlBar
25506
+ style: styles$i.controlBar
25500
25507
  }, /*#__PURE__*/React.createElement("span", {
25501
- style: styles$c.controls
25508
+ style: styles$i.controls
25502
25509
  }, "Mode:", " ", /*#__PURE__*/React.createElement("span", {
25503
25510
  onClick: () => this.setState({
25504
25511
  mode: "edit"
25505
25512
  }),
25506
- style: mode === "edit" ? styles$c.controlSelected : styles$c.control
25513
+ style: mode === "edit" ? styles$i.controlSelected : styles$i.control
25507
25514
  }, "EDIT"), " | ", /*#__PURE__*/React.createElement("span", {
25508
25515
  onClick: () => this.setState({
25509
25516
  mode: "preview"
25510
25517
  }),
25511
- style: mode === "preview" ? styles$c.controlSelected : styles$c.control
25518
+ style: mode === "preview" ? styles$i.controlSelected : styles$i.control
25512
25519
  }, "PREVIEW"), " | ", /*#__PURE__*/React.createElement("span", {
25513
25520
  onClick: () => this.setState({
25514
25521
  mode: "json"
25515
25522
  }),
25516
- style: mode === "json" ? styles$c.controlSelected : styles$c.control
25523
+ style: mode === "json" ? styles$i.controlSelected : styles$i.control
25517
25524
  }, "JSON")), /*#__PURE__*/React.createElement("span", {
25518
- style: styles$c.controls
25525
+ style: styles$i.controls
25519
25526
  }, "Screen:", " ", /*#__PURE__*/React.createElement("span", {
25520
25527
  onClick: () => this.setState({
25521
25528
  screen: "phone"
25522
25529
  }),
25523
- style: screen === "phone" ? styles$c.controlSelected : styles$c.control
25530
+ style: screen === "phone" ? styles$i.controlSelected : styles$i.control
25524
25531
  }, "PHONE"), " | ", /*#__PURE__*/React.createElement("span", {
25525
25532
  onClick: () => this.setState({
25526
25533
  screen: "tablet"
25527
25534
  }),
25528
- style: screen === "tablet" ? styles$c.controlSelected : styles$c.control
25535
+ style: screen === "tablet" ? styles$i.controlSelected : styles$i.control
25529
25536
  }, "TABLET"), " | ", /*#__PURE__*/React.createElement("span", {
25530
25537
  onClick: () => this.setState({
25531
25538
  screen: "desktop"
25532
25539
  }),
25533
- style: screen === "desktop" ? styles$c.controlSelected : styles$c.control
25540
+ style: screen === "desktop" ? styles$i.controlSelected : styles$i.control
25534
25541
  }, "DESKTOP"))), /*#__PURE__*/React.createElement("div", {
25535
- style: styles$c.editor
25542
+ style: styles$i.editor
25536
25543
  }, /*#__PURE__*/React.createElement(ArticleEditor, this.state)));
25537
25544
  }
25538
25545
  });
25539
- const styles$c = {
25546
+ const styles$i = {
25540
25547
  controlBar: {
25541
25548
  marginBottom: 25,
25542
25549
  marginTop: 5
@@ -27025,10 +27032,10 @@ class GradedGroupEditor extends React.Component {
27025
27032
  }, /*#__PURE__*/React.createElement("div", {
27026
27033
  className: "perseus-widget-row"
27027
27034
  }, /*#__PURE__*/React.createElement("label", {
27028
- className: css(styles$b.title)
27035
+ className: css(styles$h.title)
27029
27036
  }, "Title:", " ", /*#__PURE__*/React.createElement(TextInput$6, {
27030
27037
  value: this.props.title,
27031
- className: css(styles$b.input)
27038
+ className: css(styles$h.input)
27032
27039
  // @ts-expect-error - TS2554 - Expected 3 arguments, but got 1.
27033
27040
  ,
27034
27041
  onChange: this.change("title")
@@ -27053,7 +27060,7 @@ class GradedGroupEditor extends React.Component {
27053
27060
  }, /*#__PURE__*/React.createElement(InlineIcon$4, iconPlus$1), " Add a hint"), this.props.hint && /*#__PURE__*/React.createElement("div", {
27054
27061
  className: "perseus-hint-editor"
27055
27062
  }, /*#__PURE__*/React.createElement("div", {
27056
- className: css(styles$b.hintsTitle)
27063
+ className: css(styles$h.hintsTitle)
27057
27064
  }, "Hint"), /*#__PURE__*/React.createElement(Editor, {
27058
27065
  ref: this.hintEditor,
27059
27066
  content: this.props.hint ? this.props.hint.content : "",
@@ -27090,7 +27097,7 @@ GradedGroupEditor.defaultProps = {
27090
27097
  images: {},
27091
27098
  hint: null
27092
27099
  };
27093
- const styles$b = StyleSheet.create({
27100
+ const styles$h = StyleSheet.create({
27094
27101
  title: {
27095
27102
  fontSize: 18,
27096
27103
  fontWeight: "bold"
@@ -28422,13 +28429,13 @@ function MathquillInput(props) {
28422
28429
  }
28423
28430
  });
28424
28431
  return /*#__PURE__*/React.createElement(View, {
28425
- style: styles$a.outerWrapper
28432
+ style: styles$g.outerWrapper
28426
28433
  }, /*#__PURE__*/React.createElement("span", {
28427
28434
  ref: mathFieldWrapperRef,
28428
28435
  className: "perseus-math-input mq-editable-field mq-math-mode"
28429
28436
  }));
28430
28437
  }
28431
- const styles$a = StyleSheet.create({
28438
+ const styles$g = StyleSheet.create({
28432
28439
  outerWrapper: {
28433
28440
  display: "inline-block",
28434
28441
  borderStyle: "solid",
@@ -29481,48 +29488,107 @@ const GraphPointsCountSelector = ({
29481
29488
  numPoints: _numPoints = 1,
29482
29489
  onChange
29483
29490
  }) => {
29484
- return /*#__PURE__*/React.createElement("select", {
29485
- value: _numPoints,
29486
- onChange: e => {
29487
- onChange(parsePointCount(e.target.value));
29491
+ return /*#__PURE__*/React.createElement(SingleSelect, {
29492
+ selectedValue: `${_numPoints}`,
29493
+ onChange: newValue => {
29494
+ onChange(parsePointCount(newValue));
29488
29495
  }
29489
- }, [...Array(7).keys()].map(n => /*#__PURE__*/React.createElement("option", {
29496
+ // Never uses placeholder, always has value
29497
+ ,
29498
+ placeholder: "",
29499
+ style: styles$f.singleSelectShort
29500
+ }, [...[...Array(7).keys()].map(n => /*#__PURE__*/React.createElement(OptionItem, {
29490
29501
  key: n,
29491
- value: n
29492
- }, `${n} point${n > 1 ? "s" : ""}`)), /*#__PURE__*/React.createElement("option", {
29493
- value: UNLIMITED
29494
- }, "unlimited"));
29502
+ value: `${n}`,
29503
+ label: `${n} point${n > 1 ? "s" : ""}`
29504
+ })), /*#__PURE__*/React.createElement(OptionItem, {
29505
+ value: UNLIMITED,
29506
+ label: "unlimited"
29507
+ })]);
29495
29508
  };
29509
+ const styles$f = StyleSheet.create({
29510
+ singleSelectShort: {
29511
+ // Non-standard spacing, but it's the smallest we can go
29512
+ // without running into styling issues with the dropdown.
29513
+ height: 26
29514
+ }
29515
+ });
29496
29516
 
29497
29517
  const GraphTypeSelector = props => {
29498
- return /*#__PURE__*/React.createElement("select", {
29499
- value: props.graphType,
29500
- onChange: e => {
29501
- const type = e.target.value;
29502
- props.onChange(type);
29503
- }
29504
- }, /*#__PURE__*/React.createElement("option", {
29505
- value: "linear"
29506
- }, "Linear function"), /*#__PURE__*/React.createElement("option", {
29507
- value: "quadratic"
29508
- }, "Quadratic function"), /*#__PURE__*/React.createElement("option", {
29509
- value: "sinusoid"
29510
- }, "Sinusoid function"), /*#__PURE__*/React.createElement("option", {
29511
- value: "circle"
29512
- }, "Circle"), /*#__PURE__*/React.createElement("option", {
29513
- value: "point"
29514
- }, "Point(s)"), /*#__PURE__*/React.createElement("option", {
29515
- value: "linear-system"
29516
- }, "Linear System"), /*#__PURE__*/React.createElement("option", {
29517
- value: "polygon"
29518
- }, "Polygon"), /*#__PURE__*/React.createElement("option", {
29519
- value: "segment"
29520
- }, "Line Segment(s)"), /*#__PURE__*/React.createElement("option", {
29521
- value: "ray"
29522
- }, "Ray"), /*#__PURE__*/React.createElement("option", {
29523
- value: "angle"
29524
- }, "Angle"));
29518
+ return /*#__PURE__*/React.createElement(SingleSelect, {
29519
+ selectedValue: props.graphType,
29520
+ onChange: props.onChange,
29521
+ placeholder: "Select a graph type",
29522
+ style: styles$e.singleSelectShort
29523
+ }, /*#__PURE__*/React.createElement(OptionItem, {
29524
+ value: "linear",
29525
+ label: "Linear function"
29526
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29527
+ value: "quadratic",
29528
+ label: "Quadratic function"
29529
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29530
+ value: "sinusoid",
29531
+ label: "Sinusoid function"
29532
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29533
+ value: "circle",
29534
+ label: "Circle"
29535
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29536
+ value: "point",
29537
+ label: "Point(s)"
29538
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29539
+ value: "linear-system",
29540
+ label: "Linear System"
29541
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29542
+ value: "polygon",
29543
+ label: "Polygon"
29544
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29545
+ value: "segment",
29546
+ label: "Line Segment(s)"
29547
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29548
+ value: "ray",
29549
+ label: "Ray"
29550
+ }), /*#__PURE__*/React.createElement(OptionItem, {
29551
+ value: "angle",
29552
+ label: "Angle"
29553
+ }));
29554
+ };
29555
+ const styles$e = StyleSheet.create({
29556
+ singleSelectShort: {
29557
+ // Non-standard spacing, but it's the smallest we can go
29558
+ // without running into styling issues with the dropdown.
29559
+ height: 26
29560
+ }
29561
+ });
29562
+
29563
+ // Renders the given children in a View laid out horizontally.
29564
+ const LabeledRow = props => {
29565
+ const {
29566
+ children,
29567
+ label,
29568
+ labelSide = "left",
29569
+ style
29570
+ } = props;
29571
+ return /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement(View, {
29572
+ style: [styles$d.row, style]
29573
+ }, labelSide === "start" || /*#__PURE__*/React.createElement(LabelSmall, {
29574
+ style: styles$d.spaceEnd
29575
+ }, label), children, labelSide === "end" && /*#__PURE__*/React.createElement(LabelSmall, {
29576
+ style: styles$d.spaceStart
29577
+ }, label)));
29525
29578
  };
29579
+ const styles$d = StyleSheet.create({
29580
+ row: {
29581
+ flexDirection: "row",
29582
+ marginTop: spacing.xSmall_8,
29583
+ alignItems: "center"
29584
+ },
29585
+ spaceStart: {
29586
+ marginInlineStart: spacing.xSmall_8
29587
+ },
29588
+ spaceEnd: {
29589
+ marginInlineEnd: spacing.xSmall_8
29590
+ }
29591
+ });
29526
29592
 
29527
29593
  const {
29528
29594
  ButtonGroup: ButtonGroup$2,
@@ -29815,75 +29881,70 @@ class InteractiveGraphSettings extends React.Component {
29815
29881
  className: "perseus-widget-row"
29816
29882
  }, /*#__PURE__*/React.createElement("div", {
29817
29883
  className: "perseus-widget-left-col"
29818
- }, /*#__PURE__*/React.createElement("label", {
29819
- htmlFor: "labels-x"
29820
- }, "x Label"), /*#__PURE__*/React.createElement("input", {
29821
- id: "labels-x",
29884
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29885
+ label: "x Label"
29886
+ }, /*#__PURE__*/React.createElement("input", {
29822
29887
  type: "text",
29823
29888
  className: "graph-settings-axis-label",
29824
29889
  ref: this.labelXRef,
29825
29890
  onChange: e => this.changeLabel(0, e),
29826
29891
  value: this.state.labelsTextbox[0] || ""
29827
- })), /*#__PURE__*/React.createElement("div", {
29892
+ }))), /*#__PURE__*/React.createElement("div", {
29828
29893
  className: "perseus-widget-right-col"
29829
- }, /*#__PURE__*/React.createElement("label", {
29830
- htmlFor: "labels-y"
29831
- }, "y Label"), /*#__PURE__*/React.createElement("input", {
29832
- id: "labels-y",
29894
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29895
+ label: "y Label"
29896
+ }, /*#__PURE__*/React.createElement("input", {
29833
29897
  type: "text",
29834
29898
  className: "graph-settings-axis-label",
29835
29899
  ref: this.labelYRef,
29836
29900
  onChange: e => this.changeLabel(1, e),
29837
29901
  value: this.state.labelsTextbox[1] || ""
29838
- }))), /*#__PURE__*/React.createElement("div", {
29902
+ })))), /*#__PURE__*/React.createElement("div", {
29839
29903
  className: "perseus-widget-row"
29840
29904
  }, /*#__PURE__*/React.createElement("div", {
29841
29905
  className: "perseus-widget-left-col"
29842
- }, /*#__PURE__*/React.createElement("label", {
29843
- htmlFor: "range-x"
29844
- }, "x Range"), /*#__PURE__*/React.createElement(RangeInput$4, {
29845
- id: "range-x",
29906
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29907
+ label: "x Range"
29908
+ }, /*#__PURE__*/React.createElement(RangeInput$4, {
29846
29909
  value: this.state.rangeTextbox[0],
29847
29910
  onChange: vals => this.changeRange(0, vals)
29848
- })), /*#__PURE__*/React.createElement("div", {
29911
+ }))), /*#__PURE__*/React.createElement("div", {
29849
29912
  className: "perseus-widget-right-col"
29850
- }, /*#__PURE__*/React.createElement("label", {
29851
- htmlFor: "range-y"
29852
- }, "y Range"), /*#__PURE__*/React.createElement(RangeInput$4, {
29853
- id: "range-y",
29913
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29914
+ label: "y Range"
29915
+ }, /*#__PURE__*/React.createElement(RangeInput$4, {
29854
29916
  value: this.state.rangeTextbox[1],
29855
29917
  onChange: vals => this.changeRange(1, vals)
29856
- }))), /*#__PURE__*/React.createElement("div", {
29918
+ })))), /*#__PURE__*/React.createElement("div", {
29857
29919
  className: "perseus-widget-row"
29858
29920
  }, /*#__PURE__*/React.createElement("div", {
29859
29921
  className: "perseus-widget-left-col"
29860
- }, /*#__PURE__*/React.createElement("label", {
29861
- htmlFor: "tick-step"
29862
- }, "Tick Step"), /*#__PURE__*/React.createElement(RangeInput$4, {
29863
- id: "tick-step",
29922
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29923
+ label: "Tick Step"
29924
+ }, /*#__PURE__*/React.createElement(RangeInput$4, {
29864
29925
  value: this.state.stepTextbox,
29865
29926
  onChange: this.changeStep
29866
- })), /*#__PURE__*/React.createElement("div", {
29927
+ }))), /*#__PURE__*/React.createElement("div", {
29867
29928
  className: "perseus-widget-right-col"
29868
- }, /*#__PURE__*/React.createElement("label", {
29869
- htmlFor: "grid-step"
29870
- }, "Grid Step"), /*#__PURE__*/React.createElement(RangeInput$4, {
29871
- id: "grid-step",
29929
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29930
+ label: "Grid Step"
29931
+ }, /*#__PURE__*/React.createElement(RangeInput$4, {
29872
29932
  value: this.state.gridStepTextbox,
29873
29933
  onChange: this.changeGridStep
29874
- }))), /*#__PURE__*/React.createElement("div", {
29934
+ })))), /*#__PURE__*/React.createElement("div", {
29875
29935
  className: "perseus-widget-row"
29876
29936
  }, /*#__PURE__*/React.createElement("div", {
29877
29937
  className: "perseus-widget-left-col"
29878
- }, /*#__PURE__*/React.createElement("label", {
29879
- htmlFor: "snap-step"
29880
- }, "Snap Step"), /*#__PURE__*/React.createElement(RangeInput$4, {
29881
- id: "snap-step",
29938
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29939
+ label: "Snap Step"
29940
+ }, /*#__PURE__*/React.createElement(RangeInput$4, {
29882
29941
  value: this.state.snapStepTextbox,
29883
29942
  onChange: this.changeSnapStep
29884
- }))), /*#__PURE__*/React.createElement("div", {
29943
+ })))), /*#__PURE__*/React.createElement("div", {
29885
29944
  className: "perseus-widget-row"
29886
- }, /*#__PURE__*/React.createElement("label", null, "Markings: "), /*#__PURE__*/React.createElement(ButtonGroup$2, {
29945
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
29946
+ label: "Markings:"
29947
+ }, /*#__PURE__*/React.createElement(ButtonGroup$2, {
29887
29948
  value: this.props.markings,
29888
29949
  allowEmpty: false,
29889
29950
  buttons: [{
@@ -29897,24 +29958,23 @@ class InteractiveGraphSettings extends React.Component {
29897
29958
  content: "None"
29898
29959
  }],
29899
29960
  onChange: this.change("markings")
29900
- })), /*#__PURE__*/React.createElement("div", {
29961
+ }))), /*#__PURE__*/React.createElement("div", {
29901
29962
  className: "perseus-widget-left-col"
29902
29963
  }, /*#__PURE__*/React.createElement(PropCheckBox$7, {
29903
29964
  label: "Show tooltips",
29904
29965
  showTooltips: this.props.showTooltips,
29905
29966
  onChange: this.change
29906
- }))), /*#__PURE__*/React.createElement("div", {
29907
- className: "image-settings"
29908
- }, /*#__PURE__*/React.createElement("div", null, "Background image:"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
29909
- htmlFor: "bg-url"
29910
- }, "Url:"), /*#__PURE__*/React.createElement("input", {
29911
- id: "bg-url",
29967
+ }))), /*#__PURE__*/React.createElement(LabeledRow, {
29968
+ label: "Background image URL:",
29969
+ style: styles$c.resetSpaceTop
29970
+ }, /*#__PURE__*/React.createElement("input", {
29912
29971
  type: "text",
29913
- className: "graph-settings-background-url",
29972
+ className: css(styles$c.backgroundUrlInput),
29914
29973
  ref: this.bgUrlRef,
29915
29974
  value: this.state.backgroundImage.url || "",
29916
29975
  onChange: e => {
29917
- const image = _.clone(this.props.backgroundImage);
29976
+ // Shallow-copied clone
29977
+ const image = _extends({}, this.props.backgroundImage);
29918
29978
  image.url = e.target.value;
29919
29979
  this.setState({
29920
29980
  backgroundImage: image
@@ -29922,39 +29982,80 @@ class InteractiveGraphSettings extends React.Component {
29922
29982
  },
29923
29983
  onKeyPress: this.changeBackgroundUrl,
29924
29984
  onBlur: this.changeBackgroundUrl
29925
- }), /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background.")))), /*#__PURE__*/React.createElement("div", {
29926
- className: "misc-settings"
29927
- }, /*#__PURE__*/React.createElement("div", {
29928
- className: "perseus-widget-row"
29929
- }, /*#__PURE__*/React.createElement("div", {
29930
- className: "perseus-widget-left-col"
29985
+ }), /*#__PURE__*/React.createElement(InfoTip$c, null, /*#__PURE__*/React.createElement("p", null, "Create an image in graphie, or use the \"Add image\" function to create a background."))), /*#__PURE__*/React.createElement(View, {
29986
+ style: styles$c.rulerSection
29987
+ }, /*#__PURE__*/React.createElement(View, {
29988
+ style: styles$c.checkboxRow
29931
29989
  }, /*#__PURE__*/React.createElement(PropCheckBox$7, {
29932
29990
  label: "Show ruler",
29933
29991
  showRuler: this.props.showRuler,
29934
- onChange: this.change
29935
- })), /*#__PURE__*/React.createElement("div", {
29936
- className: "perseus-widget-right-col"
29937
- }, /*#__PURE__*/React.createElement(PropCheckBox$7, {
29992
+ onChange: this.change,
29993
+ style: styles$c.resetSpaceTop
29994
+ }), /*#__PURE__*/React.createElement(PropCheckBox$7, {
29938
29995
  label: "Show protractor",
29939
29996
  showProtractor: this.props.showProtractor,
29940
- onChange: this.change
29941
- }))), this.props.showRuler && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Ruler label:", " ", /*#__PURE__*/React.createElement("select", {
29942
- onChange: this.changeRulerLabel,
29943
- value: this.props.rulerLabel
29944
- }, /*#__PURE__*/React.createElement("option", {
29945
- value: ""
29946
- }, "None"), /*#__PURE__*/React.createElement("optgroup", {
29947
- label: "Metric"
29948
- }, this.renderLabelChoices([["milimeters", "mm"], ["centimeters", "cm"], ["meters", "m"], ["kilometers", "km"]])), /*#__PURE__*/React.createElement("optgroup", {
29949
- label: "Imperial"
29950
- }, this.renderLabelChoices([["inches", "in"], ["feet", "ft"], ["yards", "yd"], ["miles", "mi"]]))))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Ruler ticks:", " ", /*#__PURE__*/React.createElement("select", {
29951
- onChange: this.changeRulerTicks,
29952
- value: this.props.rulerTicks
29953
- }, _.map([1, 2, 4, 8, 10, 16], function (n) {
29954
- return /*#__PURE__*/React.createElement("option", {
29955
- key: `ruler-tick-${n}`,
29956
- value: n
29957
- }, n);
29997
+ onChange: this.change,
29998
+ style: styles$c.resetSpaceTop
29999
+ })), this.props.showRuler && /*#__PURE__*/React.createElement(View, {
30000
+ style: styles$c.spaceTop
30001
+ }, /*#__PURE__*/React.createElement(LabeledRow, {
30002
+ label: "Ruler label:",
30003
+ style: styles$c.resetSpaceTop
30004
+ }, /*#__PURE__*/React.createElement(SingleSelect, {
30005
+ id: "ruler-label-select",
30006
+ selectedValue: this.props.rulerLabel,
30007
+ onChange: newValue => {
30008
+ this.change({
30009
+ rulerLabel: newValue
30010
+ });
30011
+ },
30012
+ placeholder: "None",
30013
+ style: styles$c.singleSelectShort
30014
+ }, /*#__PURE__*/React.createElement(OptionItem, {
30015
+ value: "",
30016
+ label: "None",
30017
+ horizontalRule: "full-width"
30018
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30019
+ value: "mm",
30020
+ label: "Milimeters"
30021
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30022
+ value: "cm",
30023
+ label: "Centimeters"
30024
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30025
+ value: "m",
30026
+ label: "Meters"
30027
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30028
+ value: "km",
30029
+ label: "Kilometers",
30030
+ horizontalRule: "full-width"
30031
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30032
+ value: "in",
30033
+ label: "Inches"
30034
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30035
+ value: "ft",
30036
+ label: "Feet"
30037
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30038
+ value: "yd",
30039
+ label: "Yards"
30040
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30041
+ value: "mi",
30042
+ label: "Miles"
30043
+ }))), /*#__PURE__*/React.createElement(LabeledRow, {
30044
+ label: "Ruler ticks:"
30045
+ }, /*#__PURE__*/React.createElement(SingleSelect, {
30046
+ id: "ruler-ticks-select",
30047
+ selectedValue: `${this.props.rulerTicks}`,
30048
+ onChange: newValue => {
30049
+ this.change({
30050
+ rulerTicks: newValue
30051
+ });
30052
+ },
30053
+ placeholder: "10",
30054
+ style: styles$c.singleSelectShort
30055
+ }, [1, 2, 4, 8, 10, 16].map(value => /*#__PURE__*/React.createElement(OptionItem, {
30056
+ key: value,
30057
+ value: `${value}`,
30058
+ label: `${value}`
29958
30059
  })))))));
29959
30060
  }
29960
30061
  }
@@ -29974,21 +30075,63 @@ InteractiveGraphSettings.defaultProps = {
29974
30075
  rulerLabel: "",
29975
30076
  rulerTicks: 10
29976
30077
  };
30078
+ const styles$c = StyleSheet.create({
30079
+ resetSpaceTop: {
30080
+ marginTop: 0
30081
+ },
30082
+ spaceTop: {
30083
+ marginTop: spacing.xSmall_8
30084
+ },
30085
+ singleSelectShort: {
30086
+ // Non-standard spacing, but it's the smallest we can go
30087
+ // without running into styling issues with the dropdown.
30088
+ height: 26
30089
+ },
30090
+ backgroundUrlInput: {
30091
+ border: `1px solid ${color.offBlack32}`,
30092
+ borderRadius: spacing.xxxSmall_4,
30093
+ padding: spacing.xxxSmall_4
30094
+ },
30095
+ checkboxRow: {
30096
+ flexDirection: "row",
30097
+ alignItems: "center",
30098
+ justifyContent: "space-between"
30099
+ },
30100
+ rulerSection: {
30101
+ marginTop: spacing.xSmall_8,
30102
+ borderTop: `1px solid ${color.offBlack16}`,
30103
+ paddingTop: spacing.xSmall_8,
30104
+ paddingBottom: spacing.xSmall_8,
30105
+ borderBottom: `1px solid ${color.offBlack16}`
30106
+ }
30107
+ });
29977
30108
 
29978
30109
  const SegmentCountSelector = ({
29979
30110
  numSegments: _numSegments = 1,
29980
30111
  onChange
29981
- }) => /*#__PURE__*/React.createElement("select", {
30112
+ }) => /*#__PURE__*/React.createElement(SingleSelect, {
29982
30113
  key: "segment-select",
29983
- value: _numSegments,
29984
- onChange: e => {
29985
- const num = +e.target.value;
30114
+ selectedValue: `${_numSegments}`
30115
+ // Never uses placeholder, always has value
30116
+ ,
30117
+ placeholder: "",
30118
+ onChange: newValue => {
30119
+ const num = +newValue;
29986
30120
  onChange(num);
29987
- }
29988
- }, _.range(1, 7).map(n => /*#__PURE__*/React.createElement("option", {
30121
+ },
30122
+ style: styles$b.singleSelectShort
30123
+ }, _.range(1, 7).map(n => /*#__PURE__*/React.createElement(OptionItem, {
29989
30124
  key: n,
29990
- value: n
29991
- }, `${n} segment${n > 1 ? "s" : ""}`)));
30125
+ value: `${n}`,
30126
+ label: `${n} segment${n > 1 ? "s" : ""}`
30127
+ })));
30128
+ const styles$b = StyleSheet.create({
30129
+ singleSelectShort: {
30130
+ // Non-standard spacing, but it's the smallest we can go
30131
+ // without running into styling issues with the dropdown.
30132
+ height: 26
30133
+ }
30134
+ });
29992
30135
 
29993
30136
  const {
29994
30137
  InfoTip: InfoTip$b
@@ -30009,26 +30152,13 @@ const deprecatedProps = {
30009
30152
  };
30010
30153
  }
30011
30154
  };
30012
- // Renders the given children in a View laid out horizontally.
30013
- const Row = props => {
30014
- const {
30015
- children,
30016
- style
30017
- } = props;
30018
- return /*#__PURE__*/React.createElement(View, {
30019
- style: _extends({}, style, {
30020
- flexDirection: "row",
30021
- marginTop: Spacing.xSmall_8
30022
- })
30023
- }, children);
30024
- };
30025
- const FieldLabel = props => {
30026
- return /*#__PURE__*/React.createElement(Typography.LabelSmall, {
30027
- style: {
30028
- marginRight: Spacing.xSmall_8
30029
- }
30030
- }, props.children);
30031
- };
30155
+ const POLYGON_SIDES = _.map(_.range(3, 13), function (value) {
30156
+ return /*#__PURE__*/React.createElement(OptionItem, {
30157
+ key: `polygon-sides-${value}`,
30158
+ value: `${value}`,
30159
+ label: `${value} sides`
30160
+ });
30161
+ });
30032
30162
  /**
30033
30163
  * An editor for the InteractiveGraph widget, which allows the user to
30034
30164
  * specify the graph's properties and the correct answer.
@@ -30042,13 +30172,21 @@ class InteractiveGraphEditor extends React.Component {
30042
30172
  this.className = "perseus-widget-interactive-graph";
30043
30173
  // TODO(jack): Use versioning instead of DeprecationMixin
30044
30174
  this.deprecatedProps = deprecatedProps;
30175
+ this.changeMatchType = newValue => {
30176
+ const correct = _extends({}, this.props.correct, {
30177
+ match: newValue
30178
+ });
30179
+ this.props.onChange({
30180
+ correct: correct
30181
+ });
30182
+ };
30045
30183
  }
30046
30184
  // TODO(jangmi, CP-3288): Remove usage of `UNSAFE_componentWillMount`
30047
30185
  UNSAFE_componentWillMount() {
30048
30186
  DeprecationMixin.UNSAFE_componentWillMount.call(this);
30049
30187
  }
30050
30188
  render() {
30051
- var _this$props$graph$typ, _this$props$graph, _this$props$correct, _this$props$correct2, _this$props$correct3, _this$props$correct4, _this$props$correct5, _this$props$correct6, _this$props$correct7, _this$props$correct8, _this$props$correct9, _this$props$correct10;
30189
+ var _this$props$graph$typ, _this$props$graph, _this$props$correct, _this$props$correct2, _this$props$correct3, _this$props$correct4, _this$props$correct5, _this$props$correct6, _this$props$correct7, _this$props$correct8, _this$props$correct9, _this$props$correct10, _this$props$correct11;
30052
30190
  let graph;
30053
30191
  let equationString;
30054
30192
  const gridStep = this.props.gridStep || Util.getGridStep(this.props.range, this.props.step, interactiveSizes.defaultBoxSize);
@@ -30108,7 +30246,9 @@ class InteractiveGraphEditor extends React.Component {
30108
30246
  className: "perseus-error"
30109
30247
  }, this.props.valid);
30110
30248
  }
30111
- return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Type of Graph:"), /*#__PURE__*/React.createElement(GraphTypeSelector, {
30249
+ return /*#__PURE__*/React.createElement(View, null, /*#__PURE__*/React.createElement(LabeledRow, {
30250
+ label: "Type of Graph:"
30251
+ }, /*#__PURE__*/React.createElement(GraphTypeSelector, {
30112
30252
  graphType: (_this$props$graph$typ = (_this$props$graph = this.props.graph) == null ? void 0 : _this$props$graph.type) != null ? _this$props$graph$typ : InteractiveGraph.defaultProps.graph.type,
30113
30253
  onChange: type => {
30114
30254
  this.props.onChange({
@@ -30120,7 +30260,9 @@ class InteractiveGraphEditor extends React.Component {
30120
30260
  }
30121
30261
  });
30122
30262
  }
30123
- })), ((_this$props$correct = this.props.correct) == null ? void 0 : _this$props$correct.type) === "point" && /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Number of Points:"), /*#__PURE__*/React.createElement(GraphPointsCountSelector, {
30263
+ })), ((_this$props$correct = this.props.correct) == null ? void 0 : _this$props$correct.type) === "point" && /*#__PURE__*/React.createElement(LabeledRow, {
30264
+ label: "Number of Points:"
30265
+ }, /*#__PURE__*/React.createElement(GraphPointsCountSelector, {
30124
30266
  numPoints: (_this$props$correct2 = this.props.correct) == null ? void 0 : _this$props$correct2.numPoints,
30125
30267
  onChange: points => {
30126
30268
  this.props.onChange({
@@ -30130,12 +30272,15 @@ class InteractiveGraphEditor extends React.Component {
30130
30272
  }
30131
30273
  });
30132
30274
  }
30133
- })), ((_this$props$correct3 = this.props.correct) == null ? void 0 : _this$props$correct3.type) === "polygon" && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Number of sides:"), /*#__PURE__*/React.createElement("select", {
30275
+ })), ((_this$props$correct3 = this.props.correct) == null ? void 0 : _this$props$correct3.type) === "polygon" && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(LabeledRow, {
30276
+ label: "Number of sides:"
30277
+ }, /*#__PURE__*/React.createElement(SingleSelect, {
30134
30278
  key: "polygon-select",
30135
- value: ((_this$props$correct4 = this.props.correct) == null ? void 0 : _this$props$correct4.numSides) || 3,
30136
- onChange: e => {
30279
+ selectedValue: (_this$props$correct4 = this.props.correct) != null && _this$props$correct4.numSides ? `${this.props.correct.numSides}` : "3",
30280
+ placeholder: "",
30281
+ onChange: newValue => {
30137
30282
  const graph = _extends({}, this.props.correct, {
30138
- numSides: parsePointCount(e.target.value),
30283
+ numSides: parsePointCount(newValue),
30139
30284
  coords: null,
30140
30285
  // reset the snap for UNLIMITED, which
30141
30286
  // only supports "grid"
@@ -30145,37 +30290,44 @@ class InteractiveGraphEditor extends React.Component {
30145
30290
  this.props.onChange({
30146
30291
  correct: graph
30147
30292
  });
30148
- }
30149
- }, _.map(_.range(3, 13), function (n) {
30150
- return /*#__PURE__*/React.createElement("option", {
30151
- key: n,
30152
- value: n
30153
- }, `${n} sides`);
30154
- }), /*#__PURE__*/React.createElement("option", {
30155
- value: "unlimited"
30156
- }, "unlimited sides"))), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Snap to:"), /*#__PURE__*/React.createElement("select", {
30157
- key: "polygon-snap",
30158
- value: (_this$props$correct5 = this.props.correct) == null ? void 0 : _this$props$correct5.snapTo,
30159
- onChange: e => {
30293
+ },
30294
+ style: styles$a.singleSelectShort
30295
+ }, [...POLYGON_SIDES, /*#__PURE__*/React.createElement(OptionItem, {
30296
+ value: "unlimited",
30297
+ label: "unlimited sides"
30298
+ })])), /*#__PURE__*/React.createElement(LabeledRow, {
30299
+ label: "Snap to:"
30300
+ }, /*#__PURE__*/React.createElement(SingleSelect, {
30301
+ selectedValue: ((_this$props$correct5 = this.props.correct) == null ? void 0 : _this$props$correct5.snapTo) || "grid"
30302
+ // Never uses placeholder, always has value
30303
+ ,
30304
+ placeholder: "",
30305
+ onChange: newValue => {
30160
30306
  const graph = _extends({}, this.props.correct, {
30161
- snapTo: e.target.value,
30307
+ snapTo: newValue,
30162
30308
  coords: null
30163
30309
  });
30164
30310
  this.props.onChange({
30165
30311
  correct: graph
30166
30312
  });
30167
- }
30168
- }, /*#__PURE__*/React.createElement("option", {
30169
- value: "grid"
30170
- }, "grid"), ((_this$props$correct6 = this.props.correct) == null ? void 0 : _this$props$correct6.numSides) !== "unlimited" && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("option", {
30171
- value: "angles"
30172
- }, "interior angles"), /*#__PURE__*/React.createElement("option", {
30173
- value: "sides"
30174
- }, "side measures"))), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."), /*#__PURE__*/React.createElement("p", null, "The interior angle and side measure options guide the points to the nearest whole angle or side"), " ", "measure respectively.")), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(Typography.LabelSmall, {
30175
- tag: "label"
30176
- }, "Show angle measures:", " ", /*#__PURE__*/React.createElement("input", {
30177
- type: "checkbox",
30178
- checked: (_this$props$correct7 = this.props.correct) == null ? void 0 : _this$props$correct7.showAngles,
30313
+ },
30314
+ style: styles$a.singleSelectShort
30315
+ }, /*#__PURE__*/React.createElement(OptionItem, {
30316
+ value: "grid",
30317
+ label: "grid"
30318
+ }), ((_this$props$correct6 = this.props.correct) == null ? void 0 : _this$props$correct6.numSides) !== "unlimited" && /*#__PURE__*/React.createElement(OptionItem, {
30319
+ value: "angles",
30320
+ label: "interior angles"
30321
+ }), ((_this$props$correct7 = this.props.correct) == null ? void 0 : _this$props$correct7.numSides) !== "unlimited" && /*#__PURE__*/React.createElement(OptionItem, {
30322
+ value: "sides",
30323
+ label: "side measures"
30324
+ })), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "These options affect the movement of the vertex points. The grid option will guide the points to the nearest half step along the grid."), /*#__PURE__*/React.createElement("p", null, "The interior angle and side measure options guide the points to the nearest whole angle or side"), " ", "measure respectively.")), /*#__PURE__*/React.createElement(View, {
30325
+ style: styles$a.row
30326
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
30327
+ label: /*#__PURE__*/React.createElement(LabelSmall, null, "Show angle measures"),
30328
+ checked:
30329
+ // Don't show indeterminate checkbox state
30330
+ !!((_this$props$correct8 = this.props.correct) != null && _this$props$correct8.showAngles),
30179
30331
  onChange: () => {
30180
30332
  this.props.onChange({
30181
30333
  correct: _extends({}, this.props.correct, {
@@ -30183,11 +30335,13 @@ class InteractiveGraphEditor extends React.Component {
30183
30335
  })
30184
30336
  });
30185
30337
  }
30186
- })), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Displays the interior angle measures."))), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(Typography.LabelSmall, {
30187
- tag: "label"
30188
- }, "Show side measures:", " ", /*#__PURE__*/React.createElement("input", {
30189
- type: "checkbox",
30190
- checked: (_this$props$correct8 = this.props.correct) == null ? void 0 : _this$props$correct8.showSides,
30338
+ }), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Displays the interior angle measures."))), /*#__PURE__*/React.createElement(View, {
30339
+ style: styles$a.row
30340
+ }, /*#__PURE__*/React.createElement(Checkbox$1, {
30341
+ label: /*#__PURE__*/React.createElement(LabelSmall, null, "Show side measures"),
30342
+ checked:
30343
+ // Don't show indeterminate checkbox state
30344
+ !!((_this$props$correct9 = this.props.correct) != null && _this$props$correct9.showSides),
30191
30345
  onChange: () => {
30192
30346
  this.props.onChange({
30193
30347
  correct: _extends({}, this.props.correct, {
@@ -30195,8 +30349,10 @@ class InteractiveGraphEditor extends React.Component {
30195
30349
  })
30196
30350
  });
30197
30351
  }
30198
- })), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Displays the side lengths.")))), ((_this$props$correct9 = this.props.correct) == null ? void 0 : _this$props$correct9.type) === "segment" && /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Number of segments: "), /*#__PURE__*/React.createElement(SegmentCountSelector, {
30199
- numSegments: (_this$props$correct10 = this.props.correct) == null ? void 0 : _this$props$correct10.numSegments,
30352
+ }), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Displays the side lengths.")))), ((_this$props$correct10 = this.props.correct) == null ? void 0 : _this$props$correct10.type) === "segment" && /*#__PURE__*/React.createElement(LabeledRow, {
30353
+ label: "Number of segments:"
30354
+ }, /*#__PURE__*/React.createElement(SegmentCountSelector, {
30355
+ numSegments: (_this$props$correct11 = this.props.correct) == null ? void 0 : _this$props$correct11.numSegments,
30200
30356
  onChange: sides => {
30201
30357
  this.props.onChange({
30202
30358
  correct: {
@@ -30206,16 +30362,7 @@ class InteractiveGraphEditor extends React.Component {
30206
30362
  }
30207
30363
  });
30208
30364
  }
30209
- })), /*#__PURE__*/React.createElement(Row, null, /*#__PURE__*/React.createElement(FieldLabel, null, "Correct answer:"), /*#__PURE__*/React.createElement(Typography.BodyMonospace, {
30210
- style: {
30211
- fontSize: 12,
30212
- backgroundColor: "#eee",
30213
- paddingInline: Spacing.xxSmall_6,
30214
- borderColor: "#ccc",
30215
- borderStyle: "solid",
30216
- borderWidth: 1
30217
- }
30218
- }, equationString), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), /*#__PURE__*/React.createElement(InteractiveGraphSettings, {
30365
+ })), /*#__PURE__*/React.createElement(InteractiveGraphSettings, {
30219
30366
  box: getInteractiveBoxFromSizeClass(sizeClass),
30220
30367
  range: this.props.range,
30221
30368
  labels: this.props.labels,
@@ -30231,37 +30378,54 @@ class InteractiveGraphEditor extends React.Component {
30231
30378
  rulerLabel: this.props.rulerLabel,
30232
30379
  rulerTicks: this.props.rulerTicks,
30233
30380
  onChange: this.props.onChange
30234
- }), this.props.correct.type === "polygon" && /*#__PURE__*/React.createElement("div", {
30235
- className: "type-settings"
30236
- }, /*#__PURE__*/React.createElement("label", null, " ", "Student answer must", " ", /*#__PURE__*/React.createElement("select", {
30237
- value: this.props.correct.match,
30381
+ }), this.props.correct.type === "polygon" && /*#__PURE__*/React.createElement(LabeledRow, {
30382
+ label: "Student answer must"
30383
+ }, /*#__PURE__*/React.createElement(SingleSelect, {
30384
+ selectedValue: this.props.correct.match || "exact",
30238
30385
  onChange: this.changeMatchType
30239
- }, /*#__PURE__*/React.createElement("option", {
30240
- value: "exact"
30241
- }, "match exactly"), /*#__PURE__*/React.createElement("option", {
30242
- value: "congruent"
30243
- }, "be congruent"), /*#__PURE__*/React.createElement("option", {
30244
- value: "approx"
30245
- }, "be approximately congruent"), /*#__PURE__*/React.createElement("option", {
30246
- value: "similar"
30247
- }, "be similar"))), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Match Exactly:"), " Match exactly in size, orientation, and location on the grid even if it is not shown in the background.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Congruent:"), " Be congruent in size and shape, but can be located anywhere on the grid.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Approximately Congruent:"), " Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid.", " ", /*#__PURE__*/React.createElement("em", null, "Use this with snapping to angle measure."))), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Similar:"), " Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."))))), this.props.correct.type === "angle" && /*#__PURE__*/React.createElement("div", {
30248
- className: "type-settings"
30249
- }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", null, " ", "Student answer must", " ", /*#__PURE__*/React.createElement("select", {
30250
- value: this.props.correct.match,
30386
+ // Never uses placeholder, always has value
30387
+ ,
30388
+ placeholder: "",
30389
+ style: styles$a.singleSelectShort
30390
+ }, /*#__PURE__*/React.createElement(OptionItem, {
30391
+ value: "exact",
30392
+ label: "match exactly"
30393
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30394
+ value: "congruent",
30395
+ label: "be congruent"
30396
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30397
+ value: "approx",
30398
+ label: "be approximately congruent"
30399
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30400
+ value: "similar",
30401
+ label: "be similar"
30402
+ })), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Match Exactly:"), " Match exactly in size, orientation, and location on the grid even if it is not shown in the background.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Congruent:"), " Be congruent in size and shape, but can be located anywhere on the grid.")), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Approximately Congruent:"), " Be exactly similar, and congruent in size and shape to within 0.1 units, but can be located anywhere on the grid.", " ", /*#__PURE__*/React.createElement("em", null, "Use this with snapping to angle measure."))), /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "Be Similar:"), " Be similar with matching interior angles, and side measures that are matching or a multiple of the correct side measures. The figure can be located anywhere on the grid."))))), this.props.correct.type === "angle" && /*#__PURE__*/React.createElement(LabeledRow, {
30403
+ label: "Student answer must"
30404
+ }, /*#__PURE__*/React.createElement(SingleSelect, {
30405
+ selectedValue: this.props.correct.match || "exact",
30251
30406
  onChange: this.changeMatchType
30252
- }, /*#__PURE__*/React.createElement("option", {
30253
- value: "exact"
30254
- }, "match exactly"), /*#__PURE__*/React.createElement("option", {
30255
- value: "congruent"
30256
- }, "be congruent"))), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position.")))), graph);
30257
- }
30258
- changeMatchType(e) {
30259
- const correct = _.extend({}, this.props.correct, {
30260
- match: e.target.value
30261
- });
30262
- this.props.onChange({
30263
- correct: correct
30264
- });
30407
+ // Never uses placeholder, always has value
30408
+ ,
30409
+ placeholder: "",
30410
+ style: styles$a.singleSelectShort
30411
+ }, /*#__PURE__*/React.createElement(OptionItem, {
30412
+ value: "exact",
30413
+ label: "match exactly"
30414
+ }), /*#__PURE__*/React.createElement(OptionItem, {
30415
+ value: "congruent",
30416
+ label: "be congruent"
30417
+ })), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Congruency requires only that the angle measures are the same. An exact match implies congruency, but also requires that the angles have the same orientation and that the vertices are in the same position."))), /*#__PURE__*/React.createElement(LabeledRow, {
30418
+ label: "Correct answer:"
30419
+ }, /*#__PURE__*/React.createElement(BodyMonospace, {
30420
+ style: {
30421
+ fontSize: 12,
30422
+ backgroundColor: "#eee",
30423
+ paddingInline: Spacing.xxSmall_6,
30424
+ borderColor: "#ccc",
30425
+ borderStyle: "solid",
30426
+ borderWidth: 1
30427
+ }
30428
+ }, equationString), /*#__PURE__*/React.createElement(InfoTip$b, null, /*#__PURE__*/React.createElement("p", null, "Graph the correct answer in the graph below and ensure the equation or point coordinates displayed represent the correct answer."))), graph);
30265
30429
  }
30266
30430
  serialize() {
30267
30431
  const json = _.pick(this.props, "step", "backgroundImage", "markings", "labels", "showProtractor", "showRuler", "showTooltips", "rulerLabel", "rulerTicks", "range", "gridStep", "snapStep");
@@ -30298,6 +30462,18 @@ InteractiveGraphEditor.defaultProps = _extends({}, InteractiveGraph.defaultProps
30298
30462
  coords: null
30299
30463
  }
30300
30464
  });
30465
+ const styles$a = StyleSheet.create({
30466
+ singleSelectShort: {
30467
+ // Non-standard spacing, but it's the smallest we can go
30468
+ // without running into styling issues with the dropdown.
30469
+ height: 26
30470
+ },
30471
+ row: {
30472
+ flexDirection: "row",
30473
+ marginTop: Spacing.xSmall_8,
30474
+ alignItems: "center"
30475
+ }
30476
+ });
30301
30477
 
30302
30478
  const _excluded$1 = ["forwardedRef", "width", "grow", "shrink", "icon", "backgroundColor", "focusBorderColor", "borderColor", "color", "onSubmit", "leftSideIcon", "id", "testId", "type", "labelMediumInputText"];
30303
30479
  class FormWrappedTextField extends React.Component {