UNPKG

react-dnd-crop

Version:
510 lines (446 loc) 19.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _helper = require("./helper"); var _style = require("./style"); var _Modal = require("../Modal/Modal"); var _Modal2 = _interopRequireDefault(_Modal); var _cancel = require("../icons/cancel.svg"); var _cancel2 = _interopRequireDefault(_cancel); var _crop = require("../icons/crop.svg"); var _crop2 = _interopRequireDefault(_crop); var _image = require("../icons/image.svg"); var _image2 = _interopRequireDefault(_image); require("./Dnd.css"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Dnd = function (_Component) { _inherits(Dnd, _Component); function Dnd(props) { _classCallCheck(this, Dnd); var _this = _possibleConstructorReturn(this, (Dnd.__proto__ || Object.getPrototypeOf(Dnd)).call(this, props)); var cropRatio = props.cropRatio ? props.cropRatio : { unit: "%", width: 30, aspect: 4 / 3 }; _this.state = { files: [], fixedDataUrl: [], imageUrls: [], finalUrl: [], draggingElmIndex: null, cropImgSrc: null, currentCropImageIndex: null, open: false, url: [], cropRatio: cropRatio, mimeType: props.mimeType || "png/jpg/jpeg/gif", errorMessage: props.errorMessages || {} }; _this.INPUT_REF = _react2.default.createRef(); _this.onImageBrowse = _this.onImageBrowse.bind(_this); _this.openModal = _this.openModal.bind(_this); _this.onImageDrop = _this.onImageDrop.bind(_this); _this.onDrop = _this.onDrop.bind(_this); _this.callback = _this.callback.bind(_this); _this.getImageDataUrl = _this.getImageDataUrl.bind(_this); _this.onInputChange = _this.onInputChange.bind(_this); _this.removeImage = _this.removeImage.bind(_this); _this.checkValidImages = _this.checkValidImages.bind(_this); _this.convertImageForupload = _this.convertImageForupload.bind(_this); _this.getcropImage = _this.getcropImage.bind(_this); _this.cancelCrop = _this.cancelCrop.bind(_this); _this.handleClearToDefault = _this.handleClearToDefault.bind(_this); _this.onDragStart = _this.onDragStart.bind(_this); return _this; } _createClass(Dnd, [{ key: "preventDefaults", value: function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } }, { key: "openModal", value: function openModal(index) { var fixedDataUrl = this.state.fixedDataUrl; var cropImgSrc = fixedDataUrl.find(function (_, i) { return i === index; }); this.setState({ cropImgSrc: cropImgSrc, open: true, currentCropImageIndex: index }); } }, { key: "handleClearToDefault", value: function handleClearToDefault() { this.setState({ open: false }); } }, { key: "onDrop", value: function () { var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(e, index) { var _state, draggingElmIndex, files, imageUrls, fixedDataUrl; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: e.stopPropagation(); _state = this.state, draggingElmIndex = _state.draggingElmIndex, files = _state.files, imageUrls = _state.imageUrls, fixedDataUrl = _state.fixedDataUrl; files = (0, _helper.swap)(files, draggingElmIndex, index); imageUrls = (0, _helper.swap)(imageUrls, draggingElmIndex, index); fixedDataUrl = (0, _helper.swap)(fixedDataUrl, draggingElmIndex, index); _context.next = 7; return this.setState({ files: files, imageUrls: imageUrls, fixedDataUrl: fixedDataUrl, draggingElmIndex: null }); case 7: case "end": return _context.stop(); } } }, _callee, this); })); function onDrop(_x, _x2) { return _ref.apply(this, arguments); } return onDrop; }() }, { key: "onDragStart", value: function onDragStart(_, index) { this.setState({ draggingElmIndex: index }); } // image Events }, { key: "onImageBrowse", value: function onImageBrowse() { var DRAG_AND_DROP_AREA_INPUT = this.INPUT_REF.current; if (DRAG_AND_DROP_AREA_INPUT && document.createEvent) { var evt = document.createEvent("MouseEvents"); evt.initEvent("click", true, false); DRAG_AND_DROP_AREA_INPUT.dispatchEvent(evt); } } }, { key: "callback", value: function callback(payload) { if (this.props.callback) return this.props.callback(payload); console.log("Provide a callback"); } }, { key: "onImageDrop", value: function onImageDrop(e) { var _this2 = this; this.preventDefaults(e); var _state2 = this.state, files = _state2.files, imageUrls = _state2.imageUrls, mimeType = _state2.mimeType, errorMessage = _state2.errorMessage, cropRatio = _state2.cropRatio, freeCrop = _state2.freeCrop, validUpload = true; var newFiles = e.dataTransfer.files; if (imageUrls.length + newFiles.length > (this.props.maxImageUpload || 12)) return this.callback({ error: errorMessage.maxImageUpload || "You Cant Upload More than " + (this.props.maxImageUpload || 12) + " Files" }); [].concat(_toConsumableArray(newFiles)).forEach(function (file) { if (!(0, _helper.validateImageMimeType)(file, mimeType)) { validUpload = false; _this2.callback({ error: errorMessage.imageFormat || "Only Jpeg/Jpg/Png/Gif Allowed" }); return false; } }); if (validUpload) { this.setState({ files: [].concat(_toConsumableArray(files), _toConsumableArray(newFiles)) }); [].concat(_toConsumableArray(newFiles)).forEach(function (file) { return (0, _helper.validateImage)(file, _this2.getImageDataUrl, cropRatio, freeCrop); }); } } }, { key: "getImageDataUrl", value: function getImageDataUrl(isValid, url) { if (!this.props.crop) isValid = true; var _state3 = this.state, imageUrls = _state3.imageUrls, fixedDataUrl = _state3.fixedDataUrl, errorMessage = _state3.errorMessage; if (imageUrls.length + 1 > (this.props.maxImageUpload || 12)) return this.callback({ error: errorMessage.maxImageUpload || "You Cant Upload More than " + (this.props.maxImageUpload || 12) + " Files" }); this.setState({ fixedDataUrl: [].concat(_toConsumableArray(fixedDataUrl), [url]), imageUrls: [].concat(_toConsumableArray(imageUrls), [{ url: url, isValid: isValid }]) }); } }, { key: "onInputChange", value: function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(e) { var _this3 = this; var _state4, files, imageUrls, mimeType, errorMessage, cropRatio, file; return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _state4 = this.state, files = _state4.files, imageUrls = _state4.imageUrls, mimeType = _state4.mimeType, errorMessage = _state4.errorMessage, cropRatio = _state4.cropRatio; file = e.target.files[0]; e.target.value = null; if (file) { _context2.next = 5; break; } return _context2.abrupt("return"); case 5: files = [].concat(_toConsumableArray(files), [file]); if ((0, _helper.validateImageMimeType)(file, mimeType)) { _context2.next = 8; break; } return _context2.abrupt("return", this.callback({ error: errorMessage.imageFormat || "Only Jpeg/Jpg/Png/Gif Allowed" })); case 8: if (!(imageUrls.length + 1 > this.props.maxImageUpload)) { _context2.next = 10; break; } return _context2.abrupt("return", this.callback({ error: errorMessage.maxImageUpload || "You Cant Upload More than " + this.props.maxImageUpload + " Files" })); case 10: this.setState({ files: files }, function () { (0, _helper.validateImage)(file, _this3.getImageDataUrl, cropRatio, _this3.props.freeCrop); }); this.convertImageForupload(); case 12: case "end": return _context2.stop(); } } }, _callee2, this); })); function onInputChange(_x3) { return _ref2.apply(this, arguments); } return onInputChange; }() }, { key: "removeImage", value: function () { var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(index) { var _state5, files, imageUrls, fixedDataUrl; return regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _state5 = this.state, files = _state5.files, imageUrls = _state5.imageUrls, fixedDataUrl = _state5.fixedDataUrl; files = (0, _helper.filterWithIndex)(files, index); fixedDataUrl = (0, _helper.filterWithIndex)(fixedDataUrl, index); imageUrls = (0, _helper.filterWithIndex)(imageUrls, index); _context3.next = 6; return this.setState({ files: files, imageUrls: imageUrls, fixedDataUrl: fixedDataUrl }); case 6: case "end": return _context3.stop(); } } }, _callee3, this); })); function removeImage(_x4) { return _ref3.apply(this, arguments); } return removeImage; }() }, { key: "checkValidImages", value: function checkValidImages() { var imageUrls = this.state.imageUrls; for (var i = 0; i < imageUrls.length; i++) { if (!imageUrls[i].isValid) return false; }return true; } }, { key: "convertImageForupload", value: function convertImageForupload() { var _state6 = this.state, imageUrls = _state6.imageUrls, files = _state6.files, errorMessage = _state6.errorMessage; var fileObject = []; imageUrls.forEach(function (url, index) { var file = (0, _helper.base64StringtoFile)(url.url, files[index].name); fileObject.push(file); }); var isUploadValid = this.checkValidImages(); if (!isUploadValid) return this.callback({ error: errorMessage.aspectRatio || "Image is not in the proper Aspect Ratio" }); return this.callback({ fileObject: fileObject, imageUrls: imageUrls }); } }, { key: "getcropImage", value: function getcropImage(url) { var _state7 = this.state, currentCropImageIndex = _state7.currentCropImageIndex, imageUrls = _state7.imageUrls, files = _state7.files; var file = (0, _helper.base64StringtoFile)(url, files[currentCropImageIndex].name); imageUrls = (0, _helper.replaceWithIndex)(imageUrls, currentCropImageIndex, { url: url, isValid: true }); files = (0, _helper.replaceWithIndex)(files, currentCropImageIndex, file); this.setState({ files: files, imageUrls: imageUrls, currentCropImageIndex: null, open: false }); this.convertImageForupload(); } }, { key: "cancelCrop", value: function cancelCrop() { this.setState({ open: false }); } }, { key: "render", value: function render() { var _this4 = this; var _state8 = this.state, imageUrls = _state8.imageUrls, open = _state8.open, cropImgSrc = _state8.cropImgSrc; var styles = (0, _style.style)(this.props); return _react2.default.createElement( "div", { onMouseOut: this.convertImageForupload }, _react2.default.createElement("input", { ref: this.INPUT_REF, type: "file", id: "DRAG_AND_DROP_AREA_INPUT", onChange: this.onInputChange }), _react2.default.createElement( "div", { id: "DRAG_AND_DROP_AREA", style: styles.DRAG_AND_DROP_AREA, onDragOver: function onDragOver(e) { return _this4.preventDefaults(e); }, onDrop: this.onImageDrop, onClick: this.onImageBrowse }, imageUrls.length === 0 ? null : _react2.default.createElement( "span", { id: "DRAG_AND_DROP_MESSAGE", style: styles.DRAG_AND_DROP_MESSAGE }, this.props.message || "Hold and Drag to rearrange the order" ), imageUrls.length === 0 ? _react2.default.createElement( "div", { id: "DRAG_AND_DROP_PLACEHOLDER" }, this.props.icons && this.props.icons.labelIcon ? this.props.icons.labelIcon : _react2.default.createElement("img", { src: _image2.default, width: "30", height: "30" }), _react2.default.createElement( "h1", null, this.props.label || "Drag and drop images here" ), _react2.default.createElement( "p", null, this.props.subLabel || "or click to upload" ) ) : _react2.default.createElement( "div", null, _react2.default.createElement( "div", { id: "DRAG_AND_DROP_ZONE" }, imageUrls.map(function (item, index) { return _react2.default.createElement( "div", { id: "DRAG_AND_DROP_AREA_ITEM", key: index, draggable: true, onClick: function onClick(e) { return _this4.preventDefaults(e); }, onDragStart: function onDragStart(e) { return _this4.onDragStart(e, index); }, onDragOver: function onDragOver(e) { return _this4.preventDefaults(e); }, onDrop: function onDrop(e) { return _this4.onDrop(e, index); }, style: item.isValid ? styles.DRAG_AND_DROP_AREA_ITEM : styles.DRAG_AND_DROP_AREA_ITEM_ERROR }, _react2.default.createElement( "div", { id: "DRAG_AND_DROP_AREA_ITEM_IMAGE_CONTAINER", onDragOver: function onDragOver(e) { return _this4.preventDefaults(e); }, style: { backgroundImage: "url(" + item.url + ")" } }, _react2.default.createElement( "span", { id: "DRAG_AND_DROP_AREA_ITEM_CANCEL_ICON", style: styles.DRAG_AND_DROP_AREA_ITEM_CANCEL_ICON, onClick: function onClick() { return _this4.removeImage(index); } }, _this4.props.icons && _this4.props.icons.cancelIcon ? _this4.props.icons.cancelIcon : _react2.default.createElement("img", { src: _cancel2.default, width: "15", height: "15" }) ), _this4.props.crop ? _react2.default.createElement( "span", { id: "DRAG_AND_DROP_AREA_ITEM_CROP_ICON", style: styles.DRAG_AND_DROP_AREA_ITEM_CROP_ICON, onClick: function onClick() { return _this4.openModal(index); } }, _this4.props.icons && _this4.props.icons.cropIcon ? _this4.props.icons.cropIcon : _react2.default.createElement("img", { src: _crop2.default, width: "15", height: "15" }) ) : "" ) ); }) ) ) ), _react2.default.createElement(_Modal2.default, _extends({ isOpen: open }, this.props, { onRequestClose: this.handleClearToDefault, getcropImage: this.getcropImage, cancelCrop: this.cancelCrop, imageSrc: cropImgSrc })) ); } }]); return Dnd; }(_react.Component); exports.default = Dnd;