UNPKG

@alegendstale/holly-components

Version:

Reusable UI components created using lit

78 lines (77 loc) 3.19 kB
class g { constructor(e, t, r) { this.dropzones = e, this.draggables = t, this.result = { beforeElement: null, insertedElement: null, afterElement: null, order: this.draggables }, this.onDrop = r, this.load(); } dragStart(e, t) { e.classList.toggle("is-dragging", !0); } dragOver(e, t) { if (t.dataTransfer && Array.from(t.dataTransfer.items).some((l) => l.kind !== "element")) return; t.preventDefault(), this.result.beforeElement = this.getDragBeforeElement(t.clientX), this.result.insertedElement = this.getDraggingElement(), this.result.afterElement = this.getDragAfterElement(t.clientX); const r = this.draggables.indexOf(this.result.insertedElement); if (this.result.afterElement === null) e.appendChild(this.result.insertedElement), this.result.order.splice(r, 1), this.result.order.push(this.result.insertedElement); else { e.insertBefore(this.result.insertedElement, this.result.afterElement), this.result.order.splice(r, 1); const s = this.draggables.indexOf(this.result.afterElement); this.result.order.splice(s, 0, this.result.insertedElement); } } dragEnd(e, t) { e.classList.toggle("is-dragging", !1), this.onDrop(t, this.result), this.result = { beforeElement: null, insertedElement: null, afterElement: null, order: this.draggables }; } load() { for (let e of this.draggables) e.setAttribute("draggable", "true"), e.addEventListener("dragstart", (t) => this.dragStart(e, t)), e.addEventListener("dragend", (t) => this.dragEnd(e, t)); for (let e of this.dropzones) e.addEventListener("dragover", (t) => this.dragOver(e, t)); } unload() { for (let e of this.draggables) e.removeEventListener("dragstart", (t) => this.dragStart(e, t)), e.removeEventListener("dragend", (t) => this.dragEnd(e, t)); for (let e of this.dropzones) e.removeEventListener("dragover", (t) => this.dragOver(e, t)); } /** * @returns The element which is being dragged */ getDraggingElement() { return this.draggables.filter((e) => e.classList.contains("is-dragging"))[0]; } /** * @returns All draggable elements not being dragged */ getDraggableElements() { return this.draggables.filter((e) => !e.classList.contains("is-dragging")); } /** * Gets the closest element before the dragged element */ getDragBeforeElement(e) { return this.getDraggableElements().reduce( (t, r) => { const s = r.getBoundingClientRect(), l = e - s.left, i = s.width / 2, n = l - i; return n > 0 && n < t.offset ? { offset: n, element: r } : t; }, // Initial closest value { offset: Number.POSITIVE_INFINITY, element: null } ).element; } /** * Gets the closest element after the dragged element */ getDragAfterElement(e) { return this.getDraggableElements().reduce( (t, r) => { const s = r.getBoundingClientRect(), l = e - s.left, i = s.width / 2, n = l - i; return n < 0 && n > t.offset ? { offset: n, element: r } : t; }, // Initial closest value { offset: Number.NEGATIVE_INFINITY, element: null } ).element; } } export { g as DragDrop };