sortable-dnd
Advanced tools
Comparing version 0.5.4 to 0.5.5
/*! | ||
* sortable-dnd v0.5.4 | ||
* sortable-dnd v0.5.5 | ||
* open source under the MIT license | ||
@@ -108,3 +108,3 @@ * https://github.com/mfuu/sortable-dnd#readme | ||
// Server environment | ||
return ''; | ||
return {}; | ||
} | ||
@@ -116,31 +116,18 @@ | ||
var pre = (Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/) || styles.OLink === '' && ['', 'o'])[1]; | ||
switch (pre) { | ||
case 'ms': | ||
return 'ms'; | ||
default: | ||
return pre && pre.length ? pre[0].toUpperCase() + pre.substr(1) : ''; | ||
} | ||
var dom = 'WebKit|Moz|MS|O'.match(new RegExp('(' + pre + ')', 'i'))[1]; | ||
return { | ||
dom: dom, | ||
lowercase: pre, | ||
css: '-' + pre + '-', | ||
js: pre[0].toUpperCase() + pre.substr(1) | ||
}; | ||
}(); | ||
/** | ||
* check if is HTMLElement | ||
*/ | ||
function isHTMLElement(node) { | ||
if (!node) return false; | ||
var ctx = document.createElement('div'); | ||
try { | ||
ctx.appendChild(node.cloneNode(true)); | ||
return node.nodeType == 1 ? true : false; | ||
} catch (e) { | ||
return node == window || node == document; | ||
} | ||
} | ||
function setTransition(el, transition) { | ||
el.style["".concat(vendorPrefix, "Transition")] = transition ? transition === 'none' ? 'none' : "".concat(transition) : ''; | ||
el.style["".concat(vendorPrefix.css, "transition")] = transition ? transition === 'none' ? 'none' : "".concat(transition) : ''; | ||
} | ||
function setTransitionDuration(el, duration) { | ||
el.style["".concat(vendorPrefix, "TransitionDuration")] = duration == null ? '' : "".concat(duration, "ms"); | ||
el.style["".concat(vendorPrefix.css, "transition-duration")] = duration == null ? '' : "".concat(duration, "ms"); | ||
} | ||
function setTransform(el, transform) { | ||
el.style["".concat(vendorPrefix, "Transform")] = transform ? "".concat(transform) : ''; | ||
el.style["".concat(vendorPrefix.css, "transform")] = transform ? "".concat(transform) : ''; | ||
} | ||
@@ -156,2 +143,4 @@ | ||
el.attachEvent('on' + event, fn); | ||
} else { | ||
el['on' + event] = fn; | ||
} | ||
@@ -168,2 +157,4 @@ } | ||
el.detachEvent('on' + event, fn); | ||
} else { | ||
el['on' + event] = null; | ||
} | ||
@@ -196,3 +187,3 @@ } | ||
/** | ||
* get element's offetTop in given parent node | ||
* get element's offetTop in given parent element | ||
*/ | ||
@@ -237,8 +228,3 @@ function getOffset(el, parentEl) { | ||
function getWindowScrollingElement() { | ||
var scrollingElement = document.scrollingElement; | ||
if (scrollingElement) { | ||
return scrollingElement; | ||
} else { | ||
return document.documentElement; | ||
} | ||
return document.scrollingElement || document.documentElement; | ||
} | ||
@@ -341,4 +327,4 @@ | ||
// If it can be found directly in the child element, return | ||
var index = children.indexOf(el); | ||
if (index > -1) return children[index]; | ||
var _index = children.indexOf(el); | ||
if (_index > -1) return children[_index]; | ||
@@ -376,5 +362,5 @@ // When the dom cannot be found directly in children, need to look down | ||
*/ | ||
function lastChild(el, helper, selector) { | ||
function lastChild(el, selector) { | ||
var last = el.lastElementChild; | ||
while (last && (last === helper || css(last, 'display') === 'none' || selector && !matches(last, selector))) { | ||
while (last && (last === Sortable.ghost || css(last, 'display') === 'none' || selector && !matches(last, selector))) { | ||
last = last.previousElementSibling; | ||
@@ -386,2 +372,62 @@ } | ||
/** | ||
* Returns the index of an element within its parent for a selected set of elements | ||
*/ | ||
function index(el, selector) { | ||
var index = 0; | ||
if (!el || !el.parentNode) { | ||
return -1; | ||
} | ||
while (el = el.previousElementSibling) { | ||
if (el.nodeName.toUpperCase() !== 'TEMPLATE' && (!selector || matches(el, selector)) && css(el, 'display') !== 'none') { | ||
index++; | ||
} | ||
} | ||
return index; | ||
} | ||
/** | ||
* Gets nth child of el, ignoring hidden children, sortable's elements (does not ignore clone if it's visible) and non-draggable elements | ||
* @return {HTMLElement} The child at index childNum, or null if not found | ||
*/ | ||
function getChild(el, childNum, selector, includeDragEl) { | ||
var i = 0, | ||
currentChild = 0, | ||
children = el.children; | ||
while (i < children.length) { | ||
if (children[i] !== Sortable.ghost && css(children[i], 'display') !== 'none' && closest(children[i], selector, el, false) && (includeDragEl || children[i] !== Sortable.dragged)) { | ||
if (currentChild === childNum) { | ||
return children[i]; | ||
} | ||
currentChild++; | ||
} | ||
i++; | ||
} | ||
return null; | ||
} | ||
// https://github.com/SortableJS/Sortable/blob/c5a882267542456d75b16d000dc1b603a907613a/src/Sortable.js#L161 | ||
function detectDirection(el, selector) { | ||
var elCSS = css(el), | ||
elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) - parseInt(elCSS.borderRightWidth), | ||
child1 = getChild(el, 0, selector), | ||
child2 = getChild(el, 1, selector), | ||
child1CSS = child1 && css(child1), | ||
child2CSS = child2 && css(child2), | ||
child1Width = child1CSS && parseInt(child1CSS.marginLeft) + parseInt(child1CSS.marginRight) + getRect(child1).width, | ||
child2Width = child2CSS && parseInt(child2CSS.marginLeft) + parseInt(child2CSS.marginRight) + getRect(child2).width, | ||
CSSFloatProperty = Edge || IE11OrLess ? 'cssFloat' : 'float'; | ||
if (elCSS.display === 'flex') { | ||
return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; | ||
} | ||
if (elCSS.display === 'grid') { | ||
return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; | ||
} | ||
if (child1 && child1CSS["float"] && child1CSS["float"] !== 'none') { | ||
var touchingSideChild2 = child1CSS["float"] === 'left' ? 'left' : 'right'; | ||
return child2 && (child2CSS.clear === 'both' || child2CSS.clear === touchingSideChild2) ? 'vertical' : 'horizontal'; | ||
} | ||
return child1 && (child1CSS.display === 'block' || child1CSS.display === 'flex' || child1CSS.display === 'table' || child1CSS.display === 'grid' || child1Width >= elWidth && elCSS[CSSFloatProperty] === 'none' || child2 && elCSS[CSSFloatProperty] === 'none' && child1Width + child2Width > elWidth) ? 'vertical' : 'horizontal'; | ||
} | ||
/** | ||
* add or remove element's class | ||
@@ -422,12 +468,2 @@ */ | ||
} | ||
/** | ||
* Check whether the front and rear positions are consistent | ||
*/ | ||
function offsetChanged(o1, o2) { | ||
return o1.top !== o2.top || o1.left !== o2.left; | ||
} | ||
function sortByOffset(o1, o2) { | ||
return o1.top == o2.top ? o1.left - o2.left : o1.top - o2.top; | ||
} | ||
function css(el, prop, val) { | ||
@@ -451,148 +487,41 @@ var style = el && el.style; | ||
} | ||
function sortableChanged(from, to) { | ||
return from.sortable.el !== to.sortable.el; | ||
/** | ||
* Check if the mouse pointer is within an element | ||
*/ | ||
function within(event, element, rect) { | ||
rect = rect || getRect(element); | ||
return event.clientX <= rect.right && event.clientX >= rect.left && event.clientY >= rect.top && event.clientY <= rect.bottom; | ||
} | ||
function visible(el, visible) { | ||
css(el, 'display', visible ? '' : 'none'); | ||
/** | ||
* Reports the position of its argument node relative to the node on which it is called. | ||
* | ||
* https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition | ||
*/ | ||
function comparePosition(a, b) { | ||
return a.compareDocumentPosition ? a.compareDocumentPosition(b) : a.contains ? (a != b && a.contains(b) && 16) + (a != b && b.contains(a) && 8) + (a.sourceIndex >= 0 && b.sourceIndex >= 0 ? (a.sourceIndex < b.sourceIndex && 4) + (a.sourceIndex > b.sourceIndex && 2) : 1) + 0 : 0; | ||
} | ||
function _nextTick(fn) { | ||
return setTimeout(fn, 0); | ||
/** | ||
* Check whether the front and rear positions are consistent, ignore front and rear height width changes | ||
*/ | ||
function offsetChanged(before, after) { | ||
function inRange(from, to, diff) { | ||
if (from === to) return true; | ||
return from >= to - diff && from <= to + diff; | ||
} | ||
var diffW = Math.abs(before.width - after.width); | ||
var diffH = Math.abs(before.height - after.height); | ||
var xChanged = !inRange(before.left, after.left, diffW); | ||
var yChanged = !inRange(before.top, after.top, diffH); | ||
return xChanged || yChanged; | ||
} | ||
function randomCode() { | ||
return Number(Math.random().toString().slice(-3) + Date.now()).toString(32); | ||
function sort(before, after) { | ||
var compareValue = comparePosition(before, after); | ||
return compareValue === 2 ? 1 : compareValue === 4 ? -1 : 0; | ||
} | ||
var expando = 'Sortable' + Date.now(); | ||
var multiFromTo = { | ||
sortable: null, | ||
nodes: [] | ||
}; | ||
var multiFrom = _objectSpread2({}, multiFromTo), | ||
multiTo = _objectSpread2({}, multiFromTo), | ||
selectedElements = {}; | ||
var getMultiDiffer = function getMultiDiffer() { | ||
return { | ||
from: _objectSpread2({}, multiFrom), | ||
to: _objectSpread2({}, multiTo) | ||
}; | ||
}; | ||
function Multiple(options) { | ||
this.options = options || {}; | ||
this.groupName = options.group.name || 'group_' + randomCode(); | ||
function preventDefault(evt) { | ||
evt.preventDefault !== void 0 && evt.cancelable && evt.preventDefault(); | ||
} | ||
Multiple.prototype = { | ||
/** | ||
* Indicates whether the multi-drag mode is used | ||
* @returns {boolean} | ||
*/ | ||
allowDrag: function allowDrag(dragEl) { | ||
return this.options.multiple && selectedElements[this.groupName] && selectedElements[this.groupName].length && selectedElements[this.groupName].indexOf(dragEl) > -1; | ||
}, | ||
getHelper: function getHelper() { | ||
var container = document.createElement('div'); | ||
selectedElements[this.groupName].forEach(function (node, index) { | ||
var clone = node.cloneNode(true); | ||
var opacity = index === 0 ? 1 : 0.5; | ||
clone.style = "\n opacity: ".concat(opacity, ";\n position: absolute;\n z-index: ").concat(index, ";\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n "); | ||
container.appendChild(clone); | ||
}); | ||
return container; | ||
}, | ||
/** | ||
* Collecting Multi-Drag Elements | ||
*/ | ||
select: function select(event, dragEl, rootEl, from) { | ||
if (!dragEl) return; | ||
if (!selectedElements[this.groupName]) { | ||
selectedElements[this.groupName] = []; | ||
} | ||
var index = selectedElements[this.groupName].indexOf(dragEl); | ||
toggleClass(dragEl, this.options.selectedClass, index < 0); | ||
var params = _objectSpread2(_objectSpread2({}, from), {}, { | ||
event: event | ||
}); | ||
if (index < 0) { | ||
selectedElements[this.groupName].push(dragEl); | ||
from.sortable._dispatchEvent('onSelect', params); | ||
} else { | ||
selectedElements[this.groupName].splice(index, 1); | ||
from.sortable._dispatchEvent('onDeselect', params); | ||
} | ||
selectedElements[this.groupName].sort(function (a, b) { | ||
return sortByOffset(getOffset(a, rootEl), getOffset(b, rootEl)); | ||
}); | ||
}, | ||
onDrag: function onDrag(rootEl, sortable) { | ||
multiFrom.sortable = sortable; | ||
multiFrom.nodes = selectedElements[this.groupName].map(function (node) { | ||
return { | ||
node: node, | ||
rect: getRect(node), | ||
offset: getOffset(node, rootEl) | ||
}; | ||
}); | ||
multiTo.sortable = sortable; | ||
}, | ||
onTrulyStarted: function onTrulyStarted(dragEl, sortable) { | ||
sortable.animator.collect(dragEl, null, dragEl.parentNode); | ||
selectedElements[this.groupName].forEach(function (node) { | ||
if (node == dragEl) return; | ||
visible(node, false); | ||
}); | ||
sortable.animator.animate(); | ||
}, | ||
onChange: function onChange(dragEl, sortable) { | ||
var rect = getRect(dragEl); | ||
var offset = getOffset(dragEl, sortable.el); | ||
multiTo.sortable = sortable; | ||
multiTo.nodes = selectedElements[this.groupName].map(function (node) { | ||
return { | ||
node: node, | ||
rect: rect, | ||
offset: offset | ||
}; | ||
}); | ||
}, | ||
onDrop: function onDrop(event, dragEl, rootEl, downEvent, _emits) { | ||
var _this = this; | ||
multiTo.sortable.animator.collect(dragEl, null, dragEl.parentNode); | ||
var index = selectedElements[this.groupName].indexOf(dragEl); | ||
selectedElements[this.groupName].forEach(function (node, i) { | ||
visible(node, true); | ||
if (i < index) { | ||
dragEl.parentNode.insertBefore(node, dragEl); | ||
} else { | ||
var dropEl = i > 0 ? selectedElements[_this.groupName][i - 1] : dragEl; | ||
dragEl.parentNode.insertBefore(node, dropEl.nextSibling); | ||
} | ||
}); | ||
multiFrom.sortable = downEvent.sortable; | ||
multiTo.nodes = selectedElements[this.groupName].map(function (node) { | ||
return { | ||
node: node, | ||
rect: getRect(node), | ||
offset: getOffset(node, rootEl) | ||
}; | ||
}); | ||
var ctxChanged = sortableChanged(multiFrom, multiTo); | ||
var changed = ctxChanged || this._offsetChanged(multiFrom.nodes, multiTo.nodes); | ||
var params = _objectSpread2(_objectSpread2({}, _emits()), {}, { | ||
changed: changed, | ||
event: event | ||
}); | ||
if (ctxChanged) { | ||
multiFrom.sortable._dispatchEvent('onDrop', params); | ||
} | ||
multiTo.sortable._dispatchEvent('onDrop', params); | ||
multiTo.sortable.animator.animate(); | ||
}, | ||
_offsetChanged: function _offsetChanged(ns1, ns2) { | ||
return !!ns1.find(function (o2) { | ||
var o1 = ns2.find(function (n) { | ||
return n.node === o2.node; | ||
}); | ||
return offsetChanged(o1.offset, o2.offset); | ||
}); | ||
} | ||
}; | ||
@@ -609,8 +538,5 @@ if (!window.requestAnimationFrame) { | ||
} | ||
function AutoScroll() { | ||
function AutoScroll(options) { | ||
this.options = options; | ||
this.autoScrollAnimationFrame = null; | ||
this.speed = { | ||
x: 10, | ||
y: 10 | ||
}; | ||
} | ||
@@ -625,23 +551,18 @@ AutoScroll.prototype = { | ||
}, | ||
update: function update(scrollEl, scrollThreshold, downEvent, moveEvent) { | ||
update: function update(scrollEl, dragEvent, moveEvent) { | ||
var _this = this; | ||
cancelAnimationFrame(this.autoScrollAnimationFrame); | ||
this.autoScrollAnimationFrame = requestAnimationFrame(function () { | ||
if (downEvent && moveEvent) { | ||
_this.autoScroll(scrollEl, scrollThreshold, moveEvent); | ||
if (dragEvent && moveEvent) { | ||
_this.autoScroll(scrollEl, moveEvent); | ||
} | ||
_this.update(scrollEl, scrollThreshold, downEvent, moveEvent); | ||
_this.update(scrollEl, dragEvent, moveEvent); | ||
}); | ||
}, | ||
autoScroll: function autoScroll(scrollEl, scrollThreshold, evt) { | ||
if (!scrollEl) return; | ||
autoScroll: function autoScroll(scrollEl, evt) { | ||
if (!scrollEl || evt.clientX === void 0 || evt.clientY === void 0) return; | ||
var rect = getRect(scrollEl); | ||
if (!rect) return; | ||
var clientX = evt.clientX, | ||
clientY = evt.clientY; | ||
if (clientX === void 0 || clientY === void 0) return; | ||
var rect = getRect(scrollEl); | ||
if (!rect) return; | ||
var scrollTop = scrollEl.scrollTop, | ||
scrollLeft = scrollEl.scrollLeft, | ||
scrollHeight = scrollEl.scrollHeight, | ||
scrollWidth = scrollEl.scrollWidth; | ||
var top = rect.top, | ||
@@ -656,2 +577,9 @@ right = rect.right, | ||
} | ||
var _this$options = this.options, | ||
scrollThreshold = _this$options.scrollThreshold, | ||
scrollSpeed = _this$options.scrollSpeed; | ||
var scrollTop = scrollEl.scrollTop, | ||
scrollLeft = scrollEl.scrollLeft, | ||
scrollHeight = scrollEl.scrollHeight, | ||
scrollWidth = scrollEl.scrollWidth; | ||
@@ -666,12 +594,12 @@ // check direction | ||
if (toLeft) { | ||
scrollx = Math.floor(Math.max(-1, (clientX - left) / scrollThreshold - 1) * this.speed.x); | ||
scrollx = Math.floor(Math.max(-1, (clientX - left) / scrollThreshold - 1) * scrollSpeed.x); | ||
} | ||
if (toRight) { | ||
scrollx = Math.ceil(Math.min(1, (clientX - right) / scrollThreshold + 1) * this.speed.x); | ||
scrollx = Math.ceil(Math.min(1, (clientX - right) / scrollThreshold + 1) * scrollSpeed.x); | ||
} | ||
if (toTop) { | ||
scrolly = Math.floor(Math.max(-1, (clientY - top) / scrollThreshold - 1) * this.speed.y); | ||
scrolly = Math.floor(Math.max(-1, (clientY - top) / scrollThreshold - 1) * scrollSpeed.y); | ||
} | ||
if (toBottom) { | ||
scrolly = Math.ceil(Math.min(1, (clientY - bottom) / scrollThreshold + 1) * this.speed.y); | ||
scrolly = Math.ceil(Math.min(1, (clientY - bottom) / scrollThreshold + 1) * scrollSpeed.y); | ||
} | ||
@@ -692,26 +620,26 @@ if (scrolly) { | ||
Animation.prototype = { | ||
collect: function collect(dragEl, dropEl, container, except) { | ||
var _this = this; | ||
if (!container) return; | ||
var children = Array.prototype.slice.call(container.children); | ||
var _this$_getRange = this._getRange(children, dragEl, dropEl, except), | ||
collect: function collect(dragEl, dropEl, parentEl, except) { | ||
if (!parentEl) return; | ||
var children = Array.prototype.slice.call(parentEl.children); | ||
var _this$_getRange = this._getRange(children, dragEl, dropEl), | ||
start = _this$_getRange.start, | ||
end = _this$_getRange.end; | ||
this.animations.length = 0; | ||
children.slice(start, end + 1).forEach(function (node) { | ||
if (css(node, 'display') === 'none') return; | ||
if (node === except || node === Sortable.helper) return; | ||
_this.animations.push({ | ||
for (var i = start; i <= end; i++) { | ||
var node = children[i]; | ||
if (!node || css(node, 'display') === 'none') continue; | ||
if (node === except || node === Sortable.ghost) continue; | ||
this.animations.push({ | ||
node: node, | ||
rect: getRect(node) | ||
}); | ||
}); | ||
} | ||
}, | ||
animate: function animate() { | ||
var _this2 = this; | ||
this.animations.forEach(function (state) { | ||
var node = state.node, | ||
rect = state.rect; | ||
_this2._excute(node, rect); | ||
}); | ||
for (var i = 0, len = this.animations.length; i < len; i++) { | ||
var _this$animations$i = this.animations[i], | ||
node = _this$animations$i.node, | ||
rect = _this$animations$i.rect; | ||
this._excute(node, rect); | ||
} | ||
}, | ||
@@ -759,2 +687,172 @@ _excute: function _excute(el, _ref) { | ||
var multiFromTo = { | ||
sortable: null, | ||
nodes: [] | ||
}; | ||
var multiFrom = _objectSpread2({}, multiFromTo), | ||
multiTo = _objectSpread2({}, multiFromTo), | ||
selectedElements = {}; | ||
var randomCode = function randomCode() { | ||
return Number(Math.random().toString().slice(-3) + Date.now()).toString(32); | ||
}; | ||
function Multiple(options) { | ||
this.active = false; | ||
this.options = options || {}; | ||
this.groupName = options.group.name || 'group_' + randomCode(); | ||
} | ||
Multiple.prototype = { | ||
select: function select(element) { | ||
toggleClass(element, this.options.selectedClass, true); | ||
selectedElements[this.groupName].push(element); | ||
selectedElements[this.groupName].sort(function (a, b) { | ||
return sort(a, b); | ||
}); | ||
}, | ||
deselect: function deselect(element) { | ||
var index = selectedElements[this.groupName].indexOf(element); | ||
if (index > -1) { | ||
toggleClass(element, this.options.selectedClass, false); | ||
selectedElements[this.groupName].splice(index, 1); | ||
} | ||
}, | ||
getSelectedElements: function getSelectedElements() { | ||
return selectedElements[this.groupName] || []; | ||
}, | ||
getEmits: function getEmits() { | ||
var emit = { | ||
from: {}, | ||
to: {} | ||
}; | ||
if (this.active) { | ||
emit.from = _objectSpread2({}, multiFrom); | ||
emit.to = _objectSpread2({}, multiTo); | ||
} | ||
return emit; | ||
}, | ||
getHelper: function getHelper() { | ||
if (!this.active) return null; | ||
var container = document.createElement('div'); | ||
selectedElements[this.groupName].forEach(function (node, index) { | ||
var clone = node.cloneNode(true); | ||
var opacity = index === 0 ? 1 : 0.5; | ||
clone.style = "\n opacity: ".concat(opacity, ";\n position: absolute;\n z-index: ").concat(index, ";\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n "); | ||
container.appendChild(clone); | ||
}); | ||
return container; | ||
}, | ||
getOnEndParams: function getOnEndParams() { | ||
if (!this.active) return {}; | ||
var sortableChanged = multiFrom.sortable.el !== multiTo.sortable.el; | ||
var changed = sortableChanged || this._offsetChanged(multiFrom.nodes, multiTo.nodes); | ||
return { | ||
changed: changed | ||
}; | ||
}, | ||
onDrag: function onDrag(rootEl, sortable) { | ||
this.active = this._isActive(); | ||
if (!this.active) return; | ||
multiFrom.sortable = sortable; | ||
multiFrom.nodes = selectedElements[this.groupName].map(function (node) { | ||
return { | ||
node: node, | ||
rect: getRect(node), | ||
offset: getOffset(node, rootEl) | ||
}; | ||
}); | ||
multiTo.sortable = sortable; | ||
}, | ||
onStarted: function onStarted(sortable) { | ||
if (!this.active) return; | ||
var dragEl = Sortable.dragged; | ||
sortable.animator.collect(dragEl, null, dragEl.parentNode); | ||
selectedElements[this.groupName].forEach(function (node) { | ||
if (node == dragEl) return; | ||
css(node, 'display', 'none'); | ||
}); | ||
sortable.animator.animate(); | ||
}, | ||
onChange: function onChange(dragEl, sortable) { | ||
if (!this.active) return; | ||
var rect = getRect(dragEl); | ||
var offset = getOffset(dragEl, sortable.el); | ||
multiTo.sortable = sortable; | ||
multiTo.nodes = selectedElements[this.groupName].map(function (node) { | ||
return { | ||
node: node, | ||
rect: rect, | ||
offset: offset | ||
}; | ||
}); | ||
}, | ||
onDrop: function onDrop(dragEvent, dropEvent, from) { | ||
if (!Sortable.dragged || !this._isMouseClick(dragEvent, dropEvent)) return; | ||
var dragEl = Sortable.dragged; | ||
var selectHandle = this.options.selectHandle; | ||
var _getEvent = getEvent(dropEvent), | ||
target = _getEvent.target; | ||
if (typeof selectHandle === 'function' && !selectHandle(dropEvent)) return; | ||
if (typeof selectHandle === 'string' && !matches(target, selectHandle)) return; | ||
if (!selectedElements[this.groupName]) { | ||
selectedElements[this.groupName] = []; | ||
} | ||
var index = selectedElements[this.groupName].indexOf(dragEl); | ||
toggleClass(dragEl, this.options.selectedClass, index < 0); | ||
var params = _objectSpread2(_objectSpread2({}, from), {}, { | ||
event: dropEvent | ||
}); | ||
if (index < 0) { | ||
selectedElements[this.groupName].push(dragEl); | ||
from.sortable._dispatchEvent('onSelect', params, false); | ||
} else { | ||
selectedElements[this.groupName].splice(index, 1); | ||
from.sortable._dispatchEvent('onDeselect', params, false); | ||
} | ||
selectedElements[this.groupName].sort(function (a, b) { | ||
return sort(a, b); | ||
}); | ||
}, | ||
onEnd: function onEnd(rootEl, dragEvent) { | ||
var _this = this; | ||
if (!this.active) return; | ||
var dragEl = Sortable.dragged; | ||
multiTo.sortable.animator.collect(dragEl, null, dragEl.parentNode); | ||
var index = selectedElements[this.groupName].indexOf(dragEl); | ||
selectedElements[this.groupName].forEach(function (node, i) { | ||
css(node, 'display', ''); | ||
if (i < index) { | ||
dragEl.parentNode.insertBefore(node, dragEl); | ||
} else { | ||
var dropEl = i > 0 ? selectedElements[_this.groupName][i - 1] : dragEl; | ||
dragEl.parentNode.insertBefore(node, dropEl.nextSibling); | ||
} | ||
}); | ||
multiFrom.sortable = dragEvent.sortable; | ||
multiTo.nodes = selectedElements[this.groupName].map(function (node) { | ||
return { | ||
node: node, | ||
rect: getRect(node), | ||
offset: getOffset(node, rootEl) | ||
}; | ||
}); | ||
multiTo.sortable.animator.animate(); | ||
}, | ||
_isActive: function _isActive() { | ||
return this.options.multiple && selectedElements[this.groupName] && selectedElements[this.groupName].length && selectedElements[this.groupName].indexOf(Sortable.dragged) > -1; | ||
}, | ||
_isMouseClick: function _isMouseClick(dragEvent, dropEvent) { | ||
var difX = dropEvent.clientX - dragEvent.clientX; | ||
var difY = dropEvent.clientY - dragEvent.clientY; | ||
var difD = Math.sqrt(difX * difX + difY * difY); | ||
return difD >= 0 && difD <= 1; | ||
}, | ||
_offsetChanged: function _offsetChanged(froms, tos) { | ||
return !!froms.find(function (from) { | ||
var to = tos.find(function (t) { | ||
return t.node === from.node; | ||
}); | ||
return offsetChanged(from.offset, to.offset); | ||
}); | ||
} | ||
}; | ||
function Helper() { | ||
@@ -794,2 +892,3 @@ this.helper = null; | ||
var helperStyle = _objectSpread2({ | ||
position: 'fixed', | ||
top: rect.top, | ||
@@ -799,7 +898,9 @@ left: rect.left, | ||
height: rect.height, | ||
position: 'fixed', | ||
minWidth: rect.width, | ||
minHeight: rect.height, | ||
opacity: '0.8', | ||
'z-index': 100000, | ||
'pointer-events': 'none', | ||
'box-sizing': 'border-box' | ||
overflow: 'hidden', | ||
'z-index': '100000', | ||
'box-sizing': 'border-box', | ||
'pointer-events': 'none' | ||
}, ghostStyle); | ||
@@ -820,2 +921,3 @@ for (var key in helperStyle) { | ||
var expando = 'Sortable' + Date.now(); | ||
var FromTo = { | ||
@@ -828,20 +930,22 @@ sortable: null, | ||
}; | ||
var sortables = []; | ||
var rootEl, | ||
dragEl, | ||
dropEl, | ||
nextEl, | ||
cloneEl, | ||
downEvent, | ||
parentEl, | ||
dragEvent, | ||
moveEvent, | ||
isMultiple, | ||
lastDropEl, | ||
listenerNode, | ||
lastHoverArea, | ||
dragStartTimer, | ||
sortables = [], | ||
helper = new Helper(), | ||
autoScroller = new AutoScroll(); | ||
var from = _objectSpread2({}, FromTo); | ||
var to = _objectSpread2({}, FromTo); | ||
var lastPosition = { | ||
x: 0, | ||
y: 0 | ||
}; | ||
from = _objectSpread2({}, FromTo), | ||
to = _objectSpread2({}, FromTo), | ||
lastPosition = { | ||
x: 0, | ||
y: 0 | ||
}; | ||
var _prepareGroup = function _prepareGroup(options) { | ||
@@ -895,14 +999,2 @@ var group = {}; | ||
}; | ||
var _emits = function _emits() { | ||
var result = { | ||
from: _objectSpread2({}, from), | ||
to: _objectSpread2({}, to) | ||
}; | ||
if (isMultiple) { | ||
var ft = getMultiDiffer(); | ||
result.from = _objectSpread2(_objectSpread2({}, ft.from), result.from); | ||
result.to = _objectSpread2(_objectSpread2({}, ft.to), result.to); | ||
} | ||
return result; | ||
}; | ||
@@ -916,7 +1008,6 @@ /** | ||
if (!(el && el.nodeType && el.nodeType === 1)) { | ||
throw "Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); | ||
throw "Sortable-dnd: `el` must be an HTMLElement, not ".concat({}.toString.call(el)); | ||
} | ||
el[expando] = this; | ||
this.el = el; | ||
this.ownerDocument = el.ownerDocument; | ||
this.options = options = Object.assign({}, options); | ||
@@ -927,11 +1018,16 @@ var defaults = { | ||
animation: 150, | ||
multiple: false, | ||
draggable: null, | ||
handle: null, | ||
onDrag: null, | ||
onMove: null, | ||
onDrop: null, | ||
onChange: null, | ||
multiple: false, | ||
selectHandle: null, | ||
customGhost: null, | ||
direction: function direction() { | ||
return detectDirection(el, options.draggable); | ||
}, | ||
autoScroll: true, | ||
scrollThreshold: 55, | ||
scrollSpeed: { | ||
x: 10, | ||
y: 10 | ||
}, | ||
delay: 0, | ||
@@ -946,3 +1042,2 @@ delayOnTouchOnly: false, | ||
fallbackOnBody: false, | ||
stopPropagation: false, | ||
supportTouch: 'ontouchstart' in window, | ||
@@ -971,2 +1066,3 @@ emptyInsertThreshold: 5 | ||
sortables.push(el); | ||
this.autoScroller = new AutoScroll(this.options); | ||
this.multiplayer = new Multiple(this.options); | ||
@@ -977,29 +1073,39 @@ this.animator = new Animation(this.options); | ||
constructor: Sortable, | ||
/** | ||
* Destroy | ||
*/ | ||
// ========================================= Public Methods ========================================= | ||
destroy: function destroy() { | ||
this._dispatchEvent('destroy', this); | ||
this.el[expando] = null; | ||
for (var i = 0; i < events.start.length; i++) { | ||
off(this.el, events.start[i], this._onDrag); | ||
} | ||
var _this = this; | ||
this._dispatchEvent('onDestroy', { | ||
sortable: this | ||
}, false); | ||
events.start.forEach(function (event) { | ||
return off(_this.el, event, _this._onDrag); | ||
}); | ||
sortables.splice(sortables.indexOf(this.el), 1); | ||
this._clearState(); | ||
sortables.splice(sortables.indexOf(this.el), 1); | ||
this.el = null; | ||
this.el[expando] = this.animator = this.multiplayer = this.autoScroller = null; | ||
}, | ||
/** | ||
* Get/Set option | ||
*/ | ||
option: function option(key, value) { | ||
var options = this.options; | ||
if (value === void 0) { | ||
return options[key]; | ||
} else { | ||
options[key] = value; | ||
if (key === 'group') { | ||
_prepareGroup(options); | ||
} | ||
return this.options[key]; | ||
} | ||
// set option | ||
this.options[key] = value; | ||
this.animator.options[key] = value; | ||
this.multiplayer.options[key] = value; | ||
this.autoScroller.options[key] = value; | ||
if (key === 'group') { | ||
_prepareGroup(this.options); | ||
} | ||
}, | ||
select: function select(element) { | ||
this.multiplayer.select(element); | ||
}, | ||
deselect: function deselect(element) { | ||
this.multiplayer.deselect(element); | ||
}, | ||
getSelectedElements: function getSelectedElements() { | ||
return this.multiplayer.getSelectedElements(); | ||
}, | ||
// ========================================= Properties ========================================= | ||
_onDrag: function _onDrag( /** Event|TouchEvent */evt) { | ||
@@ -1018,32 +1124,13 @@ if (this.options.disabled || !this.options.group.pull) return; | ||
if (Safari && target && target.tagName.toUpperCase() === 'SELECT') return; | ||
var _this$options = this.options, | ||
draggable = _this$options.draggable, | ||
handle = _this$options.handle; | ||
if (typeof handle === 'function' && !handle(evt)) return; | ||
if (typeof handle === 'string' && !matches(target, handle)) return; | ||
if (typeof draggable === 'function') { | ||
// The function type must return an HTMLElement if used to specifies the drag element | ||
var element = draggable(evt); | ||
if (!element) return; | ||
if (isHTMLElement(element)) { | ||
dragEl = element; | ||
} | ||
} else { | ||
// String use as 'TagName' or '.class' or '#id' | ||
dragEl = closest(target, draggable, this.el, false); | ||
} | ||
dragEl = closest(target, this.options.draggable, this.el); | ||
// No dragging is allowed when there is no dragging element | ||
if (!dragEl || dragEl.animated) return; | ||
listenerNode = touch ? dragEl : document; | ||
cloneEl = dragEl.cloneNode(true); | ||
this._prepareStart(touch, event); | ||
}, | ||
_prepareStart: function _prepareStart(touch, event) { | ||
var _this = this; | ||
var parentEl = dragEl.parentNode; | ||
downEvent = event; | ||
downEvent.sortable = this; | ||
downEvent.group = dragEl.parentNode; | ||
isMultiple = this.options.multiple && this.multiplayer.allowDrag(dragEl); | ||
isMultiple && this.multiplayer.onDrag(this.el, this); | ||
parentEl = dragEl.parentNode; | ||
Sortable.dragged = dragEl; | ||
dragEvent = event; | ||
dragEvent.sortable = this; | ||
this.multiplayer.onDrag(this.el, this); | ||
@@ -1055,3 +1142,2 @@ // get the position of the dragEl | ||
sortable: this, | ||
group: parentEl, | ||
node: dragEl, | ||
@@ -1061,4 +1147,8 @@ rect: rect, | ||
}; | ||
to.group = parentEl; | ||
to.node = dragEl; | ||
to.sortable = this; | ||
lastPosition = { | ||
x: event.clientX, | ||
y: event.clientY | ||
}; | ||
helper.distance = { | ||
@@ -1068,17 +1158,26 @@ x: event.clientX - rect.left, | ||
}; | ||
on(document, 'touchend', this._onDrop); | ||
on(document, 'touchcancel', this._onDrop); | ||
on(document, 'mouseup', this._onDrop); | ||
var _this$options2 = this.options, | ||
delay = _this$options2.delay, | ||
delayOnTouchOnly = _this$options2.delayOnTouchOnly; | ||
on(listenerNode, 'touchend', this._onDrop); | ||
on(listenerNode, 'touchcancel', this._onDrop); | ||
on(listenerNode, 'mouseup', this._onDrop); | ||
var handle = this.options.handle; | ||
if (typeof handle === 'function' && !handle(event)) return; | ||
if (typeof handle === 'string' && !matches(target, handle)) return; | ||
this._prepareStart(touch); | ||
}, | ||
_prepareStart: function _prepareStart(touch) { | ||
var _this2 = this; | ||
var _this$options = this.options, | ||
delay = _this$options.delay, | ||
delayOnTouchOnly = _this$options.delayOnTouchOnly; | ||
// Delay is impossible for native DnD in Edge or IE | ||
if (delay && (!delayOnTouchOnly || touch) && !(Edge || IE11OrLess)) { | ||
for (var i = 0; i < events.end.length; i++) { | ||
on(this.ownerDocument, events.end[i], this._cancelStart); | ||
} | ||
for (var _i = 0; _i < events.move.length; _i++) { | ||
on(this.ownerDocument, events.move[_i], this._delayMoveHandler); | ||
} | ||
events.move.forEach(function (event) { | ||
return on(_this2.el.ownerDocument, event, _this2._delayMoveHandler); | ||
}); | ||
events.end.forEach(function (event) { | ||
return on(_this2.el.ownerDocument, event, _this2._cancelStart); | ||
}); | ||
dragStartTimer = setTimeout(function () { | ||
return _this._onStart(touch); | ||
return _this2._onStart(touch); | ||
}, delay); | ||
@@ -1090,4 +1189,4 @@ } else { | ||
_delayMoveHandler: function _delayMoveHandler(evt) { | ||
var touch = evt.touches ? evt.touches[0] : evt; | ||
if (Math.max(Math.abs(touch.clientX - downEvent.clientX), Math.abs(touch.clientY - downEvent.clientY)) >= Math.floor(this.options.touchStartThreshold / (window.devicePixelRatio || 1))) { | ||
var e = evt.touches ? evt.touches[0] : evt; | ||
if (Math.max(Math.abs(e.clientX - dragEvent.clientX), Math.abs(e.clientY - dragEvent.clientY)) >= Math.floor(this.options.touchStartThreshold / (window.devicePixelRatio || 1))) { | ||
this._cancelStart(); | ||
@@ -1097,9 +1196,10 @@ } | ||
_cancelStart: function _cancelStart() { | ||
var _this3 = this; | ||
clearTimeout(dragStartTimer); | ||
for (var i = 0; i < events.end.length; i++) { | ||
off(this.ownerDocument, events.end[i], this._cancelStart); | ||
} | ||
for (var _i2 = 0; _i2 < events.move.length; _i2++) { | ||
off(this.ownerDocument, events.move[_i2], this._delayMoveHandler); | ||
} | ||
events.move.forEach(function (event) { | ||
return off(_this3.el.ownerDocument, event, _this3._delayMoveHandler); | ||
}); | ||
events.end.forEach(function (event) { | ||
return off(_this3.el.ownerDocument, event, _this3._cancelStart); | ||
}); | ||
}, | ||
@@ -1109,5 +1209,5 @@ _onStart: function _onStart( /** TouchEvent */touch) { | ||
if (touch) { | ||
on(document, 'touchmove', this._nearestSortable); | ||
on(listenerNode, 'touchmove', this._nearestSortable); | ||
} else { | ||
on(document, 'mousemove', this._nearestSortable); | ||
on(listenerNode, 'mousemove', this._nearestSortable); | ||
} | ||
@@ -1119,5 +1219,5 @@ | ||
// Timeout neccessary for IE9 | ||
_nextTick(function () { | ||
document.selection.empty(); | ||
}); | ||
setTimeout(function () { | ||
return document.selection.empty(); | ||
}, 0); | ||
} else { | ||
@@ -1128,38 +1228,49 @@ window.getSelection().removeAllRanges(); | ||
}, | ||
_onTrulyStarted: function _onTrulyStarted() { | ||
if (!moveEvent) { | ||
this._dispatchEvent('onDrag', _objectSpread2(_objectSpread2({}, _emits()), {}, { | ||
event: downEvent | ||
})); | ||
isMultiple && this.multiplayer.onTrulyStarted(dragEl, this); | ||
_onStarted: function _onStarted() { | ||
Sortable.active = this; | ||
this._dispatchEvent('onDrag', { | ||
event: dragEvent | ||
}); | ||
this.multiplayer.onStarted(this); | ||
var element = this._getGhostElement(); | ||
helper.init(from.rect, element, this.el, this.options); | ||
Sortable.ghost = helper.node; | ||
// Init in the move event to prevent conflict with the click event | ||
var element = isMultiple ? this.multiplayer.getHelper() : dragEl; | ||
helper.init(from.rect, element, this.el, this.options); | ||
Sortable.helper = helper.node; | ||
// Hide the drag element and show the cloned dom element | ||
visible(dragEl, false); | ||
dragEl.parentNode.insertBefore(cloneEl, dragEl); | ||
toggleClass(cloneEl, this.options.chosenClass, true); | ||
Safari && css(document.body, 'user-select', 'none'); | ||
// Hide the drag element and show the cloned dom element | ||
css(dragEl, 'display', 'none'); | ||
dragEl.parentNode.insertBefore(cloneEl, dragEl); | ||
toggleClass(cloneEl, this.options.chosenClass, true); | ||
Safari && css(document.body, 'user-select', 'none'); | ||
}, | ||
_getGhostElement: function _getGhostElement() { | ||
var customGhost = this.options.customGhost; | ||
if (typeof customGhost === 'function') { | ||
var selectedElements = this.multiplayer.getSelectedElements(); | ||
return customGhost(selectedElements.length ? selectedElements : [dragEl]); | ||
} | ||
return this.multiplayer.getHelper() || dragEl; | ||
}, | ||
_nearestSortable: function _nearestSortable( /** Event|TouchEvent */evt) { | ||
this._preventEvent(evt); | ||
if (!downEvent || !dragEl || !_positionChanged(evt)) return; | ||
preventDefault(evt); | ||
if (!dragEvent || !dragEl || !_positionChanged(evt)) return; | ||
// Init in the move event to prevent conflict with the click event | ||
!moveEvent && this._onStarted(); | ||
var _getEvent2 = getEvent(evt), | ||
event = _getEvent2.event, | ||
target = _getEvent2.target; | ||
var nearest = _detectNearestSortable(event.clientX, event.clientY); | ||
this._onTrulyStarted(); | ||
moveEvent = event; | ||
helper.move(event.clientX - downEvent.clientX, event.clientY - downEvent.clientY); | ||
helper.move(event.clientX - dragEvent.clientX, event.clientY - dragEvent.clientY); | ||
this._autoScroll(target); | ||
if (nearest) { | ||
nearest[expando]._onMove(event, target); | ||
var nearest = _detectNearestSortable(event.clientX, event.clientY); | ||
nearest && nearest[expando]._onMove(event, target); | ||
}, | ||
_autoScroll: function _autoScroll(target) { | ||
if (this.options.autoScroll) { | ||
var scrollEl = getParentAutoScrollElement(target, true); | ||
this.autoScroller.update(scrollEl, dragEvent, moveEvent); | ||
} | ||
}, | ||
_allowPut: function _allowPut() { | ||
if (downEvent.sortable.el === this.el) { | ||
if (dragEvent.sortable.el === this.el) { | ||
return true; | ||
@@ -1170,47 +1281,56 @@ } else if (!this.options.group.put) { | ||
var name = this.options.group.name; | ||
var fromGroup = downEvent.sortable.options.group; | ||
var fromGroup = dragEvent.sortable.options.group; | ||
return fromGroup.name && name && fromGroup.name === name; | ||
} | ||
}, | ||
_allowSwap: function _allowSwap() { | ||
var order = sort(cloneEl, dropEl); | ||
nextEl = order < 0 ? dropEl.nextSibling : dropEl; | ||
if (lastDropEl !== dropEl) { | ||
lastHoverArea = 0; | ||
return true; | ||
} | ||
var rect = getRect(dropEl), | ||
direction = typeof this.options.direction === 'function' ? this.options.direction.call(moveEvent, dragEl, this) : this.options.direction, | ||
vertical = direction === 'vertical', | ||
mouseOnAxis = vertical ? moveEvent.clientY : moveEvent.clientX, | ||
dropElSize = dropEl[direction === 'vertical' ? 'offsetHeight' : 'offsetWidth'], | ||
hoverArea = mouseOnAxis >= (vertical ? rect.top : rect.left) && mouseOnAxis < (vertical ? rect.bottom : rect.right) - dropElSize / 2 ? -1 : 1; | ||
if (lastHoverArea !== hoverArea) { | ||
lastHoverArea = hoverArea; | ||
return hoverArea < 0 ? order > 0 : order < 0; | ||
} | ||
return false; | ||
}, | ||
_onMove: function _onMove( /** Event|TouchEvent */event, target) { | ||
if (!this._allowPut()) return; | ||
this._dispatchEvent('onMove', _objectSpread2(_objectSpread2({}, _emits()), {}, { | ||
this._dispatchEvent('onMove', { | ||
event: event | ||
})); | ||
}); | ||
rootEl = this.el; | ||
dropEl = closest(target, this.options.draggable, rootEl, false); | ||
if (dropEl) { | ||
if (dropEl === lastDropEl) return; | ||
lastDropEl = dropEl; | ||
if (dropEl === cloneEl) return; | ||
if (dropEl.animated || containes(dropEl, cloneEl)) return; | ||
dropEl = closest(target, this.options.draggable, rootEl); | ||
// insert to last | ||
if (rootEl !== from.sortable.el && (target === rootEl || !lastChild(rootEl))) { | ||
lastDropEl = null; | ||
this._onInsert(event, true); | ||
return; | ||
} | ||
if (!dropEl || dropEl.animated || dropEl === cloneEl || dropEl === dragEl) return; | ||
if (!this._allowSwap() || containes(dropEl, cloneEl)) return; | ||
if (rootEl !== from.sortable.el) { | ||
if (target === rootEl || !lastChild(rootEl, helper.node)) { | ||
this._onInsert(event, true); | ||
} else if (dropEl) { | ||
this._onInsert(event, false); | ||
} | ||
} else if (dropEl) { | ||
this._onInsert(event, false); | ||
} else if (!(within(event, parentEl) && target === parentEl)) { | ||
this._onChange(event); | ||
} | ||
lastDropEl = dropEl; | ||
}, | ||
_autoScroll: function _autoScroll(target) { | ||
var scrollEl = getParentAutoScrollElement(target, true); | ||
var _this$options3 = this.options, | ||
autoScroll = _this$options3.autoScroll, | ||
scrollThreshold = _this$options3.scrollThreshold; | ||
if (autoScroll) { | ||
autoScroller.update(scrollEl, scrollThreshold, downEvent, moveEvent); | ||
} | ||
}, | ||
_onInsert: function _onInsert( /** Event|TouchEvent */event, insertToLast) { | ||
var target = insertToLast ? cloneEl : dropEl; | ||
var parentEl = insertToLast ? rootEl : dropEl.parentNode; | ||
parentEl = insertToLast ? rootEl : dropEl.parentNode; | ||
from.sortable.animator.collect(cloneEl, null, cloneEl.parentNode, cloneEl); | ||
this.animator.collect(null, target, parentEl, cloneEl); | ||
isMultiple && this.multiplayer.onChange(cloneEl, this); | ||
this.multiplayer.onChange(cloneEl, this); | ||
to = { | ||
sortable: this, | ||
group: parentEl, | ||
node: target, | ||
@@ -1220,5 +1340,5 @@ rect: getRect(target), | ||
}; | ||
from.sortable._dispatchEvent('onRemove', _objectSpread2(_objectSpread2({}, _emits()), {}, { | ||
from.sortable._dispatchEvent('onRemove', { | ||
event: event | ||
})); | ||
}); | ||
if (insertToLast) { | ||
@@ -1229,17 +1349,15 @@ parentEl.appendChild(cloneEl); | ||
} | ||
this._dispatchEvent('onAdd', _objectSpread2(_objectSpread2({}, _emits()), {}, { | ||
this._dispatchEvent('onAdd', { | ||
event: event | ||
})); | ||
}); | ||
from.sortable.animator.animate(); | ||
this.animator.animate(); | ||
from.group = parentEl; | ||
from.sortable = this; | ||
}, | ||
_onChange: function _onChange( /** Event|TouchEvent */event) { | ||
var parentEl = dropEl.parentNode; | ||
parentEl = dropEl.parentNode; | ||
this.animator.collect(cloneEl, dropEl, parentEl); | ||
isMultiple && this.multiplayer.onChange(cloneEl, this); | ||
this.multiplayer.onChange(cloneEl, this); | ||
to = { | ||
sortable: this, | ||
group: parentEl, | ||
node: dropEl, | ||
@@ -1249,38 +1367,27 @@ rect: getRect(dropEl), | ||
}; | ||
this._dispatchEvent('onChange', _objectSpread2(_objectSpread2({}, _emits()), {}, { | ||
this._dispatchEvent('onChange', { | ||
event: event | ||
})); | ||
// the top value is compared first, and the left is compared if the top value is the same | ||
var fromOffset = getOffset(cloneEl, rootEl); | ||
var nextEl = null; | ||
if (fromOffset.top === to.offset.top) { | ||
nextEl = fromOffset.left < to.offset.left ? dropEl.nextSibling : dropEl; | ||
} else { | ||
nextEl = fromOffset.top < to.offset.top ? dropEl.nextSibling : dropEl; | ||
} | ||
}); | ||
parentEl.insertBefore(cloneEl, nextEl); | ||
this.animator.animate(); | ||
from.group = parentEl; | ||
from.sortable = this; | ||
}, | ||
_onDrop: function _onDrop( /** Event|TouchEvent */evt) { | ||
this._unbindMoveEvents(); | ||
this._unbindDropEvents(); | ||
this._preventEvent(evt); | ||
_onDrop: function _onDrop( /** Event|TouchEvent */event) { | ||
preventDefault(event); | ||
this._cancelStart(); | ||
autoScroller.clear(); | ||
if (dragEl && downEvent && moveEvent) { | ||
this._onEnd(evt); | ||
this._unbindEvents(); | ||
this.autoScroller.clear(); | ||
if (dragEl && dragEvent && moveEvent) { | ||
this._onEnd(event); | ||
} else if (this.options.multiple) { | ||
this.multiplayer.select(evt, dragEl, rootEl, _objectSpread2({}, from)); | ||
this.multiplayer.onDrop(dragEvent, event, _objectSpread2({}, from)); | ||
} | ||
this._clearState(); | ||
}, | ||
_onEnd: function _onEnd( /** Event|TouchEvent */evt) { | ||
_onEnd: function _onEnd( /** Event|TouchEvent */event) { | ||
// swap real drag element to the current drop position | ||
if (this.options.swapOnDrop) { | ||
cloneEl.parentNode.insertBefore(dragEl, cloneEl); | ||
parentEl.insertBefore(dragEl, cloneEl); | ||
} | ||
from.group = downEvent.group; | ||
from.sortable = downEvent.sortable; | ||
from.sortable = dragEvent.sortable; | ||
@@ -1290,37 +1397,36 @@ // re-acquire the offset and rect values of the dragged element as the value after the drag is completed | ||
to.offset = getOffset(cloneEl, rootEl); | ||
if (isMultiple) { | ||
this.multiplayer.onDrop(evt, dragEl, rootEl, downEvent, _emits); | ||
} else { | ||
if (to.node === cloneEl) to.node = dragEl; | ||
var ctxChanged = sortableChanged(from, to); | ||
var changed = ctxChanged || offsetChanged(from.offset, to.offset); | ||
var params = _objectSpread2(_objectSpread2({}, _emits()), {}, { | ||
changed: changed, | ||
event: evt | ||
}); | ||
if (ctxChanged) { | ||
from.sortable._dispatchEvent('onDrop', params); | ||
} | ||
to.sortable._dispatchEvent('onDrop', params); | ||
if (to.node === cloneEl) to.node = dragEl; | ||
this.multiplayer.onEnd(rootEl, dragEvent); | ||
var multiParams = this.multiplayer.getOnEndParams(); | ||
var sortableChanged = from.sortable.el !== to.sortable.el; | ||
var changed = sortableChanged || offsetChanged(from.offset, to.offset); | ||
var params = _objectSpread2({ | ||
changed: changed, | ||
event: event | ||
}, multiParams); | ||
if (sortableChanged) { | ||
from.sortable._dispatchEvent('onDrop', params); | ||
} | ||
visible(dragEl, true); | ||
cloneEl.parentNode.removeChild(cloneEl); | ||
to.sortable._dispatchEvent('onDrop', params); | ||
css(dragEl, 'display', ''); | ||
parentEl.removeChild(cloneEl); | ||
Safari && css(document.body, 'user-select', ''); | ||
}, | ||
_preventEvent: function _preventEvent( /** Event|TouchEvent */evt) { | ||
evt.preventDefault !== void 0 && evt.cancelable && evt.preventDefault(); | ||
if (this.options.stopPropagation) { | ||
if (evt && evt.stopPropagation) { | ||
evt.stopPropagation(); | ||
} else { | ||
window.event.cancelBubble = true; | ||
} | ||
_dispatchEvent: function _dispatchEvent(event) { | ||
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var needDefaultEmits = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; | ||
var callback = this.options[event]; | ||
if (typeof callback !== 'function') return; | ||
var emit = {}; | ||
if (needDefaultEmits) { | ||
var multiEmit = this.multiplayer.getEmits(); | ||
emit = { | ||
from: _objectSpread2(_objectSpread2({}, multiEmit.from), from), | ||
to: _objectSpread2(_objectSpread2({}, multiEmit.to), to) | ||
}; | ||
} | ||
callback(_objectSpread2(_objectSpread2({}, emit), params)); | ||
}, | ||
_dispatchEvent: function _dispatchEvent(emit, params) { | ||
var callback = this.options[emit]; | ||
if (typeof callback === 'function') callback(params); | ||
}, | ||
_clearState: function _clearState() { | ||
dragEl = dropEl = cloneEl = downEvent = moveEvent = isMultiple = lastDropEl = dragStartTimer = Sortable.helper = null; | ||
dragEl = dropEl = nextEl = cloneEl = parentEl = dragEvent = moveEvent = lastDropEl = listenerNode = lastHoverArea = dragStartTimer = Sortable.ghost = Sortable.active = Sortable.dragged = null; | ||
lastPosition = { | ||
@@ -1333,20 +1439,21 @@ x: 0, | ||
}, | ||
_unbindMoveEvents: function _unbindMoveEvents() { | ||
for (var i = 0; i < events.move.length; i++) { | ||
off(document, events.move[i], this._nearestSortable); | ||
} | ||
}, | ||
_unbindDropEvents: function _unbindDropEvents() { | ||
for (var i = 0; i < events.end.length; i++) { | ||
off(document, events.end[i], this._onDrop); | ||
} | ||
_unbindEvents: function _unbindEvents() { | ||
var _this4 = this; | ||
events.move.forEach(function (event) { | ||
return off(listenerNode, event, _this4._nearestSortable); | ||
}); | ||
events.end.forEach(function (event) { | ||
return off(listenerNode, event, _this4._onDrop); | ||
}); | ||
} | ||
}; | ||
Sortable.prototype.utils = { | ||
Sortable.utils = { | ||
on: on, | ||
off: off, | ||
css: css, | ||
index: index, | ||
closest: closest, | ||
getRect: getRect, | ||
getOffset: getOffset | ||
getOffset: getOffset, | ||
toggleClass: toggleClass, | ||
detectDirection: detectDirection | ||
}; | ||
@@ -1356,4 +1463,2 @@ | ||
* Get the Sortable instance of an element | ||
* @param {HTMLElement} element The element | ||
* @return {Sortable|undefined} The instance of Sortable | ||
*/ | ||
@@ -1366,4 +1471,2 @@ Sortable.get = function (element) { | ||
* Create sortable instance | ||
* @param {HTMLElement} el | ||
* @param {Object} options | ||
*/ | ||
@@ -1370,0 +1473,0 @@ Sortable.create = function (el, options) { |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function Y(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function l(o){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?Y(Object(i),!0).forEach(function(t){var e,n;e=o,n=i[t=t],(t=function(t){t=function(t,e){if("object"!=typeof t||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0===n)return("string"===e?String:Number)(t);n=n.call(t,e||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}(t,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(i)):Y(Object(i)).forEach(function(t){Object.defineProperty(o,t,Object.getOwnPropertyDescriptor(i,t))})}return o}function R(t){return(R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var F={capture:!1,passive:!1},H=/\s+/g,c={start:["touchstart","mousedown"],move:["touchmove","mousemove"],end:["touchend","touchcancel","mouseup"]};function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var e,d=t(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),L=t(/Edge/i),a=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),k=(e=!1,document.addEventListener("checkIfSupportPassive",null,{get passive(){return e=!0}}),e),u="undefined"==typeof window||"undefined"==typeof document?"":(o=window.getComputedStyle(document.documentElement,"")||["-moz-hidden-iframe"],"ms"!==(o=(Array.prototype.slice.call(o).join("").match(/-(moz|webkit|ms)-/)||""===o.OLink&&["","o"])[1])?o&&o.length?o[0].toUpperCase()+o.substr(1):"":"ms");function i(t,e){t.style["".concat(u,"TransitionDuration")]=null==e?"":"".concat(e,"ms")}function h(t,e){t.style["".concat(u,"Transform")]=e?"".concat(e):""}function p(t,e,n){window.addEventListener?t.addEventListener(e,n,!(!k&&d)&&F):window.attachEvent&&t.attachEvent("on"+e,n)}function n(t,e,n){window.removeEventListener?t.removeEventListener(e,n,!(!k&&d)&&F):window.detachEvent&&t.detachEvent("on"+e,n)}function I(t){var e=t,n=t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0],t=n?document.elementFromPoint(n.clientX,n.clientY):t.target;return!n||"clientX"in e||(e.clientX=n.clientX,e.clientY=n.clientY,e.pageX=n.pageX,e.pageY=n.pageY,e.screenX=n.screenX,e.screenY=n.screenY),{touch:n,event:e,target:t}}function f(t,e){for(var n={top:0,left:0,height:t.offsetHeight,width:t.offsetWidth};n.top+=t.offsetTop,n.left+=t.offsetLeft,(t=t.parentNode)&&t!==e;);return n}function m(){var t=document.scrollingElement;return t||document.documentElement}function g(t){var e,n,o,i,r,a,s,l=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},c=2<arguments.length?arguments[2]:void 0;if(t.getBoundingClientRect||t===window){if(t!==window&&t.parentNode&&t!==m()){if(n=(e=t.getBoundingClientRect()).top,o=e.left,i=e.bottom,r=e.right,a=e.height,s=e.width,l.parent&&t.parentNode!==t.ownerDocument.body)for(var u,h=t.parentNode;h&&h.getBoundingClientRect&&h!==t.ownerDocument.body;){if((u=h.getBoundingClientRect()).height<a)return n=u.top,o=u.left,i=u.bottom,r=u.right,a=u.height,{top:n,left:o,bottom:i,right:r,width:s=u.width,height:a};h=h.parentNode}}else o=n=0,i=window.innerHeight,r=window.innerWidth,a=window.innerHeight,s=window.innerWidth;if((l.block||l.relative)&&t!==window&&(c=c||t.parentNode,!d))do{if(c&&c.getBoundingClientRect&&("none"!==v(c,"transform")||l.relative&&"static"!==v(c,"position"))){var p=c.getBoundingClientRect();n-=p.top+parseInt(v(c,"border-top-width")),o-=p.left+parseInt(v(c,"border-left-width")),i=n+e.height,r=o+e.width;break}}while(c=c.parentNode);return{top:n,left:o,bottom:i,right:r,width:s,height:a}}}function s(t,e,n,o){if(t){n=n||document;do{if(null==e){var i=Array.prototype.slice.call(n.children),r=i.indexOf(t);if(-1<r)return i[r];for(var a=0;a<i.length;a++)if(W(t,i[a]))return i[a]}else if((">"!==e[0]||t.parentNode===n)&&q(t,e)||o&&t===n)return t}while(t=t.parentNode)}return null}function W(t,e){if(t&&e){if(e.compareDocumentPosition)return e===t||16&e.compareDocumentPosition(t);if(e.contains&&1===t.nodeType)return e.contains(t)&&e!==t;for(;t=t.parentNode;)if(t===e)return 1}}function z(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(H," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(H," ")))}function q(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function V(t,e){return t.top!==e.top||t.left!==e.left}function v(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=e in o||-1!==e.indexOf("webkit")?e:"-webkit-"+e]=n+("string"==typeof n?"":"px")}}function U(t,e){return t.sortable.el!==e.sortable.el}function y(t,e){v(t,"display",e?"":"none")}var b="Sortable"+Date.now(),o={sortable:null,nodes:[]},w=l({},o),_=l({},o),S={};function Z(t){this.options=t||{},this.groupName=t.group.name||"group_"+Number(Math.random().toString().slice(-3)+Date.now()).toString(32)}function G(){this.autoScrollAnimationFrame=null,this.speed={x:10,y:10}}function J(t){this.options=t,this.animations=[]}function K(){this.helper=null,this.distance={x:0,y:0}}Z.prototype={allowDrag:function(t){return this.options.multiple&&S[this.groupName]&&S[this.groupName].length&&-1<S[this.groupName].indexOf(t)},getHelper:function(){var n=document.createElement("div");return S[this.groupName].forEach(function(t,e){t=t.cloneNode(!0);t.style="\n opacity: ".concat(0===e?1:.5,";\n position: absolute;\n z-index: ").concat(e,";\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n "),n.appendChild(t)}),n},select:function(t,e,n,o){var i;e&&(S[this.groupName]||(S[this.groupName]=[]),i=S[this.groupName].indexOf(e),z(e,this.options.selectedClass,i<0),t=l(l({},o),{},{event:t}),i<0?(S[this.groupName].push(e),o.sortable._dispatchEvent("onSelect",t)):(S[this.groupName].splice(i,1),o.sortable._dispatchEvent("onDeselect",t)),S[this.groupName].sort(function(t,e){return t=f(t,n),e=f(e,n),t.top==e.top?t.left-e.left:t.top-e.top}))},onDrag:function(e,t){w.sortable=t,w.nodes=S[this.groupName].map(function(t){return{node:t,rect:g(t),offset:f(t,e)}}),_.sortable=t},onTrulyStarted:function(e,t){t.animator.collect(e,null,e.parentNode),S[this.groupName].forEach(function(t){t!=e&&y(t,!1)}),t.animator.animate()},onChange:function(t,e){var n=g(t),o=f(t,e.el);_.sortable=e,_.nodes=S[this.groupName].map(function(t){return{node:t,rect:n,offset:o}})},onDrop:function(t,n,e,o,i){var r=this,a=(_.sortable.animator.collect(n,null,n.parentNode),S[this.groupName].indexOf(n)),o=(S[this.groupName].forEach(function(t,e){y(t,!0),e<a?n.parentNode.insertBefore(t,n):(e=0<e?S[r.groupName][e-1]:n,n.parentNode.insertBefore(t,e.nextSibling))}),w.sortable=o.sortable,_.nodes=S[this.groupName].map(function(t){return{node:t,rect:g(t),offset:f(t,e)}}),U(w,_)),s=o||this._offsetChanged(w.nodes,_.nodes),i=l(l({},i()),{},{changed:s,event:t});o&&w.sortable._dispatchEvent("onDrop",i),_.sortable._dispatchEvent("onDrop",i),_.sortable.animator.animate()},_offsetChanged:function(t,n){return!!t.find(function(e){return V(n.find(function(t){return t.node===e.node}).offset,e.offset)})}},window.requestAnimationFrame||(window.requestAnimationFrame=function(t){return setTimeout(t,17)}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)}),G.prototype={clear:function(){null!=this.autoScrollAnimationFrame&&(cancelAnimationFrame(this.autoScrollAnimationFrame),this.autoScrollAnimationFrame=null)},update:function(t,e,n,o){var i=this;cancelAnimationFrame(this.autoScrollAnimationFrame),this.autoScrollAnimationFrame=requestAnimationFrame(function(){n&&o&&i.autoScroll(t,e,o),i.update(t,e,n,o)})},autoScroll:function(t,e,n){var o,i,r,a,s,l,c,u,h,p,d,f;t&&(o=n.clientX,n=n.clientY,void 0!==o)&&void 0!==n&&(h=g(t))&&(d=t.scrollTop,i=t.scrollLeft,r=t.scrollHeight,p=t.scrollWidth,a=h.top,s=h.right,l=h.bottom,c=h.left,f=h.height,h=h.width,n<a||s<o||l<n||o<c||(u=0<d&&a<=n&&n<=a+e,h=i+h<p&&o<=s&&s-e<=o,p=d+f<r&&n<=l&&l-e<=n,(f=d=0)<i&&c<=o&&o<=c+e&&(d=Math.floor(Math.max(-1,(o-c)/e-1)*this.speed.x)),h&&(d=Math.ceil(Math.min(1,(o-s)/e+1)*this.speed.x)),u&&(f=Math.floor(Math.max(-1,(n-a)/e-1)*this.speed.y)),(f=p?Math.ceil(Math.min(1,(n-l)/e+1)*this.speed.y):f)&&(t.scrollTop+=f),d&&(t.scrollLeft+=d)))}},J.prototype={collect:function(t,e,n,o){var i=this;n&&(n=Array.prototype.slice.call(n.children),e=(t=this._getRange(n,t,e,o)).start,t=t.end,this.animations.length=0,n.slice(e,t+1).forEach(function(t){"none"!==v(t,"display")&&t!==o&&t!==B.helper&&i.animations.push({node:t,rect:g(t)})}))},animate:function(){var n=this;this.animations.forEach(function(t){var e=t.node,t=t.rect;n._excute(e,t)})},_excute:function(t,e){var n=e.left,e=e.top,o=g(t),e=e-o.top,n=n-o.left,o=(i(t),h(t,"translate3d(".concat(n,"px, ").concat(e,"px, 0)")),t.offsetWidth,this.options.animation);i(t,o),h(t,"translate3d(0px, 0px, 0px)"),clearTimeout(t.animated),t.animated=setTimeout(function(){i(t),h(t,""),t.animated=null},o)},_getRange:function(t,e,n){var o,e=t.indexOf(e),n=t.indexOf(n);return n<e&&(e=(o=[n,e])[0],n=o[1]),e<0&&(e=n,n=t.length-1),{start:e,end:n=n<0?t.length-1:n}}},K.prototype={get node(){return this.helper},destroy:function(){this.helper&&this.helper.parentNode&&this.helper.parentNode.removeChild(this.helper),this.helper=null,this.distance={x:0,y:0}},move:function(t,e){this.helper&&h(this.helper,"translate3d(".concat(t,"px, ").concat(e,"px, 0)"))},init:function(t,e,n,o){if(!this.helper){var i,r=o.fallbackOnBody,a=o.ghostClass,o=o.ghostStyle,r=r?document.body:n,s=(this.helper=e.cloneNode(!0),z(this.helper,a,!0),l({top:t.top,left:t.left,width:t.width,height:t.height,position:"fixed",opacity:"0.8","z-index":1e5,"pointer-events":"none","box-sizing":"border-box"},o));for(i in s)v(this.helper,i,s[i]);n=this.helper,e="none",n.style["".concat(u,"Transition")]=e?"none"===e?"none":"".concat(e):"",h(this.helper,"translate3d(0px, 0px, 0px)"),r.appendChild(this.helper);a=this.distance.x/parseInt(this.helper.style.width)*100,t=this.distance.y/parseInt(this.helper.style.height)*100;v(this.helper,"transform-origin","".concat(a,"% ").concat(t,"%")),v(this.helper,"transform","translateZ(0)"),v(this.helper,"will-change","transform")}}};function r(){var t,e={from:l({},A),to:l({},j)};return C&&(t={from:l({},w),to:l({},_)},e.from=l(l({},t.from),e.from),e.to=l(l({},t.to),e.to)),e}var N,E,x,D,O,T,C,Q,$,tt={sortable:null,group:null,node:null,rect:{},offset:{}},M=[],P=new K,et=new G,A=l({},tt),j=l({},tt),X={x:0,y:0},nt=function(t){var e={},n=t.group;n&&"object"==R(n)||(n={name:n,pull:!0,put:!0}),e.name=n.name,e.pull=n.pull,e.put=n.put,t.group=e};function B(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));(t[b]=this).el=t,this.ownerDocument=t.ownerDocument,this.options=e=Object.assign({},e);var n,o,i={disabled:!1,group:"",animation:150,multiple:!1,draggable:null,handle:null,onDrag:null,onMove:null,onDrop:null,onChange:null,autoScroll:!0,scrollThreshold:55,delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,ghostClass:"",ghostStyle:{},chosenClass:"",selectedClass:"",swapOnDrop:!0,fallbackOnBody:!1,stopPropagation:!1,supportTouch:"ontouchstart"in window,emptyInsertThreshold:5};for(n in i)n in this.options||(this.options[n]=i[n]);for(o in nt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));p(t,this.options.supportTouch?"touchstart":"mousedown",this._onDrag),M.push(t),this.multiplayer=new Z(this.options),this.animator=new J(this.options)}return(B.prototype={constructor:B,destroy:function(){this._dispatchEvent("destroy",this),this.el[b]=null;for(var t=0;t<c.start.length;t++)n(this.el,c.start[t],this._onDrag);this._clearState(),M.splice(M.indexOf(this.el),1),this.el=null},option:function(t,e){var n=this.options;if(void 0===e)return n[t];n[t]=e,"group"===t&&nt(n)},_onDrag:function(t){if(!this.options.disabled&&this.options.group.pull&&(!/mousedown|pointerdown/.test(t.type)||0===t.button)){var e=I(t),n=e.touch,o=e.event,e=e.target;if(!(e===this.el||a&&e&&"SELECT"===e.tagName.toUpperCase())){var i=this.options,r=i.draggable,i=i.handle;if(("function"!=typeof i||i(t))&&("string"!=typeof i||q(e,i))){if("function"==typeof r){i=r(t);if(!i)return;!function(e){if(e){var t=document.createElement("div");try{return t.appendChild(e.cloneNode(!0)),1==e.nodeType}catch(t){return e==window||e==document}}}(i)||(E=i)}else E=s(e,r,this.el,!1);E&&!E.animated&&(D=E.cloneNode(!0),this._prepareStart(n,o))}}}},_prepareStart:function(t,e){var n=this,o=E.parentNode,i=((O=e).sortable=this,O.group=E.parentNode,(C=this.options.multiple&&this.multiplayer.allowDrag(E))&&this.multiplayer.onDrag(this.el,this),g(E)),r=f(E,this.el),r=(A={sortable:this,group:o,node:E,rect:i,offset:r},j.group=o,j.sortable=this,P.distance={x:e.clientX-i.left,y:e.clientY-i.top},p(document,"touchend",this._onDrop),p(document,"touchcancel",this._onDrop),p(document,"mouseup",this._onDrop),this.options),o=r.delay,e=r.delayOnTouchOnly;if(!o||e&&!t||L||d)this._onStart(t);else{for(var a=0;a<c.end.length;a++)p(this.ownerDocument,c.end[a],this._cancelStart);for(var s=0;s<c.move.length;s++)p(this.ownerDocument,c.move[s],this._delayMoveHandler);$=setTimeout(function(){return n._onStart(t)},o)}},_delayMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-O.clientX),Math.abs(t.clientY-O.clientY))>=Math.floor(this.options.touchStartThreshold/(window.devicePixelRatio||1))&&this._cancelStart()},_cancelStart:function(){clearTimeout($);for(var t=0;t<c.end.length;t++)n(this.ownerDocument,c.end[t],this._cancelStart);for(var e=0;e<c.move.length;e++)n(this.ownerDocument,c.move[e],this._delayMoveHandler)},_onStart:function(t){N=this.el,p(document,t?"touchmove":"mousemove",this._nearestSortable);try{document.selection?setTimeout(function(){document.selection.empty()},0):window.getSelection().removeAllRanges()}catch(t){}},_onTrulyStarted:function(){var t;T||(this._dispatchEvent("onDrag",l(l({},r()),{},{event:O})),C&&this.multiplayer.onTrulyStarted(E,this),t=C?this.multiplayer.getHelper():E,P.init(A.rect,t,this.el,this.options),B.helper=P.node,y(E,!1),E.parentNode.insertBefore(D,E),z(D,this.options.chosenClass,!0),a&&v(document.body,"user-select","none"))},_nearestSortable:function(t){var e,n,o,i,r,a,s;this._preventEvent(t),!O||!E||(e=(n=t).clientX,n=n.clientY,o=e-X.x,i=n-X.y,X.x=e,X.y=n,void 0!==e&&void 0!==n&&Math.abs(o)<=0&&Math.abs(i)<=0)||(n=(e=I(t)).event,o=e.target,r=n.clientX,a=n.clientY,M.some(function(t){var e,n,o=t[b].options.emptyInsertThreshold;if(o)return n=g(t,{parent:!0}),e=r>=n.left-o&&r<=n.right+o,n=a>=n.top-o&&a<=n.bottom+o,e&&n?s=t:void 0}),i=s,this._onTrulyStarted(),T=n,P.move(n.clientX-O.clientX,n.clientY-O.clientY),this._autoScroll(o),i&&i[b]._onMove(n,o))},_allowPut:function(){var t,e;return O.sortable.el===this.el||!!this.options.group.put&&(t=this.options.group.name,(e=O.sortable.options.group).name)&&t&&e.name===t},_onMove:function(t,e){if(this._allowPut()){if(this._dispatchEvent("onMove",l(l({},r()),{},{event:t})),N=this.el,x=s(e,this.options.draggable,N,!1)){if(x===Q)return;if((Q=x)===D)return;if(x.animated||W(x,D))return}N!==A.sortable.el?e!==N&&function(t,e,n){for(var o=t.lastElementChild;o&&(o===e||"none"===v(o,"display")||n&&!q(o,n));)o=o.previousElementSibling;return o}(N,P.node)?x&&this._onInsert(t,!1):this._onInsert(t,!0):x&&this._onChange(t)}},_autoScroll:function(t){var t=function(t,e){if(t&&t.getBoundingClientRect){var n=t,o=!1;do{if(n.clientWidth<n.scrollWidth||n.clientHeight<n.scrollHeight){var i=v(n);if(n.clientWidth<n.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||n.clientHeight<n.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!n.getBoundingClientRect||n===document.body)return m();if(o||e)return n;o=!0}}}while(n=n.parentNode)}return m()}(t,!0),e=this.options,n=e.autoScroll,e=e.scrollThreshold;n&&et.update(t,e,O,T)},_onInsert:function(t,e){var n=e?D:x,o=e?N:x.parentNode;A.sortable.animator.collect(D,null,D.parentNode,D),this.animator.collect(null,n,o,D),C&&this.multiplayer.onChange(D,this),j={sortable:this,group:o,node:n,rect:g(n),offset:f(n,N)},A.sortable._dispatchEvent("onRemove",l(l({},r()),{},{event:t})),e?o.appendChild(D):o.insertBefore(D,x),this._dispatchEvent("onAdd",l(l({},r()),{},{event:t})),A.sortable.animator.animate(),this.animator.animate(),A.group=o,A.sortable=this},_onChange:function(t){var e=x.parentNode,t=(this.animator.collect(D,x,e),C&&this.multiplayer.onChange(D,this),j={sortable:this,group:e,node:x,rect:g(x),offset:f(x,N)},this._dispatchEvent("onChange",l(l({},r()),{},{event:t})),f(D,N)),n=null,n=t.top===j.offset.top?t.left<j.offset.left?x.nextSibling:x:t.top<j.offset.top?x.nextSibling:x;e.insertBefore(D,n),this.animator.animate(),A.group=e,A.sortable=this},_onDrop:function(t){this._unbindMoveEvents(),this._unbindDropEvents(),this._preventEvent(t),this._cancelStart(),et.clear(),E&&O&&T?this._onEnd(t):this.options.multiple&&this.multiplayer.select(t,E,N,l({},A)),this._clearState()},_onEnd:function(t){var e,n;this.options.swapOnDrop&&D.parentNode.insertBefore(E,D),A.group=O.group,A.sortable=O.sortable,j.rect=g(D),j.offset=f(D,N),C?this.multiplayer.onDrop(t,E,N,O,r):(j.node===D&&(j.node=E),n=(e=U(A,j))||V(A.offset,j.offset),n=l(l({},r()),{},{changed:n,event:t}),e&&A.sortable._dispatchEvent("onDrop",n),j.sortable._dispatchEvent("onDrop",n)),y(E,!0),D.parentNode.removeChild(D),a&&v(document.body,"user-select","")},_preventEvent:function(t){void 0!==t.preventDefault&&t.cancelable&&t.preventDefault(),this.options.stopPropagation&&(t&&t.stopPropagation?t.stopPropagation():window.event.cancelBubble=!0)},_dispatchEvent:function(t,e){t=this.options[t];"function"==typeof t&&t(e)},_clearState:function(){E=x=D=O=T=C=Q=$=B.helper=null,X={x:0,y:0},A=j=l({},tt),P.destroy()},_unbindMoveEvents:function(){for(var t=0;t<c.move.length;t++)n(document,c.move[t],this._nearestSortable)},_unbindDropEvents:function(){for(var t=0;t<c.end.length;t++)n(document,c.end[t],this._onDrop)}}).utils={on:p,off:n,css:v,closest:s,getRect:g,getOffset:f},B.get=function(t){return t[b]},B.create=function(t,e){return new B(t,e)},B}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function j(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function l(o){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?j(Object(i),!0).forEach(function(t){var e,n;e=o,n=i[t=t],(t=function(t){t=function(t,e){if("object"!=typeof t||null===t)return t;var n=t[Symbol.toPrimitive];if(void 0===n)return("string"===e?String:Number)(t);n=n.call(t,e||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}(t,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(i)):j(Object(i)).forEach(function(t){Object.defineProperty(o,t,Object.getOwnPropertyDescriptor(i,t))})}return o}function R(t){return(R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var H={capture:!1,passive:!1},L=/\s+/g,i={start:["touchstart","mousedown"],move:["touchmove","mousemove"],end:["touchend","touchcancel","mouseup"]};function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var e,m=t(/(?:Trident.*rv[ :]?11\.|msie|iemobile|Windows Phone)/i),B=t(/Edge/i),r=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),k=(e=!1,document.addEventListener("checkIfSupportPassive",null,{get passive(){return e=!0}}),e),F="undefined"==typeof window||"undefined"==typeof document?{}:(o=window.getComputedStyle(document.documentElement,"")||["-moz-hidden-iframe"],o=(Array.prototype.slice.call(o).join("").match(/-(moz|webkit|ms)-/)||""===o.OLink&&["","o"])[1],{dom:"WebKit|Moz|MS|O".match(new RegExp("("+o+")","i"))[1],lowercase:o,css:"-"+o+"-",js:o[0].toUpperCase()+o.substr(1)});function W(t,e){t.style["".concat(F.css,"transition-duration")]=null==e?"":"".concat(e,"ms")}function c(t,e){t.style["".concat(F.css,"transform")]=e?"".concat(e):""}function a(t,e,n){window.addEventListener?t.addEventListener(e,n,!(!k&&m)&&H):window.attachEvent?t.attachEvent("on"+e,n):t["on"+e]=n}function n(t,e,n){window.removeEventListener?t.removeEventListener(e,n,!(!k&&m)&&H):window.detachEvent?t.detachEvent("on"+e,n):t["on"+e]=null}function z(t){var e=t,n=t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0],t=n?document.elementFromPoint(n.clientX,n.clientY):t.target;return!n||"clientX"in e||(e.clientX=n.clientX,e.clientY=n.clientY,e.pageX=n.pageX,e.pageY=n.pageY,e.screenX=n.screenX,e.screenY=n.screenY),{touch:n,event:e,target:t}}function s(t,e){for(var n={top:0,left:0,height:t.offsetHeight,width:t.offsetWidth};n.top+=t.offsetTop,n.left+=t.offsetLeft,(t=t.parentNode)&&t!==e;);return n}function q(){return document.scrollingElement||document.documentElement}function g(t,e,n){var o,i,r,a,s,l,c,h=1<arguments.length&&void 0!==e?e:{},u=2<arguments.length?n:void 0;if(t.getBoundingClientRect||t===window){if(t!==window&&t.parentNode&&t!==q()){if(i=(o=t.getBoundingClientRect()).top,r=o.left,a=o.bottom,s=o.right,l=o.height,c=o.width,h.parent&&t.parentNode!==t.ownerDocument.body)for(var d,p=t.parentNode;p&&p.getBoundingClientRect&&p!==t.ownerDocument.body;){if((d=p.getBoundingClientRect()).height<l)return i=d.top,r=d.left,a=d.bottom,s=d.right,l=d.height,{top:i,left:r,bottom:a,right:s,width:c=d.width,height:l};p=p.parentNode}}else r=i=0,a=window.innerHeight,s=window.innerWidth,l=window.innerHeight,c=window.innerWidth;if((h.block||h.relative)&&t!==window&&(u=u||t.parentNode,!m))do{if(u&&u.getBoundingClientRect&&("none"!==v(u,"transform")||h.relative&&"static"!==v(u,"position"))){var f=u.getBoundingClientRect();i-=f.top+parseInt(v(u,"border-top-width")),r-=f.left+parseInt(v(u,"border-left-width")),a=i+o.height,s=r+o.width;break}}while(u=u.parentNode);return{top:i,left:r,bottom:a,right:s,width:c,height:l}}}function h(t,e,n,o){if(t){n=n||document;do{if(null==e){var i=Array.prototype.slice.call(n.children),r=i.indexOf(t);if(-1<r)return i[r];for(var a=0;a<i.length;a++)if(G(t,i[a]))return i[a]}else if((">"!==e[0]||t.parentNode===n)&&d(t,e)||o&&t===n)return t}while(t=t.parentNode)}return null}function G(t,e){if(t&&e){if(e.compareDocumentPosition)return e===t||16&e.compareDocumentPosition(t);if(e.contains&&1===t.nodeType)return e.contains(t)&&e!==t;for(;t=t.parentNode;)if(t===e)return 1}}function U(t,e,n,o){for(var i=0,r=0,a=t.children;i<a.length;){if(a[i]!==A.ghost&&"none"!==v(a[i],"display")&&h(a[i],n,t,!1)&&(o||a[i]!==A.dragged)){if(r===e)return a[i];r++}i++}return null}function V(t,e){var n,o=v(t),i=parseInt(o.width)-parseInt(o.paddingLeft)-parseInt(o.paddingRight)-parseInt(o.borderLeftWidth)-parseInt(o.borderRightWidth),r=U(t,0,e),t=U(t,1,e),e=r&&v(r),a=t&&v(t),s=e&&parseInt(e.marginLeft)+parseInt(e.marginRight)+g(r).width,l=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+g(t).width,c=B||m?"cssFloat":"float";return"flex"===o.display?"column"===o.flexDirection||"column-reverse"===o.flexDirection?"vertical":"horizontal":"grid"===o.display?o.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal":r&&e.float&&"none"!==e.float?(n="left"===e.float?"left":"right",!t||"both"!==a.clear&&a.clear!==n?"horizontal":"vertical"):r&&("block"===e.display||"flex"===e.display||"table"===e.display||"grid"===e.display||i<=s&&"none"===o[c]||t&&"none"===o[c]&&i<s+l)?"vertical":"horizontal"}function u(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(L," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(L," ")))}function d(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function v(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=e in o||-1!==e.indexOf("webkit")?e:"-webkit-"+e]=n+("string"==typeof n?"":"px")}}function K(t,e){function n(t,e,n){return t===e||e-n<=t&&t<=e+n}var o=Math.abs(t.width-e.width),i=Math.abs(t.height-e.height),o=!n(t.left,e.left,o),t=!n(t.top,e.top,i);return o||t}function Z(t,e){e=e;t=(t=t).compareDocumentPosition?t.compareDocumentPosition(e):t.contains?(t!=e&&t.contains(e)&&16)+(t!=e&&e.contains(t)&&8)+(0<=t.sourceIndex&&0<=e.sourceIndex?(t.sourceIndex<e.sourceIndex&&4)+(t.sourceIndex>e.sourceIndex&&2):1)+0:0;return 2===t?1:4===t?-1:0}function J(t){void 0!==t.preventDefault&&t.cancelable&&t.preventDefault()}function Q(t){this.options=t,this.autoScrollAnimationFrame=null}function $(t){this.options=t,this.animations=[]}window.requestAnimationFrame||(window.requestAnimationFrame=function(t){return setTimeout(t,17)}),window.cancelAnimationFrame||(window.cancelAnimationFrame=function(t){clearTimeout(t)}),Q.prototype={clear:function(){null!=this.autoScrollAnimationFrame&&(cancelAnimationFrame(this.autoScrollAnimationFrame),this.autoScrollAnimationFrame=null)},update:function(t,e,n){var o=this;cancelAnimationFrame(this.autoScrollAnimationFrame),this.autoScrollAnimationFrame=requestAnimationFrame(function(){e&&n&&o.autoScroll(t,n),o.update(t,e,n)})},autoScroll:function(t,e){var n,o,i,r,a,s,l,c,h,u,d,p,f;t&&void 0!==e.clientX&&void 0!==e.clientY&&(u=g(t))&&(n=e.clientX,e=e.clientY,o=u.top,i=u.right,r=u.bottom,a=u.left,p=u.height,u=u.width,e<o||i<n||r<e||n<a||(s=(l=this.options).scrollThreshold,l=l.scrollSpeed,d=t.scrollTop,c=t.scrollLeft,f=t.scrollHeight,h=0<d&&o<=e&&e<=o+s,u=c+u<t.scrollWidth&&n<=i&&i-s<=n,d=d+p<f&&e<=r&&r-s<=e,(f=p=0)<c&&a<=n&&n<=a+s&&(p=Math.floor(Math.max(-1,(n-a)/s-1)*l.x)),u&&(p=Math.ceil(Math.min(1,(n-i)/s+1)*l.x)),h&&(f=Math.floor(Math.max(-1,(e-o)/s-1)*l.y)),(f=d?Math.ceil(Math.min(1,(e-r)/s+1)*l.y):f)&&(t.scrollTop+=f),p&&(t.scrollLeft+=p)))}},$.prototype={collect:function(t,e,n,o){if(n){var i=Array.prototype.slice.call(n.children),n=this._getRange(i,t,e),t=n.start,r=n.end;this.animations.length=0;for(var a=t;a<=r;a++){var s=i[a];s&&"none"!==v(s,"display")&&s!==o&&s!==A.ghost&&this.animations.push({node:s,rect:g(s)})}}},animate:function(){for(var t=0,e=this.animations.length;t<e;t++){var n=this.animations[t],o=n.node,n=n.rect;this._excute(o,n)}},_excute:function(t,e){var n=e.left,e=e.top,o=g(t),e=e-o.top,n=n-o.left,o=(W(t),c(t,"translate3d(".concat(n,"px, ").concat(e,"px, 0)")),t.offsetWidth,this.options.animation);W(t,o),c(t,"translate3d(0px, 0px, 0px)"),clearTimeout(t.animated),t.animated=setTimeout(function(){W(t),c(t,""),t.animated=null},o)},_getRange:function(t,e,n){var o,e=t.indexOf(e),n=t.indexOf(n);return n<e&&(e=(o=[n,e])[0],n=o[1]),e<0&&(e=n,n=t.length-1),{start:e,end:n=n<0?t.length-1:n}}};var o={sortable:null,nodes:[]},p=l({},o),f=l({},o),y={},tt=function(){return Number(Math.random().toString().slice(-3)+Date.now()).toString(32)};function et(t){this.active=!1,this.options=t||{},this.groupName=t.group.name||"group_"+tt()}function nt(){this.helper=null,this.distance={x:0,y:0}}et.prototype={select:function(t){u(t,this.options.selectedClass,!0),y[this.groupName].push(t),y[this.groupName].sort(Z)},deselect:function(t){var e=y[this.groupName].indexOf(t);-1<e&&(u(t,this.options.selectedClass,!1),y[this.groupName].splice(e,1))},getSelectedElements:function(){return y[this.groupName]||[]},getEmits:function(){var t={from:{},to:{}};return this.active&&(t.from=l({},p),t.to=l({},f)),t},getHelper:function(){var n;return this.active?(n=document.createElement("div"),y[this.groupName].forEach(function(t,e){t=t.cloneNode(!0);t.style="\n opacity: ".concat(0===e?1:.5,";\n position: absolute;\n z-index: ").concat(e,";\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n "),n.appendChild(t)}),n):null},getOnEndParams:function(){return this.active?{changed:p.sortable.el!==f.sortable.el||this._offsetChanged(p.nodes,f.nodes)}:{}},onDrag:function(e,t){this.active=this._isActive(),this.active&&(p.sortable=t,p.nodes=y[this.groupName].map(function(t){return{node:t,rect:g(t),offset:s(t,e)}}),f.sortable=t)},onStarted:function(t){var e;this.active&&(t.animator.collect(e=A.dragged,null,e.parentNode),y[this.groupName].forEach(function(t){t!=e&&v(t,"display","none")}),t.animator.animate())},onChange:function(t,e){var n,o;this.active&&(n=g(t),o=s(t,e.el),f.sortable=e,f.nodes=y[this.groupName].map(function(t){return{node:t,rect:n,offset:o}}))},onDrop:function(t,e,n){var o,i;A.dragged&&this._isMouseClick(t,e)&&(t=A.dragged,i=this.options.selectHandle,o=z(e).target,"function"==typeof i&&!i(e)||"string"==typeof i&&!d(o,i)||(y[this.groupName]||(y[this.groupName]=[]),o=y[this.groupName].indexOf(t),u(t,this.options.selectedClass,o<0),i=l(l({},n),{},{event:e}),o<0?(y[this.groupName].push(t),n.sortable._dispatchEvent("onSelect",i,!1)):(y[this.groupName].splice(o,1),n.sortable._dispatchEvent("onDeselect",i,!1)),y[this.groupName].sort(Z)))},onEnd:function(e,t){var n,o,i=this;this.active&&(n=A.dragged,f.sortable.animator.collect(n,null,n.parentNode),o=y[this.groupName].indexOf(n),y[this.groupName].forEach(function(t,e){v(t,"display",""),e<o?n.parentNode.insertBefore(t,n):(e=0<e?y[i.groupName][e-1]:n,n.parentNode.insertBefore(t,e.nextSibling))}),p.sortable=t.sortable,f.nodes=y[this.groupName].map(function(t){return{node:t,rect:g(t),offset:s(t,e)}}),f.sortable.animator.animate())},_isActive:function(){return this.options.multiple&&y[this.groupName]&&y[this.groupName].length&&-1<y[this.groupName].indexOf(A.dragged)},_isMouseClick:function(t,e){var n=e.clientX-t.clientX,e=e.clientY-t.clientY,t=Math.sqrt(n*n+e*e);return 0<=t&&t<=1},_offsetChanged:function(t,n){return!!t.find(function(e){var t=n.find(function(t){return t.node===e.node});return K(e.offset,t.offset)})}},nt.prototype={get node(){return this.helper},destroy:function(){this.helper&&this.helper.parentNode&&this.helper.parentNode.removeChild(this.helper),this.helper=null,this.distance={x:0,y:0}},move:function(t,e){this.helper&&c(this.helper,"translate3d(".concat(t,"px, ").concat(e,"px, 0)"))},init:function(t,e,n,o){if(!this.helper){var i,r=o.fallbackOnBody,a=o.ghostClass,o=o.ghostStyle,r=r?document.body:n,s=(this.helper=e.cloneNode(!0),u(this.helper,a,!0),l({position:"fixed",top:t.top,left:t.left,width:t.width,height:t.height,minWidth:t.width,minHeight:t.height,opacity:"0.8",overflow:"hidden","z-index":"100000","box-sizing":"border-box","pointer-events":"none"},o));for(i in s)v(this.helper,i,s[i]);n=this.helper,e="none",n.style["".concat(F.css,"transition")]=e?"none"===e?"none":"".concat(e):"",c(this.helper,"translate3d(0px, 0px, 0px)"),r.appendChild(this.helper);a=this.distance.x/parseInt(this.helper.style.width)*100,t=this.distance.y/parseInt(this.helper.style.height)*100;v(this.helper,"transform-origin","".concat(a,"% ").concat(t,"%")),v(this.helper,"transform","translateZ(0)"),v(this.helper,"will-change","transform")}}};var b,w,S,ot,_,E,x,N,C,O,D,it,M="Sortable"+Date.now(),rt={sortable:null,group:null,node:null,rect:{},offset:{}},T=[],I=new nt,P=l({},rt),X=l({},rt),Y={x:0,y:0},at=function(t){var e={},n=t.group;n&&"object"==R(n)||(n={name:n,pull:!0,put:!0}),e.name=n.name,e.pull=n.pull,e.put=n.put,t.group=e};function A(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable-dnd: `el` must be an HTMLElement, not ".concat({}.toString.call(t));(t[M]=this).el=t,this.options=e=Object.assign({},e);var n,o,i={disabled:!1,group:"",animation:150,draggable:null,handle:null,multiple:!1,selectHandle:null,customGhost:null,direction:function(){return V(t,e.draggable)},autoScroll:!0,scrollThreshold:55,scrollSpeed:{x:10,y:10},delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,ghostClass:"",ghostStyle:{},chosenClass:"",selectedClass:"",swapOnDrop:!0,fallbackOnBody:!1,supportTouch:"ontouchstart"in window,emptyInsertThreshold:5};for(n in i)n in this.options||(this.options[n]=i[n]);for(o in at(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));var r=this.options.supportTouch;a(t,r?"touchstart":"mousedown",this._onDrag),T.push(t),this.autoScroller=new Q(this.options),this.multiplayer=new et(this.options),this.animator=new $(this.options)}return A.prototype={constructor:A,destroy:function(){var e=this;this._dispatchEvent("onDestroy",{sortable:this},!1),i.start.forEach(function(t){return n(e.el,t,e._onDrag)}),T.splice(T.indexOf(this.el),1),this._clearState(),this.el[M]=this.animator=this.multiplayer=this.autoScroller=null},option:function(t,e){if(void 0===e)return this.options[t];this.options[t]=e,this.animator.options[t]=e,this.multiplayer.options[t]=e,this.autoScroller.options[t]=e,"group"===t&&at(this.options)},select:function(t){this.multiplayer.select(t)},deselect:function(t){this.multiplayer.deselect(t)},getSelectedElements:function(){return this.multiplayer.getSelectedElements()},_onDrag:function(t){var e,n,o,i;this.options.disabled||!this.options.group.pull||/mousedown|pointerdown/.test(t.type)&&0!==t.button||(e=(t=z(t)).touch,n=t.event,(t=t.target)===this.el)||r&&t&&"SELECT"===t.tagName.toUpperCase()||(w=h(t,this.options.draggable,this.el))&&!w.animated&&(O=e?w:document,_=w.cloneNode(!0),E=w.parentNode,A.dragged=w,((x=n).sortable=this).multiplayer.onDrag(this.el,this),o=g(w),i=s(w,this.el),P={sortable:this,node:w,rect:o,offset:i},X.node=w,X.sortable=this,Y={x:n.clientX,y:n.clientY},I.distance={x:n.clientX-o.left,y:n.clientY-o.top},a(O,"touchend",this._onDrop),a(O,"touchcancel",this._onDrop),a(O,"mouseup",this._onDrop),"function"!=typeof(i=this.options.handle)||i(n))&&("string"!=typeof i||d(t,i))&&this._prepareStart(e)},_prepareStart:function(t){var e=this,n=this.options,o=n.delay,n=n.delayOnTouchOnly;!o||n&&!t||B||m?this._onStart(t):(i.move.forEach(function(t){return a(e.el.ownerDocument,t,e._delayMoveHandler)}),i.end.forEach(function(t){return a(e.el.ownerDocument,t,e._cancelStart)}),it=setTimeout(function(){return e._onStart(t)},o))},_delayMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-x.clientX),Math.abs(t.clientY-x.clientY))>=Math.floor(this.options.touchStartThreshold/(window.devicePixelRatio||1))&&this._cancelStart()},_cancelStart:function(){var e=this;clearTimeout(it),i.move.forEach(function(t){return n(e.el.ownerDocument,t,e._delayMoveHandler)}),i.end.forEach(function(t){return n(e.el.ownerDocument,t,e._cancelStart)})},_onStart:function(t){b=this.el,a(O,t?"touchmove":"mousemove",this._nearestSortable);try{document.selection?setTimeout(function(){return document.selection.empty()},0):window.getSelection().removeAllRanges()}catch(t){}},_onStarted:function(){(A.active=this)._dispatchEvent("onDrag",{event:x}),this.multiplayer.onStarted(this);var t=this._getGhostElement();I.init(P.rect,t,this.el,this.options),A.ghost=I.node,v(w,"display","none"),w.parentNode.insertBefore(_,w),u(_,this.options.chosenClass,!0),r&&v(document.body,"user-select","none")},_getGhostElement:function(){var t=this.options.customGhost;return"function"==typeof t?t((t=this.multiplayer.getSelectedElements()).length?t:[w]):this.multiplayer.getHelper()||w},_nearestSortable:function(t){var e,n,o,i,r,a,s;J(t),!x||!w||(n=(o=t).clientX,o=o.clientY,i=n-Y.x,e=o-Y.y,Y.x=n,Y.y=o,void 0!==n&&void 0!==o&&Math.abs(i)<=0&&Math.abs(e)<=0)||(N||this._onStarted(),o=(n=z(t)).event,i=n.target,N=o,I.move(o.clientX-x.clientX,o.clientY-x.clientY),this._autoScroll(i),r=o.clientX,a=o.clientY,T.some(function(t){var e,n,o=t[M].options.emptyInsertThreshold;if(o)return n=g(t,{parent:!0}),e=r>=n.left-o&&r<=n.right+o,n=a>=n.top-o&&a<=n.bottom+o,e&&n?s=t:void 0}),s&&s[M]._onMove(o,i))},_autoScroll:function(t){this.options.autoScroll&&(t=function(t,e){if(t&&t.getBoundingClientRect){var n=t,o=!1;do{if(n.clientWidth<n.scrollWidth||n.clientHeight<n.scrollHeight){var i=v(n);if(n.clientWidth<n.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||n.clientHeight<n.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!n.getBoundingClientRect||n===document.body)return q();if(o||e)return n;o=!0}}}while(n=n.parentNode)}return q()}(t,!0),this.autoScroller.update(t,x,N))},_allowPut:function(){var t,e;return x.sortable.el===this.el||!!this.options.group.put&&(t=this.options.group.name,(e=x.sortable.options.group).name)&&t&&e.name===t},_allowSwap:function(){var t,e,n,o,i=Z(_,S);return ot=i<0?S.nextSibling:S,C!==S?!(D=0):(t=g(S),o=(e="vertical"===(n="function"==typeof this.options.direction?this.options.direction.call(N,w,this):this.options.direction))?N.clientY:N.clientX,n=S["vertical"===n?"offsetHeight":"offsetWidth"],o=o>=(e?t.top:t.left)&&o<(e?t.bottom:t.right)-n/2?-1:1,D!==o&&((D=o)<0?0<i:i<0))},_onMove:function(t,e){var n,o,i;this._allowPut()&&(this._dispatchEvent("onMove",{event:t}),b=this.el,S=h(e,this.options.draggable,b),b===P.sortable.el||e!==b&&function(t,e){for(var n=t.lastElementChild;n&&(n===A.ghost||"none"===v(n,"display")||e&&!d(n,e));)n=n.previousElementSibling;return n}(b)?S&&!S.animated&&S!==_&&S!==w&&this._allowSwap()&&!G(S,_)&&(b!==P.sortable.el?this._onInsert(t,!1):(n=t,o=E,i=i||g(o),n.clientX<=i.right&&n.clientX>=i.left&&n.clientY>=i.top&&n.clientY<=i.bottom&&e===E||this._onChange(t)),C=S):(C=null,this._onInsert(t,!0)))},_onInsert:function(t,e){var n=e?_:S;E=e?b:S.parentNode,P.sortable.animator.collect(_,null,_.parentNode,_),this.animator.collect(null,n,E,_),this.multiplayer.onChange(_,this),X={sortable:this,node:n,rect:g(n),offset:s(n,b)},P.sortable._dispatchEvent("onRemove",{event:t}),e?E.appendChild(_):E.insertBefore(_,S),this._dispatchEvent("onAdd",{event:t}),P.sortable.animator.animate(),this.animator.animate(),P.sortable=this},_onChange:function(t){E=S.parentNode,this.animator.collect(_,S,E),this.multiplayer.onChange(_,this),X={sortable:this,node:S,rect:g(S),offset:s(S,b)},this._dispatchEvent("onChange",{event:t}),E.insertBefore(_,ot),this.animator.animate(),P.sortable=this},_onDrop:function(t){J(t),this._cancelStart(),this._unbindEvents(),this.autoScroller.clear(),w&&x&&N?this._onEnd(t):this.options.multiple&&this.multiplayer.onDrop(x,t,l({},P)),this._clearState()},_onEnd:function(t){this.options.swapOnDrop&&E.insertBefore(w,_),P.sortable=x.sortable,X.rect=g(_),X.offset=s(_,b),X.node===_&&(X.node=w),this.multiplayer.onEnd(b,x);var e=this.multiplayer.getOnEndParams(),n=P.sortable.el!==X.sortable.el,t=l({changed:n||K(P.offset,X.offset),event:t},e);n&&P.sortable._dispatchEvent("onDrop",t),X.sortable._dispatchEvent("onDrop",t),v(w,"display",""),E.removeChild(_),r&&v(document.body,"user-select","")},_dispatchEvent:function(t){var e,n,o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},t=this.options[t];"function"==typeof t&&(n={},2<arguments.length&&void 0!==arguments[2]&&!arguments[2]||(n={from:l(l({},(e=this.multiplayer.getEmits()).from),P),to:l(l({},e.to),X)}),t(l(l({},n),o)))},_clearState:function(){w=S=ot=_=E=x=N=C=O=D=it=A.ghost=A.active=A.dragged=null,Y={x:0,y:0},P=X=l({},rt),I.destroy()},_unbindEvents:function(){var e=this;i.move.forEach(function(t){return n(O,t,e._nearestSortable)}),i.end.forEach(function(t){return n(O,t,e._onDrop)})}},A.utils={on:a,off:n,css:v,index:function(t,e){var n=0;if(!t||!t.parentNode)return-1;for(;t=t.previousElementSibling;)"TEMPLATE"===t.nodeName.toUpperCase()||e&&!d(t,e)||"none"===v(t,"display")||n++;return n},closest:h,getOffset:s,toggleClass:u,detectDirection:V},A.get=function(t){return t[M]},A.create=function(t,e){return new A(t,e)},A}); |
{ | ||
"name": "sortable-dnd", | ||
"version": "0.5.4", | ||
"version": "0.5.5", | ||
"description": "JS library for drag-and-drop lists, supports sortable and draggable", | ||
@@ -5,0 +5,0 @@ "main": "dist/sortable-dnd.min.js", |
195
README.md
@@ -0,7 +1,8 @@ | ||
# sortable-dnd | ||
[![npm](https://img.shields.io/npm/v/sortable-dnd.svg)](https://www.npmjs.com/package/sortable-dnd) [![npm](https://img.shields.io/npm/dm/sortable-dnd.svg)](https://npm-stat.com/charts.html?package=sortable-dnd) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE) | ||
A JS Library for Drag and Drop, supports Sortable-Draggable and Virtual-List | ||
A JS Library for Drag and Drop, supports Sortable and Draggable | ||
### [Live Demo](https://mfuu.github.io/sortable-dnd/) | ||
@@ -11,2 +12,7 @@ | ||
**Install** | ||
```node | ||
npm install sortable-dnd --save | ||
``` | ||
**HTML** | ||
@@ -34,39 +40,12 @@ ```html | ||
var DND = new Sortable( | ||
let sortable = new Sortable( | ||
document.getElementById('group'), | ||
{ | ||
chosenClass: 'chosen', | ||
draggable: (e) => e.target.tagName === 'LI' ? true : false, // use function | ||
// draggable: 'li' // use tagName | ||
// draggable: '.item' // use class | ||
// draggable: '#item' // use id | ||
// draggable: (e) => e.target // use function to set drag Element | ||
handle: (e) => e.target.tagName === 'I' ? true : false, // use function | ||
// draggable: 'li', // use tagName | ||
// draggable: '#item', // use id | ||
draggable: '.item', // use class | ||
// handle: 'I', // use tagName | ||
// handle: '.handle', // use class | ||
// handle: '#handle', // use id | ||
onDrag: ({ from, event }) => { | ||
// code | ||
}, | ||
onMove: ({ from, event }) => { | ||
// code | ||
}, | ||
onDrop: ({ from, to, changed, event }) => { | ||
// code | ||
}, | ||
onAdd: ({ from, to, event }) => { | ||
// code | ||
}, | ||
onRemove: ({ from, to, event }) => { | ||
// code | ||
}, | ||
onChange: ({ from, to, event }) => { | ||
// code | ||
}, | ||
onSelect: (params) => { | ||
// code | ||
}, | ||
onDeselect: (params) => { | ||
// code | ||
} | ||
// handle: (e) => e.target.tagName === 'I' ? true : false, // use function | ||
handle: '.handle', // use class | ||
} | ||
@@ -76,46 +55,120 @@ ) | ||
## Options | ||
```js | ||
new Sortable(element, { | ||
draggable: '', // Specifies which items inside the element should be draggable | ||
handle: '', // Drag handle selector within list items | ||
group: '', // string: 'name' or object: `{ name: 'group', put: true/false, pull: true/false }` | ||
multiple: false, // Enable multiple drag | ||
selectHandle: '', // Handle selector within list items which used to select element in `multiple: true` | ||
animation: 150, // Animation speed moving items when sorting | ||
chosenClass: '', // Class name for the dragging item | ||
selectedClass: '', // The class of the element when it is selected, it is usually used when multiple drag | ||
ghostStyle: {}, // The style of the mask element when dragging | ||
ghostClass: '', // The class of the mask element when dragging | ||
disabled: false, // Disables the sortable if set to true | ||
autoScroll: true, // Automatic scrolling when moving to the edge of the container | ||
scrollThreshold: 55, // Threshold to trigger autoscroll | ||
scrollSpeed: { x: 10, y: 10 }, // Vertical&Horizontal scrolling speed (px) | ||
delay: 0, // Time in milliseconds to define when the sorting should start | ||
delayOnTouchOnly: false, // Only delay if user is using touch | ||
fallbackOnBody: false, // Appends the ghost element into the document's body | ||
swapOnDrop: true, // When the value is false, the dragged element will return to the starting position of the drag | ||
customGhost: (nodes) => { | ||
// Customize the ghost element in drag, must return an HTMLElement | ||
}, | ||
// callback functions | ||
onDrag: ({ from, event }) => { | ||
// Triggered when drag is started | ||
}, | ||
onMove: ({ from, event }) => { | ||
// Triggered when the dragged element is moving | ||
}, | ||
onDrop: ({ from, to, changed, event }) => { | ||
// Triggered when drag is completed | ||
}, | ||
onAdd: ({ from, to, event }) => { | ||
// Triggered when the element is dropped into the list from another | ||
}, | ||
onRemove: ({ from, to, event }) => { | ||
// Triggered when the element is removed from the list into another | ||
}, | ||
onChange: ({ from, to, event }) => { | ||
// Triggered when the dragged element changes position in the list | ||
}, | ||
onSelect: (params) => { | ||
// Triggered when an element is selected by clicking the mouse | ||
}, | ||
onDeselect: (params) => { | ||
// Triggered when an element is unselected by clicking the mouse | ||
}, | ||
}) | ||
``` | ||
## Methods | ||
| **Method** | **Description** | | ||
|--------------|--------------| | ||
| `destroy()` | Manually clear all the state of the component, using this method the component will not be draggable | | ||
| `option(key, value?)` | Get or set the option value, depending on whether the `value` is passed in | | ||
```js | ||
let sortable = new Sortable(el); | ||
// Manually clear all the state of the component, using this method the component will not be draggable | ||
sortable.destroy(); | ||
## Options | ||
// Get or set the option value, depending on whether the `value` is passed in | ||
sortable.option(key, value?); | ||
**Common used** | ||
// Selects the provided multi-drag item | ||
sortable.select(element); | ||
| **Option** | **Type** | **Default** | **Description** | | ||
|-------------------|-------------------|-------------|--------------| | ||
| `draggable` | `String/Function` | `-` | Specifies which items inside the element should be draggable | | ||
| `handle` | `String/Funnction`| `-` | Drag handle selector within list items | | ||
| `group` | `String/Object` | `-` | string: 'name' or object: `{ name: 'group', put: true/false, pull: true/false }` | | ||
| `multiple` | `Boolean` | `false` | Enable multiple drag | | ||
| `animation` | `Number` | `150` | Animation speed moving items when sorting | | ||
| `onDrag` | `Function` | `-` | The callback function when the drag is started | | ||
| `onMove` | `Function` | `-` | The callback function when the dragged element is moving | | ||
| `onDrop` | `Function` | `-` | The callback function when the drag is completed | | ||
| `onAdd` | `Function` | `-` | The callback function when element is dropped into the list from another list | | ||
| `onRemove` | `Function` | `-` | The callback function when element is removed from the list into another list | | ||
| `onChange` | `Function` | `-` | The callback function when the dragged element changes position in the list | | ||
| `onSelect` | `Function` | `-` | The callback function when element is selected | | ||
| `onDeselect` | `Function` | `-` | The callback function when element is unselected | | ||
// Deselects the provided multi-drag item | ||
sortable.deselect(element); | ||
// Get the selected elements in the list, the return value is available in the case of `multiple` | ||
sortable.getSelectedElements(); | ||
``` | ||
**Others** | ||
## Static Methods & Properties | ||
| **Option** | **Type** | **Default** | **Description** | | ||
|-------------------|-------------------|-------------|--------------| | ||
| `disabled` | `Boolean` | `false` | Disables the sortable if set to true | | ||
| `chosenClass` | `String` | `''` | Class name for the dragging item | | ||
| `selectedClass` | `String` | `''` | The class of the element when it is selected, it is usually used when multiple drag | | ||
| `ghostStyle` | `Object` | `{}` | The style of the mask element when dragging | | ||
| `ghostClass` | `String` | `''` | The class of the mask element when dragging | | ||
| `autoScroll` | `Boolean` | `true` | Automatic scrolling when moving to the edge of the container | | ||
| `scrollThreshold` | `Number` | `55` | Threshold to trigger autoscroll | | ||
| `delay` | `Number` | `0` | Time in milliseconds to define when the sorting should start | | ||
| `delayOnTouchOnly`| `Boolean` | `false` | Only delay if user is using touch | | ||
| `fallbackOnBody` | `Boolean` | `false` | Appends the cloned DOM Element into the Document's Body | | ||
| `stopPropagation` | `Boolean` | `false` | The `stopPropagation()` method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases | | ||
| `swapOnDrop` | `Boolean` | `true` | When the value is false, the dragged element will return to the starting position of the drag | | ||
```ts | ||
import Sortable from 'sortable-dnd'; | ||
Sortable.create(el: HTMLElement, options: Options); // Create new instance | ||
Sortable.get(el: HTMLElement); // Get the Sortable instance of an element | ||
Sortable.dragged; // The element being dragged | ||
Sortable.ghost; // The ghost element | ||
Sortable.active; // Active Sortable instance | ||
``` | ||
**Utils** | ||
```ts | ||
const { on, off, css, index, closest, getOffset, toggleClass } = Sortable.utils; | ||
// attach an event handler function | ||
on(el: HTMLElement, event: String, fn: Function); | ||
// remove an event handler | ||
off(el: HTMLElement, event: String, fn: Function); | ||
// set one CSS properties | ||
css(el: HTMLElement, prop: String, value: String); | ||
// Returns the index of an element within its parent for a selected set of elements | ||
index(el: HTMLElement, selector: String); | ||
// For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. | ||
closest(el: HTMLElement, selector: String, context: HTMLElement, includeContext: Boolean); | ||
// Get element's offet in given parentNode | ||
getOffset(element: HTMLElement, parentEl: HTMLElement); | ||
// Add or remove one classes from each element | ||
toggleClass(el: HTMLElement, name: String, state: Boolean); | ||
``` |
@@ -1,228 +0,377 @@ | ||
type SortableState = { | ||
sortable: Sortable; | ||
group: HTMLElement; | ||
node: HTMLElement; | ||
offset: DOMOffset; | ||
rect: DOMRect; | ||
}; | ||
declare class Sortable { | ||
public el: HTMLElement; | ||
type MultiNode = { | ||
node: HTMLElement; | ||
offset: DOMOffset; | ||
rect: DOMRect; | ||
}; | ||
public options: Sortable.Options; | ||
export type Group = { | ||
name: String; | ||
put: Boolean; | ||
pull: Boolean; | ||
}; | ||
export type DOMOffset = { | ||
height: Number; | ||
width: Number; | ||
top: Number; | ||
left: Number; | ||
}; | ||
export type DOMRect = DOMOffset & { | ||
bottom: Number; | ||
right: Number; | ||
}; | ||
export type EventType = Event & (TouchEvent | MouseEvent); | ||
export type FromTo = SortableState & { nodes?: MultiNode[] }; | ||
export type Select = SortableState & { event: EventType }; | ||
export type Options = { | ||
/** | ||
* Specifies which items inside the element should be draggable. | ||
* @example | ||
* - (e) => e.target.tagName === 'LI' ? true : false // use function | ||
* - (e) => e.target // use function to set the drag element if retrun an HTMLElement | ||
* - 'div' // use tag name | ||
* - '.item' // use class name | ||
* - '#item' // use id | ||
* @param element The Parent which holds the draggable element(s). | ||
* @param options Options to customise the behavior of the drag animations. | ||
*/ | ||
draggable?: Function | String; | ||
constructor(element: HTMLElement, options?: Sortable.Options); | ||
/** | ||
* Drag handle selector within list items. | ||
* @example | ||
* - (e) => e.target.tagName === 'I' ? true : false | ||
* - 'i' // use tag name | ||
* - '.handle' // use class | ||
* - '#handle' // use id | ||
* Active Sortable instance. | ||
*/ | ||
handle?: Function | String; | ||
static active: Sortable | null; | ||
/** | ||
* Set value to allow drag between different lists. | ||
* @example | ||
* String: '...' | ||
* Object: { name: '...', put: true | false, pull: true | false } | ||
* @defaults `' '` | ||
* The element being dragged. | ||
*/ | ||
group?: String | Group; | ||
static dragged: HTMLElement | null; | ||
/** | ||
* Enable multi-drag | ||
* @defaults `false` | ||
* The ghost element. | ||
*/ | ||
multiple?: Boolean; | ||
static ghost: HTMLElement | null; | ||
/** | ||
* Speed of the animation (in ms) while moving the items. | ||
* @defaults `150` | ||
* Public Methods. | ||
*/ | ||
animation?: Number; | ||
static utils: Sortable.Utils; | ||
/** | ||
* Disables the sortable if set to true. | ||
* @defaults `false` | ||
* Create sortable instance. | ||
* @param el | ||
* @param options | ||
*/ | ||
disabled?: Boolean; | ||
static create(el: HTMLElement, options: Options): Sortable; | ||
/** | ||
* Automatic scrolling when moving to the edge of the container. | ||
* @defaults `true` | ||
* Get the Sortable instance of an element. | ||
* @param el | ||
*/ | ||
autoScroll?: Boolean; | ||
static get(el: HTMLElement): Sortable | undefined; | ||
/** | ||
* Threshold to trigger autoscroll. | ||
* @defaults `25` | ||
* Get or set the option value, depending on whether the `value` is passed in. | ||
* @param name a Sortable.Options property. | ||
* @param value a value. | ||
*/ | ||
scrollThreshold?: Number; | ||
option<K extends keyof Sortable.Options>(name: K, value: Sortable.Options[K]): void; | ||
option<K extends keyof Sortable.Options>(name: K): Sortable.Options[K]; | ||
/** | ||
* Time in milliseconds to define when the sorting should start. | ||
* @defaults `0` | ||
* Removes the sortable functionality completely. | ||
*/ | ||
delay?: Number; | ||
destroy(): void; | ||
/** | ||
* Only delay if user is using touch. | ||
* @defaults `false` | ||
* Selects the provided multi-drag item | ||
* @param element The element to be selected | ||
*/ | ||
dealyOnTouchOnly?: Boolean; | ||
select(element: HTMLElement): void; | ||
/** | ||
* Appends the cloned DOM Element into the Document's Body. | ||
* @defaults `false` | ||
* Deselects the provided multi-drag item | ||
* @param element The element to be deselected | ||
*/ | ||
fallbackOnBody?: Boolean; | ||
deselect(element: HTMLElement): void; | ||
/** | ||
* The `stopPropagation()` method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases. | ||
* @defualts `false` | ||
* Get the selected elements in the case of `multiple: true`. | ||
*/ | ||
stopPropagation?: Boolean; | ||
getSelectedElements(): HTMLElement[]; | ||
} | ||
/** | ||
* When the value is false, the dragged element will return to the starting position of the drag. | ||
* @defaults `true` | ||
*/ | ||
swapOnDrop?: Boolean; | ||
declare namespace Sortable { | ||
export interface Options extends SortableOptions {} | ||
/** | ||
* This class will be added to the item while dragging. | ||
* @defaults `' '` | ||
*/ | ||
chosenClass?: String; | ||
export interface DOMOffset { | ||
height: Number; | ||
width: Number; | ||
top: Number; | ||
left: Number; | ||
} | ||
/** | ||
* Class name for selected item. | ||
* @defaults `' '` | ||
*/ | ||
selectedClass?: String; | ||
export interface DOMRect extends DOMOffset { | ||
bottom: Number; | ||
right: Number; | ||
} | ||
/** | ||
* This styles will be applied to the mask of the dragging element. | ||
* @defaults `{ }` | ||
*/ | ||
ghostStyle?: CSSStyleDeclaration; | ||
export interface Group { | ||
name: String; | ||
put: Boolean; | ||
pull: Boolean; | ||
} | ||
/** | ||
* This class will be applied to the mask of the dragging element. | ||
* @defaults `' '` | ||
*/ | ||
ghostClass?: String; | ||
export interface ScrollSpeed { | ||
x: Number; | ||
y: Number; | ||
} | ||
/** | ||
* The callback function when the drag is started. | ||
*/ | ||
onDrag?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
interface SortableState { | ||
sortable: Sortable; | ||
node: HTMLElement; | ||
offset: DOMOffset; | ||
rect: DOMRect; | ||
} | ||
/** | ||
* The callback function when the dragged element is moving. | ||
*/ | ||
onMove?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
interface MultiNode { | ||
node: HTMLElement; | ||
offset: DOMOffset; | ||
rect: DOMRect; | ||
} | ||
/** | ||
* The callback function when the drag is completed. | ||
*/ | ||
onDrop?: (params: { from: FromTo; to: FromTo; event: EventType; changed: Boolean }) => void; | ||
export interface FromTo extends SortableState { | ||
nodes?: MultiNode[]; | ||
} | ||
/** | ||
* The callback function when element is dropped into the current list from another list. | ||
*/ | ||
onAdd?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
export interface Select extends SortableState { | ||
event: EventType; | ||
} | ||
/** | ||
* The callback function when element is removed from the current list into another list. | ||
*/ | ||
onRemove?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
export type Direction = 'vertical' | 'horizontal'; | ||
/** | ||
* The callback function when the dragged element changes position in the current list. | ||
*/ | ||
onChange?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
export type EventType = Event & (TouchEvent | MouseEvent); | ||
/** | ||
* The callback function when element is selected. | ||
*/ | ||
onSelect?: (params: Select) => void; | ||
export interface SortableOptions { | ||
/** | ||
* Specifies which items inside the element should be draggable. | ||
* | ||
* https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors | ||
* @example | ||
* - 'div' // use tag name | ||
* - '.item' // use class name | ||
* - '#item' // use id | ||
* @defaults `' '` | ||
*/ | ||
draggable?: String; | ||
/** | ||
* The callback function when element is unselected. | ||
*/ | ||
onDeselect?: (params: Select) => void; | ||
}; | ||
/** | ||
* Drag handle selector within list items. | ||
* @example | ||
* - (e) => e.target.tagName === 'I' ? true : false | ||
* - 'i' // use tag name | ||
* - '.handle' // use class | ||
* - '#handle' // use id | ||
* @defaults `' '` | ||
*/ | ||
handle?: String | ((event: EventType) => Boolean); | ||
declare class Sortable { | ||
/** | ||
* @param ParentElement The Parent which holds the draggable element(s). | ||
* @param options Options to customise the behavior of the drag animations. | ||
*/ | ||
constructor(ParentElement: HTMLElement, options?: Options); | ||
/** | ||
* Set value to allow drag between different lists. | ||
* @example | ||
* - String: '...' | ||
* - Object: { name: '...', put: true | false, pull: true | false } | ||
* @defaults `' '` | ||
*/ | ||
group?: String | Group; | ||
/** | ||
* Manually clear all the state of the component, using this method the component will not be draggable. | ||
*/ | ||
destroy(): void; | ||
/** | ||
* Enable multi-drag. | ||
* @defaults `false` | ||
*/ | ||
multiple?: Boolean; | ||
/** | ||
* Get or set the option value, depending on whether the `value` is passed in | ||
* @param key option name | ||
* @param value option value | ||
*/ | ||
option(key: string, value: any): any; | ||
/** | ||
* Handle selector within list items which used to select element in `multiple: true`. | ||
* @example | ||
* - (e) => e.target.tagName === 'Checkbox' ? true : false | ||
* - 'checkbox' // use tag name | ||
* - '.checkbox' // use class | ||
* - '#checkbox' // use id | ||
* @defaults `' '` | ||
*/ | ||
selectHandle?: String | ((event: EventType) => Boolean); | ||
/** | ||
* Get the Sortable instance of an element | ||
* @param el | ||
*/ | ||
get(el: HTMLElement): Sortable | undefined; | ||
/** | ||
* Customize the ghost element in drag. | ||
*/ | ||
customGhost?: (nodes: HTMLElement[]) => HTMLElement; | ||
/** | ||
* Create sortable instance | ||
* @param el | ||
* @param options | ||
*/ | ||
create(el: HTMLElement, options: Options): void; | ||
/** | ||
* `vertical/horizontal` | `Function`. By default, the direction is automatically determined. | ||
*/ | ||
direction?: Direction | ((event: EventType, dragEl: HTMLElement, sortable: Sortable) => Direction); | ||
/** | ||
* Speed of the animation (in ms) while moving the items. | ||
* @defaults `150` | ||
*/ | ||
animation?: Number; | ||
/** | ||
* Disables the sortable if set to `true`. | ||
* @defaults `false` | ||
*/ | ||
disabled?: Boolean; | ||
/** | ||
* Automatic scrolling when moving to the edge of the container. | ||
* @defaults `true` | ||
*/ | ||
autoScroll?: Boolean; | ||
/** | ||
* Threshold to trigger autoscroll. | ||
* @defaults `25` | ||
*/ | ||
scrollThreshold?: Number; | ||
/** | ||
* Vertical&Horizontal scrolling speed (px) | ||
* @defaults `{ x: 10, y: 10 }` | ||
*/ | ||
scrollSpeed?: ScrollSpeed; | ||
/** | ||
* Time in milliseconds to define when the sorting should start. | ||
* @defaults `0` | ||
*/ | ||
delay?: Number; | ||
/** | ||
* Only delay if user is using touch. | ||
* @defaults `false` | ||
*/ | ||
dealyOnTouchOnly?: Boolean; | ||
/** | ||
* Appends the cloned DOM Element into the Document's Body. | ||
* @defaults `false` | ||
*/ | ||
fallbackOnBody?: Boolean; | ||
/** | ||
* When the value is false, the dragged element will return to the starting position of the drag. | ||
* @defaults `true` | ||
*/ | ||
swapOnDrop?: Boolean; | ||
/** | ||
* This class will be added to the item while dragging. | ||
* @defaults `' '` | ||
*/ | ||
chosenClass?: String; | ||
/** | ||
* Class name for selected item. | ||
* @defaults `' '` | ||
*/ | ||
selectedClass?: String; | ||
/** | ||
* This styles will be applied to the mask of the dragging element. | ||
* @defaults `{ }` | ||
*/ | ||
ghostStyle?: CSSStyleDeclaration; | ||
/** | ||
* This class will be applied to the mask of the dragging element. | ||
* @defaults `' '` | ||
*/ | ||
ghostClass?: String; | ||
/** | ||
* Triggered when the drag is started. | ||
*/ | ||
onDrag?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
/** | ||
* Triggered when the dragged element is moving. | ||
*/ | ||
onMove?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
/** | ||
* Triggered when the drag is completed. | ||
*/ | ||
onDrop?: (params: { from: FromTo; to: FromTo; event: EventType; changed: Boolean }) => void; | ||
/** | ||
* Triggered when element is dropped into the current list from another. | ||
*/ | ||
onAdd?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
/** | ||
* Triggered when element is removed from the current list into another. | ||
*/ | ||
onRemove?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
/** | ||
* Triggered when the dragged element changes position in the current list. | ||
*/ | ||
onChange?: (params: { from: FromTo; to: FromTo; event: EventType }) => void; | ||
/** | ||
* Triggered when element is selected. | ||
*/ | ||
onSelect?: (params: Select) => void; | ||
/** | ||
* Triggered when element is unselected. | ||
*/ | ||
onDeselect?: (params: Select) => void; | ||
} | ||
export interface Utils { | ||
/** | ||
* Attach an event handler function. | ||
* @param element an HTMLElement. | ||
* @param event an Event context. | ||
* @param fn | ||
*/ | ||
on(element: HTMLElement, event: String, fn: EventListenerOrEventListenerObject): void; | ||
/** | ||
* Remove an event handler function. | ||
* @param element an HTMLElement. | ||
* @param event an Event context. | ||
* @param fn a callback. | ||
*/ | ||
off(element: HTMLElement, event: String, fn: EventListenerOrEventListenerObject): void; | ||
/** | ||
* Get the values of all the CSS properties. | ||
* @param element an HTMLElement. | ||
*/ | ||
css(element: HTMLElement): CSSStyleDeclaration; | ||
/** | ||
* Get the value of style properties. | ||
* @param element an HTMLElement. | ||
* @param prop a property key. | ||
*/ | ||
css<K extends keyof CSSStyleDeclaration>(element: HTMLElement, prop: K): CSSStyleDeclaration[K]; | ||
/** | ||
* Set one CSS property. | ||
* @param element an HTMLElement. | ||
* @param prop a property key. | ||
* @param value a property value. | ||
*/ | ||
css<K extends keyof CSSStyleDeclaration>(element: HTMLElement, prop: K, value: CSSStyleDeclaration[K]): void; | ||
/** | ||
* Returns the index of an element within its parent for a selected set of elements | ||
* @param element an HTMLElement. | ||
* @param selector an element seletor. | ||
*/ | ||
index(element: HTMLElement, selector?: String): Number; | ||
/** | ||
* For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. | ||
* @param element an HTMLElement. | ||
* @param selector an element seletor. | ||
* @param context a specific element's context. | ||
* @param includeContext whether to add `context` to comparison | ||
*/ | ||
closest(element: HTMLElement, selector: String, context: HTMLElement, includeContext: Boolean): HTMLElement | null; | ||
/** | ||
* Get element's offet in given parentNode | ||
* @param element an HTMLElement. | ||
* @param parentEl a specific element's context. | ||
*/ | ||
getOffset(element: HTMLElement, parentEl: HTMLElement): DOMOffset; | ||
/** | ||
* Add or remove one classes from each element. | ||
* @param element an HTMLElement. | ||
* @param name a class name. | ||
* @param state a class's state. | ||
*/ | ||
toggleClass(element: HTMLElement, name: String, state: Boolean): void; | ||
} | ||
} | ||
export = Sortable; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
90704
1784
172
1