UNPKG

react-optimized-dnd

Version:

A React package for building performant drag-and-drop interfaces. Provides context provider, hooks, and type definitions for flexible, optimized DnD in React apps.

613 lines (612 loc) 22.6 kB
import de, { createContext as fe, useContext as me, useRef as I, useState as Z, useEffect as Q } from "react"; var K = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, ee = { exports: {} }, B = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var oe; function ve() { if (oe) return B; oe = 1; var r = Symbol.for("react.transitional.element"), o = Symbol.for("react.fragment"); function l(c, n, i) { var a = null; if (i !== void 0 && (a = "" + i), n.key !== void 0 && (a = "" + n.key), "key" in n) { i = {}; for (var t in n) t !== "key" && (i[t] = n[t]); } else i = n; return n = i.ref, { $$typeof: r, type: c, key: a, ref: n !== void 0 ? n : null, props: i }; } return B.Fragment = o, B.jsx = l, B.jsxs = l, B; } var H = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ce; function ge() { return ce || (ce = 1, process.env.NODE_ENV !== "production" && function() { function r(e) { if (e == null) return null; if (typeof e == "function") return e.$$typeof === z ? null : e.displayName || e.name || null; if (typeof e == "string") return e; switch (e) { case f: return "Fragment"; case b: return "Profiler"; case G: return "StrictMode"; case s: return "Suspense"; case R: return "SuspenseList"; case U: return "Activity"; } if (typeof e == "object") switch (typeof e.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), e.$$typeof) { case S: return "Portal"; case L: return (e.displayName || "Context") + ".Provider"; case P: return (e._context.displayName || "Context") + ".Consumer"; case M: var u = e.render; return e = e.displayName, e || (e = u.displayName || u.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e; case A: return u = e.displayName || null, u !== null ? u : r(e.type) || "Memo"; case D: u = e._payload, e = e._init; try { return r(e(u)); } catch { } } return null; } function o(e) { return "" + e; } function l(e) { try { o(e); var u = !1; } catch { u = !0; } if (u) { u = console; var v = u.error, x = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object"; return v.call( u, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", x ), o(e); } } function c(e) { if (e === f) return "<>"; if (typeof e == "object" && e !== null && e.$$typeof === D) return "<...>"; try { var u = r(e); return u ? "<" + u + ">" : "<...>"; } catch { return "<...>"; } } function n() { var e = X.A; return e === null ? null : e.getOwner(); } function i() { return Error("react-stack-top-frame"); } function a(e) { if (O.call(e, "key")) { var u = Object.getOwnPropertyDescriptor(e, "key").get; if (u && u.isReactWarning) return !1; } return e.key !== void 0; } function t(e, u) { function v() { y || (y = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", u )); } v.isReactWarning = !0, Object.defineProperty(e, "key", { get: v, configurable: !0 }); } function E() { var e = r(this.type); return _[e] || (_[e] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), e = this.props.ref, e !== void 0 ? e : null; } function d(e, u, v, x, q, $, J, p) { return v = $.ref, e = { $$typeof: w, type: e, key: u, props: $, _owner: q }, (v !== void 0 ? v : null) !== null ? Object.defineProperty(e, "ref", { enumerable: !1, get: E }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(e, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(e, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: J }), Object.defineProperty(e, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: p }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e; } function g(e, u, v, x, q, $, J, p) { var h = u.children; if (h !== void 0) if (x) if (C(h)) { for (x = 0; x < h.length; x++) T(h[x]); Object.freeze && Object.freeze(h); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else T(h); if (O.call(u, "key")) { h = r(e); var F = Object.keys(u).filter(function(ie) { return ie !== "key"; }); x = 0 < F.length ? "{key: someKey, " + F.join(": ..., ") + ": ...}" : "{key: someKey}", W[h + x] || (F = 0 < F.length ? "{" + F.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, x, h, F, h ), W[h + x] = !0); } if (h = null, v !== void 0 && (l(v), h = "" + v), a(u) && (l(u.key), h = "" + u.key), "key" in u) { v = {}; for (var V in u) V !== "key" && (v[V] = u[V]); } else v = u; return h && t( v, typeof e == "function" ? e.displayName || e.name || "Unknown" : e ), d( e, h, $, q, n(), v, J, p ); } function T(e) { typeof e == "object" && e !== null && e.$$typeof === w && e._store && (e._store.validated = 1); } var k = de, w = Symbol.for("react.transitional.element"), S = Symbol.for("react.portal"), f = Symbol.for("react.fragment"), G = Symbol.for("react.strict_mode"), b = Symbol.for("react.profiler"), P = Symbol.for("react.consumer"), L = Symbol.for("react.context"), M = Symbol.for("react.forward_ref"), s = Symbol.for("react.suspense"), R = Symbol.for("react.suspense_list"), A = Symbol.for("react.memo"), D = Symbol.for("react.lazy"), U = Symbol.for("react.activity"), z = Symbol.for("react.client.reference"), X = k.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, O = Object.prototype.hasOwnProperty, C = Array.isArray, m = console.createTask ? console.createTask : function() { return null; }; k = { "react-stack-bottom-frame": function(e) { return e(); } }; var y, _ = {}, j = k["react-stack-bottom-frame"].bind( k, i )(), N = m(c(i)), W = {}; H.Fragment = f, H.jsx = function(e, u, v, x, q) { var $ = 1e4 > X.recentlyCreatedOwnerStacks++; return g( e, u, v, !1, x, q, $ ? Error("react-stack-top-frame") : j, $ ? m(c(e)) : N ); }, H.jsxs = function(e, u, v, x, q) { var $ = 1e4 > X.recentlyCreatedOwnerStacks++; return g( e, u, v, !0, x, q, $ ? Error("react-stack-top-frame") : j, $ ? m(c(e)) : N ); }; }()), H; } var ue; function he() { return ue || (ue = 1, process.env.NODE_ENV === "production" ? ee.exports = ve() : ee.exports = ge()), ee.exports; } var Ee = he(); const ae = fe(null); function se() { const r = me(ae); if (!r) throw new Error("useReactOptimizedDndContext must be used within a ReactOptimizedDndProvider"); return r; } function ke({ children: r, onDragStart: o, onDragEnd: l, onDragOver: c }) { const n = I(null), i = I({}), a = I({ draggingElement: { ref: null, data: null }, overElement: { ref: null, data: null } }), t = () => { if (!n.current) return; const d = n.current.getBoundingClientRect(); let g = null, T = 1 / 0; a.current.overElement.ref = null, a.current.overElement.data = null; const k = Object.keys(i.current); for (let w = 0; w < k.length; w++) { const S = k[w], f = i.current[S], G = f.isOver; if (!f.ref.current) continue; const b = f.ref.current.getBoundingClientRect(), P = d.x < b.x + b.width && d.x + d.width > b.x && d.y < b.y + b.height && d.y + d.height > b.y, L = d.x - b.x, M = d.y - b.y, s = Math.sqrt(L * L + M * M); s < T && P && (T = s, g = f), G && (f.subscriber({ isOver: !1 }), i.current[S].isOver = !1); } g && !g.isOver && (g.subscriber({ isOver: !0 }), g.isOver = !0, a.current.overElement.ref = g.ref, a.current.overElement.data = g.data, c == null || c(a.current)), requestAnimationFrame(t); }, E = (d, g) => { if (d) n.current = d.current, a.current.draggingElement.ref = d, a.current.draggingElement.data = g, o == null || o(a.current), requestAnimationFrame(t); else if (n.current) { n.current = null; for (const T in i.current) i.current[T].subscriber({ isOver: !1 }), i.current[T].isOver = !1; l == null || l(a.current), a.current.draggingElement.ref = null, a.current.draggingElement.data = null, a.current.overElement.ref = null, a.current.overElement.data = null; } }; return /* @__PURE__ */ Ee.jsx( ae.Provider, { value: { draggingElementRef: n, droppableElementRefsPool: i, setDraggingElement: E }, children: r } ); } const pe = 3, Se = 120; function je(r) { const { data: o, dragThreshold: l = pe, touchDragDelay: c = Se } = r || {}, { draggingElementRef: n, setDraggingElement: i } = se(), a = I(null), t = I({ mouseOver: !1, mouseDown: !1, dragging: !1, holdStartedX: 0, holdStartedY: 0, holdStartedScrollX: 0, holdStartedScrollY: 0 }), E = I({ deltaScrollX: 0, deltaScrollY: 0, deltaMouseX: 0, deltaMouseY: 0 }), [d, g] = Z(!1), T = I(!1); Q(() => { if (!T.current) { T.current = !0; return; } d ? i(a, o) : i(null, null); }, [d]); const [k, w] = Z({ x: 0, y: 0 }), S = I(null), f = I(!1); return Q(() => { var z, X, O, C; if (!a.current) return; const b = () => { t.current.mouseOver = !0; }, P = () => { t.current.mouseOver = !1; }, L = (m) => { t.current.mouseDown = !0, t.current.holdStartedX = m.clientX, t.current.holdStartedY = m.clientY, t.current.holdStartedScrollX = window.scrollX, t.current.holdStartedScrollY = window.scrollY; }, M = () => { t.current.mouseDown = !1, t.current.dragging = !1, t.current.holdStartedX = 0, t.current.holdStartedY = 0, t.current.holdStartedScrollX = 0, t.current.holdStartedScrollY = 0, g(!1), w({ x: 0, y: 0 }); }, s = (m) => { const y = window.scrollX - t.current.holdStartedScrollX, _ = window.scrollY - t.current.holdStartedScrollY, j = m.clientX - t.current.holdStartedX, N = m.clientY - t.current.holdStartedY; E.current.deltaMouseX = j, E.current.deltaMouseY = N, E.current.deltaScrollX = y, E.current.deltaScrollY = _; const W = j + y, e = N + _; if (t.current.dragging) { w({ x: W, y: e }); return; } !n.current && (Math.abs(W) > l || Math.abs(e) > l) && t.current.mouseOver && t.current.mouseDown && (t.current.dragging = !0, g(!0)); }, R = () => { if (t.current.dragging) { E.current.deltaScrollX = window.scrollX - t.current.holdStartedScrollX, E.current.deltaScrollY = window.scrollY - t.current.holdStartedScrollY; const m = E.current.deltaMouseX + E.current.deltaScrollX, y = E.current.deltaMouseY + E.current.deltaScrollY; w({ x: m, y }); } }, A = (m) => { if (!m.touches || m.touches.length !== 1) return; const y = m.touches[0]; t.current.mouseDown = !0, t.current.mouseOver = !0, t.current.holdStartedX = y.clientX, t.current.holdStartedY = y.clientY, t.current.holdStartedScrollX = window.scrollX, t.current.holdStartedScrollY = window.scrollY, f.current = !1, S.current && clearTimeout(S.current), S.current = setTimeout(() => { f.current = !0, t.current.dragging = !0, g(!0); }, c); }, D = () => { t.current.mouseDown = !1, t.current.dragging = !1, t.current.mouseOver = !1, t.current.holdStartedX = 0, t.current.holdStartedY = 0, t.current.holdStartedScrollX = 0, t.current.holdStartedScrollY = 0, g(!1), w({ x: 0, y: 0 }), S.current && clearTimeout(S.current), f.current = !1; }, U = (m) => { if (!m.touches || m.touches.length !== 1) return; const y = m.touches[0], _ = window.scrollX - t.current.holdStartedScrollX, j = window.scrollY - t.current.holdStartedScrollY, N = y.clientX - t.current.holdStartedX, W = y.clientY - t.current.holdStartedY; E.current.deltaMouseX = N, E.current.deltaMouseY = W, E.current.deltaScrollX = _, E.current.deltaScrollY = j; const e = N + _, u = W + j; if (!f.current) { (Math.abs(e) > l || Math.abs(u) > l) && (S.current && clearTimeout(S.current), f.current = !1); return; } if (f.current && t.current.dragging) { w({ x: e, y: u }), m.preventDefault(); return; } }; return (z = a.current) == null || z.addEventListener("mouseenter", b), (X = a.current) == null || X.addEventListener("mouseleave", P), (O = a.current) == null || O.addEventListener("mousedown", L), document.addEventListener("mouseup", M), document.addEventListener("mousemove", s), document.addEventListener("scroll", R), (C = a.current) == null || C.addEventListener("touchstart", A, { passive: !1 }), document.addEventListener("touchend", D, { passive: !1 }), document.addEventListener("touchmove", U, { passive: !1 }), () => { var m, y, _, j; (m = a.current) == null || m.removeEventListener("mouseenter", b), (y = a.current) == null || y.removeEventListener("mouseleave", P), (_ = a.current) == null || _.removeEventListener("mousedown", L), document.removeEventListener("mouseup", M), document.removeEventListener("mousemove", s), document.removeEventListener("scroll", R), (j = a.current) == null || j.removeEventListener("touchstart", A), document.removeEventListener("touchend", D), document.removeEventListener("touchmove", U); }; }, [a, l, c, n]), { handleRef: (b) => { a.current = b; }, deltaPos: k, isDragging: d }; } var re, le; function be() { if (le) return re; le = 1; var r = "Expected a function", o = NaN, l = "[object Symbol]", c = /^\s+|\s+$/g, n = /^[-+]0x[0-9a-f]+$/i, i = /^0b[01]+$/i, a = /^0o[0-7]+$/i, t = parseInt, E = typeof K == "object" && K && K.Object === Object && K, d = typeof self == "object" && self && self.Object === Object && self, g = E || d || Function("return this")(), T = Object.prototype, k = T.toString, w = Math.max, S = Math.min, f = function() { return g.Date.now(); }; function G(s, R, A) { var D, U, z, X, O, C, m = 0, y = !1, _ = !1, j = !0; if (typeof s != "function") throw new TypeError(r); R = M(R) || 0, b(A) && (y = !!A.leading, _ = "maxWait" in A, z = _ ? w(M(A.maxWait) || 0, R) : z, j = "trailing" in A ? !!A.trailing : j); function N(p) { var h = D, F = U; return D = U = void 0, m = p, X = s.apply(F, h), X; } function W(p) { return m = p, O = setTimeout(v, R), y ? N(p) : X; } function e(p) { var h = p - C, F = p - m, V = R - h; return _ ? S(V, z - F) : V; } function u(p) { var h = p - C, F = p - m; return C === void 0 || h >= R || h < 0 || _ && F >= z; } function v() { var p = f(); if (u(p)) return x(p); O = setTimeout(v, e(p)); } function x(p) { return O = void 0, j && D ? N(p) : (D = U = void 0, X); } function q() { O !== void 0 && clearTimeout(O), m = 0, D = C = U = O = void 0; } function $() { return O === void 0 ? X : x(f()); } function J() { var p = f(), h = u(p); if (D = arguments, U = this, C = p, h) { if (O === void 0) return W(C); if (_) return O = setTimeout(v, R), N(C); } return O === void 0 && (O = setTimeout(v, R)), X; } return J.cancel = q, J.flush = $, J; } function b(s) { var R = typeof s; return !!s && (R == "object" || R == "function"); } function P(s) { return !!s && typeof s == "object"; } function L(s) { return typeof s == "symbol" || P(s) && k.call(s) == l; } function M(s) { if (typeof s == "number") return s; if (L(s)) return o; if (b(s)) { var R = typeof s.valueOf == "function" ? s.valueOf() : s; s = b(R) ? R + "" : R; } if (typeof s != "string") return s === 0 ? s : +s; s = s.replace(c, ""); var A = i.test(s); return A || a.test(s) ? t(s.slice(2), A ? 2 : 8) : n.test(s) ? o : +s; } return re = G, re; } be(); function Re({ threshold: r = 0, root: o = null, rootMargin: l = "0%", freezeOnceVisible: c = !1, initialIsIntersecting: n = !1, onChange: i } = {}) { var a; const [t, E] = Z(null), [d, g] = Z(() => ({ isIntersecting: n, entry: void 0 })), T = I(); T.current = i; const k = ((a = d.entry) == null ? void 0 : a.isIntersecting) && c; Q(() => { if (!t || !("IntersectionObserver" in window) || k) return; const f = new IntersectionObserver( (G) => { const b = Array.isArray(f.thresholds) ? f.thresholds : [f.thresholds]; G.forEach((P) => { const L = P.isIntersecting && b.some((M) => P.intersectionRatio >= M); g({ isIntersecting: L, entry: P }), T.current && T.current(L, P); }); }, { threshold: r, root: o, rootMargin: l } ); return f.observe(t), () => { f.disconnect(); }; }, [ t, // eslint-disable-next-line react-hooks/exhaustive-deps JSON.stringify(r), o, l, k, c ]); const w = I(null); Q(() => { var f; !t && ((f = d.entry) != null && f.target) && !c && !k && w.current !== d.entry.target && (w.current = d.entry.target, g({ isIntersecting: n, entry: void 0 })); }, [t, d.entry, c, k, n]); const S = [ E, !!d.isIntersecting, d.entry ]; return S.ref = S[0], S.isIntersecting = S[1], S.entry = S[2], S; } const Y = []; for (let r = 0; r < 256; ++r) Y.push((r + 256).toString(16).slice(1)); function ye(r, o = 0) { return (Y[r[o + 0]] + Y[r[o + 1]] + Y[r[o + 2]] + Y[r[o + 3]] + "-" + Y[r[o + 4]] + Y[r[o + 5]] + "-" + Y[r[o + 6]] + Y[r[o + 7]] + "-" + Y[r[o + 8]] + Y[r[o + 9]] + "-" + Y[r[o + 10]] + Y[r[o + 11]] + Y[r[o + 12]] + Y[r[o + 13]] + Y[r[o + 14]] + Y[r[o + 15]]).toLowerCase(); } let te; const xe = new Uint8Array(16); function Te() { if (!te) { if (typeof crypto > "u" || !crypto.getRandomValues) throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported"); te = crypto.getRandomValues.bind(crypto); } return te(xe); } const ne = {}; function we(r, o, l) { let c; { const n = Date.now(), i = Te(); Oe(ne, n, i), c = _e(i, ne.msecs, ne.seq, o, l); } return o ?? ye(c); } function Oe(r, o, l) { return r.msecs ?? (r.msecs = -1 / 0), r.seq ?? (r.seq = 0), o > r.msecs ? (r.seq = l[6] << 23 | l[7] << 16 | l[8] << 8 | l[9], r.msecs = o) : (r.seq = r.seq + 1 | 0, r.seq === 0 && r.msecs++), r; } function _e(r, o, l, c, n = 0) { if (r.length < 16) throw new Error("Random bytes length must be >= 16"); if (!c) c = new Uint8Array(16), n = 0; else if (n < 0 || n + 16 > c.length) throw new RangeError(`UUID byte range ${n}:${n + 15} is out of buffer bounds`); return o ?? (o = Date.now()), l ?? (l = r[6] * 127 << 24 | r[7] << 16 | r[8] << 8 | r[9]), c[n++] = o / 1099511627776 & 255, c[n++] = o / 4294967296 & 255, c[n++] = o / 16777216 & 255, c[n++] = o / 65536 & 255, c[n++] = o / 256 & 255, c[n++] = o & 255, c[n++] = 112 | l >>> 28 & 15, c[n++] = l >>> 20 & 255, c[n++] = 128 | l >>> 14 & 63, c[n++] = l >>> 6 & 255, c[n++] = l << 2 & 255 | r[10] & 3, c[n++] = r[11], c[n++] = r[12], c[n++] = r[13], c[n++] = r[14], c[n++] = r[15], c; } function Ae(r) { const { data: o } = r || {}, { droppableElementRefsPool: l } = se(), c = I(we()), n = I(null), [i, a] = Z(!1), { isIntersecting: t, ref: E } = Re({ threshold: 0.01 }); return Q(() => { n.current && (t ? l.current[c.current] ? l.current[c.current].data = o : l.current[c.current] = { ref: n, subscriber: (g) => { a(g.isOver); }, data: o || null } : l.current[c.current] && (delete l.current[c.current], a(!1))); }, [t, l, o]), { droppableRef: (g) => { n.current = g, E(g); }, isOver: i }; } export { ae as ReactOptimizedDndContext, ke as ReactOptimizedDndProvider, je as useDraggable, Ae as useDroppable, se as useReactOptimizedDndContext };