UNPKG

@shopify/draggable

Version:

The JavaScript Drag & Drop library your grandparents warned you about.

507 lines (413 loc) 13.9 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("ResizeMirror", [], factory); else if(typeof exports === 'object') exports["ResizeMirror"] = factory(); else root["ResizeMirror"] = factory(); })(window, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 8); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = requestNextAnimationFrame; function requestNextAnimationFrame(callback) { return requestAnimationFrame(() => { requestAnimationFrame(callback); }); } /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _requestNextAnimationFrame = __webpack_require__(0); var _requestNextAnimationFrame2 = _interopRequireDefault(_requestNextAnimationFrame); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _requestNextAnimationFrame2.default; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = closest; const matchFunction = Element.prototype.matches || Element.prototype.webkitMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector; /** * Get the closest parent element of a given element that matches the given * selector string or matching function * * @param {Element} element The child element to find a parent of * @param {String|Function} selector The string or function to use to match * the parent element * @return {Element|null} */ function closest(element, value) { if (!element) { return null; } const selector = value; const callback = value; const nodeList = value; const singleElement = value; const isSelector = Boolean(typeof value === 'string'); const isFunction = Boolean(typeof value === 'function'); const isNodeList = Boolean(value instanceof NodeList || value instanceof Array); const isElement = Boolean(value instanceof HTMLElement); function conditionFn(currentElement) { if (!currentElement) { return currentElement; } else if (isSelector) { return matchFunction.call(currentElement, selector); } else if (isNodeList) { return [...nodeList].includes(currentElement); } else if (isElement) { return singleElement === currentElement; } else if (isFunction) { return callback(currentElement); } else { return null; } } let current = element; do { current = current.correspondingUseElement || current.correspondingElement || current; if (conditionFn(current)) { return current; } current = current.parentNode; } while (current && current !== document.body && current !== document); return null; } /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _closest = __webpack_require__(2); var _closest2 = _interopRequireDefault(_closest); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _closest2.default; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _closest = __webpack_require__(3); Object.defineProperty(exports, 'closest', { enumerable: true, get: function () { return _interopRequireDefault(_closest).default; } }); var _requestNextAnimationFrame = __webpack_require__(1); Object.defineProperty(exports, 'requestNextAnimationFrame', { enumerable: true, get: function () { return _interopRequireDefault(_requestNextAnimationFrame).default; } }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * All draggable plugins inherit from this class. * @abstract * @class AbstractPlugin * @module AbstractPlugin */ class AbstractPlugin { /** * AbstractPlugin constructor. * @constructs AbstractPlugin * @param {Draggable} draggable - Draggable instance */ constructor(draggable) { /** * Draggable instance * @property draggable * @type {Draggable} */ this.draggable = draggable; } /** * Override to add listeners * @abstract */ attach() { throw new Error('Not Implemented'); } /** * Override to remove listeners * @abstract */ detach() { throw new Error('Not Implemented'); } } exports.default = AbstractPlugin; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _AbstractPlugin = __webpack_require__(5); var _AbstractPlugin2 = _interopRequireDefault(_AbstractPlugin); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _AbstractPlugin2.default; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultOptions = undefined; 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 _AbstractPlugin = __webpack_require__(6); var _AbstractPlugin2 = _interopRequireDefault(_AbstractPlugin); var _utils = __webpack_require__(4); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const onMirrorCreated = Symbol('onMirrorCreated'); const onMirrorDestroy = Symbol('onMirrorDestroy'); const onDragOver = Symbol('onDragOver'); const resize = Symbol('resize'); /** * ResizeMirror default options * @property {Object} defaultOptions * @type {Object} */ const defaultOptions = exports.defaultOptions = {}; /** * The ResizeMirror plugin resizes the mirror element to the dimensions of the draggable element that the mirror is hovering over * @class ResizeMirror * @module ResizeMirror * @extends AbstractPlugin */ class ResizeMirror extends _AbstractPlugin2.default { /** * ResizeMirror constructor. * @constructs ResizeMirror * @param {Draggable} draggable - Draggable instance */ constructor(draggable) { super(draggable); /** * ResizeMirror options * @property {Object} options * @type {Object} */ this.options = _extends({}, defaultOptions, this.getOptions()); /** * ResizeMirror remembers the last width when resizing the mirror * to avoid additional writes to the DOM * @property {number} lastWidth */ this.lastWidth = 0; /** * ResizeMirror remembers the last height when resizing the mirror * to avoid additional writes to the DOM * @property {number} lastHeight */ this.lastHeight = 0; /** * Keeps track of the mirror element * @property {HTMLElement} mirror */ this.mirror = null; this[onMirrorCreated] = this[onMirrorCreated].bind(this); this[onMirrorDestroy] = this[onMirrorDestroy].bind(this); this[onDragOver] = this[onDragOver].bind(this); } /** * Attaches plugins event listeners */ attach() { this.draggable.on('mirror:created', this[onMirrorCreated]).on('drag:over', this[onDragOver]).on('drag:over:container', this[onDragOver]); } /** * Detaches plugins event listeners */ detach() { this.draggable.off('mirror:created', this[onMirrorCreated]).off('mirror:destroy', this[onMirrorDestroy]).off('drag:over', this[onDragOver]).off('drag:over:container', this[onDragOver]); } /** * Returns options passed through draggable * @return {Object} */ getOptions() { return this.draggable.options.resizeMirror || {}; } /** * Mirror created handler * @param {MirrorCreatedEvent} mirrorEvent * @private */ [onMirrorCreated]({ mirror }) { this.mirror = mirror; } /** * Mirror destroy handler * @param {MirrorDestroyEvent} mirrorEvent * @private */ [onMirrorDestroy]() { this.mirror = null; } /** * Drag over handler * @param {DragOverEvent | DragOverContainer} dragEvent * @private */ [onDragOver](dragEvent) { this[resize](dragEvent); } /** * Resize function for * @param {DragOverEvent | DragOverContainer} dragEvent * @private */ [resize]({ overContainer, over }) { requestAnimationFrame(() => { if (this.mirror.parentNode !== overContainer) { overContainer.appendChild(this.mirror); } const overElement = over || this.draggable.getDraggableElementsForContainer(overContainer)[0]; if (!overElement) { return; } (0, _utils.requestNextAnimationFrame)(() => { const overRect = overElement.getBoundingClientRect(); if (this.lastHeight === overRect.height && this.lastWidth === overRect.width) { return; } this.mirror.style.width = `${overRect.width}px`; this.mirror.style.height = `${overRect.height}px`; this.lastWidth = overRect.width; this.lastHeight = overRect.height; }); }); } } exports.default = ResizeMirror; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultOptions = undefined; var _ResizeMirror = __webpack_require__(7); var _ResizeMirror2 = _interopRequireDefault(_ResizeMirror); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _ResizeMirror2.default; exports.defaultOptions = _ResizeMirror.defaultOptions; /***/ }) /******/ ]); });