quiz-interactions
Version:
A React UI component Library for quiz interaction types.
250 lines (208 loc) • 11.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _find = _interopRequireDefault(require("lodash/find"));
var _uiThemeable = require("@instructure/ui-themeable");
var _uiElements = require("@instructure/ui-elements");
var _uiMenu = require("@instructure/ui-menu");
var _uiA11y = require("@instructure/ui-a11y");
var _Pill = _interopRequireDefault(require("../Pill"));
var _Category = _interopRequireDefault(require("./components/Category"));
var _DropTargetContainer = _interopRequireDefault(require("../DropTargetContainer"));
var _theme = _interopRequireDefault(require("./theme"));
var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/lib/format-message"));
var _dec, _class, _class2, _temp;
var styles = {
componentId: 'fFpbu',
template: function template(theme) {
return "\n\n.fFpbu_cIVb{display:flex;flex-flow:row wrap;padding-top:".concat(theme.categoriesContainerPadding || 'inherit', ";position:relative}\n\n.fFpbu_cghZ{flex-basis:50%}\n\n.fFpbu_dEen{background-color:").concat(theme.categoryContainerBackground || 'inherit', ";display:flex;flex-direction:column;margin:0 ").concat(theme.categoryContainerMargin || 'inherit', " ").concat(theme.categoryContainerMargin || 'inherit', " 0;padding:").concat(theme.categoryContainerPadding || 'inherit', "}\n\n.fFpbu_dEen .fFpbu_fXbH{border:").concat(theme.emptyCategoryBorderWidth || 'inherit', " dashed ").concat(theme.emptyCategoryBorderColor || 'inherit', ";border-radius:").concat(theme.emptyCategoryBorderRadius || 'inherit', ";color:").concat(theme.emptyCategoryColor || 'inherit', ";flex:1;height:3.9rem;line-height:3.9rem;text-align:center}\n\n[dir=ltr] .fFpbu_dEen .fFpbu_fXbH,[dir=rtl] .fFpbu_dEen .fFpbu_fXbH{text-align:center}\n\n.fFpbu_dEen .fFpbu_bnZK{border:").concat(theme.filledCategoryBorderWidth || 'inherit', " solid ").concat(theme.filledCategoryBorderColor || 'inherit', ";border-radius:").concat(theme.filledCategoryBorderRadius || 'inherit', ";display:flex;flex:1;flex-wrap:wrap;padding-bottom:").concat(theme.pillMargin || 'inherit', ";padding-right:").concat(theme.pillMargin || 'inherit', "}\n\n.fFpbu_bnZK>div{margin-left:").concat(theme.pillMargin || 'inherit', "!important;margin-top:").concat(theme.pillMargin || 'inherit', "!important}\n\n.fFpbu_cktN{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;background-color:").concat(theme.categoryBackground || 'inherit', ";box-sizing:border-box;cursor:pointer;display:block;margin-top:").concat(theme.categoryMargin || 'inherit', ";max-width:100%;overflow:visible;position:relative;touch-action:manipulation;transform:none;user-select:none;vertical-align:middle}\n\n.fFpbu_cktN[aria-disabled]{cursor:not-allowed;opacity:0.5;pointer-events:none}\n\n.fFpbu_cktN:focus{outline:none}\n\n.fFpbu_cktN:before{border:").concat(theme.focusBorderWidth || 'inherit', " solid ").concat(theme.focusBorderColor || 'inherit', ";border-radius:calc(").concat(theme.filledCategoryBorderRadius || 'inherit', " + 0.125rem);bottom:-0.25rem;content:\"\";left:-0.25rem;opacity:0;pointer-events:none;position:absolute;right:-0.25rem;top:-0.25rem;transform:scale(0.02);transition:").concat(theme.popoverTriggerBeforeTransition || 'inherit', "}\n\n.fFpbu_cktN:focus:before{opacity:1;transform:scale(1)}\n\n@media only screen and (max-width:48rem){.fFpbu_cghZ{flex-basis:100%}}");
},
'categoriesContainer': 'fFpbu_cIVb',
'categoryContainerWrapper': 'fFpbu_cghZ',
'categoryContainer': 'fFpbu_dEen',
'categoryContentEmpty': 'fFpbu_fXbH',
'categoryContentFilled': 'fFpbu_bnZK',
'popoverTrigger': 'fFpbu_cktN'
};
var ENTER_KEY = 'Enter';
var SPACE_KEY = ' ';
var CategoriesContainer = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles), _dec(_class = (_temp = _class2 =
/*#__PURE__*/
function (_Component) {
(0, _inherits2.default)(CategoriesContainer, _Component);
function CategoriesContainer() {
var _getPrototypeOf2;
var _this;
(0, _classCallCheck2.default)(this, CategoriesContainer);
for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
_args[_key] = arguments[_key];
}
_this = (0, _possibleConstructorReturn2.default)(this, (_getPrototypeOf2 = (0, _getPrototypeOf3.default)(CategoriesContainer)).call.apply(_getPrototypeOf2, [this].concat(_args)));
_this.handleCategoryKeyPress = function (event) {
if (event.key === ENTER_KEY || event.key === SPACE_KEY) {
event.preventDefault(); // popoverMenu triggers on keyup, so waiting to
// open it once the keyup is done
// synthetic events error with async calls on targets
// so adding this null check to avoid
var target = event.target;
setTimeout(function () {
target && target.click();
});
}
};
_this.renderTargetCategory = function (item) {
return _react.default.createElement(_DropTargetContainer.default, {
key: item.id,
className: styles.categoryContainerWrapper,
onDrop: function onDrop() {
var _this$props;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return (_this$props = _this.props).onDrop.apply(_this$props, [item.id].concat(args));
}
}, _react.default.createElement(_Category.default // Will need to remove this once inst-ui id updated and revert to old way
, {
itemBody: item.itemBody,
itemId: item.id,
userResponse: _this.userResponseCategory(item.id),
categoryTrigger: _this.renderCategoryBody(item.id),
categoryContent: _this.renderCategoryPopoverContent(item.id),
styles: styles
}));
};
_this.renderStaticCategory = function (item) {
return _react.default.createElement("div", {
key: item.id,
className: styles.categoryContainerWrapper
}, _react.default.createElement("div", {
className: styles.categoryContainer
}, _react.default.createElement("span", null, _react.default.createElement(_uiA11y.ScreenReaderContent, null, (0, _formatMessage.default)('Category')), _react.default.createElement(_uiElements.Text, {
color: "primary"
}, item.itemBody)), _this.renderCategoryBody(item.id)));
};
return _this;
}
(0, _createClass2.default)(CategoriesContainer, [{
key: "userResponseCategory",
value: function userResponseCategory(categoryId) {
var response = (0, _find.default)(this.props.userResponseValue, {
id: categoryId
});
if (!response) {
return [];
}
return response.value || [];
}
}, {
key: "isDistractorSelected",
value: function isDistractorSelected(categoryId, idDistractor) {
return this.userResponseCategory(categoryId).includes(idDistractor);
}
}, {
key: "renderCategoryBody",
// ===========
// RENDER
// ===========
value: function renderCategoryBody(categoryId) {
var _this2 = this;
if (this.props.categoryBody) {
return this.props.categoryBody(categoryId);
}
var response = this.userResponseCategory(categoryId);
var hasNoResponse = response.length === 0;
var containerProps = this.props.isDraggable ? {
tabIndex: '0',
role: 'button'
} : {};
return (// eslint-disable-next-line jsx-a11y/no-static-element-interactions
_react.default.createElement("div", Object.assign({}, containerProps, {
className: styles.popoverTrigger,
onKeyPress: this.handleCategoryKeyPress,
ref: this.props.handleCategoryRef(categoryId)
}), _react.default.createElement(_uiA11y.ScreenReaderContent, null, (0, _formatMessage.default)('Selected Answers: Click to change selection.')), _react.default.createElement("div", {
className: hasNoResponse ? styles.categoryContentEmpty : styles.categoryContentFilled
}, hasNoResponse ? _react.default.createElement(_uiElements.Text, {
color: "secondary"
}, (0, _formatMessage.default)('No Answers Chosen')) : response.map(function (distractorId) {
return _react.default.createElement(_Pill.default, {
key: distractorId,
id: _this2.props.distractors[distractorId].id,
itemBody: _this2.props.distractors[distractorId].itemBody,
isDraggable: _this2.props.isDraggable,
onDropOut: _this2.props.onDropOut
});
})))
);
}
}, {
key: "renderCategoryPopoverContent",
value: function renderCategoryPopoverContent(categoryId) {
var _this3 = this;
return this.props.filterDistractors(categoryId).map(function (distractor) {
var checked = _this3.isDistractorSelected(categoryId, distractor.id);
return _react.default.createElement(_uiMenu.Menu.Item, {
key: distractor.id,
type: "checkbox",
selected: checked,
onSelect: function onSelect(event) {
return _this3.props.onMenuItemSelected(distractor.id, categoryId, checked, event);
}
}, distractor.itemBody);
});
}
}, {
key: "render",
value: function render() {
return _react.default.createElement("div", null, _react.default.createElement("div", {
className: styles.categoriesContainer
}, this.props.sortedCategories.map(this.props.isDraggable ? this.renderTargetCategory : this.renderStaticCategory)));
}
}]);
CategoriesContainer.displayName = "CategoriesContainer";
return CategoriesContainer;
}(_react.Component), _class2.propTypes = {
sortedCategories: _propTypes.default.arrayOf(_propTypes.default.shape({
id: _propTypes.default.string,
itemBody: _propTypes.default.string
})).isRequired,
categoryBody: _propTypes.default.func,
distractors: _propTypes.default.objectOf(_propTypes.default.shape({
id: _propTypes.default.string,
itemBody: _propTypes.default.string
})).isRequired,
filterDistractors: _propTypes.default.func,
handleCategoryRef: _propTypes.default.func,
isDraggable: _propTypes.default.bool,
onDrop: _propTypes.default.func,
onDropOut: _propTypes.default.func,
onMenuItemSelected: _propTypes.default.func,
userResponseValue: _propTypes.default.arrayOf(_propTypes.default.shape({
id: _propTypes.default.string,
value: _propTypes.default.arrayOf(_propTypes.default.string),
type: _propTypes.default.string
}))
}, _class2.defaultProps = {
categoryBody: null,
isDraggable: false,
filterDistractors: function filterDistractors() {},
handleCategoryRef: function handleCategoryRef() {},
onDrop: function onDrop() {},
onDropOut: function onDropOut() {},
onMenuItemSelected: function onMenuItemSelected() {},
userResponseValue: [] // ===========
// HELPERS
// ===========
}, _temp)) || _class);
exports.default = CategoriesContainer;