@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
203 lines (202 loc) • 8.02 kB
JavaScript
function _array_like_to_array(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
return arr2;
}
function _array_with_holes(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterable_to_array_limit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally{
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally{
if (_d) throw _e;
}
}
return _arr;
}
function _non_iterable_rest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _sliced_to_array(arr, i) {
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _unsupported_iterable_to_array(o, minLen) {
if (!o) return;
if (typeof o === "string") return _array_like_to_array(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { SimpleSelect } from '@instructure/quiz-common/components/SimpleSelect/index';
import { Flex } from '@instructure/quiz-common/components/Flex/index';
import { Decimal } from '@instructure/quiz-i18n/util/Decimal';
import { ScientificNumberInput } from '@instructure/quiz-number-input/components/ScientificNumberInput';
import { decimals, significantDigits } from 'instructure-validations';
import t from '@instructure/quiz-i18n/format-message';
import { DECIMALS, SIGNIFICANT_DIGITS } from './constants';
function PreciseResponse(param) {
var id = param.id, locale = param.locale, messages = param.messages, numericTypeSelect = param.numericTypeSelect, precision = param.precision, precisionType = param.precisionType, onChange = param.onChange, valueProp = param.value;
var _useState = _sliced_to_array(useState(function() {
if (valueProp) {
try {
return Decimal.toLocaleString(valueProp, locale);
} catch (e) {
return valueProp;
}
}
return '';
}), 2), value = _useState[0], setValue = _useState[1];
var parsedValue = function() {
return Decimal.parse(valueProp);
};
var minPrecision = function() {
var val = parsedValue();
if (precisionType === SIGNIFICANT_DIGITS) {
return val.isNaN() ? 1 : significantDigits(val.toString());
}
return val.isNaN() ? 0 : decimals(val.toString());
};
var maxPrecision = function() {
// These are the limits for toPrecision and toFixed in Chrome
if (precisionType === SIGNIFICANT_DIGITS) {
var val = parseFloat(valueProp);
return val === 0 ? 1 : 21;
}
return 100;
};
var handlePrecisionChange = function(event, _, normalized) {
// When precision changes, update the value to match the new precision (add
// or remove trailing zeros)
var newPrecision = normalized;
var newValue = valueProp;
var valueDecimal = parsedValue();
if (newPrecision != null && !valueDecimal.isNaN()) {
var precisionNumber = parseInt(newPrecision, 10);
newValue = precisionType === SIGNIFICANT_DIGITS ? valueDecimal.toPrecision(precisionNumber, locale) : valueDecimal.toFixed(precisionNumber, locale);
}
setValue(newValue);
onChange(event, {
id: id,
precision: newPrecision,
value: newValue
});
};
var handlePrecisionTypeChange = function(event, param) {
var newValue = param.value;
var newPrecisionType = newValue;
var newPrecision = precision;
if (valueProp) {
newPrecision = precisionFromValue(valueProp, newPrecisionType).toString();
}
onChange(event, {
id: id,
precision: newPrecision,
precisionType: newPrecisionType
});
};
var handleValueChange = function(event, newValue, normalized) {
// When the answer value changes, update the precision to match the
// precision of the answer
var newPrecision = precision;
if (normalized != null) {
newPrecision = precisionFromValue(normalized, precisionType).toString();
}
setValue(newValue);
onChange(event, {
id: id,
precision: newPrecision,
value: normalized
});
};
return /*#__PURE__*/ React.createElement(Flex, {
alignItems: "start"
}, /*#__PURE__*/ React.createElement(Flex.Item, {
shouldGrow: true,
shouldShrink: true,
margin: "0 xx-small"
}, numericTypeSelect), /*#__PURE__*/ React.createElement(Flex.Item, {
shouldGrow: true,
shouldShrink: true,
margin: "0 xx-small"
}, /*#__PURE__*/ React.createElement(ScientificNumberInput, {
renderLabel: t('Answer'),
locale: locale,
messages: messages.value,
onChange: handleValueChange,
value: value,
"aria-valuetext": "".concat(value, " ").concat(t('Answer')),
"data-automation": "sdk-numeric-precise-answer-number-input",
isRequired: true
})), /*#__PURE__*/ React.createElement(Flex.Item, {
shouldGrow: true,
shouldShrink: true,
margin: "0 xx-small"
}, /*#__PURE__*/ React.createElement(ScientificNumberInput, {
renderLabel: t('Precision'),
locale: locale,
max: maxPrecision(),
messages: messages.precision,
min: minPrecision(),
onChange: handlePrecisionChange,
step: 1,
value: precision,
"aria-valuetext": "".concat(precision, " ").concat(t('Precision')),
"data-automation": "sdk-numeric-precise-precision-number-input",
isRequired: true
})), /*#__PURE__*/ React.createElement(Flex.Item, {
shouldGrow: true,
shouldShrink: true,
margin: "0 xx-small"
}, /*#__PURE__*/ React.createElement(SimpleSelect, {
renderLabel: t('Type'),
onChange: handlePrecisionTypeChange,
value: precisionType
}, /*#__PURE__*/ React.createElement(SimpleSelect.Option, {
id: "precise-response-select-option-significant-digits",
value: SIGNIFICANT_DIGITS
}, t('Significant digits')), /*#__PURE__*/ React.createElement(SimpleSelect.Option, {
id: "precise-response-select-option-decimals",
value: DECIMALS
}, t('Decimal places')))));
}
PreciseResponse.propTypes = {
id: PropTypes.string.isRequired,
locale: PropTypes.string.isRequired,
messages: PropTypes.objectOf(PropTypes.array),
numericTypeSelect: PropTypes.node.isRequired,
precision: PropTypes.string,
precisionType: PropTypes.oneOf([
SIGNIFICANT_DIGITS,
DECIMALS
]).isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.string
};
PreciseResponse.defaultProps = {
messages: void 0,
precision: void 0,
value: void 0
};
export default PreciseResponse;
function precisionFromValue(value, precisionType) {
return precisionType === SIGNIFICANT_DIGITS ? significantDigits(value) : decimals(value);
}