UNPKG

@shopify/draggable

Version:

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

1,926 lines (1,527 loc) 188 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("Draggable", [], factory); else if(typeof exports === 'object') exports["Draggable"] = factory(); else root["Draggable"] = 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 = 66); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _AbstractEvent = __webpack_require__(64); var _AbstractEvent2 = _interopRequireDefault(_AbstractEvent); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _AbstractEvent2.default; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _AbstractPlugin = __webpack_require__(60); var _AbstractPlugin2 = _interopRequireDefault(_AbstractPlugin); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _AbstractPlugin2.default; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _closest = __webpack_require__(51); Object.defineProperty(exports, 'closest', { enumerable: true, get: function () { return _interopRequireDefault(_closest).default; } }); var _requestNextAnimationFrame = __webpack_require__(49); Object.defineProperty(exports, 'requestNextAnimationFrame', { enumerable: true, get: function () { return _interopRequireDefault(_requestNextAnimationFrame).default; } }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _SensorEvent = __webpack_require__(44); Object.keys(_SensorEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _SensorEvent[key]; } }); }); /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _Sensor = __webpack_require__(47); var _Sensor2 = _interopRequireDefault(_Sensor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _Sensor2.default; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _DragEvent = __webpack_require__(14); Object.keys(_DragEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _DragEvent[key]; } }); }); var _DraggableEvent = __webpack_require__(13); Object.keys(_DraggableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _DraggableEvent[key]; } }); }); var _Plugins = __webpack_require__(12); Object.keys(_Plugins).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _Plugins[key]; } }); }); var _Sensors = __webpack_require__(6); Object.keys(_Sensors).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _Sensors[key]; } }); }); var _Draggable = __webpack_require__(37); var _Draggable2 = _interopRequireDefault(_Draggable); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _Draggable2.default; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _Sensor = __webpack_require__(4); Object.defineProperty(exports, 'Sensor', { enumerable: true, get: function () { return _interopRequireDefault(_Sensor).default; } }); var _MouseSensor = __webpack_require__(46); Object.defineProperty(exports, 'MouseSensor', { enumerable: true, get: function () { return _interopRequireDefault(_MouseSensor).default; } }); var _TouchSensor = __webpack_require__(43); Object.defineProperty(exports, 'TouchSensor', { enumerable: true, get: function () { return _interopRequireDefault(_TouchSensor).default; } }); var _DragSensor = __webpack_require__(41); Object.defineProperty(exports, 'DragSensor', { enumerable: true, get: function () { return _interopRequireDefault(_DragSensor).default; } }); var _ForceTouchSensor = __webpack_require__(39); Object.defineProperty(exports, 'ForceTouchSensor', { enumerable: true, get: function () { return _interopRequireDefault(_ForceTouchSensor).default; } }); var _SensorEvent = __webpack_require__(3); Object.keys(_SensorEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _SensorEvent[key]; } }); }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _SnappableEvent = __webpack_require__(18); Object.keys(_SnappableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _SnappableEvent[key]; } }); }); /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _CollidableEvent = __webpack_require__(23); Object.keys(_CollidableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _CollidableEvent[key]; } }); }); /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _SortableEvent = __webpack_require__(27); Object.keys(_SortableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _SortableEvent[key]; } }); }); /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _SwappableEvent = __webpack_require__(30); Object.keys(_SwappableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _SwappableEvent[key]; } }); }); /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _DroppableEvent = __webpack_require__(33); Object.keys(_DroppableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _DroppableEvent[key]; } }); }); /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _Announcement = __webpack_require__(62); Object.defineProperty(exports, 'Announcement', { enumerable: true, get: function () { return _interopRequireDefault(_Announcement).default; } }); Object.defineProperty(exports, 'defaultAnnouncementOptions', { enumerable: true, get: function () { return _Announcement.defaultOptions; } }); var _Focusable = __webpack_require__(59); Object.defineProperty(exports, 'Focusable', { enumerable: true, get: function () { return _interopRequireDefault(_Focusable).default; } }); var _Mirror = __webpack_require__(57); Object.defineProperty(exports, 'Mirror', { enumerable: true, get: function () { return _interopRequireDefault(_Mirror).default; } }); Object.defineProperty(exports, 'defaultMirrorOptions', { enumerable: true, get: function () { return _Mirror.defaultOptions; } }); var _Scrollable = __webpack_require__(53); Object.defineProperty(exports, 'Scrollable', { enumerable: true, get: function () { return _interopRequireDefault(_Scrollable).default; } }); Object.defineProperty(exports, 'defaultScrollableOptions', { enumerable: true, get: function () { return _Scrollable.defaultOptions; } }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _DraggableEvent = __webpack_require__(63); Object.keys(_DraggableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _DraggableEvent[key]; } }); }); /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _DragEvent = __webpack_require__(65); Object.keys(_DragEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _DragEvent[key]; } }); }); /***/ }), /* 15 */ /***/ (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__(1); var _AbstractPlugin2 = _interopRequireDefault(_AbstractPlugin); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const onSortableSorted = Symbol('onSortableSorted'); /** * SwapAnimation default options * @property {Object} defaultOptions * @property {Number} defaultOptions.duration * @property {String} defaultOptions.easingFunction * @property {Boolean} defaultOptions.horizontal * @type {Object} */ const defaultOptions = exports.defaultOptions = { duration: 150, easingFunction: 'ease-in-out', horizontal: false }; /** * SwapAnimation plugin adds swap animations for sortable * @class SwapAnimation * @module SwapAnimation * @extends AbstractPlugin */ class SwapAnimation extends _AbstractPlugin2.default { /** * SwapAnimation constructor. * @constructs SwapAnimation * @param {Draggable} draggable - Draggable instance */ constructor(draggable) { super(draggable); /** * SwapAnimation options * @property {Object} options * @property {Number} defaultOptions.duration * @property {String} defaultOptions.easingFunction * @type {Object} */ this.options = _extends({}, defaultOptions, this.getOptions()); /** * Last animation frame * @property {Number} lastAnimationFrame * @type {Number} */ this.lastAnimationFrame = null; this[onSortableSorted] = this[onSortableSorted].bind(this); } /** * Attaches plugins event listeners */ attach() { this.draggable.on('sortable:sorted', this[onSortableSorted]); } /** * Detaches plugins event listeners */ detach() { this.draggable.off('sortable:sorted', this[onSortableSorted]); } /** * Returns options passed through draggable * @return {Object} */ getOptions() { return this.draggable.options.swapAnimation || {}; } /** * Sortable sorted handler * @param {SortableSortedEvent} sortableEvent * @private */ [onSortableSorted]({ oldIndex, newIndex, dragEvent }) { const { source, over } = dragEvent; cancelAnimationFrame(this.lastAnimationFrame); // Can be done in a separate frame this.lastAnimationFrame = requestAnimationFrame(() => { if (oldIndex >= newIndex) { animate(source, over, this.options); } else { animate(over, source, this.options); } }); } } exports.default = SwapAnimation; /** * Animates two elements * @param {HTMLElement} from * @param {HTMLElement} to * @param {Object} options * @param {Number} options.duration * @param {String} options.easingFunction * @param {String} options.horizontal * @private */ function animate(from, to, { duration, easingFunction, horizontal }) { for (const element of [from, to]) { element.style.pointerEvents = 'none'; } if (horizontal) { const width = from.offsetWidth; from.style.transform = `translate3d(${width}px, 0, 0)`; to.style.transform = `translate3d(-${width}px, 0, 0)`; } else { const height = from.offsetHeight; from.style.transform = `translate3d(0, ${height}px, 0)`; to.style.transform = `translate3d(0, -${height}px, 0)`; } requestAnimationFrame(() => { for (const element of [from, to]) { element.addEventListener('transitionend', resetElementOnTransitionEnd); element.style.transition = `transform ${duration}ms ${easingFunction}`; element.style.transform = ''; } }); } /** * Resets animation style properties after animation has completed * @param {Event} event * @private */ function resetElementOnTransitionEnd(event) { event.target.style.transition = ''; event.target.style.pointerEvents = ''; event.target.removeEventListener('transitionend', resetElementOnTransitionEnd); } /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultOptions = undefined; var _SwapAnimation = __webpack_require__(15); var _SwapAnimation2 = _interopRequireDefault(_SwapAnimation); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _SwapAnimation2.default; exports.defaultOptions = _SwapAnimation.defaultOptions; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _AbstractPlugin = __webpack_require__(1); var _AbstractPlugin2 = _interopRequireDefault(_AbstractPlugin); var _SnappableEvent = __webpack_require__(7); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const onDragStart = Symbol('onDragStart'); const onDragStop = Symbol('onDragStop'); const onDragOver = Symbol('onDragOver'); const onDragOut = Symbol('onDragOut'); const onMirrorCreated = Symbol('onMirrorCreated'); const onMirrorDestroy = Symbol('onMirrorDestroy'); /** * Snappable plugin which snaps draggable elements into place * @class Snappable * @module Snappable * @extends AbstractPlugin */ class Snappable extends _AbstractPlugin2.default { /** * Snappable constructor. * @constructs Snappable * @param {Draggable} draggable - Draggable instance */ constructor(draggable) { super(draggable); /** * Keeps track of the first source element * @property {HTMLElement|null} firstSource */ this.firstSource = null; /** * Keeps track of the mirror element * @property {HTMLElement} mirror */ this.mirror = null; this[onDragStart] = this[onDragStart].bind(this); this[onDragStop] = this[onDragStop].bind(this); this[onDragOver] = this[onDragOver].bind(this); this[onDragOut] = this[onDragOut].bind(this); this[onMirrorCreated] = this[onMirrorCreated].bind(this); this[onMirrorDestroy] = this[onMirrorDestroy].bind(this); } /** * Attaches plugins event listeners */ attach() { this.draggable.on('drag:start', this[onDragStart]).on('drag:stop', this[onDragStop]).on('drag:over', this[onDragOver]).on('drag:out', this[onDragOut]).on('droppable:over', this[onDragOver]).on('droppable:out', this[onDragOut]).on('mirror:created', this[onMirrorCreated]).on('mirror:destroy', this[onMirrorDestroy]); } /** * Detaches plugins event listeners */ detach() { this.draggable.off('drag:start', this[onDragStart]).off('drag:stop', this[onDragStop]).off('drag:over', this[onDragOver]).off('drag:out', this[onDragOut]).off('droppable:over', this[onDragOver]).off('droppable:out', this[onDragOut]).off('mirror:created', this[onMirrorCreated]).off('mirror:destroy', this[onMirrorDestroy]); } /** * Drag start handler * @private * @param {DragStartEvent} event - Drag start event */ [onDragStart](event) { if (event.canceled()) { return; } this.firstSource = event.source; } /** * Drag stop handler * @private * @param {DragStopEvent} event - Drag stop event */ [onDragStop]() { this.firstSource = null; } /** * Drag over handler * @private * @param {DragOverEvent|DroppableOverEvent} event - Drag over event */ [onDragOver](event) { if (event.canceled()) { return; } const source = event.source || event.dragEvent.source; if (source === this.firstSource) { this.firstSource = null; return; } const snapInEvent = new _SnappableEvent.SnapInEvent({ dragEvent: event, snappable: event.over || event.droppable }); this.draggable.trigger(snapInEvent); if (snapInEvent.canceled()) { return; } if (this.mirror) { this.mirror.style.display = 'none'; } source.classList.remove(this.draggable.getClassNameFor('source:dragging')); source.classList.add(this.draggable.getClassNameFor('source:placed')); // Need to cancel this in drag out setTimeout(() => { source.classList.remove(this.draggable.getClassNameFor('source:placed')); }, this.draggable.options.placedTimeout); } /** * Drag out handler * @private * @param {DragOutEvent|DroppableOutEvent} event - Drag out event */ [onDragOut](event) { if (event.canceled()) { return; } const source = event.source || event.dragEvent.source; const snapOutEvent = new _SnappableEvent.SnapOutEvent({ dragEvent: event, snappable: event.over || event.droppable }); this.draggable.trigger(snapOutEvent); if (snapOutEvent.canceled()) { return; } if (this.mirror) { this.mirror.style.display = ''; } source.classList.add(this.draggable.getClassNameFor('source:dragging')); } /** * Mirror created handler * @param {MirrorCreatedEvent} mirrorEvent * @private */ [onMirrorCreated]({ mirror }) { this.mirror = mirror; } /** * Mirror destroy handler * @param {MirrorDestroyEvent} mirrorEvent * @private */ [onMirrorDestroy]() { this.mirror = null; } } exports.default = Snappable; /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SnapOutEvent = exports.SnapInEvent = exports.SnapEvent = undefined; var _AbstractEvent = __webpack_require__(0); var _AbstractEvent2 = _interopRequireDefault(_AbstractEvent); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Base snap event * @class SnapEvent * @module SnapEvent * @extends AbstractEvent */ class SnapEvent extends _AbstractEvent2.default { /** * Drag event that triggered this snap event * @property dragEvent * @type {DragEvent} * @readonly */ get dragEvent() { return this.data.dragEvent; } /** * Snappable element * @property snappable * @type {HTMLElement} * @readonly */ get snappable() { return this.data.snappable; } } exports.SnapEvent = SnapEvent; /** * Snap in event * @class SnapInEvent * @module SnapInEvent * @extends SnapEvent */ SnapEvent.type = 'snap'; class SnapInEvent extends SnapEvent {} exports.SnapInEvent = SnapInEvent; /** * Snap out event * @class SnapOutEvent * @module SnapOutEvent * @extends SnapEvent */ SnapInEvent.type = 'snap:in'; SnapInEvent.cancelable = true; class SnapOutEvent extends SnapEvent {} exports.SnapOutEvent = SnapOutEvent; SnapOutEvent.type = 'snap:out'; SnapOutEvent.cancelable = true; /***/ }), /* 19 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _SnappableEvent = __webpack_require__(7); Object.keys(_SnappableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _SnappableEvent[key]; } }); }); var _Snappable = __webpack_require__(17); var _Snappable2 = _interopRequireDefault(_Snappable); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _Snappable2.default; /***/ }), /* 20 */ /***/ (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__(1); var _AbstractPlugin2 = _interopRequireDefault(_AbstractPlugin); var _utils = __webpack_require__(2); 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; /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultOptions = undefined; var _ResizeMirror = __webpack_require__(20); var _ResizeMirror2 = _interopRequireDefault(_ResizeMirror); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _ResizeMirror2.default; exports.defaultOptions = _ResizeMirror.defaultOptions; /***/ }), /* 22 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _AbstractPlugin = __webpack_require__(1); var _AbstractPlugin2 = _interopRequireDefault(_AbstractPlugin); var _utils = __webpack_require__(2); var _CollidableEvent = __webpack_require__(8); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const onDragMove = Symbol('onDragMove'); const onDragStop = Symbol('onDragStop'); const onRequestAnimationFrame = Symbol('onRequestAnimationFrame'); /** * Collidable plugin which detects colliding elements while dragging * @class Collidable * @module Collidable * @extends AbstractPlugin */ class Collidable extends _AbstractPlugin2.default { /** * Collidable constructor. * @constructs Collidable * @param {Draggable} draggable - Draggable instance */ constructor(draggable) { super(draggable); /** * Keeps track of currently colliding elements * @property {HTMLElement|null} currentlyCollidingElement * @type {HTMLElement|null} */ this.currentlyCollidingElement = null; /** * Keeps track of currently colliding elements * @property {HTMLElement|null} lastCollidingElement * @type {HTMLElement|null} */ this.lastCollidingElement = null; /** * Animation frame for finding colliding elements * @property {Number|null} currentAnimationFrame * @type {Number|null} */ this.currentAnimationFrame = null; this[onDragMove] = this[onDragMove].bind(this); this[onDragStop] = this[onDragStop].bind(this); this[onRequestAnimationFrame] = this[onRequestAnimationFrame].bind(this); } /** * Attaches plugins event listeners */ attach() { this.draggable.on('drag:move', this[onDragMove]).on('drag:stop', this[onDragStop]); } /** * Detaches plugins event listeners */ detach() { this.draggable.off('drag:move', this[onDragMove]).off('drag:stop', this[onDragStop]); } /** * Returns current collidables based on `collidables` option * @return {HTMLElement[]} */ getCollidables() { const collidables = this.draggable.options.collidables; if (typeof collidables === 'string') { return Array.prototype.slice.call(document.querySelectorAll(collidables)); } else if (collidables instanceof NodeList || collidables instanceof Array) { return Array.prototype.slice.call(collidables); } else if (collidables instanceof HTMLElement) { return [collidables]; } else if (typeof collidables === 'function') { return collidables(); } else { return []; } } /** * Drag move handler * @private * @param {DragMoveEvent} event - Drag move event */ [onDragMove](event) { const target = event.sensorEvent.target; this.currentAnimationFrame = requestAnimationFrame(this[onRequestAnimationFrame](target)); if (this.currentlyCollidingElement) { event.cancel(); } const collidableInEvent = new _CollidableEvent.CollidableInEvent({ dragEvent: event, collidingElement: this.currentlyCollidingElement }); const collidableOutEvent = new _CollidableEvent.CollidableOutEvent({ dragEvent: event, collidingElement: this.lastCollidingElement }); const enteringCollidable = Boolean(this.currentlyCollidingElement && this.lastCollidingElement !== this.currentlyCollidingElement); const leavingCollidable = Boolean(!this.currentlyCollidingElement && this.lastCollidingElement); if (enteringCollidable) { if (this.lastCollidingElement) { this.draggable.trigger(collidableOutEvent); } this.draggable.trigger(collidableInEvent); } else if (leavingCollidable) { this.draggable.trigger(collidableOutEvent); } this.lastCollidingElement = this.currentlyCollidingElement; } /** * Drag stop handler * @private * @param {DragStopEvent} event - Drag stop event */ [onDragStop](event) { const lastCollidingElement = this.currentlyCollidingElement || this.lastCollidingElement; const collidableOutEvent = new _CollidableEvent.CollidableOutEvent({ dragEvent: event, collidingElement: lastCollidingElement }); if (lastCollidingElement) { this.draggable.trigger(collidableOutEvent); } this.lastCollidingElement = null; this.currentlyCollidingElement = null; } /** * Animation frame function * @private * @param {HTMLElement} target - Current move target * @return {Function} */ [onRequestAnimationFrame](target) { return () => { const collidables = this.getCollidables(); this.currentlyCollidingElement = (0, _utils.closest)(target, element => collidables.includes(element)); }; } } exports.default = Collidable; /***/ }), /* 23 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CollidableOutEvent = exports.CollidableInEvent = exports.CollidableEvent = undefined; var _AbstractEvent = __webpack_require__(0); var _AbstractEvent2 = _interopRequireDefault(_AbstractEvent); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Base collidable event * @class CollidableEvent * @module CollidableEvent * @extends AbstractEvent */ class CollidableEvent extends _AbstractEvent2.default { /** * Drag event that triggered this colliable event * @property dragEvent * @type {DragEvent} * @readonly */ get dragEvent() { return this.data.dragEvent; } } exports.CollidableEvent = CollidableEvent; /** * Collidable in event * @class CollidableInEvent * @module CollidableInEvent * @extends CollidableEvent */ CollidableEvent.type = 'collidable'; class CollidableInEvent extends CollidableEvent { /** * Element you are currently colliding with * @property collidingElement * @type {HTMLElement} * @readonly */ get collidingElement() { return this.data.collidingElement; } } exports.CollidableInEvent = CollidableInEvent; /** * Collidable out event * @class CollidableOutEvent * @module CollidableOutEvent * @extends CollidableEvent */ CollidableInEvent.type = 'collidable:in'; class CollidableOutEvent extends CollidableEvent { /** * Element you were previously colliding with * @property collidingElement * @type {HTMLElement} * @readonly */ get collidingElement() { return this.data.collidingElement; } } exports.CollidableOutEvent = CollidableOutEvent; CollidableOutEvent.type = 'collidable:out'; /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _CollidableEvent = __webpack_require__(8); Object.keys(_CollidableEvent).forEach(function (key) { if (key === "default" || key === "__esModule") return; Object.defineProperty(exports, key, { enumerable: true, get: function () { return _CollidableEvent[key]; } }); }); var _Collidable = __webpack_require__(22); var _Collidable2 = _interopRequireDefault(_Collidable); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.default = _Collidable2.default; /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _Collidable = __webpack_require__(24); Object.defineProperty(exports, 'Collidable', { enumerable: true, get: function () { return _interopRequireDefault(_Collidable).default; } }); var _ResizeMirror = __webpack_require__(21); Object.defineProperty(exports, 'ResizeMirror', { enumerable: true, get: function () { return _interopRequireDefault(_ResizeMirror).default; } }); Object.defineProperty(exports, 'defaultResizeMirrorOptions', { enumerable: true, get: function () { return _ResizeMirror.defaultOptions; } }); var _Snappable = __webpack_require__(19); Object.defineProperty(exports, 'Snappable', { enumerable: true, get: function () { return _interopRequireDefault(_Snappable).default; } }); var _SwapAnimation = __webpack_require__(16); Object.defineProperty(exports, 'SwapAnimation', { enumerable: true, get: function () { return _interopRequireDefault(_SwapAnimation).default; } }); Object.defineProperty(exports, 'defaultSwapAnimationOptions', { enumerable: true, get: function () { return _SwapAnimation.defaultOptions; } }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), /* 26 */ /***/ (function(module, exports, __webpack_require__) { "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 _Draggable = __webpack_require__(5); var _Draggable2 = _interopRequireDefault(_Draggable); var _SortableEvent = __webpack_require__(9); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const onDragStart = Symbol('onDragStart'); const onDragOverContainer = Symbol('onDragOverContainer'); const onDragOver = Symbol('onDragOver'); const onDragStop = Symbol('onDragStop'); /** * Returns announcement message when a Draggable element has been sorted with another Draggable element * or moved into a new container * @param {SortableSortedEvent} sortableEvent * @return {String} */ function onSortableSortedDefaultAnnouncement({ dragEvent }) { const sourceText = dragEvent.source.textContent.trim() || dragEvent.source.id || 'sortable element'; if (dragEvent.over) { const overText = dragEvent.over.textContent.trim() || dragEvent.over.id || 'sortable element'; const isFollowing = dragEvent.source.compareDocumentPosition(dragEvent.over) & Node.DOCUMENT_POSITION_FOLLOWING; if (isFollowing) { return `Placed ${sourceText} after ${overText}`; } else { return `Placed ${sourceText} before ${overText}`; } } else { // need to figure out how to compute container name return `Placed ${sourceText} into a different container`; } } /** * @const {Object} defaultAnnouncements * @const {Function} defaultAnnouncements['sortable:sorted'] */ const defaultAnnouncements = { 'sortable:sorted': onSortableSortedDefaultAnnouncement }; /** * Sortable is built on top of Draggable and allows sorting of draggable elements. Sortable will keep * track of the original index and emits the new index as you drag over draggable elements. * @class Sortable * @module Sortable * @extends Draggable */ class Sortable extends _Draggable2.default { /** * Sortable constructor. * @constructs Sortable * @param {HTMLElement[]|NodeList|HTMLElement} containers - Sortable containers * @param {Object} options - Options for Sortable */ constructor(containers = [], options = {}) { super(containers, _extends({}, options, { announcements: _extends({}, defaultAnnouncements, options.announcements || {}) })); /** * start index of source on drag start * @property startIndex * @type {Number} */ this.startIndex = null; /** * start container on drag start * @property startContainer * @type {HTMLElement} * @default null */ this.startContainer = null; this[onDragStart] = this[onDragStart].bind(this); this[onDragOverContainer] = this[onDragOverContainer].bind(this); this[onDragOver] = this[onDragOver].bind(this); this[onDragStop] = this[onDragStop].bind(this); this.on('drag:start', this[onDragStart]).on('drag:over:container', this[onDragOverContainer]).on('drag:over', this[onDragOver]).on('drag:stop', this[onDragStop]); } /** * Destroys Sortable instance. */ destroy() { super.destroy(); this.off('drag:start', this[onDragStart]).off('drag:over:container', this[onDragOverContainer]).off('drag:over', this[onDragOver]).off('drag:stop', this[onDragStop]); } /** * Returns true index of element within its container during drag operation, i.e. excluding mirror and original source * @param {HTMLElement} element - An element * @return {Number} */ index(element) { return this.getDraggableElementsForContainer(element.parentNode).indexOf(element); } /** * Drag start handler * @private * @param {DragStartEvent} event - Drag start event */ [onDragStart](event) { this.startContainer = event.source.parentNode; this.startIndex = this.index(event.source); const sortableStartEvent = new _SortableEvent.SortableStartEvent({ dragEvent: event, startIndex: this.startIndex, startContainer: this.startContainer }); this.trigger(sortableStartEvent); if (sortableStartEvent.canceled()) { event.cancel(); } } /** * Drag over container handler * @private * @param {DragOverContainerEvent} event - Drag over container event */ [onDragOverContainer](event) { if (event.canceled()) { return; } const { source, over, overContainer } = event; const oldIndex = this.index(source); const sortableSortEvent = new _SortableEvent.SortableSortEvent({ dragEvent: event, currentIndex: oldIndex, source, over }); this.trigger(sortableSortEvent); if (sortableSortEvent.canceled()) { return; } const children = this.getDraggableElementsForContainer(overContainer); const moves = move({ source, over, overContainer, children }); if (!moves) { return; } const { oldContainer, newContainer } = moves; const newIndex = this.index(event.source); const sortableSortedEvent = new _SortableEvent.SortableSortedEvent({ dragEvent: event, oldIndex, newIndex, oldContainer, newContainer }); this.trigger(sortableSortedEvent); } /** * Drag over handler * @private * @param {DragOverEvent} event - Drag over event */ [onDragOver](event) { if (event.over === event.originalSource || event.over === event.source) { return; } const { source, over, overContainer } = event; const oldIndex = this.index(source); const sortableSortEvent = new _SortableEvent.SortableSortEvent({ dragEvent: event, currentIndex: oldIndex, source, over }); this.trigger(sortableSortEvent); if (sortableSortEvent.canceled()) { return; } const children = this.getDraggableElementsForContainer(overContainer); const moves = move({ source, over, overContainer, children }); if (!moves) { return; } const { oldContainer, newContainer } = moves; const newIndex = this.index(source); const sortableSortedEvent = new _SortableEvent.SortableSortedEvent({ dragEvent: event, oldIndex, newIndex, oldContainer, newContainer }); this.trigger(sortableSortedEvent); } /** * Drag stop handler * @private * @param {DragStopEvent} event - Drag stop event */ [onDragStop](event) { const sortableStopEvent = new _SortableEvent.SortableStopEvent({ dragEvent: event, oldIndex: this.startIndex, newIndex: this.index(event.source), oldContainer: this.startContainer, newContainer: event.source.parentNode }); this.trigger(sortableStopEvent); this.startIndex = null; this.startContainer = null; } } exports.default = Sortable; function index(element) { return Array.prototype.indexOf.call(element.parentNode.children, element); } function move({ source, over, overContainer, children }) { const emptyOverContainer = !children.length; const differentContainer = source.parentNode !== overContainer; const sameContainer = over && !differentContainer; if (emptyOverContainer) { return moveInsideEmptyContainer(source, overContainer); } else if (sameContainer) { return moveWithinContainer(source, over); } else if (differentContainer) { return moveOutsideContainer(source, over, overContainer); } else { return null; } } function moveInsideEmptyContainer(source, overContainer) { const oldContainer = source.parentNode; overContainer.appendChild(source); return { oldContainer, newContainer: overContainer }; } function moveWithinContainer(source, over) { const oldIndex = index(source); const newIndex = index(over); if (oldIndex < newIndex) { source.parentNode.insertBefore(source, over.nextElementSibling); } else { source.parentNode.insertBefore(source, over); } return { oldContainer: source.parentNode, newContainer: source.parentNode }; } function moveOutsideContainer(source, over, overContainer) { const oldContainer = source.parentNode; if (over) { over.parentNode.insertBefore(source, over); } else { // need to figure out proper position overContainer.appendChild(source); } return { oldContainer, newContainer: source.parentNode }; } /***/ }), /* 27 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SortableStopEvent = exports.SortableSortedEvent = exports.SortableSortEvent = exports.SortableStartEvent = exports.SortableEvent = undefined; var _AbstractEvent = __webpack_require__(0); var _AbstractEvent2 = _interopRequireDefault(_AbstractEvent); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Base sortable event * @class SortableEvent * @module SortableEvent * @extends AbstractEvent */ class SortableEvent extends _AbstractEvent2.default { /** * Original drag event that triggered this sortable event * @property dragEvent * @type {DragEvent} * @readonly */ get dragEvent() { return this.data.dragEvent; } } exports.SortableEvent = SortableEvent; /** * Sortable start event