UNPKG

react-smooth-flow

Version:

Effortless React animations for entering, exiting, and updating elements

746 lines (745 loc) 26.7 kB
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 };