@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
1,027 lines (1,026 loc) • 47.5 kB
JavaScript
/** @jsx jsx */ 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 _array_without_holes(arr) {
if (Array.isArray(arr)) return _array_like_to_array(arr);
}
function _assert_this_initialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _call_super(_this, derived, args) {
derived = _get_prototype_of(derived);
return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
}
function _class_call_check(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _create_class(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _get_prototype_of(o) {
_get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _get_prototype_of(o);
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _set_prototype_of(subClass, superClass);
}
function _iterable_to_array(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
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 _non_iterable_spread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _object_spread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_define_property(target, key, source[key]);
});
}
return target;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) {
symbols = symbols.filter(function(sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
}
keys.push.apply(keys, symbols);
}
return keys;
}
function _object_spread_props(target, source) {
source = source != null ? source : {};
if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function(key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _possible_constructor_return(self, call) {
if (call && (_type_of(call) === "object" || typeof call === "function")) {
return call;
}
return _assert_this_initialized(self);
}
function _set_prototype_of(o, p) {
_set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _set_prototype_of(o, p);
}
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 _to_consumable_array(arr) {
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
}
function _type_of(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
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);
}
function _is_native_reflect_construct() {
try {
var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
} catch (_) {}
return (_is_native_reflect_construct = function() {
return !!result;
})();
}
function _ts_decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
import { Component, createRef } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import debounce from 'lodash/debounce';
import { Button, CondensedButton, IconButton } from '@instructure/ui-buttons';
import { IconTrashLine, IconUploadLine, IconExpandItemsLine } from '@instructure/ui-icons';
import { Text } from '@instructure/ui-text';
import { Spinner } from '@instructure/ui-spinner';
import { Popover } from '@instructure/ui-popover';
import { jsx } from '@instructure/emotion';
import { FileDrop, FormFieldGroup, SimpleModal, withStyleOverrides } from '@instructure/quiz-common';
import generateStyle from './styles';
import generateComponentTheme from './theme';
import t from '@instructure/quiz-i18n/format-message';
import { ScreenReaderContent } from '@instructure/ui-a11y-content';
var DrawingContainer = /*#__PURE__*/ function(Component) {
"use strict";
_inherits(DrawingContainer, Component);
function DrawingContainer() {
_class_call_check(this, DrawingContainer);
var _this;
_this = _call_super(this, DrawingContainer, arguments), _define_property(_this, "state", {
imageWidth: 0,
imageHeight: 0,
isModalOpen: false,
currentPolygonCoordinates: null
}), _define_property(_this, "drawingContainerRef", /*#__PURE__*/ createRef()), _define_property(_this, "modalDrawingContainerRef", /*#__PURE__*/ createRef()), // ===========
// HELPERS
// ===========
_define_property(_this, "currentImageWidth", function() {
return _this.state.imageWidth;
}), _define_property(_this, "currentImageHeight", function() {
return _this.state.imageHeight;
}), _define_property(_this, "updateSize", debounce(function() {
if (_this.props.url && _this.image) {
// ref element (this.image) is not enough to get the updated image dimensions
var rectObject = ReactDOM.findDOMNode(_this.image).getBoundingClientRect();
_this.setDimensions(rectObject);
}
}, 50)), _define_property(_this, "setDimensions", function(rectObject) {
_this.setState({
imageWidth: rectObject.width,
imageHeight: rectObject.height
});
}), _define_property(_this, "transformCoordinates", function(coordinates, imageWidth, imageHeight) {
return coordinates === null || coordinates === void 0 ? void 0 : coordinates.map(function(param) {
var x = param.x, y = param.y;
return {
x: x * imageWidth,
y: y * imageHeight
};
});
}), _define_property(_this, "updateCoordinates", function(coordinates, key, increment, imageWidth, imageHeight, shiftKey, altKey) {
var updatedCoordinates = _to_consumable_array(coordinates);
var _updatedCoordinates = _sliced_to_array(updatedCoordinates, 2), topLeft = _updatedCoordinates[0], bottomRight = _updatedCoordinates[1];
if (shiftKey && altKey) {
switch(key){
case 'ArrowLeft':
bottomRight.x = Math.max(topLeft.x + increment, bottomRight.x - increment);
break;
case 'ArrowRight':
topLeft.x = Math.min(bottomRight.x - increment, topLeft.x + increment);
break;
case 'ArrowUp':
bottomRight.y = Math.max(topLeft.y + increment, bottomRight.y - increment);
break;
case 'ArrowDown':
topLeft.y = Math.min(bottomRight.y - increment, topLeft.y + increment);
break;
default:
break;
}
} else if (shiftKey) {
switch(key){
case 'ArrowUp':
topLeft.y = Math.max(0, topLeft.y - increment);
break;
case 'ArrowDown':
bottomRight.y = Math.min(imageHeight, bottomRight.y + increment);
break;
case 'ArrowLeft':
topLeft.x = Math.max(0, topLeft.x - increment);
break;
case 'ArrowRight':
bottomRight.x = Math.min(imageWidth, bottomRight.x + increment);
break;
default:
break;
}
} else {
switch(key){
case 'ArrowUp':
topLeft.y = Math.max(0, topLeft.y - increment);
bottomRight.y = Math.max(0, bottomRight.y - increment);
break;
case 'ArrowDown':
topLeft.y = Math.min(imageHeight, topLeft.y + increment);
bottomRight.y = Math.min(imageHeight, bottomRight.y + increment);
break;
case 'ArrowLeft':
topLeft.x = Math.max(0, topLeft.x - increment);
bottomRight.x = Math.max(0, bottomRight.x - increment);
break;
case 'ArrowRight':
topLeft.x = Math.min(imageWidth, topLeft.x + increment);
bottomRight.x = Math.min(imageWidth, bottomRight.x + increment);
break;
default:
break;
}
}
return updatedCoordinates;
}), _define_property(_this, "isImageUploaded", function() {
return !!_this.image;
}), _define_property(_this, "isArrowKey", function(key) {
return [
'ArrowUp',
'ArrowDown',
'ArrowLeft',
'ArrowRight'
].includes(key);
}), _define_property(_this, "isLetterKey", function(key) {
return [
'b',
'B',
'd',
'D',
'e',
'E',
'f',
'F',
'i',
'I',
'o',
'O',
'p',
'P',
'r',
'R'
].includes(key);
}), _define_property(_this, "getCurrentHotspot", function() {
return _this.props.multipleHotSpotEnabled ? _this.props.hotspots.find(function(hotspot) {
return hotspot.id === _this.props.currentHotspotId;
}) : _this.props.hotspots[0];
}), _define_property(_this, "isOutsideDrawingContainer", function() {
var _this_drawingContainerRef_current, _this_drawingContainerRef, _this_modalDrawingContainerRef_current, _this_modalDrawingContainerRef;
var activeElement = document.activeElement;
return !((_this_drawingContainerRef = _this.drawingContainerRef) === null || _this_drawingContainerRef === void 0 ? void 0 : (_this_drawingContainerRef_current = _this_drawingContainerRef.current) === null || _this_drawingContainerRef_current === void 0 ? void 0 : _this_drawingContainerRef_current.contains(activeElement)) && !((_this_modalDrawingContainerRef = _this.modalDrawingContainerRef) === null || _this_modalDrawingContainerRef === void 0 ? void 0 : (_this_modalDrawingContainerRef_current = _this_modalDrawingContainerRef.current) === null || _this_modalDrawingContainerRef_current === void 0 ? void 0 : _this_modalDrawingContainerRef_current.contains(activeElement));
}), _define_property(_this, "isBankOrOutcomesModalOpen", function() {
return !!document.querySelector('[data-automation="sdk-add-to-bank-modal"], [data-automation="outcomePicker__modal"]');
}), // ===========
// HANDLERS
// ============
_define_property(_this, "handleImageLoad", function(e) {
_this.setDimensions({
height: e.target.offsetHeight,
width: e.target.offsetWidth
});
}), _define_property(_this, "handleSelectDrawOption", function(type) {
_this.props.onSetType(type);
}), _define_property(_this, "handleExpandImage", function() {
if (_this.isOutsideDrawingContainer()) {
return;
}
_this.props.onModalOpen();
_this.setState({
isModalOpen: true
});
}), _define_property(_this, "handleCloseModal", function() {
_this.props.onModalClose();
_this.setState({
isModalOpen: false
});
}), _define_property(_this, "handleCanvasRef", function(node) {
_this.canvas = node && node.canvas;
}), _define_property(_this, "handleImageRef", function(node) {
_this.image = node;
}), _define_property(_this, "handleFileDropRef", function(node) {
_this.fileDrop = node;
}), _define_property(_this, "moveOrResizePolygon", function(key, shiftKey, altKey) {
var hotspot = _this.getCurrentHotspot();
var coordinates = _this.transformCoordinates(hotspot.coordinates, _this.state.imageWidth, _this.state.imageHeight);
var increment = 10;
var updatedCoordinates = _to_consumable_array(coordinates);
var lastCoordinate = updatedCoordinates[updatedCoordinates.length - 1];
var lastCoordinatesCopy = _object_spread({}, lastCoordinate);
_this.canvas = _this.canvas || _this.props.canvasRef;
if (_this.props.currentType !== 'polygon' || !_this.canvas.isDrawing()) {
return;
}
if (altKey && shiftKey) {
switch(key){
case 'ArrowUp':
lastCoordinatesCopy.y = Math.max(0, lastCoordinatesCopy.y + increment);
break;
case 'ArrowDown':
lastCoordinatesCopy.y = Math.min(_this.state.imageHeight, lastCoordinatesCopy.y - increment);
break;
case 'ArrowLeft':
lastCoordinatesCopy.x = Math.max(0, lastCoordinatesCopy.x - increment);
break;
case 'ArrowRight':
lastCoordinatesCopy.x = Math.min(_this.state.imageWidth, lastCoordinatesCopy.x + increment);
break;
default:
return;
}
if (updatedCoordinates.length > 1) {
var lastIndex = updatedCoordinates.length - 1;
var secondLastIndex = lastIndex - 1;
if (updatedCoordinates[lastIndex].x === updatedCoordinates[secondLastIndex].x && updatedCoordinates[lastIndex].y === updatedCoordinates[secondLastIndex].y || updatedCoordinates[lastIndex].x === updatedCoordinates[0].x && updatedCoordinates[lastIndex].y === updatedCoordinates[0].y) {
updatedCoordinates.pop();
}
}
updatedCoordinates = updatedCoordinates.slice(0, -1).concat(lastCoordinatesCopy);
_this.setState({
currentPolygonCoordinates: lastCoordinatesCopy
});
} else if (shiftKey) {
switch(key){
case 'ArrowUp':
lastCoordinatesCopy.y = Math.max(0, lastCoordinatesCopy.y - increment);
break;
case 'ArrowDown':
lastCoordinatesCopy.y = Math.min(_this.state.imageHeight, lastCoordinatesCopy.y + increment);
break;
case 'ArrowLeft':
lastCoordinatesCopy.x = Math.max(0, lastCoordinatesCopy.x - increment);
break;
case 'ArrowRight':
lastCoordinatesCopy.x = Math.min(_this.state.imageWidth, lastCoordinatesCopy.x + increment);
break;
default:
return;
}
_this.setState({
currentPolygonCoordinates: lastCoordinatesCopy
});
updatedCoordinates = updatedCoordinates.slice(0, -1).concat(lastCoordinatesCopy);
} else {
updatedCoordinates = updatedCoordinates.map(function(coord) {
switch(key){
case 'ArrowUp':
return _object_spread_props(_object_spread({}, coord), {
y: Math.max(0, coord.y - increment)
});
case 'ArrowDown':
return _object_spread_props(_object_spread({}, coord), {
y: Math.min(_this.state.imageHeight, coord.y + increment)
});
case 'ArrowLeft':
return _object_spread_props(_object_spread({}, coord), {
x: Math.max(0, coord.x - increment)
});
case 'ArrowRight':
return _object_spread_props(_object_spread({}, coord), {
x: Math.min(_this.state.imageWidth, coord.x + increment)
});
default:
return coord;
}
});
}
var lines = _to_consumable_array(updatedCoordinates);
if (lines.length > 2) {
lines.push(lines[0]);
}
_this.canvas.drawShape(lines);
_this.props.convertCoordinates(updatedCoordinates, true, true);
}), _define_property(_this, "calculateCoordinates", function(shapeType, imageWidth, imageHeight) {
var x1 = (imageWidth - 50) / 2;
var y1 = (imageHeight - 50) / 2;
var coordinates;
switch(shapeType){
case 'square':
coordinates = [
{
x: x1,
y: y1
},
{
x: x1 + 50,
y: y1 + 50
}
];
break;
case 'oval':
coordinates = [
{
x: imageWidth / 2 - 50,
y: imageHeight / 2 - 50
},
{
x: imageWidth / 2 + 50,
y: imageHeight / 2 + 50
}
];
break;
case 'polygon':
coordinates = [
{
x: x1,
y: y1
},
{
x: x1 + 50,
y: y1
}
];
break;
default:
coordinates = [];
}
return coordinates;
}), _define_property(_this, "addSquareHotspot", function() {
_this.props.onSetType('square');
var initialCoordinate = _this.calculateCoordinates('square', _this.state.imageWidth, _this.state.imageHeight);
_this.props.convertCoordinates(initialCoordinate, _this.props.tempHotspot ? true : false);
}), _define_property(_this, "addOvalHotspot", function() {
_this.props.onSetType('oval');
var initialCoordinate = _this.calculateCoordinates('oval', _this.state.imageWidth, _this.state.imageHeight);
_this.props.convertCoordinates(initialCoordinate, _this.props.tempHotspot ? true : false);
}), _define_property(_this, "drawPolygonHotspot", function() {
var _this_canvas, _this_canvas1;
if ((_this_canvas = _this.canvas) === null || _this_canvas === void 0 ? void 0 : _this_canvas.isDrawing()) {
return;
}
_this.props.onSetType('polygon');
var initialCoordinate = _this.calculateCoordinates('polygon', _this.state.imageWidth, _this.state.imageHeight);
var currentHotspot = _this.getCurrentHotspot();
var lines = currentHotspot.coordinates.concat(initialCoordinate);
// add initial coordinate at the end of the array to close the polygon
if (lines.length > 2) {
lines = lines.concat([
lines[0]
]);
}
_this.props.setCanvasRef(_this.canvas);
_this.props.convertCoordinates(initialCoordinate, _this.props.tempHotspot ? true : false);
_this.canvas = _this.canvas || _this.props.canvasRef;
(_this_canvas1 = _this.canvas) === null || _this_canvas1 === void 0 ? void 0 : _this_canvas1.setState({
isDrawing: true
});
}), _define_property(_this, "addPolygonPoint", function() {
var _this_props = _this.props, currentType = _this_props.currentType, convertCoordinates = _this_props.convertCoordinates;
var _this_state = _this.state, currentPolygonCoordinates = _this_state.currentPolygonCoordinates, imageWidth = _this_state.imageWidth, imageHeight = _this_state.imageHeight;
var currentHotspot = _this.getCurrentHotspot();
if (currentType !== 'polygon' || !_this.canvas.isDrawing() || !currentHotspot.coordinates || !currentPolygonCoordinates && currentHotspot.coordinates.length !== 2) {
_this.setState({
currentPolygonCoordinates: null
});
return;
}
var transformedCoordinates = _this.transformCoordinates(currentHotspot.coordinates, imageWidth, imageHeight);
var updatedCoordinates;
if (currentHotspot.coordinates.length === 2) {
var lastCoordinate = _this.transformCoordinates([
currentHotspot.coordinates[1]
], imageWidth, imageHeight);
updatedCoordinates = transformedCoordinates.concat(lastCoordinate);
} else {
updatedCoordinates = transformedCoordinates.concat(currentPolygonCoordinates);
}
convertCoordinates(updatedCoordinates, true, true);
_this.setState({
currentPolygonCoordinates: null
});
}), _define_property(_this, "OpenShortcutsModal", function() {
if (_this.isBankOrOutcomesModalOpen()) {
return;
}
_this.props.onOpenShortcutsModal();
}), _define_property(_this, "handleCloseShape", function() {
var _this_canvas;
var currentType = _this.props.currentType;
var _this_state = _this.state, imageWidth = _this_state.imageWidth, imageHeight = _this_state.imageHeight;
var currentHotspot = _this.getCurrentHotspot();
if (currentType !== 'polygon' && !_this.canvas.isDrawing()) {
return;
}
var transformedCoordinates = _this.transformCoordinates(currentHotspot.coordinates, imageWidth, imageHeight);
var finalCoordinates = transformedCoordinates.concat(transformedCoordinates[0]);
(_this_canvas = _this.canvas) === null || _this_canvas === void 0 ? void 0 : _this_canvas.stopDrawing(finalCoordinates);
}), _define_property(_this, "handleKeyPress", function(event) {
var key = event.key, shiftKey = event.shiftKey, altKey = event.altKey;
var normalizedKey = _this.isLetterKey(key) ? key.toLowerCase() : key;
var activeElement = document.activeElement;
var hasHotspots = _this.props.hotspots.length > 0;
var isImageUploaded = _this.isImageUploaded();
var controlKeyAction = {
b: function() {
return _this.triggerFileUpload();
},
i: function() {
return _this.props.onOpenShortcutsModal();
}
};
var isInteractiveElement = [
'INPUT',
'TEXTAREA',
'BUTTON'
].includes(activeElement.tagName);
if (isInteractiveElement) {
return;
}
if (!isImageUploaded) {
var handleHotkey = controlKeyAction[normalizedKey];
if (handleHotkey) {
event.preventDefault();
handleHotkey();
return;
}
}
var imageKeyActions = {
Delete: function() {
return _this.deleteSelectedHotspot();
},
Backspace: function() {
return _this.deleteSelectedHotspot();
},
ArrowUp: function() {
return _this.moveOrResizeHotspot(normalizedKey, shiftKey, altKey);
},
ArrowDown: function() {
return _this.moveOrResizeHotspot(normalizedKey, shiftKey, altKey);
},
ArrowLeft: function() {
return _this.moveOrResizeHotspot(normalizedKey, shiftKey, altKey);
},
ArrowRight: function() {
return _this.moveOrResizeHotspot(normalizedKey, shiftKey, altKey);
},
i: function() {
return _this.OpenShortcutsModal();
},
f: function() {
return _this.handleExpandImage();
},
r: function() {
return _this.addSquareHotspot();
},
o: function() {
return _this.addOvalHotspot();
},
p: function() {
return _this.drawPolygonHotspot();
},
d: function() {
return _this.props.onRemoveImage();
},
e: function() {
return _this.handleCloseShape();
},
Enter: function() {
return _this.addPolygonPoint();
},
Escape: function() {
return _this.handleCloseModal();
}
};
if (_this.isArrowKey(normalizedKey) && hasHotspots) {
event.preventDefault();
}
var handleHotkey1 = imageKeyActions[normalizedKey];
if (handleHotkey1) {
event.preventDefault();
handleHotkey1();
}
}), _define_property(_this, "deleteSelectedHotspot", function() {
_this.props.onRemoveHotspot(_this.props.currentHotspotId);
}), _define_property(_this, "triggerFileUpload", function() {
_this.fileDrop.fileInputEl.click();
}), _define_property(_this, "moveOrResizeHotspot", function(key, shiftKey, altKey) {
var currentHotspot = _this.getCurrentHotspot();
if (currentHotspot.coordinates.length === 0) return;
if (_this.props.currentType === 'polygon') {
_this.moveOrResizePolygon(key, shiftKey, altKey);
} else {
var coordinates = _this.transformCoordinates(currentHotspot.coordinates, _this.state.imageWidth, _this.state.imageHeight);
var increment = 10 // Move or resize by 10px
;
var updatedCoordinates = _this.updateCoordinates(coordinates, key, increment, _this.state.imageWidth, _this.state.imageHeight, shiftKey, altKey);
_this.props.convertCoordinates(updatedCoordinates, true, true);
}
}), _define_property(_this, "convertCoordinatesForRendering", function(coordinates) {
return coordinates.map(function(item) {
var x = item.x * _this.state.imageWidth;
var y = item.y * _this.state.imageHeight;
return {
x: x,
y: y
};
});
}), // ===========
// RENDER
// ===========
_define_property(_this, "renderCanvas", function() {
var _this_props = _this.props, hotspots = _this_props.hotspots, tempHotspot = _this_props.tempHotspot, isUploading = _this_props.isUploading;
if (!hotspots.length && !tempHotspot || isUploading) {
return null;
}
// Create an array that includes all hotspots and tempHotspot if it exists
var hotspotsToRender = tempHotspot ? _to_consumable_array(hotspots).concat([
tempHotspot
]) : hotspots;
return hotspotsToRender.map(function(hotspot, index) {
var SelectedType = _this.getSelectedTypeComponent(hotspot.type);
var coordinates = _this.convertCoordinatesForRendering(hotspot.coordinates || []);
return /*#__PURE__*/ jsx(SelectedType, {
key: hotspot.id || index,
ref: _this.handleCanvasRef,
handleSetCoordinates: _this.props.convertCoordinates,
coordinates: coordinates,
width: _this.state.imageWidth,
height: _this.state.imageHeight,
hotspotId: hotspot.id
});
});
});
return _this;
}
_create_class(DrawingContainer, [
{
key: "componentDidMount",
value: function componentDidMount() {
window.addEventListener('resize', this.updateSize);
window.addEventListener('keydown', this.handleKeyPress);
this.updateSize();
this.props.makeStyles({
isModal: this.state.isModalOpen
});
}
},
{
key: "componentDidUpdate",
value: function componentDidUpdate(lastProps, lastState) {
if (lastProps.url && this.props.url === void 0) {
this.fileDrop.fileInputEl.focus();
}
if (lastState.imageWidth !== this.state.imageWidth || lastState.imageHeight !== this.state.imageHeight) {
this.updateSize();
}
this.props.makeStyles({
isModal: this.state.isModalOpen
});
}
},
{
key: "componentWillUnmount",
value: function componentWillUnmount() {
window.removeEventListener('resize', this.updateSize);
window.removeEventListener('keydown', this.handleKeyPress);
this.updateSize.cancel();
}
},
{
key: "getSelectedTypeComponent",
value: function getSelectedTypeComponent(currentType) {
var type = this.props.drawTypes.find(function(item) {
return item.type === currentType;
});
return type === null || type === void 0 ? void 0 : type.component;
}
},
{
key: "renderTypes",
value: function renderTypes() {
var _this = this;
return /*#__PURE__*/ jsx("div", {
className: "mainContainerType",
css: this.props.styles.mainContainerType
}, this.props.drawTypes.map(function(item) {
var TypeIcon = item.icon;
var onButtonClick = function() {
return _this.handleSelectDrawOption(item.type);
};
var color = 'secondary';
var wrapperStyle = _this.props.styles.mainContainerTypeUnselected;
if (item.type === (_this.props.currentType || 'square')) {
onButtonClick = null;
color = 'primary-inverse';
wrapperStyle = _this.props.styles.mainContainerTypeSelected;
}
return /*#__PURE__*/ jsx(Popover, {
key: item.type,
color: "primary-inverse",
onClick: onButtonClick,
renderTrigger: /*#__PURE__*/ jsx("div", {
css: wrapperStyle
}, /*#__PURE__*/ jsx(IconButton, {
color: color,
withBackground: false,
withBorder: false,
screenReaderLabel: item.title,
renderIcon: /*#__PURE__*/ jsx(TypeIcon, {
title: item.title
})
}))
}, /*#__PURE__*/ jsx("div", {
css: _this.props.styles.popoverContent
}, item.title));
}));
}
},
{
key: "renderActionButton",
value: function renderActionButton(onClick, label, Icon) {
var automationData = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : '';
return /*#__PURE__*/ jsx(Popover, {
onClick: onClick,
color: "primary-inverse",
renderTrigger: /*#__PURE__*/ jsx(IconButton, _object_spread({
renderIcon: Icon,
withBackground: false,
withBorder: false,
screenReaderLabel: label
}, automationData && {
'data-automation': automationData
}))
}, /*#__PURE__*/ jsx("div", {
css: this.props.styles.popoverContent
}, label));
}
},
{
key: "renderActions",
value: function renderActions() {
return /*#__PURE__*/ jsx("div", {
css: this.props.styles.mainContainerActions
}, this.renderActionButton(this.handleExpandImage, t('Expand Image'), IconExpandItemsLine), /*#__PURE__*/ jsx("div", {
css: this.props.styles.mainContainerActionsRemove
}, this.renderActionButton(this.props.onRemoveImage, t('Remove Image'), IconTrashLine, 'sdk-remove-image-button')));
}
},
{
key: "renderHeaderText",
value: function renderHeaderText(isModal) {
var _this_props = this.props, styles = _this_props.styles, currentType = _this_props.currentType, hotspots = _this_props.hotspots;
if (currentType === 'polygon' && hotspots.length > 0) {
return /*#__PURE__*/ jsx("div", {
css: styles.headerText
}, t.rich('<0>Double click to</0> <1>close shape</1>', [
function(param) {
var children = param.children;
return /*#__PURE__*/ jsx(Text, {
key: "1"
}, children);
},
function(param) {
var children = param.children;
return /*#__PURE__*/ jsx(CondensedButton, {
key: "2",
size: "large",
margin: "0 0 0 x-small",
themeOverride: {
largePadding: styles.headerText.condensedButton.padding,
largeFontSize: styles.headerText.condensedButton.fontSize,
largeHeight: styles.headerText.condensedButton.height
}
}, children);
}
]));
}
return /*#__PURE__*/ jsx(Text, {
color: "primary"
}, t("Draw the hot spot's shape"));
}
},
{
key: "renderImage",
value: function renderImage() {
return /*#__PURE__*/ jsx("div", {
css: this.props.styles.imageHolder
}, /*#__PURE__*/ jsx("img", {
alt: t('Uploaded Image'),
css: this.props.styles.mainContainerContentImage,
onLoad: this.handleImageLoad,
ref: this.handleImageRef,
src: this.props.url
}), !this.props.isUploading ? null : /*#__PURE__*/ jsx("div", {
css: this.props.styles.spinnerWrapper
}, /*#__PURE__*/ jsx("div", {
css: this.props.styles.spinner
}, /*#__PURE__*/ jsx(Spinner, {
renderTitle: t('Loading'),
size: "large",
variant: "inverse"
}))), this.renderCanvas());
}
},
{
key: "renderDrawingContainer",
value: function renderDrawingContainer() {
return /*#__PURE__*/ jsx("div", {
css: this.props.styles.mainContainer,
ref: this.drawingContainerRef
}, this.props.isUploading ? null : /*#__PURE__*/ jsx("div", {
css: this.props.styles.mainContainerHeader
}, /*#__PURE__*/ jsx(FormFieldGroup, {
description: /*#__PURE__*/ jsx(ScreenReaderContent, null, t('Hot Spot editor')),
messages: this.props.typeErrors
}, /*#__PURE__*/ jsx("div", {
css: this.props.styles.mainContainerHeader
}, /*#__PURE__*/ jsx("div", null, this.renderHeaderText()), this.renderTypes())), this.renderActions()), /*#__PURE__*/ jsx("div", {
css: this.props.styles.mainContainerContentWrapper
}, this.renderImage()));
}
},
{
key: "renderFileDropContent",
value: function renderFileDropContent() {
var _this = this;
return /*#__PURE__*/ jsx("div", {
css: this.props.styles.fileDropContent
}, /*#__PURE__*/ jsx("div", {
css: this.props.styles.fileDropContentIcon
}, /*#__PURE__*/ jsx(IconUploadLine, null)), /*#__PURE__*/ jsx("div", {
css: this.props.styles.fileDropContentLabel
}, t.rich("Drag n' Drop here or <0>Browse</0>", [
function(param) {
var children = param.children;
return /*#__PURE__*/ jsx("div", {
key: "1",
css: _this.props.styles.fileDropContentLabelBrowse
}, children);
}
])));
}
},
{
key: "renderFileDrop",
value: function renderFileDrop() {
return /*#__PURE__*/ jsx("div", {
css: this.props.styles.fileDropWrapper
}, /*#__PURE__*/ jsx(FileDrop, {
accept: "image/*",
renderLabel: this.renderFileDropContent(),
onDropAccepted: this.props.onDropAccepted,
ref: this.handleFileDropRef,
messages: this.props.fileDropErrors
}));
}
},
{
key: "renderModal",
value: function renderModal() {
return /*#__PURE__*/ jsx(SimpleModal, {
footerContent: /*#__PURE__*/ jsx(Button, {
onClick: this.handleCloseModal,
color: "primary"
}, t('Done')),
isModalOpen: this.state.isModalOpen,
onModalDismiss: this.handleCloseModal,
size: "fullscreen",
title: this.renderHeaderText(true),
label: t('Modal Dialog: Draw a hot spot')
}, /*#__PURE__*/ jsx("div", {
css: this.props.styles.modalContent,
ref: this.modalDrawingContainerRef
}, /*#__PURE__*/ jsx("div", {
css: this.props.styles.modalContentTypes
}, this.renderTypes()), /*#__PURE__*/ jsx("div", {
css: this.props.styles.modalContentImage
}, this.renderImage())));
}
},
{
key: "render",
value: function render() {
if (!this.props.url) {
return /*#__PURE__*/ jsx("div", null, this.renderFileDrop());
} else if (this.state.isModalOpen === true) {
return /*#__PURE__*/ jsx("div", null, this.renderModal());
} else {
return /*#__PURE__*/ jsx(FormFieldGroup, {
required: true,
messages: this.props.canvasErrors,
description: t('Hot Spot')
}, this.renderDrawingContainer());
}
}
}
]);
return DrawingContainer;
}(Component);
_define_property(DrawingContainer, "displayName", 'DrawingContainer');
_define_property(DrawingContainer, "componentId", "Quizzes".concat(DrawingContainer.displayName));
_define_property(DrawingContainer, "propTypes", {
canvasErrors: PropTypes.array,
convertCoordinates: PropTypes.func,
currentType: PropTypes.string,
drawTypes: PropTypes.array,
fileDropErrors: PropTypes.array,
isUploading: PropTypes.bool,
onModalOpen: PropTypes.func,
onModalClose: PropTypes.func,
onDropAccepted: PropTypes.func,
onSetType: PropTypes.func,
onRemoveImage: PropTypes.func,
onRemoveHotspot: PropTypes.func,
typeErrors: PropTypes.array,
url: PropTypes.string,
makeStyles: PropTypes.func,
styles: PropTypes.object,
onOpenShortcutsModal: PropTypes.func,
onCloseShortcutsModal: PropTypes.func,
isShortcutsModalOpen: PropTypes.bool,
hotspots: PropTypes.array,
tempHotspot: PropTypes.object,
currentHotspotId: PropTypes.number,
setTempHotspot: PropTypes.func,
setCanvasRef: PropTypes.func,
canvasRef: PropTypes.object,
multipleHotSpotEnabled: PropTypes.bool
});
_define_property(DrawingContainer, "defaultProps", {
onModalOpen: Function.prototype,
onModalClose: Function.prototype,
canvasErrors: void 0,
convertCoordinates: void 0,
currentType: void 0,
drawTypes: void 0,
fileDropErrors: void 0,
isUploading: void 0,
onDropAccepted: void 0,
onSetType: void 0,
onRemoveImage: void 0,
typeErrors: void 0,
url: void 0,
hotspots: void 0,
tempHotspot: void 0,
multipleHotSpotEnabled: false
});
export { DrawingContainer as default };
DrawingContainer = _ts_decorate([
withStyleOverrides(generateStyle, generateComponentTheme)
], DrawingContainer);