@khanacademy/perseus 1.4.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/es/index.css +9 -245
  3. package/dist/es/index.js +138 -584
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +9 -245
  6. package/dist/index.js +135 -581
  7. package/dist/index.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/__stories__/hints-renderer.stories.jsx +9 -1
  10. package/src/__testdata__/graphie_testdata.js +53 -0
  11. package/src/__tests__/__snapshots__/perseus-markdown_test.jsx.snap +0 -9
  12. package/src/__tests__/__snapshots__/renderer_test.jsx.snap +0 -9
  13. package/src/components/__stories__/graphie.stories.jsx +5 -1
  14. package/src/hint-renderer.jsx +11 -14
  15. package/src/perseus-api.jsx +0 -23
  16. package/src/perseus-markdown.jsx +0 -25
  17. package/src/styles/constants.js +0 -21
  18. package/src/styles/global-constants.js +0 -6
  19. package/src/styles/khan-exercise.css +9 -1
  20. package/src/styles/perseus-renderer.less +0 -259
  21. package/src/styles/variables.less +0 -11
  22. package/src/styles/variables.shared.less +0 -10
  23. package/src/types.js +0 -16
  24. package/src/widgets/__stories__/input-number.stories.jsx +0 -14
  25. package/src/widgets/__stories__/radio.stories.jsx +0 -3
  26. package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +18 -28
  27. package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +0 -9
  28. package/src/widgets/__tests__/__snapshots__/image_test.jsx.snap +0 -18
  29. package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +2 -440
  30. package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +66 -3726
  31. package/src/widgets/__tests__/numeric-input_test.jsx +54 -118
  32. package/src/widgets/__tests__/radio/choice-icon_test.jsx +25 -75
  33. package/src/widgets/__tests__/radio_test.jsx +362 -394
  34. package/src/widgets/definition.jsx +27 -14
  35. package/src/widgets/input-number.jsx +2 -60
  36. package/src/widgets/numeric-input.jsx +17 -89
  37. package/src/widgets/radio/__stories__/base-radio.stories.jsx +1 -3
  38. package/src/widgets/radio/__stories__/choice-icon.stories.jsx +23 -105
  39. package/src/widgets/radio/__stories__/option-status.stories.jsx +0 -8
  40. package/src/widgets/radio/base-radio.jsx +13 -96
  41. package/src/widgets/radio/choice-icon/choice-icon.jsx +177 -50
  42. package/src/widgets/radio/choice-icon/cross-out-line.jsx +9 -13
  43. package/src/widgets/radio/choice-icon/shared-styles.js +2 -3
  44. package/src/widgets/radio/choice.jsx +5 -59
  45. package/src/widgets/radio/option-status.jsx +2 -14
  46. package/src/components/__stories__/possible-answers.stories.jsx +0 -22
  47. package/src/components/possible-answers.jsx +0 -36
  48. package/src/styles/widgets/definition.less +0 -86
  49. package/src/widgets/radio/__stories__/sat-styles.stories.jsx +0 -191
  50. package/src/widgets/radio/choice-icon/library-choice-icon.jsx +0 -225
  51. package/src/widgets/radio/choice-icon/sat-choice-icon.jsx +0 -120
package/dist/index.js CHANGED
@@ -370,7 +370,6 @@ _defineProperty(StubTagEditor, "defaultProps", {
370
370
  const ApiOptions = {
371
371
  propTypes: PropTypes__default["default"].shape({
372
372
  isArticle: PropTypes__default["default"].bool.isRequired,
373
- satStyling: PropTypes__default["default"].bool.isRequired,
374
373
  onInputError: PropTypes__default["default"].func.isRequired,
375
374
  onFocusChange: PropTypes__default["default"].func.isRequired,
376
375
  staticRender: PropTypes__default["default"].bool.isRequired,
@@ -432,18 +431,6 @@ const ApiOptions = {
432
431
  setDrawingAreaAvailable: PropTypes__default["default"].func,
433
432
  // Whether to use the Draft.js editor or the legacy textarea
434
433
  useDraftEditor: PropTypes__default["default"].bool,
435
- // Styling options that control the visual behavior of Perseus
436
- // items.
437
- // TODO(mdr): If we adopt this pattern, we'll need to think about
438
- // how to make individual `styling` options be optional, and
439
- // how to set their default values without overwriting provided
440
- // values. For now, though, you must either specify all fields
441
- // of `styling`, or omit the `styling` option entirely.
442
- styling: PropTypes__default["default"].shape({
443
- // TODO(Nicole): Remove this after landing wonderblock-ifying
444
- // the radio widget
445
- primaryProductColor: PropTypes__default["default"].string
446
- }),
447
434
  // The color used for the hint progress indicator (eg. 1 / 3)
448
435
  hintProgressColor: PropTypes__default["default"].string,
449
436
  // Whether this Renderer is allowed to auto-scroll the rest of the
@@ -476,7 +463,6 @@ const ApiOptions = {
476
463
  defaults: {
477
464
  isArticle: false,
478
465
  isMobile: false,
479
- satStyling: false,
480
466
  onInputError: function () {},
481
467
  onFocusChange: function () {},
482
468
  staticRender: false,
@@ -493,7 +479,6 @@ const ApiOptions = {
493
479
  },
494
480
  setDrawingAreaAvailable: function () {},
495
481
  useDraftEditor: false,
496
- styling: {},
497
482
  canScrollPage: false,
498
483
  inModal: false,
499
484
  crossOutEnabled: false,
@@ -3000,28 +2985,7 @@ const pureMdMax$2 = "1023px"; // @pure-lg-max: (@pure-xl-min - 1);
3000
2985
 
3001
2986
  const pureLgMax$2 = "1279px"; // @tableBackgroundAccent: #f9f9f9; // for striping
3002
2987
 
3003
- const tableBackgroundAccent$1 = "#F9F9F9";
3004
- const gtpBlue = "#4c00ff";
3005
- const gtpIncorrectColor = "#babec2";
3006
- const gtpCorrectColor = "#ffbe26"; // @satBlue: #0084ce;
3007
-
3008
- const satBlue = "#0084CE"; // @satSelectedBackgroundColor: #e4f3f9;
3009
-
3010
- const satSelectedBackgroundColor = "#E4F3F9"; // @satActiveBackgroundColor: #d0edf4;
3011
-
3012
- const satActiveBackgroundColor = "#D0EDF4"; // @satCorrectColor: #009900;
3013
-
3014
- const satCorrectColor = "#009900"; // @satCorrectBorderColor: #00cc00;
3015
-
3016
- const satCorrectBorderColor = "#00CC00"; // @satCorrectBackgroundColor: #e4f7e4;
3017
-
3018
- const satCorrectBackgroundColor = "#E4F7E4"; // @satIncorrectColor: #990000;
3019
-
3020
- const satIncorrectColor = "#990000"; // @satIncorrectBorderColor: #cc5252;
3021
-
3022
- const satIncorrectBorderColor = "#CC5252"; // @satIncorrectBackgroundColor: #f2ebeb;
3023
-
3024
- const satIncorrectBackgroundColor = "#F2EBEB"; // @zIndexScratchPad: 1;
2988
+ const tableBackgroundAccent$1 = "#F9F9F9"; // @zIndexScratchPad: 1;
3025
2989
 
3026
2990
  const zIndexScratchPad = 1; // @zIndexAboveScratchpad: @zIndexScratchPad + 1;
3027
2991
 
@@ -3089,18 +3053,6 @@ var constants$1 = /*#__PURE__*/Object.freeze({
3089
3053
  pureMdMax: pureMdMax$2,
3090
3054
  pureLgMax: pureLgMax$2,
3091
3055
  tableBackgroundAccent: tableBackgroundAccent$1,
3092
- gtpBlue: gtpBlue,
3093
- gtpIncorrectColor: gtpIncorrectColor,
3094
- gtpCorrectColor: gtpCorrectColor,
3095
- satBlue: satBlue,
3096
- satSelectedBackgroundColor: satSelectedBackgroundColor,
3097
- satActiveBackgroundColor: satActiveBackgroundColor,
3098
- satCorrectColor: satCorrectColor,
3099
- satCorrectBorderColor: satCorrectBorderColor,
3100
- satCorrectBackgroundColor: satCorrectBackgroundColor,
3101
- satIncorrectColor: satIncorrectColor,
3102
- satIncorrectBorderColor: satIncorrectBorderColor,
3103
- satIncorrectBackgroundColor: satIncorrectBackgroundColor,
3104
3056
  zIndexScratchPad: zIndexScratchPad,
3105
3057
  zIndexAboveScratchpad: zIndexAboveScratchpad$1,
3106
3058
  zIndexInteractiveComponent: zIndexInteractiveComponent$1,
@@ -17869,17 +17821,17 @@ class Lint extends React__namespace.Component {
17869
17821
  let warningTextStyle;
17870
17822
 
17871
17823
  if (this.props.severity === 1) {
17872
- severityStyle = styles$B.indicatorError;
17824
+ severityStyle = styles$A.indicatorError;
17873
17825
  warningText = "Error";
17874
- warningTextStyle = styles$B.publishBlockingError;
17826
+ warningTextStyle = styles$A.publishBlockingError;
17875
17827
  } else if (this.props.severity === 2) {
17876
- severityStyle = styles$B.indicatorWarning;
17828
+ severityStyle = styles$A.indicatorWarning;
17877
17829
  warningText = "Warning";
17878
- warningTextStyle = styles$B.warning;
17830
+ warningTextStyle = styles$A.warning;
17879
17831
  } else {
17880
- severityStyle = styles$B.indicatorGuideline;
17832
+ severityStyle = styles$A.indicatorGuideline;
17881
17833
  warningText = "Recommendation";
17882
- warningTextStyle = styles$B.warning;
17834
+ warningTextStyle = styles$A.warning;
17883
17835
  }
17884
17836
 
17885
17837
  return /*#__PURE__*/React__namespace.createElement("a", {
@@ -17887,16 +17839,16 @@ class Lint extends React__namespace.Component {
17887
17839
  target: "lint-help-window",
17888
17840
  className: aphrodite.css(style)
17889
17841
  }, /*#__PURE__*/React__namespace.createElement("span", {
17890
- className: aphrodite.css(styles$B.indicator, severityStyle)
17842
+ className: aphrodite.css(styles$A.indicator, severityStyle)
17891
17843
  }, this.props.severity === 1 && /*#__PURE__*/React__namespace.createElement(InlineIcon, exclamationIcon)), /*#__PURE__*/React__namespace.createElement("div", {
17892
- className: aphrodite.css(styles$B.tooltip, tooltipAbove && styles$B.tooltipAbove)
17844
+ className: aphrodite.css(styles$A.tooltip, tooltipAbove && styles$A.tooltipAbove)
17893
17845
  }, this.props.message.split("\n\n").map((m, i) => /*#__PURE__*/React__namespace.createElement("p", {
17894
17846
  key: i,
17895
- className: aphrodite.css(styles$B.tooltipParagraph)
17847
+ className: aphrodite.css(styles$A.tooltipParagraph)
17896
17848
  }, /*#__PURE__*/React__namespace.createElement("span", {
17897
17849
  className: aphrodite.css(warningTextStyle)
17898
17850
  }, warningText, ":", " "), m)), /*#__PURE__*/React__namespace.createElement("div", {
17899
- className: aphrodite.css(styles$B.tail, tooltipAbove && styles$B.tailAbove)
17851
+ className: aphrodite.css(styles$A.tail, tooltipAbove && styles$A.tailAbove)
17900
17852
  })));
17901
17853
  });
17902
17854
  }
@@ -17944,19 +17896,19 @@ class Lint extends React__namespace.Component {
17944
17896
 
17945
17897
  if (blockHighlight) {
17946
17898
  return /*#__PURE__*/React__namespace.createElement("span", {
17947
- className: aphrodite.css(styles$B.lintContainer, styles$B.lintContainerBlock)
17948
- }, this.renderLink(styles$B.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17899
+ className: aphrodite.css(styles$A.lintContainer, styles$A.lintContainerBlock)
17900
+ }, this.renderLink(styles$A.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17949
17901
  }
17950
17902
 
17951
17903
  if (inline) {
17952
17904
  return /*#__PURE__*/React__namespace.createElement("span", {
17953
- className: aphrodite.css(styles$B.lintContainer)
17954
- }, this.renderLink(styles$B.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17905
+ className: aphrodite.css(styles$A.lintContainer)
17906
+ }, this.renderLink(styles$A.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17955
17907
  }
17956
17908
 
17957
17909
  return /*#__PURE__*/React__namespace.createElement("div", {
17958
- className: aphrodite.css(styles$B.lintContainer)
17959
- }, this.renderLink(styles$B.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
17910
+ className: aphrodite.css(styles$A.lintContainer)
17911
+ }, this.renderLink(styles$A.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
17960
17912
  }
17961
17913
 
17962
17914
  } // $FlowFixMe[prop-missing]
@@ -17981,7 +17933,7 @@ _defineProperty(Lint, "propTypes", {
17981
17933
  severity: PropTypes__default["default"].number
17982
17934
  });
17983
17935
 
17984
- const styles$B = aphrodite.StyleSheet.create({
17936
+ const styles$A = aphrodite.StyleSheet.create({
17985
17937
  // This is the class of the outermost element.
17986
17938
  // We use relative positioning so that the lint indicator can be
17987
17939
  // positioned absolutely relative to the position of the linty container.
@@ -18221,14 +18173,8 @@ const rules$1 = { ...pureMarkdown.pureMarkdownRules,
18221
18173
  }, output(node.col1, state))), /*#__PURE__*/React__namespace.createElement("div", {
18222
18174
  className: "perseus-column"
18223
18175
  }, /*#__PURE__*/React__namespace.createElement("div", {
18224
- className: "sat-header-grafting-area"
18225
- }), /*#__PURE__*/React__namespace.createElement("div", {
18226
18176
  className: "perseus-column-content"
18227
- }, /*#__PURE__*/React__namespace.createElement("div", {
18228
- className: "sat-skill-subscore-grafting-area"
18229
- }), output(node.col2, state), /*#__PURE__*/React__namespace.createElement("div", {
18230
- className: "sat-grafting-area"
18231
- }))));
18177
+ }, output(node.col2, state))));
18232
18178
  }
18233
18179
  },
18234
18180
  // Match paragraphs consisting solely of crowdin IDs
@@ -19874,7 +19820,7 @@ class Renderer extends React__namespace.Component {
19874
19820
  paddingRight: margin
19875
19821
  };
19876
19822
  const mobileInnerStyle = { ...innerStyle,
19877
- ...styles$A.mobileZoomableParentFix
19823
+ ...styles$z.mobileZoomableParentFix
19878
19824
  };
19879
19825
  return /*#__PURE__*/React__namespace.createElement("div", {
19880
19826
  key: state.key,
@@ -20014,7 +19960,7 @@ class Renderer extends React__namespace.Component {
20014
19960
  paddingRight: 0
20015
19961
  };
20016
19962
  const mobileInnerStyle = { ...innerStyle,
20017
- ...styles$A.mobileZoomableParentFix
19963
+ ...styles$z.mobileZoomableParentFix
20018
19964
  };
20019
19965
  const wrappedOutput = /*#__PURE__*/React__namespace.createElement("div", {
20020
19966
  style: { ...mobileInnerStyle,
@@ -20695,7 +20641,7 @@ _defineProperty(Renderer, "defaultProps", {
20695
20641
  linterContext: PerseusLinter__namespace.linterContextDefault
20696
20642
  });
20697
20643
 
20698
- const styles$A = {
20644
+ const styles$z = {
20699
20645
  mobileZoomableParentFix: {
20700
20646
  // NOTE(abdul): There is an issue where transform animations will
20701
20647
  // cause the Zoomable component to disappear when running on the
@@ -22839,31 +22785,6 @@ var Expression$1 = {
22839
22785
  isLintable: true
22840
22786
  };
22841
22787
 
22842
- class PossibleAnswers extends React__namespace.Component {
22843
- render() {
22844
- // It's redundant to show duplicate answers.
22845
- // So, remove duplicates from the given list of answer strings.
22846
- const answers = ___default["default"].uniq(this.props.answers);
22847
-
22848
- const answerComponents = ___default["default"].map(answers, answer => {
22849
- // Plus, now that our answers are distinct, we can safely use the
22850
- // answer string as a key.
22851
- return /*#__PURE__*/React__namespace.createElement("dd", {
22852
- key: answer
22853
- }, answer);
22854
- });
22855
-
22856
- return /*#__PURE__*/React__namespace.createElement("dl", {
22857
- className: "perseus-possible-answers"
22858
- }, /*#__PURE__*/React__namespace.createElement("dt", null, i18n__namespace.doNotTranslate("Correct Answer")), answerComponents);
22859
- }
22860
-
22861
- }
22862
-
22863
- _defineProperty(PossibleAnswers, "propTypes", {
22864
- answers: PropTypes__default["default"].arrayOf(PropTypes__default["default"].string)
22865
- });
22866
-
22867
22788
  class SimpleKeypadInput extends React__namespace.Component {
22868
22789
  constructor() {
22869
22790
  super(...arguments);
@@ -23124,54 +23045,20 @@ class InputNumber extends React__namespace.Component {
23124
23045
  return input;
23125
23046
  } // HACK(johnsullivan): Create a function with shared logic between
23126
23047
  // this and NumericInput.
23048
+ // TODO(jeremy): Deprecate this widget and prefer numeric-input.
23127
23049
 
23128
23050
 
23129
- const rubric = this.props.reviewModeRubric;
23130
- let correct = null;
23131
- let answerBlurb = null; // SAT is deprecated and not testable
23132
-
23133
- /* c8 ignore if */
23134
-
23135
- if (this.props.apiOptions.satStyling && rubric) {
23136
- const score = this.simpleValidate(rubric);
23137
- correct = score.type === "points" && score.earned === score.total;
23138
-
23139
- if (!correct) {
23140
- // TODO(johnsullivan): Make this a little more
23141
- // human-friendly.
23142
- let answerString = String(rubric.value);
23143
-
23144
- if (rubric.inexact && rubric.maxError) {
23145
- answerString += " \u00B1 " + rubric.maxError;
23146
- }
23147
-
23148
- const answerStrings = [answerString];
23149
- answerBlurb = /*#__PURE__*/React__namespace.createElement(PossibleAnswers, {
23150
- answers: answerStrings
23151
- });
23152
- }
23153
- } // Note: This is _very_ similar to what `numeric-input.jsx` does. If
23051
+ const rubric = this.props.reviewModeRubric; // Note: This is _very_ similar to what `numeric-input.jsx` does. If
23154
23052
  // you modify this, double-check if you also need to modify that
23155
23053
  // component.
23156
23054
 
23157
-
23158
- const inputStyles = [styles$z.default, this.props.size === "small" ? styles$z.small : null, this.props.rightAlign ? styles$z.rightAlign : styles$z.leftAlign]; // Correct
23159
-
23160
- if (rubric && correct === true && this.props.currentValue) {
23161
- inputStyles.push(styles$z.answerStateCorrect);
23162
- } // Incorrect
23163
-
23164
-
23165
- if (rubric && correct === false && this.props.currentValue) {
23166
- inputStyles.push(styles$z.answerStateIncorrect);
23167
- } // Unanswered
23168
-
23055
+ const inputStyles = [styles$y.default, this.props.size === "small" ? styles$y.small : null, this.props.rightAlign ? styles$y.rightAlign : styles$y.leftAlign]; // Unanswered
23169
23056
 
23170
23057
  if (rubric && !this.props.currentValue) {
23171
- inputStyles.push(styles$z.answerStateUnanswered);
23058
+ inputStyles.push(styles$y.answerStateUnanswered);
23172
23059
  }
23173
23060
 
23174
- const input = /*#__PURE__*/React__namespace.createElement(InputWithExamples // eslint-disable-next-line react/no-string-refs
23061
+ return /*#__PURE__*/React__namespace.createElement(InputWithExamples // eslint-disable-next-line react/no-string-refs
23175
23062
  , {
23176
23063
  ref: "input",
23177
23064
  value: this.props.currentValue,
@@ -23185,17 +23072,7 @@ class InputNumber extends React__namespace.Component {
23185
23072
  id: this.props.widgetId,
23186
23073
  disabled: this.props.apiOptions.readOnly,
23187
23074
  linterContext: this.props.linterContext
23188
- }); // SAT is deprecated, answer blurb is an SAT feature
23189
-
23190
- /* c8 ignore if */
23191
-
23192
- if (answerBlurb) {
23193
- return /*#__PURE__*/React__namespace.createElement("span", {
23194
- className: "perseus-input-with-answer-blurb"
23195
- }, input, answerBlurb);
23196
- }
23197
-
23198
- return input;
23075
+ });
23199
23076
  }
23200
23077
 
23201
23078
  static validate(state, rubric) {
@@ -23272,7 +23149,7 @@ _defineProperty(InputNumber, "defaultProps", {
23272
23149
  linterContext: PerseusLinter.linterContextDefault
23273
23150
  });
23274
23151
 
23275
- const styles$z = aphrodite.StyleSheet.create({
23152
+ const styles$y = aphrodite.StyleSheet.create({
23276
23153
  default: {
23277
23154
  width: 80,
23278
23155
  height: "auto"
@@ -23289,16 +23166,6 @@ const styles$z = aphrodite.StyleSheet.create({
23289
23166
  paddingLeft: 0,
23290
23167
  paddingRight: Spacing__default["default"].xxxSmall_4
23291
23168
  },
23292
- answerStateCorrect: {
23293
- color: satCorrectColor,
23294
- backgroundColor: satCorrectBackgroundColor,
23295
- border: "solid 1px ".concat(satCorrectBorderColor)
23296
- },
23297
- answerStateIncorrect: {
23298
- color: satIncorrectColor,
23299
- backgroundColor: satIncorrectBackgroundColor,
23300
- border: "solid 1px ".concat(satIncorrectBorderColor)
23301
- },
23302
23169
  answerStateUnanswered: {
23303
23170
  backgroundColor: "#eee",
23304
23171
  border: "solid 1px #999"
@@ -23376,49 +23243,6 @@ class NumericInput extends React__namespace.Component {
23376
23243
  previousValues: [""]
23377
23244
  });
23378
23245
 
23379
- _defineProperty(this, "getAnswerBlurb", rubric => {
23380
- let correct;
23381
- let answerBlurb;
23382
- /* Ignore this block because SAT is deprecated */
23383
-
23384
- /* c8 ignore next */
23385
-
23386
- if (this.props.apiOptions.satStyling && rubric) {
23387
- const score = this.simpleValidate(rubric);
23388
- correct = score.type === "points" && score.earned === score.total;
23389
-
23390
- if (!correct) {
23391
- const correctAnswers = rubric.answers.filter(answer => answer.status === "correct");
23392
- const answerStrings = correctAnswers.map(answer => {
23393
- // Figure out how this answer is supposed to be
23394
- // displayed
23395
- let format = "decimal";
23396
-
23397
- if (answer.answerForms && answer.answerForms[0]) {
23398
- // NOTE(johnsullivan): This isn't exactly ideal, but
23399
- // it does behave well for all the currently known
23400
- // problems. See D14742 for some discussion on
23401
- // alternate strategies.
23402
- format = answer.answerForms[0];
23403
- }
23404
-
23405
- let answerString = KhanMath.toNumericString(answer.value, format);
23406
-
23407
- if (answer.maxError) {
23408
- answerString += " \u00B1 " + KhanMath.toNumericString(answer.maxError, format);
23409
- }
23410
-
23411
- return answerString;
23412
- });
23413
- answerBlurb = /*#__PURE__*/React__namespace.createElement(PossibleAnswers, {
23414
- answers: answerStrings
23415
- });
23416
- }
23417
- }
23418
-
23419
- return [answerBlurb, !!correct];
23420
- });
23421
-
23422
23246
  _defineProperty(this, "examples", () => {
23423
23247
  var _this$props$answerFor;
23424
23248
 
@@ -23647,9 +23471,6 @@ class NumericInput extends React__namespace.Component {
23647
23471
  }
23648
23472
 
23649
23473
  render() {
23650
- const rubric = this.props.reviewModeRubric;
23651
- const answers = this.getAnswerBlurb(rubric);
23652
- const answerBlurb = answers[0];
23653
23474
  let labelText = this.props.labelText;
23654
23475
 
23655
23476
  if (labelText == null || labelText === "") {
@@ -23686,7 +23507,7 @@ class NumericInput extends React__namespace.Component {
23686
23507
  height: "auto"
23687
23508
  }
23688
23509
  });
23689
- const input = /*#__PURE__*/React__namespace.createElement(InputWithExamples, {
23510
+ return /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement(InputWithExamples, {
23690
23511
  ref: ref => this.inputRef = ref,
23691
23512
  value: this.props.currentValue,
23692
23513
  onChange: this.handleChange,
@@ -23699,30 +23520,7 @@ class NumericInput extends React__namespace.Component {
23699
23520
  id: this.props.widgetId,
23700
23521
  disabled: this.props.apiOptions.readOnly,
23701
23522
  style: styles.input
23702
- });
23703
- /* This only gets used with SAT Content */
23704
-
23705
- /* c8 ignore next if */
23706
-
23707
- if (answerBlurb) {
23708
- return /*#__PURE__*/React__namespace.createElement("span", {
23709
- className: "perseus-input-with-answer-blurb"
23710
- }, input, answerBlurb);
23711
- }
23712
-
23713
- if (this.props.apiOptions.satStyling) {
23714
- // NOTE(amy): the input widgets themselves already have
23715
- // a default aria label of "Your Answer", so we hide this
23716
- // redundant label from screen-readers.
23717
- return /*#__PURE__*/React__namespace.createElement("label", {
23718
- className: "perseus-input-with-label"
23719
- }, /*#__PURE__*/React__namespace.createElement("span", {
23720
- className: "perseus-input-label",
23721
- "aria-hidden": "true"
23722
- }, i18n__namespace.doNotTranslate("Answer:")), input);
23723
- }
23724
-
23725
- return /*#__PURE__*/React__namespace.createElement("div", null, input);
23523
+ }));
23726
23524
  }
23727
23525
 
23728
23526
  } // TODO(thomas): Currently we receive a list of lists of acceptable answer types
@@ -24518,7 +24316,7 @@ class HighlightRenderer extends React__namespace.PureComponent {
24518
24316
  const rects = this.state.cachedHighlightRects;
24519
24317
  return /*#__PURE__*/React__namespace.createElement("div", null, rects.map((rect, index) => /*#__PURE__*/React__namespace.createElement("div", {
24520
24318
  key: index,
24521
- className: aphrodite.css(styles$y.highlightRect),
24319
+ className: aphrodite.css(styles$x.highlightRect),
24522
24320
  style: {
24523
24321
  // NOTE(mdr): We apply `position: absolute` here
24524
24322
  // rather than in Aphrodite styles, because
@@ -24539,7 +24337,7 @@ class HighlightRenderer extends React__namespace.PureComponent {
24539
24337
 
24540
24338
  }
24541
24339
 
24542
- const styles$y = aphrodite.StyleSheet.create({
24340
+ const styles$x = aphrodite.StyleSheet.create({
24543
24341
  highlightRect: {
24544
24342
  background: "#fffabe" // highlighter yellow :)
24545
24343
 
@@ -24621,7 +24419,7 @@ class HighlightTooltip extends React__namespace.PureComponent {
24621
24419
 
24622
24420
 
24623
24421
  const content = /*#__PURE__*/React__namespace.createElement("div", {
24624
- className: aphrodite.css(styles$x.tooltipLabel),
24422
+ className: aphrodite.css(styles$w.tooltipLabel),
24625
24423
  onClick: this.props.onClick
24626
24424
  }, this.props.label);
24627
24425
  const style = {
@@ -24643,7 +24441,7 @@ class HighlightTooltip extends React__namespace.PureComponent {
24643
24441
 
24644
24442
  }
24645
24443
 
24646
- const styles$x = aphrodite.StyleSheet.create({
24444
+ const styles$w = aphrodite.StyleSheet.create({
24647
24445
  tooltipLabel: {
24648
24446
  // Unlike most tooltip contents, we don't want this label to be
24649
24447
  // selectable. Selecting it is not only unhelpful, but dangerous: if
@@ -25245,7 +25043,7 @@ class HighlightableContent extends React__namespace.PureComponent {
25245
25043
  const buildHighlight = r => this._buildHighlight(r);
25246
25044
 
25247
25045
  return /*#__PURE__*/React__namespace.createElement("div", {
25248
- className: aphrodite.css(styles$w.container),
25046
+ className: aphrodite.css(styles$v.container),
25249
25047
  ref: container => this._container = container
25250
25048
  }, /*#__PURE__*/React__namespace.createElement("div", null, this.props.enabled && this._container && this._content && /*#__PURE__*/React__namespace.createElement(HighlightingUI, {
25251
25049
  buildHighlight: buildHighlight,
@@ -25266,7 +25064,7 @@ class HighlightableContent extends React__namespace.PureComponent {
25266
25064
  onAddHighlight: this._handleAddHighlight,
25267
25065
  onRemoveHighlight: this._handleRemoveHighlight
25268
25066
  })), /*#__PURE__*/React__namespace.createElement("div", {
25269
- className: aphrodite.css(styles$w.content),
25067
+ className: aphrodite.css(styles$v.content),
25270
25068
  ref: content => this._content = content
25271
25069
  }, /*#__PURE__*/React__namespace.createElement(WordIndexer, {
25272
25070
  onWordsUpdate: this._handleWordsUpdate
@@ -25275,7 +25073,7 @@ class HighlightableContent extends React__namespace.PureComponent {
25275
25073
 
25276
25074
  }
25277
25075
 
25278
- const styles$w = aphrodite.StyleSheet.create({
25076
+ const styles$v = aphrodite.StyleSheet.create({
25279
25077
  // We render content with z-index 1, and highlights with z-index 0, so that
25280
25078
  // content will receive the browser's native pointer events. (Highlights
25281
25079
  // have their own magic code to manage hover detection, despite being
@@ -25691,7 +25489,7 @@ class LineHeightMeasurer extends React__namespace.Component {
25691
25489
 
25692
25490
  render() {
25693
25491
  return /*#__PURE__*/React__namespace.createElement("div", {
25694
- className: aphrodite.css(styles$v.measurer),
25492
+ className: aphrodite.css(styles$u.measurer),
25695
25493
  "aria-hidden": "true"
25696
25494
  }, /*#__PURE__*/React__namespace.createElement("div", {
25697
25495
  ref: ref => this._line = ref,
@@ -25700,7 +25498,7 @@ class LineHeightMeasurer extends React__namespace.Component {
25700
25498
  }
25701
25499
 
25702
25500
  }
25703
- const styles$v = aphrodite.StyleSheet.create({
25501
+ const styles$u = aphrodite.StyleSheet.create({
25704
25502
  measurer: {
25705
25503
  position: "absolute",
25706
25504
  top: 0,
@@ -26725,36 +26523,6 @@ function getA11yText(letter, checked, correct, crossedOut, showCorrectness) {
26725
26523
  });
26726
26524
  }
26727
26525
 
26728
- /**
26729
- * Given a choice's position in the radio widget, return the corresponding
26730
- * "choice letter". (For example, in English, `getChoiceLetter(0)` is "A",
26731
- * `getChoiceLetter(1)` is "B", etc.)
26732
- */
26733
-
26734
- function getChoiceLetter(pos) {
26735
- /* I18N: This is a list of single-character labels that will appear in
26736
- * front of multiple-choice options. For instance, a multiple-choice
26737
- * question with three options would display
26738
- * (A) first option
26739
- * (B) second option
26740
- * (C) third option
26741
- * There must be spaces between each of the different characters. The
26742
- * characters will show up next to options in the order that they are
26743
- * listed here. Most multiple choice questions have 5 or fewer options.
26744
- */
26745
- const lettersString = i18n__namespace._("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");
26746
-
26747
- const letters = lettersString.split(" ");
26748
-
26749
- if (pos < letters.length) {
26750
- // If the position we need is listed in the localized string, use that.
26751
- return letters[pos];
26752
- } // If we're out of letters, give up and return a space.
26753
-
26754
-
26755
- return " ";
26756
- }
26757
-
26758
26526
  /**
26759
26527
  * Renders a circular selection ring around the child.
26760
26528
  */
@@ -26774,7 +26542,7 @@ function FocusRing(props) {
26774
26542
  };
26775
26543
  return /*#__PURE__*/React__namespace.createElement("span", {
26776
26544
  "data-test-id": "focus-ring",
26777
- className: aphrodite.css(styles$u.ring),
26545
+ className: aphrodite.css(styles$t.ring),
26778
26546
  style: style
26779
26547
  }, children);
26780
26548
  }
@@ -26784,7 +26552,7 @@ FocusRing.defaultProps = {
26784
26552
  color: kaGreen$1,
26785
26553
  multipleSelect: false
26786
26554
  };
26787
- const styles$u = aphrodite.StyleSheet.create({
26555
+ const styles$t = aphrodite.StyleSheet.create({
26788
26556
  ring: {
26789
26557
  margin: "auto",
26790
26558
  display: "inline-block",
@@ -26794,9 +26562,38 @@ const styles$u = aphrodite.StyleSheet.create({
26794
26562
  }
26795
26563
  });
26796
26564
 
26797
- const SAT_ICON_SIZE = 25;
26798
- const LIBRARY_ICON_SIZE = 24;
26799
- const styles$t = aphrodite.StyleSheet.create({
26565
+ /**
26566
+ * Given a choice's position in the radio widget, return the corresponding
26567
+ * "choice letter". (For example, in English, `getChoiceLetter(0)` is "A",
26568
+ * `getChoiceLetter(1)` is "B", etc.)
26569
+ */
26570
+
26571
+ function getChoiceLetter(pos) {
26572
+ /* I18N: This is a list of single-character labels that will appear in
26573
+ * front of multiple-choice options. For instance, a multiple-choice
26574
+ * question with three options would display
26575
+ * (A) first option
26576
+ * (B) second option
26577
+ * (C) third option
26578
+ * There must be spaces between each of the different characters. The
26579
+ * characters will show up next to options in the order that they are
26580
+ * listed here. Most multiple choice questions have 5 or fewer options.
26581
+ */
26582
+ const lettersString = i18n__namespace._("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");
26583
+
26584
+ const letters = lettersString.split(" ");
26585
+
26586
+ if (pos < letters.length) {
26587
+ // If the position we need is listed in the localized string, use that.
26588
+ return letters[pos];
26589
+ } // If we're out of letters, give up and return a space.
26590
+
26591
+
26592
+ return " ";
26593
+ }
26594
+
26595
+ const CHOICE_ICON_SIZE = 24;
26596
+ const styles$s = aphrodite.StyleSheet.create({
26800
26597
  iconWrapper: {
26801
26598
  display: "inline-block",
26802
26599
  position: "relative"
@@ -26807,28 +26604,26 @@ const styles$t = aphrodite.StyleSheet.create({
26807
26604
  // extra space for the cute rounded line cap.
26808
26605
 
26809
26606
  const CROSS_OUT_LINE_PADDING = 2;
26810
- const CROSS_OUT_LINE_SIZE = LIBRARY_ICON_SIZE + CROSS_OUT_LINE_PADDING * 2;
26811
- const SAT_CROSS_OUT_LINE_SIZE = SAT_ICON_SIZE + CROSS_OUT_LINE_PADDING * 2;
26607
+ const CROSS_OUT_LINE_SIZE = CHOICE_ICON_SIZE + CROSS_OUT_LINE_PADDING * 2;
26812
26608
  /**
26813
26609
  * The "cross-out line" that appears over the icon when the choice has been
26814
26610
  * `crossedOut`.
26815
26611
  */
26816
26612
 
26817
26613
  function CrossOutLine(props) {
26818
- const crossOutLineSize = props.sat ? SAT_CROSS_OUT_LINE_SIZE : CROSS_OUT_LINE_SIZE;
26819
26614
  return /*#__PURE__*/React__namespace.createElement("svg", {
26820
- width: crossOutLineSize,
26821
- height: crossOutLineSize,
26822
- viewBox: "0 0 ".concat(crossOutLineSize, " ").concat(crossOutLineSize),
26823
- className: aphrodite.css(styles$s.crossOutLine),
26615
+ width: CROSS_OUT_LINE_SIZE,
26616
+ height: CROSS_OUT_LINE_SIZE,
26617
+ viewBox: "0 0 ".concat(CROSS_OUT_LINE_SIZE, " ").concat(CROSS_OUT_LINE_SIZE),
26618
+ className: aphrodite.css(styles$r.crossOutLine),
26824
26619
  "data-test-id": "choice-icon__cross-out-line"
26825
26620
  }, /*#__PURE__*/React__namespace.createElement("line", {
26826
26621
  // The line stretches from the bottom-left to top-right.
26827
26622
  // We don't quite go to the _very_ corner, because the cute
26828
26623
  // rounded line cap needs to bleed into our padding.
26829
26624
  x1: CROSS_OUT_LINE_PADDING,
26830
- x2: crossOutLineSize - CROSS_OUT_LINE_PADDING,
26831
- y1: crossOutLineSize - CROSS_OUT_LINE_PADDING,
26625
+ x2: CROSS_OUT_LINE_SIZE - CROSS_OUT_LINE_PADDING,
26626
+ y1: CROSS_OUT_LINE_SIZE - CROSS_OUT_LINE_PADDING,
26832
26627
  y2: CROSS_OUT_LINE_PADDING,
26833
26628
  stroke: props.color,
26834
26629
  strokeWidth: "2",
@@ -26836,7 +26631,7 @@ function CrossOutLine(props) {
26836
26631
  }));
26837
26632
  }
26838
26633
 
26839
- const styles$s = aphrodite.StyleSheet.create({
26634
+ const styles$r = aphrodite.StyleSheet.create({
26840
26635
  crossOutLine: {
26841
26636
  // Center the icon within the container.
26842
26637
  position: "absolute",
@@ -26847,10 +26642,11 @@ const styles$s = aphrodite.StyleSheet.create({
26847
26642
 
26848
26643
  function ChoiceInner(props) {
26849
26644
  const {
26850
- letter,
26645
+ pos,
26851
26646
  showCorrectness,
26852
26647
  correct
26853
26648
  } = props;
26649
+ const letter = getChoiceLetter(pos);
26854
26650
 
26855
26651
  if (!showCorrectness) {
26856
26652
  return letter;
@@ -26872,19 +26668,17 @@ function ChoiceInner(props) {
26872
26668
  // related to the selected state dynamically.
26873
26669
 
26874
26670
 
26875
- function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, primaryProductColor, correct, transparentBackground) {
26671
+ function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct) {
26876
26672
  let backgroundColor;
26877
26673
  let borderColor;
26878
26674
  let color;
26879
26675
 
26880
26676
  if (!showCorrectness && pressed) {
26881
- borderColor = primaryProductColor;
26882
- color = primaryProductColor;
26883
- backgroundColor = transparentBackground ? "transparent" : white$1;
26677
+ borderColor = Color__default["default"].blue;
26678
+ color = Color__default["default"].blue;
26679
+ backgroundColor = "transparent";
26884
26680
  } else if (checked) {
26885
- // Note: kaGreen is not only the default product color,
26886
- // but also the "correctness" color
26887
- const bg = showCorrectness && correct ? Color__default["default"].green : primaryProductColor;
26681
+ const bg = showCorrectness && correct ? Color__default["default"].green : Color__default["default"].blue;
26888
26682
  color = white$1;
26889
26683
  backgroundColor = bg;
26890
26684
  borderColor = bg;
@@ -26899,7 +26693,7 @@ function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, pri
26899
26693
  if (multipleSelect) {
26900
26694
  borderRadius = 3;
26901
26695
  } else {
26902
- borderRadius = LIBRARY_ICON_SIZE;
26696
+ borderRadius = CHOICE_ICON_SIZE;
26903
26697
  }
26904
26698
 
26905
26699
  return {
@@ -26910,7 +26704,7 @@ function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, pri
26910
26704
  };
26911
26705
  }
26912
26706
 
26913
- function LibraryChoiceIcon(props) {
26707
+ function ChoiceIcon(props) {
26914
26708
  const {
26915
26709
  checked,
26916
26710
  crossedOut,
@@ -26919,30 +26713,28 @@ function LibraryChoiceIcon(props) {
26919
26713
  focused,
26920
26714
  hovered,
26921
26715
  multipleSelect,
26922
- primaryProductColor,
26716
+ pos,
26923
26717
  previouslyAnswered,
26924
- letter,
26925
- pressed,
26926
- transparentBackground
26718
+ pressed
26927
26719
  } = props;
26928
- const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, primaryProductColor, correct, transparentBackground);
26720
+ const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct);
26929
26721
  return /*#__PURE__*/React__namespace.createElement("div", {
26930
- className: aphrodite.css(styles$t.iconWrapper)
26722
+ className: aphrodite.css(styles$s.iconWrapper)
26931
26723
  }, /*#__PURE__*/React__namespace.createElement(FocusRing, {
26932
- color: primaryProductColor,
26724
+ color: Color__default["default"].blue,
26933
26725
  visible: focused || hovered,
26934
26726
  multipleSelect: multipleSelect
26935
26727
  }, /*#__PURE__*/React__namespace.createElement("div", {
26936
26728
  style: dynamicStyles,
26937
26729
  "data-test-id": "choice-icon__library-choice-icon",
26938
- className: aphrodite.css(styles$r.circle, showCorrectness && correct && styles$r.circleCorrect, showCorrectness && !correct && styles$r.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$r.circleIncorrectAnswered) // used in BaseRadio editMode to check
26730
+ className: aphrodite.css(styles$q.circle, showCorrectness && correct && styles$q.circleCorrect, showCorrectness && !correct && styles$q.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$q.circleIncorrectAnswered) // used in BaseRadio editMode to check
26939
26731
  // if we actually clicked on the radio icon
26940
26732
  ,
26941
26733
  "data-is-radio-icon": true
26942
26734
  }, /*#__PURE__*/React__namespace.createElement("div", {
26943
- className: aphrodite.css(styles$r.innerWrapper)
26735
+ className: aphrodite.css(styles$q.innerWrapper)
26944
26736
  }, /*#__PURE__*/React__namespace.createElement(ChoiceInner, {
26945
- letter: letter,
26737
+ pos: pos,
26946
26738
  showCorrectness: showCorrectness,
26947
26739
  correct: correct
26948
26740
  })))), crossedOut && /*#__PURE__*/React__namespace.createElement(CrossOutLine, {
@@ -26950,10 +26742,10 @@ function LibraryChoiceIcon(props) {
26950
26742
  }));
26951
26743
  }
26952
26744
 
26953
- const styles$r = aphrodite.StyleSheet.create({
26745
+ const styles$q = aphrodite.StyleSheet.create({
26954
26746
  innerWrapper: {
26955
- width: LIBRARY_ICON_SIZE,
26956
- height: LIBRARY_ICON_SIZE,
26747
+ width: CHOICE_ICON_SIZE,
26748
+ height: CHOICE_ICON_SIZE,
26957
26749
  // Center the contents of the icon.
26958
26750
  display: "flex",
26959
26751
  alignItems: "center",
@@ -26961,8 +26753,8 @@ const styles$r = aphrodite.StyleSheet.create({
26961
26753
  },
26962
26754
  circle: {
26963
26755
  // Make the circle
26964
- width: LIBRARY_ICON_SIZE,
26965
- height: LIBRARY_ICON_SIZE,
26756
+ width: CHOICE_ICON_SIZE,
26757
+ height: CHOICE_ICON_SIZE,
26966
26758
  boxSizing: "border-box",
26967
26759
  borderStyle: "solid",
26968
26760
  borderWidth: 2,
@@ -26985,10 +26777,10 @@ const styles$r = aphrodite.StyleSheet.create({
26985
26777
  lineHeight: "1px"
26986
26778
  },
26987
26779
  circleCorrect: {
26988
- fontSize: LIBRARY_ICON_SIZE
26780
+ fontSize: CHOICE_ICON_SIZE
26989
26781
  },
26990
26782
  circleIncorrect: {
26991
- fontSize: LIBRARY_ICON_SIZE,
26783
+ fontSize: CHOICE_ICON_SIZE,
26992
26784
  borderColor: gray68,
26993
26785
  color: gray68
26994
26786
  },
@@ -26999,161 +26791,6 @@ const styles$r = aphrodite.StyleSheet.create({
26999
26791
  }
27000
26792
  });
27001
26793
 
27002
- /* Component for rendering a letter icon in a SAT radio choice */
27003
-
27004
- // TODO(amy): figure out a better scheme for specifying these
27005
- // styles that isn't such a pain to grok. See some neat ideas
27006
- // from MDR in https://phabricator.khanacademy.org/D35249.
27007
- function constructSATStyles(reviewMode, correct, checked, multipleSelect) {
27008
- let backgroundColor;
27009
- let borderColor = satBlue;
27010
- let color = satBlue;
27011
-
27012
- if (reviewMode) {
27013
- if (correct) {
27014
- borderColor = satCorrectColor;
27015
- color = checked ? white$1 : satCorrectColor;
27016
- backgroundColor = checked ? satCorrectColor : white$1;
27017
- } else if (checked) {
27018
- borderColor = satIncorrectColor;
27019
- color = white$1;
27020
- backgroundColor = satIncorrectColor;
27021
- }
27022
- } else if (checked) {
27023
- color = white$1;
27024
- backgroundColor = satBlue;
27025
- }
27026
-
27027
- let borderRadius;
27028
-
27029
- if (multipleSelect) {
27030
- borderRadius = 3;
27031
- } else {
27032
- borderRadius = SAT_ICON_SIZE;
27033
- }
27034
-
27035
- return {
27036
- color,
27037
- backgroundColor,
27038
- borderColor,
27039
- borderRadius
27040
- };
27041
- }
27042
-
27043
- function SATChoiceIcon(props) {
27044
- const {
27045
- letter,
27046
- crossedOut,
27047
- reviewMode,
27048
- correct,
27049
- checked,
27050
- multipleSelect
27051
- } = props;
27052
- const {
27053
- color,
27054
- backgroundColor,
27055
- borderColor,
27056
- borderRadius
27057
- } = constructSATStyles(reviewMode, correct, checked, multipleSelect);
27058
- return /*#__PURE__*/React__namespace.createElement("div", {
27059
- className: aphrodite.css(styles$t.iconWrapper)
27060
- }, /*#__PURE__*/React__namespace.createElement("div", {
27061
- className: aphrodite.css(styles$q.satCircle),
27062
- "data-test-id": "choice-icon__sat-choice-icon",
27063
- style: {
27064
- backgroundColor,
27065
- borderColor,
27066
- borderRadius
27067
- }
27068
- }), /*#__PURE__*/React__namespace.createElement("div", {
27069
- style: {
27070
- color
27071
- },
27072
- className: aphrodite.css(styles$q.letter)
27073
- }, /*#__PURE__*/React__namespace.createElement("span", null, letter)), crossedOut && /*#__PURE__*/React__namespace.createElement(CrossOutLine, {
27074
- color: borderColor,
27075
- sat: true
27076
- }));
27077
- }
27078
-
27079
- const styles$q = aphrodite.StyleSheet.create({
27080
- satCircle: {
27081
- display: "block",
27082
- borderStyle: "solid",
27083
- borderWidth: 2,
27084
- content: "''",
27085
- height: SAT_ICON_SIZE,
27086
- width: SAT_ICON_SIZE,
27087
- top: 1,
27088
- left: 1
27089
- },
27090
- letter: {
27091
- // These properties make sure that this element has the exact
27092
- // same size as `circle` so that we can center things
27093
- // inside of it.
27094
- border: "2px solid transparent",
27095
- width: SAT_ICON_SIZE,
27096
- height: SAT_ICON_SIZE,
27097
- position: "absolute",
27098
- top: 1,
27099
- // Center contained items.
27100
- display: "flex",
27101
- alignItems: "center",
27102
- justifyContent: "center",
27103
- fontFamily: boldFontFamily,
27104
- fontSize: 13
27105
- }
27106
- });
27107
-
27108
- /* Component for rendering a letter icon in radio choice */
27109
-
27110
- function ChoiceIcon(props) {
27111
- const {
27112
- pos,
27113
- reviewMode,
27114
- checked,
27115
- crossedOut,
27116
- correct,
27117
- product,
27118
- multipleSelect,
27119
- showCorrectness,
27120
- focused,
27121
- hovered,
27122
- pressed,
27123
- primaryProductColor = Color__default["default"].blue,
27124
- previouslyAnswered,
27125
- transparentBackground
27126
- } = props;
27127
- const letter = getChoiceLetter(pos);
27128
-
27129
- if (product === "sat") {
27130
- return /*#__PURE__*/React__namespace.createElement(SATChoiceIcon, {
27131
- letter: letter,
27132
- reviewMode: reviewMode,
27133
- checked: checked,
27134
- correct: correct,
27135
- crossedOut: crossedOut,
27136
- multipleSelect: multipleSelect
27137
- });
27138
- }
27139
-
27140
- return /*#__PURE__*/React__namespace.createElement(LibraryChoiceIcon, {
27141
- letter: letter,
27142
- reviewMode: reviewMode,
27143
- checked: checked,
27144
- crossedOut: crossedOut,
27145
- focused: focused,
27146
- hovered: hovered,
27147
- pressed: pressed,
27148
- correct: correct,
27149
- showCorrectness: showCorrectness,
27150
- primaryProductColor: primaryProductColor,
27151
- previouslyAnswered: previouslyAnswered,
27152
- transparentBackground: transparentBackground,
27153
- multipleSelect: multipleSelect
27154
- });
27155
- }
27156
-
27157
26794
  /**
27158
26795
  * Renders text indicating whether the choice was correct or
27159
26796
  * not and whether the choice was selected or not.
@@ -27192,16 +26829,10 @@ function OptionStatus(props) {
27192
26829
  correct,
27193
26830
  crossedOut,
27194
26831
  previouslyAnswered,
27195
- reviewMode,
27196
- satStyling
27197
- } = props; // Option status is exclued for SAT
27198
-
27199
- if (satStyling) {
27200
- return null;
27201
- } // Option status is shown only in review mode, or for incorrectly
26832
+ reviewMode
26833
+ } = props; // Option status is shown only in review mode, or for incorrectly
27202
26834
  // answered items.
27203
26835
 
27204
-
27205
26836
  if (!reviewMode && !previouslyAnswered) {
27206
26837
  return null;
27207
26838
  }
@@ -27299,21 +26930,14 @@ function Choice(props) {
27299
26930
  checked: updatedChecked,
27300
26931
  crossedOut: updatedCrossedOut
27301
26932
  });
27302
- } // HACK: while most of the styling for rendering SAT items is handled
27303
- // via aphrodite, we also need to assign normal CSS classnames here to
27304
- // special-case the coloring of MathJax formulas (see .MathJax .math in
27305
- // stylesheets/task-package/tasks.less)
27306
-
26933
+ }
27307
26934
 
27308
- const satCorrectChoice = apiOptions.satStyling && reviewMode && correct;
27309
- const satIncorrectChecked = apiOptions.satStyling && reviewMode && !correct && checked;
27310
- const descriptionClassName = classNames__default["default"]("description", satCorrectChoice && "sat-correct", satIncorrectChecked && "sat-incorrect", aphrodite.css(!apiOptions.satStyling && styles$o.description, apiOptions.satStyling && styles$o.satDescription, satCorrectChoice && checked && styles$o.satDescriptionCorrectChecked, satIncorrectChecked && styles$o.satDescriptionIncorrectChecked));
27311
- const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$o.rationale, !apiOptions.satStyling && styles$o.nonSatRationale, apiOptions.satStyling && styles$o.satReviewRationale)); // We want to show the choices as dimmed out when the choices are
27312
- // disabled. However, we don't want to do this in the SAT product and
27313
- // we also don't want to do this when we're in review mode in the
26935
+ const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$o.description));
26936
+ const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$o.rationale)); // We want to show the choices as dimmed out when the choices are disabled.
26937
+ // However, we don't want to do this when we're in review mode in the
27314
26938
  // content library.
27315
26939
 
27316
- const showDimmed = !apiOptions.satStyling && !reviewMode && apiOptions.readOnly || crossedOut;
26940
+ const showDimmed = !reviewMode && apiOptions.readOnly || crossedOut;
27317
26941
  const letter = getChoiceLetter(pos);
27318
26942
  const a11yText = getA11yText(letter, checked, correct, crossedOut, showCorrectness);
27319
26943
  const choiceId = uniqueId();
@@ -27368,8 +26992,6 @@ function Choice(props) {
27368
26992
  ref: forwardedRef,
27369
26993
  "aria-hidden": "true"
27370
26994
  }, _ref => {
27371
- var _apiOptions$styling;
27372
-
27373
26995
  let {
27374
26996
  hovered,
27375
26997
  focused,
@@ -27396,8 +27018,6 @@ function Choice(props) {
27396
27018
  showCorrectness: showCorrectness,
27397
27019
  multipleSelect: multipleSelect,
27398
27020
  reviewMode: reviewMode,
27399
- product: apiOptions.satStyling ? "sat" : "library",
27400
- primaryProductColor: (_apiOptions$styling = apiOptions.styling) === null || _apiOptions$styling === void 0 ? void 0 : _apiOptions$styling.primaryProductColor,
27401
27021
  previouslyAnswered: previouslyAnswered
27402
27022
  }), /*#__PURE__*/React__namespace.createElement("span", {
27403
27023
  style: {
@@ -27411,8 +27031,7 @@ function Choice(props) {
27411
27031
  correct: correct,
27412
27032
  crossedOut: crossedOut,
27413
27033
  previouslyAnswered: previouslyAnswered,
27414
- reviewMode: reviewMode,
27415
- satStyling: apiOptions.satStyling
27034
+ reviewMode: reviewMode
27416
27035
  })), /*#__PURE__*/React__namespace.createElement("div", null, content)));
27417
27036
  }), apiOptions.crossOutEnabled && !reviewMode && /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.Popover, {
27418
27037
  dismissEnabled: true,
@@ -27495,24 +27114,8 @@ const styles$o = aphrodite.StyleSheet.create({
27495
27114
  display: "inline-block",
27496
27115
  width: "100%"
27497
27116
  },
27498
- satDescription: {
27499
- display: "block",
27500
- position: "relative",
27501
- boxSizing: "border-box",
27502
- cursor: "pointer",
27503
- marginLeft: 0,
27504
- padding: "17px 14px 17px 0"
27505
- },
27506
- satDescriptionCorrectChecked: {
27507
- backgroundColor: satCorrectBackgroundColor
27508
- },
27509
- satDescriptionIncorrectChecked: {
27510
- backgroundColor: satIncorrectBackgroundColor
27511
- },
27512
27117
  rationale: {
27513
- display: "block"
27514
- },
27515
- nonSatRationale: {
27118
+ display: "block",
27516
27119
  padding: intermediateCheckboxPadding,
27517
27120
  paddingTop: 0,
27518
27121
  marginLeft: 54,
@@ -27520,10 +27123,6 @@ const styles$o = aphrodite.StyleSheet.create({
27520
27123
  padding: intermediateCheckboxPaddingPhone,
27521
27124
  paddingTop: 0
27522
27125
  }
27523
- },
27524
- satReviewRationale: {
27525
- marginTop: 13,
27526
- marginLeft: 45
27527
27126
  }
27528
27127
  });
27529
27128
  var Choice$1 = /*#__PURE__*/React__namespace.forwardRef((props, ref) => /*#__PURE__*/React__namespace.createElement(Choice, _extends({}, props, {
@@ -27696,22 +27295,18 @@ function BaseRadio(props) {
27696
27295
  }); // some commonly used shorthands
27697
27296
 
27698
27297
  const reviewMode = !!reviewModeRubric;
27699
- const sat = apiOptions.satStyling;
27700
27298
  const isMobile = apiOptions.isMobile;
27701
27299
  const firstChoiceHighlighted = choices[0].highlighted;
27702
27300
  const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
27703
- const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$n.radio, // SAT doesn't use the "responsive styling" as it conflicts
27704
- // with their custom theming.
27705
- !sat && styles$n.responsiveRadioContainer, !sat && firstChoiceHighlighted && isMobile && styles$n.radioContainerFirstHighlighted, !sat && lastChoiceHighlighted && isMobile && styles$n.radioContainerLastHighlighted, sat && styles$n.satRadio));
27301
+ const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$n.radio, styles$n.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$n.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$n.radioContainerLastHighlighted));
27706
27302
  const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$n.instructions, isMobile && styles$n.instructionsMobile));
27707
27303
  const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect);
27708
- const shouldShowInstructions = !sat;
27709
27304
  const responsiveClassName = aphrodite.css(styles$n.responsiveFieldset);
27710
27305
  const fieldset = /*#__PURE__*/React__namespace.createElement("fieldset", {
27711
27306
  className: "perseus-widget-radio-fieldset ".concat(responsiveClassName)
27712
- }, shouldShowInstructions && /*#__PURE__*/React__namespace.createElement("legend", {
27307
+ }, /*#__PURE__*/React__namespace.createElement("legend", {
27713
27308
  className: "perseus-sr-only"
27714
- }, instructions), shouldShowInstructions && /*#__PURE__*/React__namespace.createElement("div", {
27309
+ }, instructions), /*#__PURE__*/React__namespace.createElement("div", {
27715
27310
  className: instructionsClassName,
27716
27311
  "aria-hidden": "true"
27717
27312
  }, instructions), /*#__PURE__*/React__namespace.createElement("ul", {
@@ -27762,9 +27357,7 @@ function BaseRadio(props) {
27762
27357
  const aphroditeClassName = checked => {
27763
27358
  // Whether or not to show correctness borders
27764
27359
  // for this choice and the next choice.
27765
- const satShowCorrectness = sat && reviewMode && checked;
27766
- const satShowCorrectnessNext = sat && reviewMode && nextChoice && nextChoice.checked;
27767
- return aphrodite.css(sharedStyles.aboveScratchpad, styles$n.item, !sat && styles$n.responsiveItem, !sat && checked && styles$n.selectedItem, !sat && checked && choice.highlighted && styles$n.aboveBackdrop, !sat && checked && choice.highlighted && apiOptions.isMobile && styles$n.aboveBackdropMobile, !sat && nextChoiceHighlighted && apiOptions.isMobile && styles$n.nextHighlighted, sat && styles$n.satRadioOption, satShowCorrectness && !choice.correct && styles$n.satRadioOptionIncorrect, satShowCorrectness && choice.correct && styles$n.satRadioOptionCorrect, satShowCorrectnessNext && !nextChoice.correct && styles$n.satRadioOptionNextIncorrect, satShowCorrectnessNext && nextChoice.correct && styles$n.satRadioOptionNextCorrect, sat && reviewModeRubric && styles$n.satReviewRadioOption);
27360
+ return aphrodite.css(sharedStyles.aboveScratchpad, styles$n.item, styles$n.responsiveItem, checked && styles$n.selectedItem, checked && choice.highlighted && styles$n.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$n.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$n.nextHighlighted);
27768
27361
  }; // HACK(abdulrahman): Preloads the selection-state
27769
27362
  // css because of a bug that causes iOS to lag
27770
27363
  // when selecting the button for the first time.
@@ -27826,10 +27419,9 @@ function BaseRadio(props) {
27826
27419
  }, /*#__PURE__*/React__namespace.createElement(Element, elementProps));
27827
27420
  }))); // Allow for horizontal scrolling if content is too wide, which may be
27828
27421
  // an issue especially on phones.
27829
- // This is disabled in SAT, since it conflicts with their theming.
27830
27422
 
27831
27423
  return /*#__PURE__*/React__namespace.createElement("div", {
27832
- className: aphrodite.css(!sat && styles$n.responsiveContainer)
27424
+ className: aphrodite.css(styles$n.responsiveContainer)
27833
27425
  }, fieldset);
27834
27426
  }
27835
27427
 
@@ -27878,40 +27470,6 @@ const styles$n = aphrodite.StyleSheet.create({
27878
27470
  radioContainerLastHighlighted: {
27879
27471
  borderBottom: "1px solid rgba(0, 0, 0, 0)"
27880
27472
  },
27881
- satRadio: {
27882
- background: "none",
27883
- marginLeft: 0,
27884
- userSelect: "none"
27885
- },
27886
- satRadioOption: {
27887
- margin: 0,
27888
- padding: 0,
27889
- borderBottom: "1px solid #ccc",
27890
- ":first-child": {
27891
- borderTop: "1px solid #ccc"
27892
- }
27893
- },
27894
- satRadioOptionCorrect: {
27895
- borderBottomColor: satCorrectBorderColor,
27896
- ":first-child": {
27897
- borderTopColor: satCorrectBorderColor
27898
- }
27899
- },
27900
- satRadioOptionIncorrect: {
27901
- borderBottomColor: satIncorrectBorderColor,
27902
- ":first-child": {
27903
- borderTopColor: satIncorrectBorderColor
27904
- }
27905
- },
27906
- satRadioOptionNextCorrect: {
27907
- borderBottomColor: satCorrectBorderColor
27908
- },
27909
- satRadioOptionNextIncorrect: {
27910
- borderBottomColor: satIncorrectBorderColor
27911
- },
27912
- satReviewRadioOption: {
27913
- pointerEvents: "none"
27914
- },
27915
27473
  item: {
27916
27474
  marginLeft: 20
27917
27475
  },
@@ -29013,16 +28571,24 @@ class Definition extends React__namespace.Component {
29013
28571
  opened: activeDefinitionId === this.props.widgetId,
29014
28572
  onClose: () => setActiveDefinitionId(null),
29015
28573
  placement: "top"
29016
- }, /*#__PURE__*/React__namespace.createElement("span", {
29017
- className: "perseus-widget-definition"
29018
- }, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
29019
- size: "medium",
29020
- kind: "tertiary",
28574
+ }, /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
29021
28575
  onClick: () => {
29022
28576
  this.props.trackInteraction();
29023
28577
  setActiveDefinitionId(this.props.widgetId);
29024
28578
  }
29025
- }, this.props.togglePrompt)));
28579
+ }, _ref2 => {
28580
+ let {
28581
+ hovered,
28582
+ focused,
28583
+ pressed
28584
+ } = _ref2;
28585
+ return /*#__PURE__*/React__namespace.createElement("span", {
28586
+ style: {
28587
+ color: Color__default["default"].blue,
28588
+ borderBottom: hovered || focused || pressed ? "2px solid ".concat(Color__default["default"].blue) : "none"
28589
+ }
28590
+ }, this.props.togglePrompt);
28591
+ }));
29026
28592
  });
29027
28593
  }
29028
28594
 
@@ -35384,12 +34950,6 @@ const collegeCareersMoreTopicColor = "#329A86";
35384
34950
  const collegeCareersMoreHoverColor = "#218270";
35385
34951
  const collegeCareersMoreLinkColor = "#218270";
35386
34952
  const collegeCareersMoreLinkHoverColor = "#329A86";
35387
- const satDomainColor = "#0084CE";
35388
- const satSubjectColor = "#0084CE";
35389
- const satTopicColor = "#0084CE";
35390
- const satHoverColor = "#0084CE";
35391
- const satLinkColor = "#0084CE";
35392
- const satLinkHoverColor = "#0084CE";
35393
34953
  const colorProficient = "#1C758A";
35394
34954
  const colorPracticed = "rgb(158, 221, 235)";
35395
34955
  const colorMastery1 = "rgb(90, 197, 221)";
@@ -35735,12 +35295,6 @@ var globalConstants = /*#__PURE__*/Object.freeze({
35735
35295
  collegeCareersMoreHoverColor: collegeCareersMoreHoverColor,
35736
35296
  collegeCareersMoreLinkColor: collegeCareersMoreLinkColor,
35737
35297
  collegeCareersMoreLinkHoverColor: collegeCareersMoreLinkHoverColor,
35738
- satDomainColor: satDomainColor,
35739
- satSubjectColor: satSubjectColor,
35740
- satTopicColor: satTopicColor,
35741
- satHoverColor: satHoverColor,
35742
- satLinkColor: satLinkColor,
35743
- satLinkHoverColor: satLinkHoverColor,
35744
35298
  colorProficient: colorProficient,
35745
35299
  colorPracticed: colorPracticed,
35746
35300
  colorMastery1: colorMastery1,
@@ -48579,7 +48133,7 @@ class HintRenderer extends React__namespace.Component {
48579
48133
  className: "perseus-sr-only"
48580
48134
  }, i18n__namespace._("Hint #%(pos)s", {
48581
48135
  pos: pos + 1
48582
- })), !apiOptions.isMobile && !apiOptions.satStyling && totalHints && pos != null && /*#__PURE__*/React__namespace.createElement("span", {
48136
+ })), !apiOptions.isMobile && totalHints != null && pos != null && /*#__PURE__*/React__namespace.createElement("span", {
48583
48137
  className: "perseus-hint-label",
48584
48138
  style: {
48585
48139
  display: "block",