UNPKG

vue3-drag-drop

Version:

Simple drag and drop using native event API for Vue 3

307 lines (306 loc) 13.5 kB
import { openBlock as c, createBlock as D, resolveDynamicComponent as y, withCtx as E, renderSlot as u, createElementBlock as T, normalizeStyle as P, withModifiers as m } from "vue"; var v; (function(o) { var a = function() { function r() { this._dropEffect = "move", this._effectAllowed = "all", this._data = {}; } return Object.defineProperty(r.prototype, "dropEffect", { get: function() { return this._dropEffect; }, set: function(t) { this._dropEffect = t; }, enumerable: !0, configurable: !0 }), Object.defineProperty(r.prototype, "effectAllowed", { get: function() { return this._effectAllowed; }, set: function(t) { this._effectAllowed = t; }, enumerable: !0, configurable: !0 }), Object.defineProperty(r.prototype, "types", { get: function() { return Object.keys(this._data); }, enumerable: !0, configurable: !0 }), r.prototype.clearData = function(t) { t !== null ? delete this._data[t.toLowerCase()] : this._data = {}; }, r.prototype.getData = function(t) { return this._data[t.toLowerCase()] || ""; }, r.prototype.setData = function(t, e) { this._data[t.toLowerCase()] = e; }, r.prototype.setDragImage = function(t, e, i) { var s = n._instance; s._imgCustom = t, s._imgOffset = { x: e, y: i }; }, r; }(); o.DataTransfer = a; var n = function() { function r() { if (this._lastClick = 0, r._instance) throw "DragDropTouch instance already created."; var t = !1; if (document.addEventListener("test", function() { }, { get passive() { return t = !0, !0; } }), navigator.maxTouchPoints) { var e = document, i = this._touchstart.bind(this), s = this._touchmove.bind(this), d = this._touchend.bind(this), l = t ? { passive: !1, capture: !1 } : !1; e.addEventListener("touchstart", i, l), e.addEventListener("touchmove", s, l), e.addEventListener("touchend", d), e.addEventListener("touchcancel", d); } } return r.getInstance = function() { return r._instance; }, r.prototype._touchstart = function(t) { var e = this; if (this._shouldHandle(t)) { this._reset(); var i = this._closestDraggable(t.target); i && !this._dispatchEvent(t, "mousemove", t.target) && !this._dispatchEvent(t, "mousedown", t.target) && (this._dragSource = i, this._ptDown = this._getPoint(t), this._lastTouch = t, t.preventDefault(), setTimeout(function() { e._dragSource === i && e._img === null && e._dispatchEvent(t, "contextmenu", i) && e._reset(); }, r._CTXMENU), r._ISPRESSHOLDMODE && (this._pressHoldInterval = setTimeout(function() { e._isDragEnabled = !0, e._touchmove(t); }, r._PRESSHOLDAWAIT))); } }, r.prototype._touchmove = function(t) { if (this._shouldCancelPressHoldMove(t)) { this._reset(); return; } if (this._shouldHandleMove(t) || this._shouldHandlePressHoldMove(t)) { var e = this._getTarget(t); if (this._dispatchEvent(t, "mousemove", e)) { this._lastTouch = t, t.preventDefault(); return; } if (this._dragSource && !this._img && this._shouldStartDragging(t)) { if (this._dispatchEvent(this._lastTouch, "dragstart", this._dragSource)) { this._dragSource = null; return; } this._createImage(t), this._dispatchEvent(t, "dragenter", e); } this._img && (this._lastTouch = t, t.preventDefault(), this._dispatchEvent(t, "drag", this._dragSource), e !== this._lastTarget && (this._dispatchEvent(this._lastTouch, "dragleave", this._lastTarget), this._dispatchEvent(t, "dragenter", e), this._lastTarget = e), this._moveImage(t), this._isDropZone = this._dispatchEvent(t, "dragover", e)); } }, r.prototype._touchend = function(t) { if (this._shouldHandle(t)) { if (this._dispatchEvent(this._lastTouch, "mouseup", t.target)) { t.preventDefault(); return; } this._img || (this._dragSource = null, this._dispatchEvent(this._lastTouch, "click", t.target), this._lastClick = Date.now()), this._destroyImage(), this._dragSource && (t.type.indexOf("cancel") < 0 && this._isDropZone && this._dispatchEvent(this._lastTouch, "drop", this._lastTarget), this._dispatchEvent(this._lastTouch, "dragend", this._dragSource), this._reset()); } }, r.prototype._shouldHandle = function(t) { return t && !t.defaultPrevented && t.touches && t.touches.length < 2; }, r.prototype._shouldHandleMove = function(t) { return !r._ISPRESSHOLDMODE && this._shouldHandle(t); }, r.prototype._shouldHandlePressHoldMove = function(t) { return r._ISPRESSHOLDMODE && this._isDragEnabled && t && t.touches && t.touches.length; }, r.prototype._shouldCancelPressHoldMove = function(t) { return r._ISPRESSHOLDMODE && !this._isDragEnabled && this._getDelta(t) > r._PRESSHOLDMARGIN; }, r.prototype._shouldStartDragging = function(t) { var e = this._getDelta(t); return e > r._THRESHOLD || r._ISPRESSHOLDMODE && e >= r._PRESSHOLDTHRESHOLD; }, r.prototype._reset = function() { this._destroyImage(), this._dragSource = null, this._lastTouch = null, this._lastTarget = null, this._ptDown = null, this._isDragEnabled = !1, this._isDropZone = !1, this._dataTransfer = new a(), clearInterval(this._pressHoldInterval); }, r.prototype._getPoint = function(t, e) { return t && t.touches && (t = t.touches[0]), { x: e ? t.pageX : t.clientX, y: e ? t.pageY : t.clientY }; }, r.prototype._getDelta = function(t) { if (r._ISPRESSHOLDMODE && !this._ptDown) return 0; var e = this._getPoint(t); return Math.abs(e.x - this._ptDown.x) + Math.abs(e.y - this._ptDown.y); }, r.prototype._getTarget = function(t) { for (var e = this._getPoint(t), i = document.elementFromPoint(e.x, e.y); i && getComputedStyle(i).pointerEvents == "none"; ) i = i.parentElement; return i; }, r.prototype._createImage = function(t) { this._img && this._destroyImage(); var e = this._imgCustom || this._dragSource; if (this._img = e.cloneNode(!0), this._copyStyle(e, this._img), this._img.style.top = this._img.style.left = "-9999px", !this._imgCustom) { var i = e.getBoundingClientRect(), s = this._getPoint(t); this._imgOffset = { x: s.x - i.left, y: s.y - i.top }, this._img.style.opacity = r._OPACITY.toString(); } this._moveImage(t), document.body.appendChild(this._img); }, r.prototype._destroyImage = function() { this._img && this._img.parentElement && this._img.parentElement.removeChild(this._img), this._img = null, this._imgCustom = null; }, r.prototype._moveImage = function(t) { var e = this; requestAnimationFrame(function() { if (e._img) { var i = e._getPoint(t, !0), s = e._img.style; s.position = "absolute", s.pointerEvents = "none", s.zIndex = "999999", s.left = Math.round(i.x - e._imgOffset.x) + "px", s.top = Math.round(i.y - e._imgOffset.y) + "px"; } }); }, r.prototype._copyProps = function(t, e, i) { for (var s = 0; s < i.length; s++) { var d = i[s]; t[d] = e[d]; } }, r.prototype._copyStyle = function(t, e) { if (r._rmvAtts.forEach(function(O) { e.removeAttribute(O); }), t instanceof HTMLCanvasElement) { var i = t, s = e; s.width = i.width, s.height = i.height, s.getContext("2d").drawImage(i, 0, 0); } for (var d = getComputedStyle(t), l = 0; l < d.length; l++) { var g = d[l]; g.indexOf("transition") < 0 && (e.style[g] = d[g]); } e.style.pointerEvents = "none"; for (var l = 0; l < t.children.length; l++) this._copyStyle(t.children[l], e.children[l]); }, r.prototype._setOffsetAndLayerProps = function(t, e) { var i = void 0; t.offsetX === void 0 && (i = e.getBoundingClientRect(), t.offsetX = t.clientX - i.x, t.offsetY = t.clientY - i.y), t.layerX === void 0 && (i = i || e.getBoundingClientRect(), t.layerX = t.pageX - i.left, t.layerY = t.pageY - i.top); }, r.prototype._dispatchEvent = function(t, e, i) { if (t && i) { var s = document.createEvent("Event"), d = t.touches ? t.touches[0] : t; return s.initEvent(e, !0, !0), s.button = 0, s.which = s.buttons = 1, this._copyProps(s, t, r._kbdProps), this._copyProps(s, d, r._ptProps), this._setOffsetAndLayerProps(s, i), s.dataTransfer = this._dataTransfer, i.dispatchEvent(s), s.defaultPrevented; } return !1; }, r.prototype._closestDraggable = function(t) { for (; t; t = t.parentElement) if (t.hasAttribute("draggable") && t.draggable) return t; return null; }, r; }(); n._instance = new n(), n._THRESHOLD = 5, n._OPACITY = 0.5, n._DBLCLICK = 500, n._CTXMENU = 900, n._ISPRESSHOLDMODE = !1, n._PRESSHOLDAWAIT = 400, n._PRESSHOLDMARGIN = 25, n._PRESSHOLDTHRESHOLD = 0, n._rmvAtts = "id,class,style,draggable".split(","), n._kbdProps = "altKey,ctrlKey,metaKey,shiftKey".split(","), n._ptProps = "pageX,pageY,clientX,clientY,screenX,screenY,offsetX,offsetY".split(","), o.DragDropTouch = n; })(v || (v = {})); const _ = { data: void 0 }, p = (o) => o.reduce((a, n) => (a[n] = n) && a, {}), f = p([ "drag", "dragend", "dragenter", "dragleave", "dragstart", "dragover", "drop" ]), b = p(["copy", "move", "link", "none"]), H = p([ "none", "copy", "copyLink", "copyMove", "link", "linkMove", "move", "all", "uninitialized" ]), S = (o, a) => { const n = o.__vccOpts || o; for (const [r, t] of a) n[r] = t; return n; }, w = { props: { draggable: { type: Boolean, default: !0 }, transferData: {}, dropEffect: { validator: (o) => o in b }, effectAllowed: { validator: (o) => o in H }, image: String, imageXOffset: { type: Number, default: 0 }, imageYOffset: { type: Number, default: 0 }, hideImageHtml: { type: Boolean, default: !0 }, tag: { type: String, default: "div" } }, emits: f, data() { return { dragging: !1 }; }, computed: { events: () => f, scopedData() { return this.dragging && this.transferData; }, hideImageStyle: () => ({ position: "fixed", top: "-1000px" }) }, methods: { emitEvent(o, a) { const n = a.dataTransfer; if ([f.dragenter, f.dragover].includes(o) && this.dropEffect && (n.dropEffect = this.dropEffect), o === f.dragstart) { if (this.effectAllowed && (n.effectAllowed = this.effectAllowed), this.image || this.$slots.image) { let r; this.image ? (r = new Image(), r.src = this.image) : this.$slots.image && (r = this.$slots.image[0].elm), n.setDragImage && n.setDragImage(r, this.imageXOffset, this.imageYOffset); } this.transferData !== void 0 && (_.data = this.transferData, a.dataTransfer.setData("text", "")), this.dragging = !0; } this.$emit(o, this.transferData, a), o === f.dragend && (_.data = void 0, this.dragging = !1); } } }; function I(o, a, n, r, t, e) { return c(), D(y(n.tag), { draggable: n.draggable, onDrag: a[0] || (a[0] = (i) => e.emitEvent(e.events.drag, i)), onDragstart: a[1] || (a[1] = (i) => e.emitEvent(e.events.dragstart, i)), onDragenter: a[2] || (a[2] = (i) => e.emitEvent(e.events.dragenter, i)), onDragleave: a[3] || (a[3] = (i) => e.emitEvent(e.events.dragleave, i)), onDragend: a[4] || (a[4] = (i) => e.emitEvent(e.events.dragend, i)) }, { default: E(() => [ u(o.$slots, "default", { transferData: e.scopedData }), n.hideImageHtml ? (c(), T("div", { key: 0, style: P(e.hideImageStyle) }, [ u(o.$slots, "image", { transferData: e.scopedData }) ], 4)) : u(o.$slots, "image", { key: 1, transferData: e.scopedData }) ]), _: 3 }, 40, ["draggable"]); } const L = /* @__PURE__ */ S(w, [["render", I]]), h = /* @__PURE__ */ new Set(), C = { data() { return { transferData: void 0, isDraggingOver: !1 }; }, props: { tag: { type: String, default: "div" } }, emits: f, computed: { events: () => f, scopedData() { return this.isDraggingOver && this.transferData; } }, methods: { emitEvent(o, a) { this.transferData = _.data, this.$emit(o, this.transferData, a), o === f.dragenter && (h.size || a.target === this.$el) && h.add(a.target), o === f.dragleave && h.delete(a.target), o === f.drop && h.clear(), this.isDraggingOver = Boolean(h.size); } } }; function M(o, a, n, r, t, e) { return c(), D(y(n.tag), { onDragenter: a[0] || (a[0] = (i) => e.emitEvent(e.events.dragenter, i)), onDragleave: a[1] || (a[1] = (i) => e.emitEvent(e.events.dragleave, i)), onDragover: a[2] || (a[2] = m((i) => e.emitEvent(e.events.dragover, i), ["prevent"])), onDrop: a[3] || (a[3] = m((i) => e.emitEvent(e.events.drop, i), ["prevent"])) }, { default: E(() => [ u(o.$slots, "default", { transferData: e.scopedData }) ]), _: 3 }, 32); } const A = /* @__PURE__ */ S(C, [["render", M]]), x = { install(o) { o.component("drag", L), o.component("drop", A); } }; typeof window < "u" && window.Vue && window.Vue.use(x); export { L as Drag, A as Drop, x as default };