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
JavaScript
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
};