@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
273 lines (272 loc) • 11.9 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
var _dec, _class, _CategoryForm;
function _callSuper(_this, derived, args) {
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
return !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (e) {
return false;
}
}
derived = _getPrototypeOf(derived);
return _possibleConstructorReturn(_this, isNativeReflectConstruct() ? Reflect.construct(derived, args || [], _getPrototypeOf(_this).constructor) : derived.apply(_this, args));
}
/** @jsx jsx */
import { Component } from 'react';
import PropTypes from 'prop-types';
import { jsx } from '@instructure/emotion';
import { Flex, withStyleOverrides, FormFieldGroup } from '@instructure/quiz-common';
import { Text } from '@instructure/ui-text';
import ChoiceInput from '../../../common/edit/components/ChoiceInput';
import AnswerInput from '../../../common/edit/components/AnswerInput';
import RemoveChoiceButton from '../../../common/edit/components/RemoveChoiceButton';
import Footer from '../../../common/edit/components/Footer';
import generateStyle from './styles';
import generateComponentTheme from './theme';
import t from '@instructure/quiz-i18n/es/format-message';
import { normalizeErrors } from '../../../../util/normalizeErrors';
var CategoryForm = (_dec = withStyleOverrides(generateStyle, generateComponentTheme), _dec(_class = (_CategoryForm = /*#__PURE__*/function (_Component) {
function CategoryForm() {
var _this2;
_classCallCheck(this, CategoryForm);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this2 = _callSuper(this, CategoryForm, [].concat(args));
_defineProperty(_this2, "answerRefs", {});
_defineProperty(_this2, "categoryRefs", {});
_defineProperty(_this2, "categoryAnswerInputRefs", {});
_defineProperty(_this2, "_answerRemoveHandlers", {});
_defineProperty(_this2, "_categoryRemoveHandlers", {});
_defineProperty(_this2, "_createAnswerHandlers", {});
_defineProperty(_this2, "_isMounted", false);
_defineProperty(_this2, "getCreateAnswerHandler", function (categoryId) {
var createAnswerHandler = _this2._createAnswerHandlers[categoryId];
if (createAnswerHandler) return createAnswerHandler;
createAnswerHandler = _this2.props.onCreateAnswer.bind(_this2, categoryId);
_this2._createAnswerHandlers[categoryId] = createAnswerHandler;
return createAnswerHandler;
});
_defineProperty(_this2, "getAnswerRemoveHandler", function (answerId, categoryId) {
var answerRemoveHandler = _this2._answerRemoveHandlers[categoryId];
if (answerRemoveHandler) return answerRemoveHandler;
answerRemoveHandler = _this2.props.onRemoveAnswer.bind(_this2, answerId, categoryId);
_this2._answerRemoveHandlers[answerId] = answerRemoveHandler;
return answerRemoveHandler;
});
_defineProperty(_this2, "getCategoryRemoveHandler", function (categoryId) {
var categoryRemoveHandler = _this2._categoryRemoveHandlers[categoryId];
if (categoryRemoveHandler) return categoryRemoveHandler;
categoryRemoveHandler = _this2.props.onRemoveCategory.bind(_this2, categoryId);
_this2._categoryRemoveHandlers[categoryId] = categoryRemoveHandler;
return categoryRemoveHandler;
});
_defineProperty(_this2, "handleFooterRef", function (node) {
_this2.footerRef = node;
});
_defineProperty(_this2, "renderRemoveButton", function (category, index) {
var onRemoveCategory = _this2.getCategoryRemoveHandler(category.id);
var singleCategory = _this2.props.sortedCategories.length === 1;
if (!singleCategory && !_this2.props.disabled) {
return jsx(RemoveChoiceButton, {
choiceId: category.id,
screenReaderText: t('Remove Category {index}: {category}', {
index: index,
category: category.itemBody
}),
onRemoveChoice: onRemoveCategory,
automationData: "sdk-remove-category-".concat(category.id)
});
}
});
_defineProperty(_this2, "renderCategory", function (category, index, focusOnMount) {
var onCreateAnswer = _this2.getCreateAnswerHandler(category.id);
var categoryAnswerInputRefs = function categoryAnswerInputRefs(node) {
_this2.categoryAnswerInputRefs[category.id] = node;
};
var categoryRef = function categoryRef(node) {
_this2.categoryRefs[category.id] = node;
};
return jsx("div", {
key: category.id,
className: "categoryContainer",
css: _this2.props.styles.categoryContainer
}, jsx("div", {
css: _this2.props.styles.categoryContainerWrapper
}, jsx("div", {
css: _this2.props.styles.itemContainer
}, jsx("div", {
css: _this2.props.styles.itemContainerBody
}, jsx(Text, {
color: "primary"
}, t('Category {position, number}', {
position: index + 1
}))), _this2.renderRemoveButton(category, index + 1)), jsx("div", {
css: _this2.props.styles.categoryBody
}, jsx("div", {
css: _this2.props.styles.categoryBodyDescriptionInput
}, jsx(AnswerInput, {
ref: categoryAnswerInputRefs,
disabled: _this2.props.disabled,
onChangeHandler: _this2.props.onCategoryInputChange,
onModalClose: _this2.props.onModalClose,
onModalOpen: _this2.props.onModalOpen,
id: category.id,
itemBody: category.itemBody,
errors: _this2.props.getCategoryErrors(category.id),
renderLabel: t('Description'),
screenReaderText: t('Category Description'),
focusOnMount: focusOnMount && _this2._isMounted,
noRCE: true,
automationData: "sdk-category-".concat(index + 1, "-description"),
isRequired: true
})), jsx(Flex, {
padding: "x-small",
direction: "column",
gap: "small"
}, _this2.props.categoryScoringData(category.id).map(function (answerId, index, source) {
var answer = _this2.props.distractors[answerId];
var focusOnMount = index + 1 === source.length && !answer.itemBody;
return jsx(Flex.Item, {
key: "answerInput".concat(answer.id)
}, _this2.renderAnswer(answer, category.id, focusOnMount));
})), jsx("div", {
css: _this2.props.styles.categoryBodyAnswers
}), !_this2.props.disabled && jsx(Footer, {
onCreateChoice: onCreateAnswer,
ref: categoryRef,
screenReaderText: t('Add answer to category {position, number}', {
position: index + 1
}),
notifyScreenreader: _this2.props.notifyScreenreader,
automationData: "sdk-add-answer-to-category-".concat(index + 1, "-button")
}))));
});
return _this2;
}
_inherits(CategoryForm, _Component);
return _createClass(CategoryForm, [{
key: "componentDidMount",
value: function componentDidMount() {
// focusOnMount is conditional on this component being mounted so that focus
// is not stolen on initial render when creating a new categorization question
this._isMounted = true;
}
}, {
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(nextProps) {
if (this.props.onCreateAnswer !== nextProps.onCreateAnswer) {
this._createAnswerHandlers = {};
}
if (this.props.onRemoveAnswer !== nextProps.onRemoveAnswer) {
this._answerRemoveHandlers = {};
}
if (this.props.onRemoveCategory !== nextProps.onRemoveCategory) {
this._categoryRemoveHandlers = {};
}
}
}, {
key: "renderAnswer",
value:
// ===========
// RENDER
// ===========
function renderAnswer(answer, categoryId, focusOnMount, index) {
var _this3 = this;
var onRemoveAnswer = this.getAnswerRemoveHandler(answer.id, categoryId);
return jsx(ChoiceInput, {
key: "answerInput".concat(answer.id),
ref: function ref(node) {
_this3.answerRefs[answer.id] = node;
},
disabledFields: this.props.disabled ? ['answerInput'] : [],
id: answer.id,
itemBody: answer.itemBody,
errors: this.props.distractorErrors(answer.id),
onInputChange: this.props.onDistractorInputChange,
onModalClose: this.props.onModalClose,
onModalOpen: this.props.onModalOpen,
onRemoveChoice: onRemoveAnswer,
shouldRenderRemoveChoice: !this.props.disabled,
focusOnMount: focusOnMount && this._isMounted,
noRCE: true,
notifyScreenreader: this.props.notifyScreenreader,
isRequired: true,
automationData: "sdk-category-".concat(index + 1, "-answer")
});
}
}, {
key: "render",
value: function render() {
var _this4 = this;
return jsx("div", {
css: this.props.styles.categoriesWrapper
}, jsx(FormFieldGroup, {
description: t('Categories'),
messages: normalizeErrors(this.props.categoriesErrors)
}, jsx("div", {
css: this.props.styles.categoriesContainer
}, this.props.sortedCategories.map(function (category, index, source) {
var focusOnMount = index + 1 === source.length && !category.itemBody;
return _this4.renderCategory(category, index, focusOnMount);
}))), !this.props.disabled && jsx(Footer, {
ref: this.handleFooterRef,
onCreateChoice: this.props.onCreateCategory,
buttonText: t('Category'),
screenReaderText: t('Add Category'),
notifyScreenreader: this.props.notifyScreenreader,
automationData: "sdk-add-category-button"
}));
}
}]);
}(Component), _defineProperty(_CategoryForm, "displayName", 'CategoryForm'), _defineProperty(_CategoryForm, "componentId", "Quizzes".concat(_CategoryForm.displayName)), _defineProperty(_CategoryForm, "propTypes", {
categoriesErrors: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string,
type: PropTypes.string
})),
getCategoryErrors: PropTypes.func,
categoryScoringData: PropTypes.func,
disabled: PropTypes.bool,
distractors: PropTypes.objectOf(PropTypes.shape({
id: PropTypes.string.isRequired,
itemBody: PropTypes.string.isRequired
})).isRequired,
distractorErrors: PropTypes.func,
notifyScreenreader: PropTypes.func.isRequired,
onCategoryInputChange: PropTypes.func,
onCreateAnswer: PropTypes.func,
onCreateCategory: PropTypes.func,
onDistractorInputChange: PropTypes.func,
onModalClose: PropTypes.func,
onModalOpen: PropTypes.func,
onRemoveAnswer: PropTypes.func,
onRemoveCategory: PropTypes.func,
sortedCategories: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
itemBody: PropTypes.string
})).isRequired,
styles: PropTypes.object
}), _defineProperty(_CategoryForm, "defaultProps", {
categoriesErrors: [],
getCategoryErrors: void 0,
categoryScoringData: void 0,
disabled: void 0,
distractorErrors: void 0,
onCategoryInputChange: void 0,
onCreateAnswer: void 0,
onCreateCategory: void 0,
onDistractorInputChange: void 0,
onModalClose: void 0,
onModalOpen: void 0,
onRemoveAnswer: void 0,
onRemoveCategory: void 0
}), _CategoryForm)) || _class);
export { CategoryForm as default };