@khanacademy/perseus 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/es/index.css +17 -8
- package/dist/es/index.js +258 -223
- package/dist/es/index.js.map +1 -1
- package/dist/index.css +17 -8
- package/dist/index.js +261 -225
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/__stories__/input-with-examples.stories.jsx +1 -0
- package/src/components/input-with-examples.jsx +41 -24
- package/src/components/number-input.jsx +2 -2
- package/src/components/simple-keypad-input.jsx +18 -21
- package/src/components/text-input.jsx +5 -3
- package/src/index.js +1 -1
- package/src/multi-items/__tests__/__snapshots__/multi-renderer_test.js.snap +356 -65
- package/src/multi-items/__tests__/multi-renderer_test.js +9 -9
- package/src/perseus-types.js +18 -7
- package/src/styles/perseus-renderer.less +8 -2
- package/src/styles/widgets/matrix.less +2 -0
- package/src/styles/widgets/passage.less +9 -5
- package/src/util/answer-types.js +2 -3
- package/src/util/math.js +3 -10
- package/src/widgets/__stories__/numeric-input.stories.jsx +94 -7
- package/src/widgets/__tests__/__snapshots__/definition_test.js.snap +4 -4
- package/src/widgets/__tests__/__snapshots__/graded-group-set-jipt_test.jsx.snap +15 -6
- package/src/widgets/__tests__/__snapshots__/graded-group-set_test.jsx.snap +5 -2
- package/src/widgets/__tests__/__snapshots__/graded-group_test.jsx.snap +4 -1
- package/src/widgets/__tests__/__snapshots__/group_test.jsx.snap +228 -67
- package/src/widgets/__tests__/__snapshots__/matrix_test.jsx.snap +24 -24
- package/src/widgets/__tests__/__snapshots__/numeric-input_test.jsx.snap +4 -4
- package/src/widgets/__tests__/__snapshots__/radio_test.jsx.snap +2581 -679
- package/src/widgets/__tests__/group_test.jsx +4 -4
- package/src/widgets/__tests__/numeric-input_test.jsx +12 -8
- package/src/widgets/__tests__/passage_test.jsx +81 -0
- package/src/widgets/__tests__/radio/base-radio_test.jsx +55 -7
- package/src/widgets/__tests__/radio/choice_test.jsx +164 -63
- package/src/widgets/__tests__/radio_test.jsx +39 -15
- package/src/widgets/definition.jsx +1 -1
- package/src/widgets/graded-group.jsx +5 -1
- package/src/widgets/group.jsx +84 -102
- package/src/widgets/input-number.jsx +6 -1
- package/src/widgets/matrix.jsx +17 -1
- package/src/widgets/numeric-input.jsx +99 -86
- package/src/widgets/radio/base-radio.jsx +3 -1
- package/src/widgets/radio/choice-a11y-text.js +62 -0
- package/src/widgets/radio/choice-icon/choice-icon.jsx +0 -68
- package/src/widgets/radio/choice-icon/library-choice-icon.jsx +5 -10
- package/src/widgets/radio/choice-icon/sat-choice-icon.jsx +3 -12
- package/src/widgets/radio/choice.jsx +46 -3
package/dist/index.js
CHANGED
|
@@ -1417,8 +1417,7 @@ const KhanAnswerTypes = {
|
|
|
1417
1417
|
*/
|
|
1418
1418
|
number: {
|
|
1419
1419
|
convertToPredicate: function (correctAnswer, options) {
|
|
1420
|
-
|
|
1421
|
-
const correctFloat = parseFloat($__default["default"].trim(correctAnswer));
|
|
1420
|
+
const correctFloat = parseFloat(correctAnswer);
|
|
1422
1421
|
return [function (guess, maxError) {
|
|
1423
1422
|
return Math.abs(guess - correctFloat) < maxError;
|
|
1424
1423
|
}, $__default["default"].extend({}, options, {
|
|
@@ -21597,13 +21596,15 @@ class TextInput extends React__namespace.Component {
|
|
|
21597
21596
|
onBlur,
|
|
21598
21597
|
disabled,
|
|
21599
21598
|
placeholder,
|
|
21600
|
-
onKeyDown
|
|
21599
|
+
onKeyDown,
|
|
21600
|
+
style
|
|
21601
21601
|
} = this.props;
|
|
21602
21602
|
const formattedValue = value === null ? "" : value.toString();
|
|
21603
21603
|
return (
|
|
21604
21604
|
/*#__PURE__*/
|
|
21605
21605
|
// $FlowIgnore
|
|
21606
21606
|
React__namespace.createElement(wonderBlocksForm.TextField, {
|
|
21607
|
+
style: style,
|
|
21607
21608
|
disabled: disabled,
|
|
21608
21609
|
id: this.id,
|
|
21609
21610
|
value: formattedValue,
|
|
@@ -22001,7 +22002,8 @@ class InputWithExamples extends React__namespace.Component {
|
|
|
22001
22002
|
value: this.props.value,
|
|
22002
22003
|
onFocus: this._handleFocus,
|
|
22003
22004
|
onBlur: this._handleBlur,
|
|
22004
|
-
disabled: this.props.disabled
|
|
22005
|
+
disabled: this.props.disabled,
|
|
22006
|
+
style: this.props.style
|
|
22005
22007
|
};
|
|
22006
22008
|
|
|
22007
22009
|
if (this.props.type === TEX) {
|
|
@@ -22135,32 +22137,14 @@ class InputWithExamples extends React__namespace.Component {
|
|
|
22135
22137
|
|
|
22136
22138
|
}
|
|
22137
22139
|
|
|
22138
|
-
_defineProperty(InputWithExamples, "propTypes", {
|
|
22139
|
-
type: PropTypes__default["default"].oneOf([MATH, TEXT, TEX]),
|
|
22140
|
-
value: PropTypes__default["default"].string,
|
|
22141
|
-
onChange: PropTypes__default["default"].func.isRequired,
|
|
22142
|
-
className: PropTypes__default["default"].string,
|
|
22143
|
-
examples: PropTypes__default["default"].arrayOf(PropTypes__default["default"].string).isRequired,
|
|
22144
|
-
shouldShowExamples: PropTypes__default["default"].bool,
|
|
22145
|
-
convertDotToTimes: PropTypes__default["default"].bool,
|
|
22146
|
-
buttonSet: PropTypes__default["default"].string,
|
|
22147
|
-
buttonsVisible: PropTypes__default["default"].oneOf(["always", "never", "focused"]),
|
|
22148
|
-
labelText: PropTypes__default["default"].string,
|
|
22149
|
-
onFocus: PropTypes__default["default"].func,
|
|
22150
|
-
onBlur: PropTypes__default["default"].func,
|
|
22151
|
-
disabled: PropTypes__default["default"].bool,
|
|
22152
|
-
// A unique string identifying this InputWithExamples
|
|
22153
|
-
id: PropTypes__default["default"].string.isRequired,
|
|
22154
|
-
linterContext: PerseusLinter__namespace.linterContextProps
|
|
22155
|
-
});
|
|
22156
|
-
|
|
22157
22140
|
_defineProperty(InputWithExamples, "defaultProps", {
|
|
22158
22141
|
type: TEXT,
|
|
22159
22142
|
shouldShowExamples: true,
|
|
22160
22143
|
onFocus: function () {},
|
|
22161
22144
|
onBlur: function () {},
|
|
22162
22145
|
disabled: false,
|
|
22163
|
-
linterContext: PerseusLinter__namespace.linterContextDefault
|
|
22146
|
+
linterContext: PerseusLinter__namespace.linterContextDefault,
|
|
22147
|
+
className: ""
|
|
22164
22148
|
});
|
|
22165
22149
|
|
|
22166
22150
|
/**
|
|
@@ -22850,35 +22834,36 @@ _defineProperty(PossibleAnswers, "propTypes", {
|
|
|
22850
22834
|
answers: PropTypes__default["default"].arrayOf(PropTypes__default["default"].string)
|
|
22851
22835
|
});
|
|
22852
22836
|
|
|
22853
|
-
|
|
22854
|
-
|
|
22855
|
-
|
|
22856
|
-
|
|
22857
|
-
|
|
22858
|
-
|
|
22859
|
-
|
|
22860
|
-
componentDidMount
|
|
22837
|
+
class SimpleKeypadInput extends React__namespace.Component {
|
|
22838
|
+
constructor() {
|
|
22839
|
+
super(...arguments);
|
|
22840
|
+
|
|
22841
|
+
_defineProperty(this, "_isMounted", false);
|
|
22842
|
+
}
|
|
22843
|
+
|
|
22844
|
+
componentDidMount() {
|
|
22861
22845
|
// TODO(scottgrant): This is a hack to remove the deprecated call to
|
|
22862
22846
|
// this.isMounted() but is still considered an anti-pattern.
|
|
22863
22847
|
this._isMounted = true;
|
|
22864
|
-
}
|
|
22865
|
-
|
|
22848
|
+
}
|
|
22849
|
+
|
|
22850
|
+
componentWillUnmount() {
|
|
22866
22851
|
this._isMounted = false;
|
|
22867
|
-
}
|
|
22852
|
+
}
|
|
22868
22853
|
|
|
22869
22854
|
focus() {
|
|
22870
22855
|
// $FlowFixMe[object-this-reference]
|
|
22871
22856
|
this.refs.input.focus(); // eslint-disable-line react/no-string-refs
|
|
22872
|
-
}
|
|
22857
|
+
}
|
|
22873
22858
|
|
|
22874
22859
|
blur() {
|
|
22875
22860
|
// $FlowFixMe[object-this-reference]
|
|
22876
22861
|
this.refs.input.blur(); // eslint-disable-line react/no-string-refs
|
|
22877
|
-
}
|
|
22862
|
+
}
|
|
22878
22863
|
|
|
22879
|
-
getValue
|
|
22864
|
+
getValue() {
|
|
22880
22865
|
return this.props.value;
|
|
22881
|
-
}
|
|
22866
|
+
}
|
|
22882
22867
|
|
|
22883
22868
|
render() {
|
|
22884
22869
|
// $FlowFixMe[object-this-reference]
|
|
@@ -22915,7 +22900,12 @@ const SimpleKeypadInput = createReactClass__default["default"]({
|
|
|
22915
22900
|
}, rest));
|
|
22916
22901
|
}
|
|
22917
22902
|
|
|
22918
|
-
}
|
|
22903
|
+
}
|
|
22904
|
+
SimpleKeypadInput.propTypes = {
|
|
22905
|
+
keypadElement: mathInput.keypadElementPropType,
|
|
22906
|
+
onFocus: PropTypes__default["default"].func,
|
|
22907
|
+
value: PropTypes__default["default"].oneOfType([PropTypes__default["default"].string, PropTypes__default["default"].number])
|
|
22908
|
+
};
|
|
22919
22909
|
|
|
22920
22910
|
const ParseTex$1 = TexWrangler.parseTex;
|
|
22921
22911
|
const answerTypes = {
|
|
@@ -23170,9 +23160,13 @@ class InputNumber extends React__namespace.Component {
|
|
|
23170
23160
|
|
|
23171
23161
|
if (rubric.answerType == null) {
|
|
23172
23162
|
rubric.answerType = "number";
|
|
23173
|
-
}
|
|
23163
|
+
} // note(matthewc): this will get immediately parsed again by
|
|
23164
|
+
// `KhanAnswerTypes.number.convertToPredicate`, but a string is
|
|
23165
|
+
// expected here
|
|
23174
23166
|
|
|
23175
|
-
|
|
23167
|
+
|
|
23168
|
+
const stringValue = "".concat(rubric.value);
|
|
23169
|
+
const val = KhanAnswerTypes.number.createValidatorFunctional(stringValue, {
|
|
23176
23170
|
simplify: rubric.simplify,
|
|
23177
23171
|
inexact: rubric.inexact || undefined,
|
|
23178
23172
|
maxError: rubric.maxError,
|
|
@@ -23298,6 +23292,8 @@ class NumericInput extends React__namespace.Component {
|
|
|
23298
23292
|
constructor() {
|
|
23299
23293
|
super(...arguments);
|
|
23300
23294
|
|
|
23295
|
+
_defineProperty(this, "inputRef", void 0);
|
|
23296
|
+
|
|
23301
23297
|
_defineProperty(this, "state", {
|
|
23302
23298
|
// keeps track of the other set of values when switching
|
|
23303
23299
|
// between 0 and finite solutions
|
|
@@ -23316,9 +23312,8 @@ class NumericInput extends React__namespace.Component {
|
|
|
23316
23312
|
correct = score.type === "points" && score.earned === score.total;
|
|
23317
23313
|
|
|
23318
23314
|
if (!correct) {
|
|
23319
|
-
const correctAnswers =
|
|
23320
|
-
|
|
23321
|
-
const answerStrings = ___default["default"].map(correctAnswers, answer => {
|
|
23315
|
+
const correctAnswers = rubric.answers.filter(answer => answer.status === "correct");
|
|
23316
|
+
const answerStrings = correctAnswers.map(answer => {
|
|
23322
23317
|
// Figure out how this answer is supposed to be
|
|
23323
23318
|
// displayed
|
|
23324
23319
|
let format = "decimal";
|
|
@@ -23339,7 +23334,6 @@ class NumericInput extends React__namespace.Component {
|
|
|
23339
23334
|
|
|
23340
23335
|
return answerString;
|
|
23341
23336
|
});
|
|
23342
|
-
|
|
23343
23337
|
answerBlurb = /*#__PURE__*/React__namespace.createElement(PossibleAnswers, {
|
|
23344
23338
|
answers: answerStrings
|
|
23345
23339
|
});
|
|
@@ -23353,7 +23347,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
23353
23347
|
var _this$props$answerFor;
|
|
23354
23348
|
|
|
23355
23349
|
// if the set of specified forms are empty, allow all forms
|
|
23356
|
-
const forms = ((_this$props$answerFor = this.props.answerForms) === null || _this$props$answerFor === void 0 ? void 0 : _this$props$answerFor.length) !== 0 ? this.props.answerForms :
|
|
23350
|
+
const forms = ((_this$props$answerFor = this.props.answerForms) === null || _this$props$answerFor === void 0 ? void 0 : _this$props$answerFor.length) !== 0 ? this.props.answerForms : Object.keys(formExamples).map(name => {
|
|
23357
23351
|
return {
|
|
23358
23352
|
name: name,
|
|
23359
23353
|
simplify: "required"
|
|
@@ -23379,8 +23373,7 @@ class NumericInput extends React__namespace.Component {
|
|
|
23379
23373
|
|
|
23380
23374
|
const answerFormNames = ___default["default"].uniq((_this$props$answerFor3 = this.props.answerForms) === null || _this$props$answerFor3 === void 0 ? void 0 : _this$props$answerFor3.map(form => form.name));
|
|
23381
23375
|
|
|
23382
|
-
const allFormsAccepted = answerFormNames.length >=
|
|
23383
|
-
|
|
23376
|
+
const allFormsAccepted = answerFormNames.length >= Object.keys(formExamples).length;
|
|
23384
23377
|
return !noFormsAccepted && !allFormsAccepted;
|
|
23385
23378
|
});
|
|
23386
23379
|
|
|
@@ -23389,20 +23382,22 @@ class NumericInput extends React__namespace.Component {
|
|
|
23389
23382
|
});
|
|
23390
23383
|
|
|
23391
23384
|
_defineProperty(this, "focus", () => {
|
|
23392
|
-
|
|
23393
|
-
|
|
23385
|
+
var _this$inputRef;
|
|
23386
|
+
|
|
23387
|
+
(_this$inputRef = this.inputRef) === null || _this$inputRef === void 0 ? void 0 : _this$inputRef.focus();
|
|
23394
23388
|
return true;
|
|
23395
23389
|
});
|
|
23396
23390
|
|
|
23397
|
-
_defineProperty(this, "focusInputPath",
|
|
23398
|
-
|
|
23399
|
-
|
|
23400
|
-
this.
|
|
23391
|
+
_defineProperty(this, "focusInputPath", () => {
|
|
23392
|
+
var _this$inputRef2;
|
|
23393
|
+
|
|
23394
|
+
(_this$inputRef2 = this.inputRef) === null || _this$inputRef2 === void 0 ? void 0 : _this$inputRef2.focus();
|
|
23401
23395
|
});
|
|
23402
23396
|
|
|
23403
|
-
_defineProperty(this, "blurInputPath",
|
|
23404
|
-
|
|
23405
|
-
|
|
23397
|
+
_defineProperty(this, "blurInputPath", () => {
|
|
23398
|
+
var _this$inputRef3;
|
|
23399
|
+
|
|
23400
|
+
(_this$inputRef3 = this.inputRef) === null || _this$inputRef3 === void 0 ? void 0 : _this$inputRef3.blur();
|
|
23406
23401
|
});
|
|
23407
23402
|
|
|
23408
23403
|
_defineProperty(this, "getInputPaths", () => {
|
|
@@ -23470,9 +23465,8 @@ class NumericInput extends React__namespace.Component {
|
|
|
23470
23465
|
}
|
|
23471
23466
|
|
|
23472
23467
|
static getOneCorrectAnswerFromRubric(rubric) {
|
|
23473
|
-
const correctAnswers =
|
|
23474
|
-
|
|
23475
|
-
const answerStrings = ___default["default"].map(correctAnswers, answer => {
|
|
23468
|
+
const correctAnswers = rubric.answers.filter(answer => answer.status === "correct");
|
|
23469
|
+
const answerStrings = correctAnswers.map(answer => {
|
|
23476
23470
|
// Figure out how this answer is supposed to be
|
|
23477
23471
|
// displayed
|
|
23478
23472
|
let format = "decimal";
|
|
@@ -23502,31 +23496,30 @@ class NumericInput extends React__namespace.Component {
|
|
|
23502
23496
|
}
|
|
23503
23497
|
|
|
23504
23498
|
static validate(useInput, rubric) {
|
|
23505
|
-
const allAnswerForms =
|
|
23506
|
-
|
|
23507
|
-
const createValidator = answer =>
|
|
23508
|
-
|
|
23509
|
-
|
|
23510
|
-
|
|
23511
|
-
|
|
23512
|
-
|
|
23513
|
-
|
|
23514
|
-
|
|
23499
|
+
const allAnswerForms = answerFormButtons.map(e => e["value"]);
|
|
23500
|
+
|
|
23501
|
+
const createValidator = answer => {
|
|
23502
|
+
const stringAnswer = "".concat(answer.value);
|
|
23503
|
+
return KhanAnswerTypes.number.createValidatorFunctional(stringAnswer, {
|
|
23504
|
+
message: answer.message,
|
|
23505
|
+
simplify: answer.status === "correct" ? answer.simplify : "optional",
|
|
23506
|
+
inexact: true,
|
|
23507
|
+
// TODO(merlob) backfill / delete
|
|
23508
|
+
maxError: answer.maxError,
|
|
23509
|
+
forms: answer.strict && answer.answerForms && answer.answerForms.length !== 0 ? answer.answerForms : allAnswerForms
|
|
23510
|
+
});
|
|
23511
|
+
}; // We may have received TeX; try to parse it before grading.
|
|
23515
23512
|
// If `currentValue` is not TeX, this should be a no-op.
|
|
23516
23513
|
|
|
23517
23514
|
|
|
23518
23515
|
const currentValue = ParseTex(useInput.currentValue);
|
|
23519
|
-
|
|
23520
|
-
const correctAnswers = ___default["default"].where(rubric.answers, {
|
|
23521
|
-
status: "correct"
|
|
23522
|
-
});
|
|
23523
|
-
|
|
23516
|
+
const correctAnswers = rubric.answers.filter(answer => answer.status === "correct");
|
|
23524
23517
|
const normalizedAnswerExpected = correctAnswers.every(answer => Math.abs(answer.value) <= 1); // Look through all correct answers for one that matches either
|
|
23525
23518
|
// precisely or approximately and return the appropriate message:
|
|
23526
23519
|
// - if precise, return the message that the answer came with
|
|
23527
23520
|
// - if it needs to be simplified, etc., show that message
|
|
23528
23521
|
|
|
23529
|
-
let result =
|
|
23522
|
+
let result = correctAnswers.map(answer => {
|
|
23530
23523
|
// The coefficient is an attribute of the widget
|
|
23531
23524
|
let localValue = currentValue;
|
|
23532
23525
|
|
|
@@ -23540,22 +23533,17 @@ class NumericInput extends React__namespace.Component {
|
|
|
23540
23533
|
|
|
23541
23534
|
const validate = createValidator(answer);
|
|
23542
23535
|
return validate(maybeParsePercentInput(localValue, normalizedAnswerExpected));
|
|
23543
|
-
})
|
|
23536
|
+
}).find(match => match.correct || match.empty);
|
|
23544
23537
|
|
|
23545
23538
|
if (!result) {
|
|
23546
23539
|
// Otherwise, if the guess is not correct
|
|
23547
|
-
const otherAnswers = [].concat(
|
|
23548
|
-
status: "ungraded"
|
|
23549
|
-
}), ___default["default"].where(rubric.answers, {
|
|
23550
|
-
status: "wrong"
|
|
23551
|
-
})); // Look through all other answers and if one matches either
|
|
23540
|
+
const otherAnswers = [].concat(rubric.answers.filter(answer => answer.status === "ungraded"), rubric.answers.filter(answer => answer.status === "wrong")); // Look through all other answers and if one matches either
|
|
23552
23541
|
// precisely or approximately return the answer's message
|
|
23553
23542
|
|
|
23554
|
-
const match =
|
|
23543
|
+
const match = otherAnswers.find(answer => {
|
|
23555
23544
|
const validate = createValidator(answer);
|
|
23556
23545
|
return validate(maybeParsePercentInput(currentValue, normalizedAnswerExpected)).correct;
|
|
23557
23546
|
});
|
|
23558
|
-
|
|
23559
23547
|
result = {
|
|
23560
23548
|
empty: match ? match.status === "ungraded" : false,
|
|
23561
23549
|
correct: match ? match.status === "correct" : false,
|
|
@@ -23586,7 +23574,6 @@ class NumericInput extends React__namespace.Component {
|
|
|
23586
23574
|
const rubric = this.props.reviewModeRubric;
|
|
23587
23575
|
const answers = this.getAnswerBlurb(rubric);
|
|
23588
23576
|
const answerBlurb = answers[0];
|
|
23589
|
-
const classes = [];
|
|
23590
23577
|
let labelText = this.props.labelText;
|
|
23591
23578
|
|
|
23592
23579
|
if (labelText == null || labelText === "") {
|
|
@@ -23602,9 +23589,8 @@ class NumericInput extends React__namespace.Component {
|
|
|
23602
23589
|
|
|
23603
23590
|
if (this.props.apiOptions.customKeypad) {
|
|
23604
23591
|
// TODO(charlie): Support "Review Mode".
|
|
23605
|
-
return maybeRightAlignKeypadInput( /*#__PURE__*/React__namespace.createElement(SimpleKeypadInput
|
|
23606
|
-
|
|
23607
|
-
ref: "input",
|
|
23592
|
+
return maybeRightAlignKeypadInput( /*#__PURE__*/React__namespace.createElement(SimpleKeypadInput, {
|
|
23593
|
+
ref: ref => this.inputRef = ref,
|
|
23608
23594
|
value: this.props.currentValue,
|
|
23609
23595
|
keypadElement: this.props.keypadElement,
|
|
23610
23596
|
onChange: this.handleChange,
|
|
@@ -23613,12 +23599,18 @@ class NumericInput extends React__namespace.Component {
|
|
|
23613
23599
|
}));
|
|
23614
23600
|
}
|
|
23615
23601
|
|
|
23616
|
-
const
|
|
23617
|
-
|
|
23618
|
-
|
|
23602
|
+
const styles = aphrodite.StyleSheet.create({
|
|
23603
|
+
input: {
|
|
23604
|
+
textAlign: this.props.rightAlign ? "right" : "left",
|
|
23605
|
+
width: this.props.size === "small" ? 40 : 80,
|
|
23606
|
+
padding: 0,
|
|
23607
|
+
height: "auto"
|
|
23608
|
+
}
|
|
23609
|
+
});
|
|
23610
|
+
const input = /*#__PURE__*/React__namespace.createElement(InputWithExamples, {
|
|
23611
|
+
ref: ref => this.inputRef = ref,
|
|
23619
23612
|
value: this.props.currentValue,
|
|
23620
23613
|
onChange: this.handleChange,
|
|
23621
|
-
className: classNames__default["default"](classes),
|
|
23622
23614
|
labelText: labelText,
|
|
23623
23615
|
type: this._getInputType(),
|
|
23624
23616
|
examples: this.examples(),
|
|
@@ -23626,9 +23618,8 @@ class NumericInput extends React__namespace.Component {
|
|
|
23626
23618
|
onFocus: this._handleFocus,
|
|
23627
23619
|
onBlur: this._handleBlur,
|
|
23628
23620
|
id: this.props.widgetId,
|
|
23629
|
-
disabled: this.props.apiOptions.readOnly
|
|
23630
|
-
|
|
23631
|
-
highlightLint: this.props.highlightLint
|
|
23621
|
+
disabled: this.props.apiOptions.readOnly,
|
|
23622
|
+
style: styles.input
|
|
23632
23623
|
});
|
|
23633
23624
|
/* This only gets used with SAT Content */
|
|
23634
23625
|
|
|
@@ -23682,7 +23673,7 @@ const unionAnswerForms = function (answerFormsList) {
|
|
|
23682
23673
|
// two elements are equal, and returns a list of unique elements. This is
|
|
23683
23674
|
// just a helper function here, but works generally.
|
|
23684
23675
|
const uniqueBy = function (list, iteratee) {
|
|
23685
|
-
return
|
|
23676
|
+
return list.reduce((uniqueList, element) => {
|
|
23686
23677
|
// For each element, decide whether it's already in the list of
|
|
23687
23678
|
// unique items.
|
|
23688
23679
|
const inList = ___default["default"].find(uniqueList, iteratee.bind(null, element));
|
|
@@ -23696,13 +23687,13 @@ const unionAnswerForms = function (answerFormsList) {
|
|
|
23696
23687
|
}; // Pull out all of the forms from the different lists.
|
|
23697
23688
|
|
|
23698
23689
|
|
|
23699
|
-
const allForms =
|
|
23700
|
-
|
|
23690
|
+
const allForms = answerFormsList.flat(); // Pull out the unique forms using uniqueBy.
|
|
23701
23691
|
|
|
23702
23692
|
const uniqueForms = uniqueBy(allForms, ___default["default"].isEqual); // Sort them by the order they appear in the `formExamples` list.
|
|
23703
23693
|
|
|
23694
|
+
const formExampleKeys = Object.keys(formExamples);
|
|
23704
23695
|
return ___default["default"].sortBy(uniqueForms, form => {
|
|
23705
|
-
return
|
|
23696
|
+
return formExampleKeys.indexOf(form.name);
|
|
23706
23697
|
});
|
|
23707
23698
|
};
|
|
23708
23699
|
// This function checks if the user inputted a percent value, parsing
|
|
@@ -23711,7 +23702,7 @@ const unionAnswerForms = function (answerFormsList) {
|
|
|
23711
23702
|
// can accept several input forms with or without "%", the decision
|
|
23712
23703
|
// to parse based on the presence of "%" in the input, is so that we
|
|
23713
23704
|
// don't accidently scale the user typed value before grading, CP-930.
|
|
23714
|
-
|
|
23705
|
+
function maybeParsePercentInput(inputValue, normalizedAnswerExpected) {
|
|
23715
23706
|
// If the input value is not a string ending with "%", then there's
|
|
23716
23707
|
// nothing more to do. The value will be graded as inputted by user.
|
|
23717
23708
|
if (!(typeof inputValue === "string" && inputValue.endsWith("%"))) {
|
|
@@ -23736,13 +23727,13 @@ const maybeParsePercentInput = (inputValue, normalizedAnswerExpected) => {
|
|
|
23736
23727
|
|
|
23737
23728
|
|
|
23738
23729
|
return value;
|
|
23739
|
-
}
|
|
23730
|
+
}
|
|
23740
23731
|
|
|
23741
23732
|
const propsTransform = function (widgetOptions) {
|
|
23742
23733
|
const rendererProps = ___default["default"].extend(___default["default"].omit(widgetOptions, "answers"), {
|
|
23743
23734
|
answerForms: unionAnswerForms( // Pull out the name of each form and whether that form has
|
|
23744
23735
|
// required simplification.
|
|
23745
|
-
|
|
23736
|
+
widgetOptions.answers.map(answer => {
|
|
23746
23737
|
return ___default["default"].map(answer.answerForms, form => {
|
|
23747
23738
|
return {
|
|
23748
23739
|
simplify: answer.simplify,
|
|
@@ -24285,6 +24276,66 @@ _defineProperty(Icon, "defaultProps", {
|
|
|
24285
24276
|
color: "currentColor"
|
|
24286
24277
|
});
|
|
24287
24278
|
|
|
24279
|
+
function getA11yText(letter, checked, correct, crossedOut, showCorrectness) {
|
|
24280
|
+
// There are two pieces of metadata we want to add to each a11yText:
|
|
24281
|
+
// whether the answer was checked/crossed-out/neither, and whether the
|
|
24282
|
+
// answer is correct/incorrect/not-yet-revealed.
|
|
24283
|
+
//
|
|
24284
|
+
// Translation is tricky for cross-product situations like this, so
|
|
24285
|
+
// we've just enumerated all 9 possibilities as separate strings.
|
|
24286
|
+
if (showCorrectness && correct) {
|
|
24287
|
+
if (checked) {
|
|
24288
|
+
return i18n__namespace._("(Choice %(letter)s, Checked, Correct)", {
|
|
24289
|
+
letter
|
|
24290
|
+
});
|
|
24291
|
+
}
|
|
24292
|
+
|
|
24293
|
+
if (crossedOut) {
|
|
24294
|
+
return i18n__namespace._("(Choice %(letter)s, Crossed out, Correct)", {
|
|
24295
|
+
letter
|
|
24296
|
+
});
|
|
24297
|
+
}
|
|
24298
|
+
|
|
24299
|
+
return i18n__namespace._("(Choice %(letter)s, Correct)", {
|
|
24300
|
+
letter
|
|
24301
|
+
});
|
|
24302
|
+
}
|
|
24303
|
+
|
|
24304
|
+
if (showCorrectness && !correct) {
|
|
24305
|
+
if (checked) {
|
|
24306
|
+
return i18n__namespace._("(Choice %(letter)s, Checked, Incorrect)", {
|
|
24307
|
+
letter
|
|
24308
|
+
});
|
|
24309
|
+
}
|
|
24310
|
+
|
|
24311
|
+
if (crossedOut) {
|
|
24312
|
+
return i18n__namespace._("(Choice %(letter)s, Crossed out, Incorrect)", {
|
|
24313
|
+
letter
|
|
24314
|
+
});
|
|
24315
|
+
}
|
|
24316
|
+
|
|
24317
|
+
return i18n__namespace._("(Choice %(letter)s, Incorrect)", {
|
|
24318
|
+
letter
|
|
24319
|
+
});
|
|
24320
|
+
}
|
|
24321
|
+
|
|
24322
|
+
if (checked) {
|
|
24323
|
+
return i18n__namespace._("(Choice %(letter)s, Checked)", {
|
|
24324
|
+
letter
|
|
24325
|
+
});
|
|
24326
|
+
}
|
|
24327
|
+
|
|
24328
|
+
if (crossedOut) {
|
|
24329
|
+
return i18n__namespace._("(Choice %(letter)s, Crossed out)", {
|
|
24330
|
+
letter
|
|
24331
|
+
});
|
|
24332
|
+
}
|
|
24333
|
+
|
|
24334
|
+
return i18n__namespace._("(Choice %(letter)s)", {
|
|
24335
|
+
letter
|
|
24336
|
+
});
|
|
24337
|
+
}
|
|
24338
|
+
|
|
24288
24339
|
/**
|
|
24289
24340
|
* Given a choice's position in the radio widget, return the corresponding
|
|
24290
24341
|
* "choice letter". (For example, in English, `getChoiceLetter(0)` is "A",
|
|
@@ -24471,7 +24522,6 @@ function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, pri
|
|
|
24471
24522
|
|
|
24472
24523
|
function LibraryChoiceIcon(props) {
|
|
24473
24524
|
const {
|
|
24474
|
-
a11yText,
|
|
24475
24525
|
checked,
|
|
24476
24526
|
crossedOut,
|
|
24477
24527
|
showCorrectness,
|
|
@@ -24499,15 +24549,11 @@ function LibraryChoiceIcon(props) {
|
|
|
24499
24549
|
// radio icon
|
|
24500
24550
|
,
|
|
24501
24551
|
"data-is-radio-icon": true
|
|
24502
|
-
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24503
|
-
className: "perseus-sr-only"
|
|
24504
|
-
}, a11yText), /*#__PURE__*/React__namespace.createElement("div", {
|
|
24505
|
-
"aria-hidden": true
|
|
24506
24552
|
}, /*#__PURE__*/React__namespace.createElement(ChoiceInner, {
|
|
24507
24553
|
letter: letter,
|
|
24508
24554
|
showCorrectness: showCorrectness,
|
|
24509
24555
|
correct: correct
|
|
24510
|
-
})))
|
|
24556
|
+
}))), crossedOut && /*#__PURE__*/React__namespace.createElement(CrossOutLine, {
|
|
24511
24557
|
color: dynamicStyles.borderColor
|
|
24512
24558
|
}));
|
|
24513
24559
|
}
|
|
@@ -24597,7 +24643,6 @@ function constructSATStyles(reviewMode, correct, checked, multipleSelect) {
|
|
|
24597
24643
|
function SATChoiceIcon(props) {
|
|
24598
24644
|
const {
|
|
24599
24645
|
letter,
|
|
24600
|
-
a11yText,
|
|
24601
24646
|
crossedOut,
|
|
24602
24647
|
reviewMode,
|
|
24603
24648
|
correct,
|
|
@@ -24625,11 +24670,7 @@ function SATChoiceIcon(props) {
|
|
|
24625
24670
|
color
|
|
24626
24671
|
},
|
|
24627
24672
|
className: aphrodite.css(styles$u.letter)
|
|
24628
|
-
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
24629
|
-
className: "perseus-sr-only"
|
|
24630
|
-
}, a11yText), /*#__PURE__*/React__namespace.createElement("span", {
|
|
24631
|
-
"aria-hidden": "true"
|
|
24632
|
-
}, letter)), crossedOut && /*#__PURE__*/React__namespace.createElement(CrossOutLine, {
|
|
24673
|
+
}, /*#__PURE__*/React__namespace.createElement("span", null, letter)), crossedOut && /*#__PURE__*/React__namespace.createElement(CrossOutLine, {
|
|
24633
24674
|
color: borderColor,
|
|
24634
24675
|
sat: true
|
|
24635
24676
|
}));
|
|
@@ -24666,66 +24707,6 @@ const styles$u = aphrodite.StyleSheet.create({
|
|
|
24666
24707
|
|
|
24667
24708
|
/* Component for rendering a letter icon in radio choice */
|
|
24668
24709
|
|
|
24669
|
-
function getA11yText(letter, checked, correct, crossedOut, showCorrectness) {
|
|
24670
|
-
// There are two pieces of metadata we want to add to each a11yText:
|
|
24671
|
-
// whether the answer was checked/crossed-out/neither, and whether the
|
|
24672
|
-
// answer is correct/incorrect/not-yet-revealed.
|
|
24673
|
-
//
|
|
24674
|
-
// Translation is tricky for cross-product situations like this, so
|
|
24675
|
-
// we've just enumerated all 9 possibilities as separate strings.
|
|
24676
|
-
if (showCorrectness && correct) {
|
|
24677
|
-
if (checked) {
|
|
24678
|
-
return i18n__namespace._("(Choice %(letter)s, Checked, Correct)", {
|
|
24679
|
-
letter
|
|
24680
|
-
});
|
|
24681
|
-
}
|
|
24682
|
-
|
|
24683
|
-
if (crossedOut) {
|
|
24684
|
-
return i18n__namespace._("(Choice %(letter)s, Crossed out, Correct)", {
|
|
24685
|
-
letter
|
|
24686
|
-
});
|
|
24687
|
-
}
|
|
24688
|
-
|
|
24689
|
-
return i18n__namespace._("(Choice %(letter)s, Correct)", {
|
|
24690
|
-
letter
|
|
24691
|
-
});
|
|
24692
|
-
}
|
|
24693
|
-
|
|
24694
|
-
if (showCorrectness && !correct) {
|
|
24695
|
-
if (checked) {
|
|
24696
|
-
return i18n__namespace._("(Choice %(letter)s, Checked, Incorrect)", {
|
|
24697
|
-
letter
|
|
24698
|
-
});
|
|
24699
|
-
}
|
|
24700
|
-
|
|
24701
|
-
if (crossedOut) {
|
|
24702
|
-
return i18n__namespace._("(Choice %(letter)s, Crossed out, Incorrect)", {
|
|
24703
|
-
letter
|
|
24704
|
-
});
|
|
24705
|
-
}
|
|
24706
|
-
|
|
24707
|
-
return i18n__namespace._("(Choice %(letter)s, Incorrect)", {
|
|
24708
|
-
letter
|
|
24709
|
-
});
|
|
24710
|
-
}
|
|
24711
|
-
|
|
24712
|
-
if (checked) {
|
|
24713
|
-
return i18n__namespace._("(Choice %(letter)s, Checked)", {
|
|
24714
|
-
letter
|
|
24715
|
-
});
|
|
24716
|
-
}
|
|
24717
|
-
|
|
24718
|
-
if (crossedOut) {
|
|
24719
|
-
return i18n__namespace._("(Choice %(letter)s, Crossed out)", {
|
|
24720
|
-
letter
|
|
24721
|
-
});
|
|
24722
|
-
}
|
|
24723
|
-
|
|
24724
|
-
return i18n__namespace._("(Choice %(letter)s)", {
|
|
24725
|
-
letter
|
|
24726
|
-
});
|
|
24727
|
-
}
|
|
24728
|
-
|
|
24729
24710
|
function ChoiceIcon(props) {
|
|
24730
24711
|
const {
|
|
24731
24712
|
pos,
|
|
@@ -24744,12 +24725,10 @@ function ChoiceIcon(props) {
|
|
|
24744
24725
|
transparentBackground
|
|
24745
24726
|
} = props;
|
|
24746
24727
|
const letter = getChoiceLetter(pos);
|
|
24747
|
-
const a11yText = getA11yText(letter, checked, correct, crossedOut, showCorrectness);
|
|
24748
24728
|
|
|
24749
24729
|
if (product === "sat") {
|
|
24750
24730
|
return /*#__PURE__*/React__namespace.createElement(SATChoiceIcon, {
|
|
24751
24731
|
letter: letter,
|
|
24752
|
-
a11yText: a11yText,
|
|
24753
24732
|
reviewMode: reviewMode,
|
|
24754
24733
|
checked: checked,
|
|
24755
24734
|
correct: correct,
|
|
@@ -24760,7 +24739,6 @@ function ChoiceIcon(props) {
|
|
|
24760
24739
|
|
|
24761
24740
|
return /*#__PURE__*/React__namespace.createElement(LibraryChoiceIcon, {
|
|
24762
24741
|
letter: letter,
|
|
24763
|
-
a11yText: a11yText,
|
|
24764
24742
|
reviewMode: reviewMode,
|
|
24765
24743
|
checked: checked,
|
|
24766
24744
|
crossedOut: crossedOut,
|
|
@@ -24871,6 +24849,15 @@ const ellipsisHorizontalIcon = {
|
|
|
24871
24849
|
width: 100,
|
|
24872
24850
|
height: 27.284
|
|
24873
24851
|
};
|
|
24852
|
+
// Note(TB): Received errors when using useUniqueIdWithMock
|
|
24853
|
+
// so created this workaround function. Will update when
|
|
24854
|
+
// useUniqueIdWithMock is available.
|
|
24855
|
+
// https://khanacademy.atlassian.net/browse/FEI-4861?atlOrigin=eyJpIjoiNDJlZWMwNjM1NWJhNDBkMWFjY2FmN2I0ZjcxZmQxOGUiLCJwIjoiaiJ9
|
|
24856
|
+
let id = 0;
|
|
24857
|
+
|
|
24858
|
+
function uniqueId() {
|
|
24859
|
+
return "choice-".concat(id++);
|
|
24860
|
+
}
|
|
24874
24861
|
|
|
24875
24862
|
function Choice(props) {
|
|
24876
24863
|
const {
|
|
@@ -24927,6 +24914,9 @@ function Choice(props) {
|
|
|
24927
24914
|
// content library.
|
|
24928
24915
|
|
|
24929
24916
|
const showDimmed = !apiOptions.satStyling && !reviewMode && apiOptions.readOnly || crossedOut;
|
|
24917
|
+
const letter = getChoiceLetter(pos);
|
|
24918
|
+
const a11yText = getA11yText(letter, checked, correct, crossedOut, showCorrectness);
|
|
24919
|
+
const choiceId = uniqueId();
|
|
24930
24920
|
return /*#__PURE__*/React__namespace.createElement("div", {
|
|
24931
24921
|
style: {
|
|
24932
24922
|
dispay: "flex",
|
|
@@ -24939,7 +24929,26 @@ function Choice(props) {
|
|
|
24939
24929
|
width: "100%",
|
|
24940
24930
|
opacity: showDimmed ? 0.5 : 1.0
|
|
24941
24931
|
}
|
|
24942
|
-
}, /*#__PURE__*/React__namespace.createElement(
|
|
24932
|
+
}, /*#__PURE__*/React__namespace.createElement("div", {
|
|
24933
|
+
className: "perseus-sr-only"
|
|
24934
|
+
}, /*#__PURE__*/React__namespace.createElement("input", {
|
|
24935
|
+
type: multipleSelect ? "checkbox" : "radio",
|
|
24936
|
+
id: choiceId,
|
|
24937
|
+
checked: checked,
|
|
24938
|
+
onClick: () => {
|
|
24939
|
+
// If we're checking a crossed-out option, let's
|
|
24940
|
+
// also uncross it.
|
|
24941
|
+
sendChange({
|
|
24942
|
+
checked: !checked,
|
|
24943
|
+
crossedOut: false
|
|
24944
|
+
});
|
|
24945
|
+
},
|
|
24946
|
+
onChange: () => {},
|
|
24947
|
+
disabled: disabled || apiOptions.staticRender || apiOptions.readOnly,
|
|
24948
|
+
tabIndex: -1
|
|
24949
|
+
}), /*#__PURE__*/React__namespace.createElement("label", {
|
|
24950
|
+
htmlFor: choiceId
|
|
24951
|
+
}, a11yText, " \xA0 ", content)), /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
|
|
24943
24952
|
onClick: () => {
|
|
24944
24953
|
// If we're checking a crossed-out option, let's
|
|
24945
24954
|
// also uncross it.
|
|
@@ -24950,13 +24959,11 @@ function Choice(props) {
|
|
|
24950
24959
|
},
|
|
24951
24960
|
className: descriptionClassName,
|
|
24952
24961
|
disabled: disabled || apiOptions.staticRender || apiOptions.readOnly,
|
|
24953
|
-
"aria-label": "Select Choice ".concat(getChoiceLetter(pos)),
|
|
24954
|
-
"aria-checked": checked ? "true" : "false",
|
|
24955
|
-
role: "checkbox",
|
|
24956
24962
|
style: {
|
|
24957
24963
|
flex: 1
|
|
24958
24964
|
},
|
|
24959
|
-
ref: forwardedRef
|
|
24965
|
+
ref: forwardedRef,
|
|
24966
|
+
"aria-hidden": "true"
|
|
24960
24967
|
}, _ref => {
|
|
24961
24968
|
var _apiOptions$styling;
|
|
24962
24969
|
|
|
@@ -25297,7 +25304,8 @@ function BaseRadio(props) {
|
|
|
25297
25304
|
}, /*#__PURE__*/React__namespace.createElement("legend", {
|
|
25298
25305
|
className: "perseus-sr-only"
|
|
25299
25306
|
}, instructions), shouldShowInstructions && /*#__PURE__*/React__namespace.createElement("div", {
|
|
25300
|
-
className: instructionsClassName
|
|
25307
|
+
className: instructionsClassName,
|
|
25308
|
+
"aria-hidden": "true"
|
|
25301
25309
|
}, instructions), /*#__PURE__*/React__namespace.createElement("ul", {
|
|
25302
25310
|
className: className,
|
|
25303
25311
|
style: {
|
|
@@ -26574,7 +26582,7 @@ class Definition extends React__namespace.Component {
|
|
|
26574
26582
|
}, /*#__PURE__*/React__namespace.createElement("span", {
|
|
26575
26583
|
className: "perseus-widget-definition"
|
|
26576
26584
|
}, /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
26577
|
-
size: "
|
|
26585
|
+
size: "medium",
|
|
26578
26586
|
kind: "tertiary",
|
|
26579
26587
|
onClick: () => {
|
|
26580
26588
|
this.props.trackInteraction();
|
|
@@ -27255,7 +27263,10 @@ class GradedGroup$1 extends React__namespace.Component {
|
|
|
27255
27263
|
className: aphrodite.css(a11y.srOnly),
|
|
27256
27264
|
role: "alert",
|
|
27257
27265
|
"aria-label": gradeStatus
|
|
27258
|
-
}, gradeStatus), !apiOptions.isMobile && /*#__PURE__*/React__namespace.createElement("p",
|
|
27266
|
+
}, gradeStatus), !apiOptions.isMobile && /*#__PURE__*/React__namespace.createElement("p", {
|
|
27267
|
+
role: "status",
|
|
27268
|
+
"aria-live": "polite"
|
|
27269
|
+
}, this.state.message), !apiOptions.isMobile && /*#__PURE__*/React__namespace.createElement(Button__default["default"], {
|
|
27259
27270
|
kind: "secondary",
|
|
27260
27271
|
disabled: this.props.apiOptions.readOnly,
|
|
27261
27272
|
onClick: this._checkAnswer
|
|
@@ -28783,6 +28794,8 @@ class Group extends React__namespace.Component {
|
|
|
28783
28794
|
super(...arguments);
|
|
28784
28795
|
_this = this;
|
|
28785
28796
|
|
|
28797
|
+
_defineProperty(this, "rendererRef", void 0);
|
|
28798
|
+
|
|
28786
28799
|
_defineProperty(this, "change", function () {
|
|
28787
28800
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
28788
28801
|
args[_key] = arguments[_key];
|
|
@@ -28792,56 +28805,66 @@ class Group extends React__namespace.Component {
|
|
|
28792
28805
|
});
|
|
28793
28806
|
|
|
28794
28807
|
_defineProperty(this, "getUserInput", () => {
|
|
28795
|
-
|
|
28796
|
-
|
|
28808
|
+
var _this$rendererRef;
|
|
28809
|
+
|
|
28810
|
+
return (_this$rendererRef = this.rendererRef) === null || _this$rendererRef === void 0 ? void 0 : _this$rendererRef.getUserInput();
|
|
28797
28811
|
});
|
|
28798
28812
|
|
|
28799
28813
|
_defineProperty(this, "getSerializedState", () => {
|
|
28800
|
-
|
|
28801
|
-
|
|
28814
|
+
var _this$rendererRef2;
|
|
28815
|
+
|
|
28816
|
+
return (_this$rendererRef2 = this.rendererRef) === null || _this$rendererRef2 === void 0 ? void 0 : _this$rendererRef2.getSerializedState();
|
|
28802
28817
|
});
|
|
28803
28818
|
|
|
28804
28819
|
_defineProperty(this, "restoreSerializedState", (state, callback) => {
|
|
28805
|
-
|
|
28806
|
-
|
|
28820
|
+
var _this$rendererRef3;
|
|
28821
|
+
|
|
28822
|
+
(_this$rendererRef3 = this.rendererRef) === null || _this$rendererRef3 === void 0 ? void 0 : _this$rendererRef3.restoreSerializedState(state, callback); // Tell our renderer that we have no props to change
|
|
28807
28823
|
// (all our changes were in state):
|
|
28808
28824
|
|
|
28809
28825
|
return null;
|
|
28810
28826
|
});
|
|
28811
28827
|
|
|
28812
28828
|
_defineProperty(this, "simpleValidate", rubric => {
|
|
28813
|
-
|
|
28814
|
-
|
|
28829
|
+
var _this$rendererRef4;
|
|
28830
|
+
|
|
28831
|
+
return (_this$rendererRef4 = this.rendererRef) === null || _this$rendererRef4 === void 0 ? void 0 : _this$rendererRef4.score();
|
|
28815
28832
|
});
|
|
28816
28833
|
|
|
28817
28834
|
_defineProperty(this, "getInputPaths", () => {
|
|
28818
|
-
|
|
28819
|
-
|
|
28835
|
+
var _this$rendererRef5;
|
|
28836
|
+
|
|
28837
|
+
return (_this$rendererRef5 = this.rendererRef) === null || _this$rendererRef5 === void 0 ? void 0 : _this$rendererRef5.getInputPaths();
|
|
28820
28838
|
});
|
|
28821
28839
|
|
|
28822
|
-
_defineProperty(this, "setInputValue", (path, newValue,
|
|
28823
|
-
|
|
28824
|
-
|
|
28840
|
+
_defineProperty(this, "setInputValue", (path, newValue, callback) => {
|
|
28841
|
+
var _this$rendererRef6;
|
|
28842
|
+
|
|
28843
|
+
return (_this$rendererRef6 = this.rendererRef) === null || _this$rendererRef6 === void 0 ? void 0 : _this$rendererRef6.setInputValue(path, newValue, callback);
|
|
28825
28844
|
});
|
|
28826
28845
|
|
|
28827
28846
|
_defineProperty(this, "focus", () => {
|
|
28828
|
-
|
|
28829
|
-
|
|
28847
|
+
var _this$rendererRef7;
|
|
28848
|
+
|
|
28849
|
+
return (_this$rendererRef7 = this.rendererRef) === null || _this$rendererRef7 === void 0 ? void 0 : _this$rendererRef7.focus();
|
|
28830
28850
|
});
|
|
28831
28851
|
|
|
28832
28852
|
_defineProperty(this, "focusInputPath", path => {
|
|
28833
|
-
|
|
28834
|
-
|
|
28853
|
+
var _this$rendererRef8;
|
|
28854
|
+
|
|
28855
|
+
(_this$rendererRef8 = this.rendererRef) === null || _this$rendererRef8 === void 0 ? void 0 : _this$rendererRef8.focusPath(path);
|
|
28835
28856
|
});
|
|
28836
28857
|
|
|
28837
28858
|
_defineProperty(this, "blurInputPath", path => {
|
|
28838
|
-
|
|
28839
|
-
|
|
28859
|
+
var _this$rendererRef9;
|
|
28860
|
+
|
|
28861
|
+
(_this$rendererRef9 = this.rendererRef) === null || _this$rendererRef9 === void 0 ? void 0 : _this$rendererRef9.blurPath(path);
|
|
28840
28862
|
});
|
|
28841
28863
|
|
|
28842
28864
|
_defineProperty(this, "showRationalesForCurrentlySelectedChoices", () => {
|
|
28843
|
-
|
|
28844
|
-
|
|
28865
|
+
var _this$rendererRef10;
|
|
28866
|
+
|
|
28867
|
+
(_this$rendererRef10 = this.rendererRef) === null || _this$rendererRef10 === void 0 ? void 0 : _this$rendererRef10.showRationalesForCurrentlySelectedChoices();
|
|
28845
28868
|
});
|
|
28846
28869
|
}
|
|
28847
28870
|
|
|
@@ -28853,7 +28876,10 @@ class Group extends React__namespace.Component {
|
|
|
28853
28876
|
}
|
|
28854
28877
|
|
|
28855
28878
|
render() {
|
|
28856
|
-
|
|
28879
|
+
var _this$rendererRef11;
|
|
28880
|
+
|
|
28881
|
+
const apiOptions = { ...ApiOptions.defaults,
|
|
28882
|
+
...this.props.apiOptions,
|
|
28857
28883
|
// Api Rewriting to support correct onFocus/onBlur
|
|
28858
28884
|
// events for the mobile API
|
|
28859
28885
|
onFocusChange: (newFocus, oldFocus) => {
|
|
@@ -28865,7 +28891,7 @@ class Group extends React__namespace.Component {
|
|
|
28865
28891
|
this.props.onFocus(newFocus);
|
|
28866
28892
|
}
|
|
28867
28893
|
}
|
|
28868
|
-
}
|
|
28894
|
+
}; // Allow a problem number annotation to be added.
|
|
28869
28895
|
// This is cyclical and should probably be reconsidered. In order to
|
|
28870
28896
|
// render the annotation ("Question 3 of 10"), we call findWidgets to
|
|
28871
28897
|
// figure out our index in the list of all fellow group widgets. On
|
|
@@ -28874,9 +28900,8 @@ class Group extends React__namespace.Component {
|
|
|
28874
28900
|
// componentDidMount so that we can number ourselves properly. But,
|
|
28875
28901
|
// really we should have a more unidirectional flow. TODO(marcia): fix.
|
|
28876
28902
|
|
|
28877
|
-
|
|
28878
|
-
const number =
|
|
28879
|
-
|
|
28903
|
+
const groupWidgets = this.props.findWidgets("group");
|
|
28904
|
+
const number = groupWidgets.indexOf(this);
|
|
28880
28905
|
const problemNumComponent = this.props.apiOptions.groupAnnotator(number, this.props.widgetId); // This is a little strange because the id of the widget that actually
|
|
28881
28906
|
// changed is going to be lost in favor of the group widget's id. The
|
|
28882
28907
|
// widgets prop also wasn't actually changed, and this only serves to
|
|
@@ -28884,15 +28909,12 @@ class Group extends React__namespace.Component {
|
|
|
28884
28909
|
// has occurred.
|
|
28885
28910
|
|
|
28886
28911
|
const onInteractWithWidget = id => {
|
|
28887
|
-
|
|
28888
|
-
|
|
28889
|
-
// eslint-disable-next-line react/no-string-refs
|
|
28890
|
-
this.change("widgets", this.refs.renderer.props.widgets);
|
|
28912
|
+
if (this.rendererRef) {
|
|
28913
|
+
this.change("widgets", this.rendererRef.props.widgets);
|
|
28891
28914
|
}
|
|
28892
|
-
};
|
|
28893
|
-
|
|
28915
|
+
};
|
|
28894
28916
|
|
|
28895
|
-
const score = this.
|
|
28917
|
+
const score = (_this$rendererRef11 = this.rendererRef) === null || _this$rendererRef11 === void 0 ? void 0 : _this$rendererRef11.score();
|
|
28896
28918
|
const isValid = score && score.type !== "invalid";
|
|
28897
28919
|
const isInvalid = score && score.type === "invalid"; // TODO(mdr): Widgets inside this Renderer are not discoverable through
|
|
28898
28920
|
// the parent Renderer's `findWidgets` function.
|
|
@@ -28903,15 +28925,17 @@ class Group extends React__namespace.Component {
|
|
|
28903
28925
|
"perseus-group-valid-answer": isValid,
|
|
28904
28926
|
"perseus-group-invalid-answer": isInvalid
|
|
28905
28927
|
})
|
|
28906
|
-
}, problemNumComponent, /*#__PURE__*/React__namespace.createElement(Renderer,
|
|
28907
|
-
|
|
28908
|
-
|
|
28928
|
+
}, problemNumComponent, /*#__PURE__*/React__namespace.createElement(Renderer, {
|
|
28929
|
+
content: this.props.content,
|
|
28930
|
+
widgets: this.props.widgets,
|
|
28931
|
+
images: this.props.images,
|
|
28932
|
+
ref: ref => this.rendererRef = ref,
|
|
28909
28933
|
apiOptions: apiOptions,
|
|
28910
28934
|
findExternalWidgets: this.props.findWidgets,
|
|
28911
28935
|
reviewMode: !!this.props.reviewModeRubric,
|
|
28912
28936
|
onInteractWithWidget: onInteractWithWidget,
|
|
28913
28937
|
linterContext: this.props.linterContext
|
|
28914
|
-
})
|
|
28938
|
+
}), this.props.icon && /*#__PURE__*/React__namespace.createElement("div", {
|
|
28915
28939
|
className: "group-icon"
|
|
28916
28940
|
}, this.props.icon));
|
|
28917
28941
|
}
|
|
@@ -28926,7 +28950,9 @@ _defineProperty(Group, "defaultProps", {
|
|
|
28926
28950
|
});
|
|
28927
28951
|
|
|
28928
28952
|
const traverseChildWidgets$1 = function (props, traverseRenderer) {
|
|
28929
|
-
return
|
|
28953
|
+
return { ...props,
|
|
28954
|
+
...traverseRenderer(props)
|
|
28955
|
+
};
|
|
28930
28956
|
};
|
|
28931
28957
|
|
|
28932
28958
|
var Group$1 = {
|
|
@@ -36604,7 +36630,17 @@ class Matrix extends React__namespace.Component {
|
|
|
36604
36630
|
} else if (this.props.numericInput) {
|
|
36605
36631
|
MatrixInput = /*#__PURE__*/React__namespace.createElement(NumberInput, inputProps);
|
|
36606
36632
|
} else {
|
|
36607
|
-
|
|
36633
|
+
const updatedProps = { ...inputProps,
|
|
36634
|
+
style: aphrodite.StyleSheet.create({
|
|
36635
|
+
// eslint-disable-next-line react-native/no-unused-styles
|
|
36636
|
+
input: { ...inputProps.style,
|
|
36637
|
+
display: "inline-block",
|
|
36638
|
+
padding: 0,
|
|
36639
|
+
backgroundColor: outside ? "#f3f3f3" : "#fff"
|
|
36640
|
+
}
|
|
36641
|
+
}).input
|
|
36642
|
+
};
|
|
36643
|
+
MatrixInput = /*#__PURE__*/React__namespace.createElement(TextInput, updatedProps);
|
|
36608
36644
|
}
|
|
36609
36645
|
|
|
36610
36646
|
return /*#__PURE__*/React__namespace.createElement("span", {
|