@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
227 lines (226 loc) • 10.3 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
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 _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = require("react");
var _propTypes = _interopRequireDefault(require("prop-types"));
var _reactDom = _interopRequireDefault(require("react-dom"));
var _minBy = _interopRequireDefault(require("lodash/fp/minBy"));
var _emotion = require("@instructure/emotion");
var _styles = _interopRequireDefault(require("./styles"));
var _theme = _interopRequireDefault(require("./theme"));
var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
var _quizCommon = require("@instructure/quiz-common");
var _dec, _class, _TargetContainer;
/** @jsx jsx */
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 = (0, _getPrototypeOf2["default"])(derived);
return (0, _possibleConstructorReturn2["default"])(_this, isNativeReflectConstruct() ? Reflect.construct(derived, args || [], (0, _getPrototypeOf2["default"])(_this).constructor) : derived.apply(_this, args));
}
var TargetContainer = exports["default"] = (_dec = (0, _quizCommon.withStyleOverrides)(_styles["default"], _theme["default"]), _dec(_class = (_TargetContainer = /*#__PURE__*/function (_Component) {
function TargetContainer() {
var _this2;
(0, _classCallCheck2["default"])(this, TargetContainer);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this2 = _callSuper(this, TargetContainer, [].concat(args));
(0, _defineProperty2["default"])(_this2, "state", {
imageWidth: 0,
imageHeight: 0
});
(0, _defineProperty2["default"])(_this2, "canvas", null);
(0, _defineProperty2["default"])(_this2, "image", null);
// ===========
// HELPERS
// ===========
(0, _defineProperty2["default"])(_this2, "convertCoordinate", function (item) {
return {
x: item.x * _this2.state.imageWidth,
y: item.y * _this2.state.imageHeight
};
});
(0, _defineProperty2["default"])(_this2, "currentCoordinates", function (coordinates) {
if (!coordinates || !coordinates.length) return null;
return coordinates.map(_this2.convertCoordinate);
});
(0, _defineProperty2["default"])(_this2, "getResponseDetails", function (index, feedbackCoordinates) {
var _this2$props$userResp;
var flipResponse = false;
var responseCoordinates = null;
var isCorrect = null;
var userResponse = (_this2$props$userResp = _this2.props.userResponseCoordinate) === null || _this2$props$userResp === void 0 ? void 0 : _this2$props$userResp[index];
if (_this2.validCoordinates(userResponse)) {
responseCoordinates = _this2.convertCoordinate(userResponse);
isCorrect = userResponse.correct;
flipResponse = _this2.shouldFlipResponse(responseCoordinates, feedbackCoordinates);
}
return {
responseCoordinates: responseCoordinates,
isCorrect: isCorrect,
flipResponse: flipResponse
};
});
(0, _defineProperty2["default"])(_this2, "shouldFlipResponse", function (responseCoordinates, feedbackCoordinates) {
if (feedbackCoordinates) {
var min = (0, _minBy["default"])('y', feedbackCoordinates);
return min && responseCoordinates.y > min.y;
}
return true;
});
// ===========
// HANDLERS
// ===========
(0, _defineProperty2["default"])(_this2, "handleCanvasRef", function (node) {
_this2.canvas = node;
});
(0, _defineProperty2["default"])(_this2, "handleImageRef", function (node) {
_this2.image = node;
});
(0, _defineProperty2["default"])(_this2, "updateImageDimensions", function () {
var rectObject = _reactDom["default"].findDOMNode(_this2.image).getBoundingClientRect();
_this2.setState({
imageWidth: rectObject.width,
imageHeight: rectObject.height
});
});
(0, _defineProperty2["default"])(_this2, "handleImageLoad", function (event) {
_this2.setState({
imageWidth: event.target.offsetWidth,
imageHeight: event.target.offsetHeight
});
});
// ===========
// RENDER
// ===========
(0, _defineProperty2["default"])(_this2, "renderCanvas", function () {
var hotspots = _this2.props.hotspots;
if (!(hotspots !== null && hotspots !== void 0 && hotspots.length)) return null;
if ((hotspots === null || hotspots === void 0 ? void 0 : hotspots.length) > 0) {
return hotspots.map(function (hotspot) {
var DrawingType = hotspot.drawingType;
var convertedCoordinates = _this2.currentCoordinates(hotspot.coordinates);
return (0, _emotion.jsx)(DrawingType, {
key: JSON.stringify(hotspot.coordinates),
coordinates: convertedCoordinates || [],
readOnly: _this2.props.readOnly,
height: _this2.state.imageHeight,
handleSetCoordinates: _this2.props.handleSetCoordinates,
width: _this2.state.imageWidth
});
});
}
});
(0, _defineProperty2["default"])(_this2, "renderImage", function () {
return (0, _emotion.jsx)("img", {
alt: (0, _formatMessage["default"])('Target Image'),
css: _this2.props.styles.image,
onLoad: _this2.handleImageLoad,
ref: _this2.handleImageRef,
src: _this2.props.url
});
});
(0, _defineProperty2["default"])(_this2, "renderFeedbackComponents", function () {
if (!_this2.props.results) {
return null;
}
return _this2.props.hotspots.map(function (hotspot, index) {
var feedbackCoordinates = _this2.currentCoordinates(hotspot.coordinates);
var renderFeedback = hotspot.renderScoringDataFeedback;
var _this2$getResponseDet = _this2.getResponseDetails(index, feedbackCoordinates),
responseCoordinates = _this2$getResponseDet.responseCoordinates,
isCorrect = _this2$getResponseDet.isCorrect,
flipResponse = _this2$getResponseDet.flipResponse;
return (0, _emotion.jsx)("div", {
key: hotspot.id || index
}, _this2.props.renderUserResponseFeedback(responseCoordinates, flipResponse, isCorrect), renderFeedback(feedbackCoordinates, !flipResponse));
});
});
return _this2;
}
(0, _inherits2["default"])(TargetContainer, _Component);
return (0, _createClass2["default"])(TargetContainer, [{
key: "componentDidMount",
value: function componentDidMount() {
window.addEventListener('resize', this.updateImageDimensions);
this.props.makeStyles();
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
window.removeEventListener('resize', this.updateImageDimensions);
this.props.makeStyles();
}
}, {
key: "validCoordinates",
value: function validCoordinates(coordinates) {
if (!coordinates) return false;
var x = coordinates.x,
y = coordinates.y,
correct = coordinates.correct;
return x != null && y != null && correct != null;
}
}, {
key: "render",
value: function render() {
return (0, _emotion.jsx)("div", {
className: "fs-mask",
css: this.props.styles.targetContainerWrapper,
onFocus: this.props.onFocus,
onBlur: this.props.onBlur
}, (0, _emotion.jsx)("div", {
css: this.props.styles.targetContainerMain
}, (0, _emotion.jsx)("div", {
css: this.props.styles.mainContainerContentWrapper
}, (0, _emotion.jsx)("div", {
css: this.props.styles.mainContainerContent
}, this.renderImage(), this.renderCanvas())), this.renderFeedbackComponents()));
}
}]);
}(_react.Component), (0, _defineProperty2["default"])(_TargetContainer, "displayName", 'TargetContainer'), (0, _defineProperty2["default"])(_TargetContainer, "componentId", "Quizzes".concat(_TargetContainer.displayName)), (0, _defineProperty2["default"])(_TargetContainer, "propTypes", {
hotspots: _propTypes["default"].arrayOf(_propTypes["default"].shape({
coordinates: _propTypes["default"].array,
drawingType: _propTypes["default"].oneOfType([_propTypes["default"].func, _propTypes["default"].object]),
renderScoringDataFeedback: _propTypes["default"].func
})),
readOnly: _propTypes["default"].bool,
handleSetCoordinates: _propTypes["default"].func,
justifyContent: _propTypes["default"].oneOf(['left', 'center']),
renderUserResponseFeedback: _propTypes["default"].func,
results: _propTypes["default"].bool,
url: _propTypes["default"].string.isRequired,
userResponseCoordinate: _propTypes["default"].arrayOf(_propTypes["default"].shape({
x: _propTypes["default"].number,
y: _propTypes["default"].number,
correct: _propTypes["default"].string
})),
makeStyles: _propTypes["default"].func,
styles: _propTypes["default"].object,
onFocus: _propTypes["default"].func,
onBlur: _propTypes["default"].func
}), (0, _defineProperty2["default"])(_TargetContainer, "defaultProps", {
justifyContent: 'center',
readOnly: false,
results: false,
handleSetCoordinates: void 0,
renderUserResponseFeedback: void 0,
userResponseCoordinate: []
}), _TargetContainer)) || _class);