react-smooth-flow
Version:
Effortless React animations for entering, exiting, and updating elements
746 lines (745 loc) • 26.7 kB
JavaScript
import { flushSync as H } from "react-dom";
import { useRef as v, useMemo as Y } from "react";
const Mt = (t) => ({
"data-transition": JSON.stringify(t)
}), kt = (t) => ({
"data-transitionroot": t
}), F = [
"opacity",
"backgroundColor",
"boxShadow",
"backdropFilter",
"borderRadius",
"borderWidth",
"borderTopWidth",
"borderRightWidth",
"borderBottomWidth",
"borderLeftWidth",
"borderColor",
"borderStyle",
"pointerEvents",
"margin",
"display"
], O = [
"opacity",
"backgroundColor",
"boxShadow",
"backdropFilter",
"borderRadius",
"borderWidth",
"borderTopWidth",
"borderRightWidth",
"borderBottomWidth",
"borderLeftWidth",
"borderColor",
"borderStyle",
"pointerEvents"
], D = [
"opacity",
"backgroundColor",
"boxShadow",
"borderRadius",
"borderWidth",
"borderColor",
"borderStyle"
], B = [
"duration",
"easing",
"delay",
"ignoreReducedMotion",
"scaleContent",
"positionAnchor",
"transitionRootTag",
"forcePresenceTransition",
"clip",
"transitionLayout"
], X = ["tag", "transitionRoot"], w = {
debug: !1,
transitionOptions: {
duration: 300,
easing: "ease",
delay: 0,
ignoreReducedMotion: !1,
enterKeyframes: { opacity: [0, 1] },
exitKeyframes: { opacity: [1, 0] },
contentEnterKeyframes: { opacity: [0, 1, 1] },
contentExitKeyframes: { opacity: [1, 1, 0] },
scaleContent: !1,
contentAlign: "topLeft",
positionAnchor: "topLeft",
forcePresenceTransition: !1,
transitionRootTag: null,
clip: !0,
relevantStyleProperties: [],
persistBounds: !0,
transitionLayout: !1,
disabled: !1
}
}, q = () => {
const t = "transitionRoot";
let o = document.getElementById(t);
return o || (o = document.createElement("div"), o.id = t, o.ariaHidden = "true", document.body.append(o), document.documentElement.style.position = "relative"), o;
}, Z = (t) => {
const o = q();
t.forEach((e) => {
const n = e.shared.transitionRoot ?? o;
e.transitionType === "mutation" ? n.append(e.image) : e.transitionType === "presence" && (e.prevImage && n.append(e.prevImage), e.nextImage && n.append(e.nextImage));
});
}, J = (t) => {
const o = t.map(
({ prevSnapshot: n, nextSnapshot: s }) => Math.max((n == null ? void 0 : n.totalZIndex) ?? -1, (s == null ? void 0 : s.totalZIndex) ?? -1)
), e = Math.max(...o);
t.forEach((n) => {
n.transitionType === "mutation" ? n.image.style.zIndex = e.toString() : n.transitionType === "presence" && (n.prevImage && (n.prevImage.style.zIndex = e.toString()), n.nextImage && (n.nextImage.style.zIndex = e.toString()));
});
}, z = (t, o) => {
t.forEach((e) => {
if (e.transitionType === "mutation" && e.prevSnapshot.transitionOptions.persistBounds) {
const n = Object.keys(e.prevSnapshot.transitionMapping);
for (const s of n) {
const i = o[s];
if (i) {
e.prevSnapshot.bounds = i;
break;
}
}
}
});
}, L = (t) => t.filter(Boolean), m = {}, G = () => {
const t = `${Date.now()}-${Math.random().toString(36)}`;
return m[t] = {}, t;
}, V = (t) => m[t], U = (t) => {
var o;
return (o = Object.entries(m).find(([e, n]) => Object.keys(n).includes(t))) == null ? void 0 : o[1];
}, Q = () => Object.keys(m).flatMap((t) => Object.values(m[t]).flat()), tt = (t) => Object.keys(m[t]).flatMap((o) => m[t][o]), et = (...t) => {
const o = L(t), e = Object.entries(m).filter(([i, r]) => Object.keys(r).some((l) => o.includes(l))).map((i) => i[0]);
e.map((i) => m[i]).flatMap((i) => Object.keys(i).flatMap((r) => i[r])).forEach((i) => {
var r;
i.animation.cancel(), (r = i.cleanup) == null || r.call(i);
}), e.forEach((i) => delete m[i]);
}, nt = (t) => {
Object.keys(m[t]).flatMap((n) => m[t][n]).forEach((n) => {
var s;
n.animation.cancel(), (s = n.cleanup) == null || s.call(n);
}), delete m[t];
}, ot = (t) => Q().some((e) => e.snapshotPair.shared.transitionRoot === t), st = (t) => {
const o = [];
for (const { shared: e } of t)
e.transitionRoot && !o.includes(e.transitionRoot) && o.push(e.transitionRoot);
return o.forEach((e) => {
window.getComputedStyle(e).position === "static" && (e.setAttribute("data-savedposition", e.style.position), e.style.setProperty("position", "relative", "important"));
}), () => {
o.forEach((e) => {
ot(e) || e.dataset.savedposition !== void 0 && (e.style.setProperty("position", e.dataset.savedposition), e.removeAttribute("data-savedposition"));
});
};
}, I = (t, o, e, n) => {
t.style.position = o;
let s = 0, i = 0, r = 0, l = 0;
if (o === "absolute" && !n) {
const c = document.documentElement.scrollWidth - (document.documentElement.scrollLeft + document.documentElement.clientWidth), a = document.documentElement.scrollHeight - (document.documentElement.scrollTop + document.documentElement.clientHeight);
s = window.scrollY, i = c, r = a, l = window.scrollX;
}
switch (e.transitionOptions.positionAnchor) {
case "topLeft":
t.style.top = `${e.bounds.top + s}px`, t.style.left = `${e.bounds.left + l}px`;
break;
case "topRight":
t.style.top = `${e.bounds.top + s}px`, t.style.right = `${e.bounds.right + i}px`;
break;
case "bottomRight":
t.style.right = `${e.bounds.right + i}px`, t.style.bottom = `${e.bounds.bottom + r}px`;
break;
case "bottomLeft":
t.style.bottom = `${e.bounds.bottom + r}px`, t.style.left = `${e.bounds.left + l}px`;
break;
}
}, it = (t) => {
t.forEach((o) => {
if (o.transitionType === "mutation") {
const { prevSnapshot: e, nextSnapshot: n, image: s, shared: i } = o, r = n ?? e, l = r.hasFixedPosition && !r.transitionRoot ? "fixed" : "absolute";
I(s, l, r, !!i.transitionRoot);
} else if (o.transitionType === "presence") {
const { prevSnapshot: e, nextSnapshot: n, prevImage: s, nextImage: i, shared: r } = o;
[
{ snapshot: e, image: s },
{ snapshot: n, image: i }
].filter(({ snapshot: c, image: a }) => c && a).forEach(({ snapshot: c, image: a }) => {
const d = c.hasFixedPosition && !c.transitionRoot ? "fixed" : "absolute";
I(a, d, c, !!r.transitionRoot);
});
}
});
}, rt = (t) => {
const o = {};
t.forEach((e) => {
if (e.transitionType === "presence")
return;
const { firstValidSnapshot: n, image: s } = e, i = n.targetElement.dataset.transitionroot;
i && (o[i] = s);
}), t.forEach((e) => {
const { shared: n, prevSnapshot: s, nextSnapshot: i } = e;
if (!n.transitionOptions.transitionRootTag || !Object.keys(o).includes(n.transitionOptions.transitionRootTag))
return;
const r = o[n.transitionOptions.transitionRootTag];
s && (s.transitionRoot = r), i && (i.transitionRoot = r), n.transitionRoot = r;
});
}, S = (t) => {
const o = t.getBoundingClientRect(), e = o.width - t.clientWidth, n = o.height - t.clientHeight;
return {
top: o.top,
right: document.documentElement.clientWidth - o.right,
bottom: document.documentElement.clientHeight - o.bottom,
left: o.left,
width: o.width,
height: o.height,
scrollBarWidth: e,
scrollBarHeight: n
};
}, W = (t, o) => {
const e = S(o);
e && (t.top -= e.top - o.scrollTop, t.right -= e.right + e.scrollBarWidth + o.scrollLeft, t.left -= e.left - o.scrollLeft, t.bottom -= e.bottom + e.scrollBarHeight + o.scrollTop);
}, N = (t, o, e) => {
const n = window.getComputedStyle(t);
e.forEach((r) => {
o.style.setProperty(r, n.getPropertyValue(r), "important");
});
const s = t.children, i = o.children;
for (let r = 0; r < s.length; r++)
N(s[r], i[r], e);
}, at = (t) => {
let o = t;
for (; o && o !== document.body; ) {
if (window.getComputedStyle(o).position === "fixed")
return !0;
o = o.parentElement;
}
return !1;
}, ct = (t) => {
const o = window.getComputedStyle(t);
return Object.fromEntries(
F.map((n) => [n, o[n]])
);
}, lt = (t, o = document) => {
const e = o.querySelectorAll(`[data-transitionroot='${t}']`);
if (e.length) {
if (e.length > 1)
throw Error(
`Transition root tag must be unique. Found ${e.length} elements with the "${t}" root tag.`
);
return e[0];
} else return null;
}, C = (t) => {
var o;
if (Array.isArray(t)) {
const e = [...t].reverse();
return e.forEach(
(n) => n.offset = n.offset === void 0 ? void 0 : 1 - n.offset
), e;
} else {
const e = JSON.parse(JSON.stringify(t));
return Object.keys(e).forEach((n) => e[n].reverse()), e.offset = (o = e.offset) == null ? void 0 : o.map((n) => 1 - n), e;
}
}, x = (t) => {
if (!t.dataset.transition)
return null;
const o = JSON.parse(t.dataset.transition);
return Object.keys(o).forEach((e) => {
const n = o[e];
if (n.exitKeyframes === "reversedEnter") {
if (!n.enterKeyframes)
throw Error(
`Transition target with tag "${e}" has "exitKeyframes" property set to "reversedEnter", but "enterKeyframes" was not specified. Either specify "enterKeyframes" or don't set "exitKeyframes" to "reversedEnter"`
);
n.exitKeyframes = C(n.enterKeyframes);
}
if (n.contentExitKeyframes === "reversedEnter") {
if (!n.contentEnterKeyframes)
throw Error(
`Transition target with tag "${e}" has "contentExitKeyframes" property set to "reversedEnter", but "contentEnterKeyframes" was not specified. Either specify "contentEnterKeyframes" or don't set "contentExitKeyframes" to "reversedEnter"`
);
n.contentExitKeyframes = C(n.contentEnterKeyframes);
}
Object.keys(
w.transitionOptions
).forEach((i) => {
if (n[i] === void 0) {
const r = w.transitionOptions[i];
n[i] = r;
}
});
}), o;
}, dt = (t, o = document.body) => {
let e = t, n = 1;
for (; e && e !== o; ) {
const s = window.getComputedStyle(e), i = parseFloat(s.opacity);
Number.isNaN(i) || (n *= i), e = e.parentElement;
}
return n;
}, pt = (t, o = document.body) => {
let e = t, n = 0;
for (; e && e !== o; ) {
const s = window.getComputedStyle(e), i = parseInt(s.zIndex);
Number.isNaN(i) || (n += i), e = e.parentElement;
}
return n;
}, E = (t, o = document) => {
const e = o.querySelectorAll("[data-transition]"), n = [];
if (e.forEach((s) => {
const i = x(s);
!i || !Object.keys(i).includes(t) || i[t].disabled || n.push(s);
}), n.length) {
if (n.length > 1)
throw Error(`Found ${n.length} elements with tag "${t}". Transition tag must be unique`);
return n[0];
} else return null;
}, ut = (t, o) => {
t.forEach((e) => {
const n = E(e, o);
n && (n.style.setProperty("opacity", "0", "important"), n.style.setProperty("transition", "none", "important"));
});
}, ft = (t, o) => {
const e = x(t);
if (!e)
return !1;
const n = Object.keys(e);
for (const s of n)
if (o.includes(s))
return !0;
return !1;
}, mt = (t, o) => {
const e = [];
t.matches("[id]") && e.push(t), e.push(...t.querySelectorAll("[id]"));
const n = {};
e.forEach((s) => {
if (!s.id || ft(s, o))
return;
const i = `rsf-${Math.random().toString(16).split(".")[1]}`;
n[s.id] = i, s.id = i;
}), t.querySelectorAll('[clip-path^="url(#"]').forEach((s) => {
var r, l;
const i = (l = (r = s.getAttribute("clip-path")) == null ? void 0 : r.match(/url\(#(.+)\)/)) == null ? void 0 : l[1];
i && s.setAttribute("clip-path", `url(#${n[i]})`);
}), t.querySelectorAll('[mask^="url(#"]').forEach((s) => {
var r, l;
const i = (l = (r = s.getAttribute("mask")) == null ? void 0 : r.match(/url\(#(.+)\)/)) == null ? void 0 : l[1];
i && s.setAttribute("mask", `url(#${n[i]})`);
}), t.querySelectorAll('use[href^="#"]').forEach((s) => {
var r;
const i = (r = s.getAttribute("href")) == null ? void 0 : r.replace("#", "");
i && s.setAttribute("href", `#${n[i]}`);
});
}, M = (t, o, e) => {
if (!t)
return null;
const n = x(t), s = n[o], i = s.transitionRootTag ? lt(s.transitionRootTag) : null;
if (s.transitionRootTag && !i)
throw Error(`Failed to find transition root with tag "${s.transitionRootTag}"`);
const r = ct(t);
r.opacity = `${dt(t, i ?? void 0)}`;
const l = S(t);
i && W(l, i);
const c = t.cloneNode(!0);
s.relevantStyleProperties.length && N(t, c, s.relevantStyleProperties), ut(e, c), mt(c, e), c.style.setProperty("background-color", "transparent", "important"), c.style.setProperty("border-radius", "0", "important"), c.style.setProperty("border-width", "0", "important"), c.style.setProperty("position", "static", "important"), c.style.setProperty("margin", "0", "important"), c.style.setProperty("opacity", "1", "important"), c.style.setProperty("box-shadow", "none", "important"), c.style.setProperty("backdrop-filter", "none", "important");
const a = document.createElement("div");
a.inert = !0, a.classList.add("rsf-snapshotContainer", `rsf-${s.contentAlign}`), a.style.setProperty("--borderTopWidth", r.borderTopWidth), a.style.setProperty("--borderRightWidth", r.borderRightWidth), a.style.setProperty("--borderBottomWidth", r.borderBottomWidth), a.style.setProperty("--borderLeftWidth", r.borderLeftWidth);
const d = document.createElement("div");
return d.className = "rsf-transformContainer", d.style.width = `${l.width}px`, d.style.height = `${l.height}px`, d.innerHTML = c.outerHTML.replace(/\sdata-transition=".+?"/gm, "").replace(/\sdata-transitionroot=".+?"/gm, ""), a.append(d), {
tag: o,
bounds: l,
image: a,
computedStyle: r,
transitionOptions: s,
transitionMapping: n,
hasFixedPosition: at(t),
transitionRoot: i,
targetElement: t,
targetDOMPosition: {
parentElement: t.parentElement,
index: Array.from(t.parentElement.children).indexOf(t)
},
totalZIndex: pt(t, i ?? void 0)
};
}, ht = (t) => {
const o = [];
return t.forEach((e) => {
const n = E(e);
if (!n) {
o.push(e);
return;
}
const s = x(n);
if (!s) {
o.push(e);
return;
}
const i = Object.keys(s);
o.push(...i);
}), o;
}, yt = (t) => {
const o = U(t);
if (!o)
return null;
const e = o[t][0].snapshotPair;
if (e.transitionType === "presence")
return null;
const n = S(e.image);
return e.shared.transitionRoot && W(n, e.shared.transitionRoot), n;
}, gt = () => window.matchMedia("(prefers-reduced-motion: reduce)").matches, P = (t, o) => {
const e = document.createElement("div");
return e.className = "rsf-image", e.style.overflow = t ? "hidden" : "visible", e.style.width = `${o.width}px`, e.style.height = `${o.height}px`, e;
}, bt = (t, o) => t.map((s, i) => ({ prevSnapshot: s, nextSnapshot: o[i] })).filter(
(s) => {
var i, r;
return ((i = s.prevSnapshot) == null ? void 0 : i.transitionOptions.ignoreReducedMotion) || ((r = s.nextSnapshot) == null ? void 0 : r.transitionOptions.ignoreReducedMotion) || !gt();
}
).map(({ prevSnapshot: s, nextSnapshot: i }) => {
const r = s ?? i;
if (!r)
return null;
const l = Object.fromEntries(
B.map((a) => [a, r.transitionOptions[a]])
), c = {
tag: r.tag,
transitionRoot: r.transitionRoot ?? null,
transitionOptions: l
};
if (s && i && !c.transitionOptions.forcePresenceTransition) {
const a = r.computedStyle, d = P(c.transitionOptions.clip, r.bounds);
return O.forEach((u) => d.style[u] = a[u]), s && d.append(s.image), i && d.append(i.image), {
prevSnapshot: s,
nextSnapshot: i,
firstValidSnapshot: r,
image: d,
shared: c,
transitionType: "mutation"
};
} else {
let a = null, d = null;
return s && (a = P(c.transitionOptions.clip, s.bounds), O.forEach(
(u) => a.style[u] = s.computedStyle[u]
), a.append(s.image)), i && (d = P(c.transitionOptions.clip, i.bounds), O.forEach(
(u) => d.style[u] = i.computedStyle[u]
), d.append(i.image)), {
prevSnapshot: s,
nextSnapshot: i,
firstValidSnapshot: r,
prevImage: a,
nextImage: d,
shared: c,
transitionType: "presence"
};
}
}).filter(Boolean), y = (t) => {
if (Array.isArray(t)) {
const o = t.slice(0, 1);
return o.length ? (delete o[0].offset, o) : [];
} else {
const o = JSON.parse(JSON.stringify(t));
return delete o.offset, Object.keys(o).forEach((e) => o[e].splice(1)), o;
}
}, R = (t) => {
const o = document.createElement("rsf-layout-proxy");
return o.inert = !0, o.style.display = t, o;
}, j = (t) => {
const o = window.getComputedStyle(t), e = o.rowGap, n = o.columnGap, s = e === "normal" ? "0" : `-${e}`, i = n === "normal" ? "0" : `-${n}`;
return `${s} 0 0 ${i}`;
}, Tt = (t, o, e) => {
const { prevSnapshot: n, nextSnapshot: s, shared: i } = t;
if (!n || !s)
return;
const { targetElement: r } = s, l = R(s.computedStyle.display), c = r.style.display;
r.style.setProperty("display", "none", "important"), r.after(l);
const a = {
width: [`${n == null ? void 0 : n.bounds.width}px`, `${s.bounds.width}px`],
height: [`${n == null ? void 0 : n.bounds.height}px`, `${s.bounds.height}px`],
margin: [n == null ? void 0 : n.computedStyle.margin, s.computedStyle.margin]
};
i.transitionOptions.delay && l.animate(y(a), { fill: "forwards" });
const d = l.animate(a, e);
o.push({
animation: d,
snapshotPair: t,
cleanup: () => {
r.style.setProperty("display", c), l.remove();
}
});
}, Et = (t, o, e) => {
const { nextSnapshot: n, shared: s } = t;
if (!n)
return;
const { targetElement: i } = n, r = R(n.computedStyle.display), l = i.style.display;
i.style.setProperty("display", "none", "important"), i.after(r);
const c = {
width: ["0px", `${n.bounds.width}px`],
height: ["0px", `${n.bounds.height}px`],
margin: [
j(n.targetDOMPosition.parentElement),
n.computedStyle.margin
]
};
s.transitionOptions.delay && r.animate(y(c), { fill: "forwards" });
const a = r.animate(c, e);
o.push({
animation: a,
snapshotPair: t,
cleanup: () => {
i.style.setProperty("display", l), r.remove();
}
});
}, xt = (t, o, e) => {
const { prevSnapshot: n, shared: s } = t;
if (!n)
return;
const {
targetDOMPosition: { parentElement: i, index: r }
} = n, l = R(n.computedStyle.display);
if (!i)
return;
i.insertBefore(l, i.children[r] ?? null);
const c = {
width: [`${n.bounds.width}px`, "0px"],
height: [`${n.bounds.height}px`, "0px"],
margin: [n.computedStyle.margin, j(i)]
};
s.transitionOptions.delay && l.animate(y(c), { fill: "forwards" });
const a = l.animate(c, e);
o.push({
animation: a,
snapshotPair: t,
cleanup: () => l.remove()
});
}, Ot = (t, o) => {
const { shared: e, prevSnapshot: n, nextSnapshot: s } = t, i = {
duration: e.transitionOptions.duration,
easing: e.transitionOptions.easing,
delay: e.transitionOptions.delay,
fill: "forwards"
};
n && s && n.targetDOMPosition.parentElement === s.targetDOMPosition.parentElement && n.targetDOMPosition.index === s.targetDOMPosition.index ? Tt(t, o, i) : (s && Et(t, o, i), n && xt(t, o, i));
}, _ = (t) => {
const o = {
opacity: t.style.opacity,
transition: t.style.transition,
pointerEvents: t.style.pointerEvents,
ariaHidden: t.ariaHidden
};
return t.style.setProperty("opacity", "0", "important"), t.style.setProperty("transition", "none", "important"), t.style.setProperty("pointer-events", "none", "important"), t.ariaHidden = "true", () => {
t.style.opacity = o.opacity, t.style.pointerEvents = o.pointerEvents, t.ariaHidden = o.ariaHidden, setTimeout(() => t.style.transition = o.transition);
};
}, k = (t) => {
const [o, e, n, s, i, r] = t.replace("matrix(", "").replace(")", "").split(", ").map((c) => parseInt(c));
return {
scaleX: o,
skewY: e,
skewX: n,
scaleY: s,
translateX: i,
translateY: r,
toString: function() {
return `matrix(${this.scaleX}, ${this.skewY}, ${this.skewX}, ${this.scaleY}, ${this.translateX}, ${this.translateY})`;
}
};
}, Pt = (t, o, e, n) => {
const { prevSnapshot: s, nextSnapshot: i, shared: r, image: l } = t, c = [s, i].map((f) => {
const T = {
width: `${f.bounds.width}px`,
height: `${f.bounds.height}px`
};
return D.forEach(($) => T[$] = f.computedStyle[$]), T;
});
let a = "";
const d = s.bounds.top - i.bounds.top, u = i.bounds.right - s.bounds.right, g = i.bounds.bottom - s.bounds.bottom, h = s.bounds.left - i.bounds.left;
switch (r.transitionOptions.positionAnchor) {
case "topLeft":
a = `translate(${h}px, ${d}px)`;
break;
case "topRight":
a = `translate(${u}px, ${d}px)`;
break;
case "bottomRight":
a = `translate(${u}px, ${g}px)`;
break;
case "bottomLeft":
a = `translate(${h}px, ${g}px)`;
break;
}
const b = [
{ ...c[0], transform: a },
{ ...c[1], transform: "translate(0, 0)" }
];
r.transitionOptions.delay && l.animate(y(b), { fill: "forwards" });
const p = l.animate(b, o);
e.push({
animation: p,
snapshotPair: t,
cleanup: n
});
}, wt = (t, o, e, n) => {
const { image: s, shared: i, prevSnapshot: r, nextSnapshot: l } = t, c = s.children[0], a = s.children[1];
i.transitionOptions.delay && (c.animate(y(r.transitionOptions.contentExitKeyframes), {
fill: "forwards"
}), a.animate(y(l.transitionOptions.contentEnterKeyframes), {
fill: "forwards"
}));
const d = c.animate(
r.transitionOptions.contentExitKeyframes,
o
), u = a.animate(
l.transitionOptions.contentEnterKeyframes,
o
);
e.push(
{ animation: d, snapshotPair: t, cleanup: n },
{ animation: u, snapshotPair: t, cleanup: n }
);
}, A = (t, o) => {
switch (t) {
case "topLeft":
o.style.transformOrigin = "top left";
break;
case "topCenter":
o.style.transformOrigin = "top center";
break;
case "topRight":
o.style.transformOrigin = "top right";
break;
case "centerRight":
o.style.transformOrigin = "center right";
break;
case "bottomRight":
o.style.transformOrigin = "bottom right";
break;
case "bottomCenter":
o.style.transformOrigin = "bottom center";
break;
case "bottomLeft":
o.style.transformOrigin = "bottom left";
break;
case "centerLeft":
o.style.transformOrigin = "center left";
break;
case "center":
o.style.transformOrigin = "center";
break;
}
}, St = (t, o, e, n) => {
const { prevSnapshot: s, nextSnapshot: i, image: r, shared: l } = t, c = r.children[0].children[0], a = r.children[1].children[0];
A(s.transitionOptions.contentAlign, c), A(i.transitionOptions.contentAlign, a);
const d = k(getComputedStyle(c).transform), u = d.toString();
d.scaleX = i.bounds.width / s.bounds.width, d.scaleY = i.bounds.height / s.bounds.height;
const g = { transform: [u, d.toString()] }, h = k(getComputedStyle(a).transform), b = h.toString();
h.scaleX = s.bounds.width / i.bounds.width, h.scaleY = s.bounds.height / i.bounds.height;
const p = { transform: [h.toString(), b] };
l.transitionOptions.delay && (c.animate(y(g), {
fill: "forwards"
}), a.animate(y(p), {
fill: "forwards"
}));
const f = c.animate(g, o), T = a.animate(
p,
o
);
e.push(
{ animation: f, snapshotPair: t, cleanup: n },
{ animation: T, snapshotPair: t, cleanup: n }
);
}, Rt = (t, o) => {
const { nextSnapshot: e, image: n, shared: s } = t, i = _(e.targetElement), r = {
duration: s.transitionOptions.duration,
easing: s.transitionOptions.easing,
delay: s.transitionOptions.delay,
fill: "forwards"
}, l = () => {
n.remove(), i();
};
Pt(t, r, o, l), wt(t, r, o, l), s.transitionOptions.scaleContent && St(t, r, o, l);
}, K = (t, o, e, n, s) => {
const { shared: i } = e;
i.transitionOptions.delay && t.animate(y(o), {
fill: "forwards"
});
const r = t.animate(o, {
duration: i.transitionOptions.duration,
easing: i.transitionOptions.easing,
delay: i.transitionOptions.delay,
fill: "forwards"
});
return n.push({
snapshotPair: e,
animation: r,
cleanup: () => {
t.remove(), s == null || s();
}
}), r.finished;
}, $t = (t, o) => {
const { prevSnapshot: e, nextSnapshot: n, prevImage: s, nextImage: i } = t, r = n != null && n.targetElement ? _(n.targetElement) : null;
e && s && K(s, e.transitionOptions.exitKeyframes, t, o, r), n && i && K(i, n.transitionOptions.enterKeyframes, t, o, r);
}, vt = (t, o) => {
t.forEach(({ prevSnapshot: e, nextSnapshot: n }) => {
e && n && (B.forEach((s) => {
if (e.transitionOptions[s] !== n.transitionOptions[s])
throw Error(
`"${s}" transition property differ for previous and next snapshots. It should never update while snapshots are being captured. Transition tag: ${e.tag}`
);
}), X.forEach((s) => {
if (e[s] !== n[s])
throw Error(
`"${s}" snapshot property differ for previous and next snapshots. It should never update while snapshots are being captured. Transition tag: ${e.tag}`
);
}));
});
}, At = async (t, o, e) => {
var g, h, b;
const n = { flushSync: !0, ...e }, s = L(t), i = ht(s), r = Object.fromEntries(
i.map((p) => [p, yt(p)])
);
et(...i);
const l = s.map(
(p) => M(
E(p),
p,
s.filter((f) => f !== p)
)
);
o ? n.flushSync ? H(o) : o() : await void 0;
const c = s.map(
(p) => M(
E(p),
p,
s.filter((f) => f !== p)
)
), a = bt(l, c);
vt(a), rt(a), Z(a), z(a, r), it(a), J(a);
const d = st(a);
(g = n.onBegin) == null || g.call(n);
const u = G();
try {
for (const p of a) {
const f = V(u);
f[p.shared.tag] = [], p.transitionType === "mutation" ? Rt(p, f[p.shared.tag]) : p.transitionType === "presence" && $t(p, f[p.shared.tag]), p.shared.transitionOptions.transitionLayout && Ot(p, f[p.shared.tag]);
}
if (w.debug)
return;
await Promise.all(tt(u).map((p) => p.animation.finished)), nt(u), d(), (h = n.onFinish) == null || h.call(n);
} catch (p) {
if (p.name === "AbortError") {
d(), (b = n.onCancel) == null || b.call(n);
return;
}
throw p;
}
}, Kt = (t, o) => {
const e = v(!0), n = v(null);
Y(() => {
n.current && n.current(), n.current = t(e.current), e.current && (e.current = !1);
}, o ?? [{}]);
};
export {
et as cancelTransition,
Mt as constructTransition,
kt as constructTransitionRoot,
w as defaults,
At as startTransition,
Kt as usePreCommitEffect
};