UNPKG

flemo

Version:

A modern React router library with built-in motion animations and smooth transitions

1,705 lines (1,704 loc) 46.1 kB
import { jsx as D, jsxs as ct } from "react/jsx-runtime"; import nt, { useEffect as z, createContext as dt, useContext as pt, useReducer as Ht, Children as It, Suspense as _t, useImperativeHandle as jt, useState as mt, useRef as H, useLayoutEffect as Et } from "react"; import { transform as ft, useAnimate as Lt, motion as J, useDragControls as Ft, AnimatePresence as Qt, MotionConfig as qt } from "motion/react"; var _ = {}, wt; function Yt() { if (wt) return _; wt = 1, Object.defineProperty(_, "__esModule", { value: !0 }), _.PathError = _.TokenData = void 0, _.parse = l, _.compile = m, _.match = P, _.pathToRegexp = L, _.stringify = U; const n = "/", e = (i) => i, t = /^[$_\p{ID_Start}]$/u, r = /^[$\u200c\u200d\p{ID_Continue}]$/u, s = { // Groups. "{": "{", "}": "}", // Reserved. "(": "(", ")": ")", "[": "[", "]": "]", "+": "+", "?": "?", "!": "!" }; function a(i) { return i.replace(/[{}()\[\]+?!:*\\]/g, "\\$&"); } function o(i) { return i.replace(/[.+*?^${}()[\]|/\\]/g, "\\$&"); } class c { constructor(y, g) { this.tokens = y, this.originalPath = g; } } _.TokenData = c; class h extends TypeError { constructor(y, g) { let E = y; g && (E += `: ${g}`), E += "; visit https://git.new/pathToRegexpError for info", super(E), this.originalPath = g; } } _.PathError = h; function l(i, y = {}) { const { encodePath: g = e } = y, E = [...i], p = []; let f = 0, I = 0; function T() { let S = ""; if (t.test(E[f])) do S += E[f++]; while (r.test(E[f])); else if (E[f] === '"') { let M = f; for (; f++ < E.length; ) { if (E[f] === '"') { f++, M = 0; break; } E[f] === "\\" && f++, S += E[f]; } if (M) throw new h(`Unterminated quote at index ${M}`, i); } if (!S) throw new h(`Missing parameter name at index ${f}`, i); return S; } for (; f < E.length; ) { const S = E[f], M = s[S]; M ? p.push({ type: M, index: f++, value: S }) : S === "\\" ? p.push({ type: "escape", index: f++, value: E[f++] }) : S === ":" ? p.push({ type: "param", index: f++, value: T() }) : S === "*" ? p.push({ type: "wildcard", index: f++, value: T() }) : p.push({ type: "char", index: f++, value: S }); } p.push({ type: "end", index: f, value: "" }); function O(S) { const M = []; for (; ; ) { const x = p[I++]; if (x.type === S) break; if (x.type === "char" || x.type === "escape") { let C = x.value, b = p[I]; for (; b.type === "char" || b.type === "escape"; ) C += b.value, b = p[++I]; M.push({ type: "text", value: g(C) }); continue; } if (x.type === "param" || x.type === "wildcard") { M.push({ type: x.type, name: x.value }); continue; } if (x.type === "{") { M.push({ type: "group", tokens: O("}") }); continue; } throw new h(`Unexpected ${x.type} at index ${x.index}, expected ${S}`, i); } return M; } return new c(O("end"), i); } function m(i, y = {}) { const { encode: g = encodeURIComponent, delimiter: E = n } = y, p = typeof i == "object" ? i : l(i, y), f = d(p.tokens, E, g); return function(T = {}) { const [O, ...S] = f(T); if (S.length) throw new TypeError(`Missing parameters: ${S.join(", ")}`); return O; }; } function d(i, y, g) { const E = i.map((p) => u(p, y, g)); return (p) => { const f = [""]; for (const I of E) { const [T, ...O] = I(p); f[0] += T, f.push(...O); } return f; }; } function u(i, y, g) { if (i.type === "text") return () => [i.value]; if (i.type === "group") { const p = d(i.tokens, y, g); return (f) => { const [I, ...T] = p(f); return T.length ? [""] : [I]; }; } const E = g || e; return i.type === "wildcard" && g !== !1 ? (p) => { const f = p[i.name]; if (f == null) return ["", i.name]; if (!Array.isArray(f) || f.length === 0) throw new TypeError(`Expected "${i.name}" to be a non-empty array`); return [ f.map((I, T) => { if (typeof I != "string") throw new TypeError(`Expected "${i.name}/${T}" to be a string`); return E(I); }).join(y) ]; } : (p) => { const f = p[i.name]; if (f == null) return ["", i.name]; if (typeof f != "string") throw new TypeError(`Expected "${i.name}" to be a string`); return [E(f)]; }; } function P(i, y = {}) { const { decode: g = decodeURIComponent, delimiter: E = n } = y, { regexp: p, keys: f } = L(i, y), I = f.map((T) => g === !1 ? e : T.type === "param" ? g : (O) => O.split(E).map(g)); return function(O) { const S = p.exec(O); if (!S) return !1; const M = S[0], x = /* @__PURE__ */ Object.create(null); for (let C = 1; C < S.length; C++) { if (S[C] === void 0) continue; const b = f[C - 1], W = I[C - 1]; x[b.name] = W(S[C]); } return { path: M, params: x }; }; } function L(i, y = {}) { const { delimiter: g = n, end: E = !0, sensitive: p = !1, trailing: f = !0 } = y, I = [], T = p ? "" : "i", O = []; for (const x of N(i, [])) { const C = typeof x == "object" ? x : l(x, y); for (const b of w(C.tokens, 0, [])) O.push(k(b, g, I, C.originalPath)); } let S = `^(?:${O.join("|")})`; return f && (S += `(?:${o(g)}$)?`), S += E ? "$" : `(?=${o(g)}|$)`, { regexp: new RegExp(S, T), keys: I }; } function N(i, y) { if (Array.isArray(i)) for (const g of i) N(g, y); else y.push(i); return y; } function* w(i, y, g) { if (y === i.length) return yield g; const E = i[y]; if (E.type === "group") for (const p of w(E.tokens, 0, g.slice())) yield* w(i, y + 1, p); else g.push(E); yield* w(i, y + 1, g); } function k(i, y, g, E) { let p = "", f = "", I = !0; for (const T of i) { if (T.type === "text") { p += o(T.value), f += T.value, I || (I = T.value.includes(y)); continue; } if (T.type === "param" || T.type === "wildcard") { if (!I && !f) throw new h(`Missing text before "${T.name}" ${T.type}`, E); T.type === "param" ? p += `(${F(y, I ? "" : f)}+)` : p += "([\\s\\S]+)", g.push(T), f = "", I = !1; continue; } } return p; } function F(i, y) { return y.length < 2 ? i.length < 2 ? `[^${o(i + y)}]` : `(?:(?!${o(i)})[^${o(y)}])` : i.length < 2 ? `(?:(?!${o(y)})[^${o(i)}])` : `(?:(?!${o(y)}|${o(i)})[\\s\\S])`; } function Q(i) { let y = "", g = 0; function E(p) { return R(p) && A(i[g]) ? p : JSON.stringify(p); } for (; g < i.length; ) { const p = i[g++]; if (p.type === "text") { y += a(p.value); continue; } if (p.type === "group") { y += `{${Q(p.tokens)}}`; continue; } if (p.type === "param") { y += `:${E(p.name)}`; continue; } if (p.type === "wildcard") { y += `*${E(p.name)}`; continue; } throw new TypeError(`Unknown token type: ${p.type}`); } return y; } function U(i) { return Q(i.tokens); } function R(i) { const [y, ...g] = i; return t.test(y) && g.every((E) => r.test(E)); } function A(i) { return i && i.type === "text" ? !r.test(i.value[0]) : !0; } return _; } var V = Yt(); function Bt(n, e, t) { const r = Array.isArray(n) ? n.find((c) => V.pathToRegexp(c).regexp.test(e)) || "" : V.pathToRegexp(n).regexp.test(e) ? n : "", s = V.match(r)(e), a = new URLSearchParams(t), o = Object.fromEntries(a.entries()); return s ? { ...s.params, ...o } : {}; } function St() { return typeof document > "u"; } class Xt { tasks = /* @__PURE__ */ new Map(); instanceId = Date.now().toString(); isLocked = !1; currentTaskId = null; taskQueue = Promise.resolve(); signalListeners = /* @__PURE__ */ new Map(); pendingTaskQueue = []; isProcessingPending = !1; async acquireLock(e) { for (let s = 0; s < 10; s++) { if (!this.isLocked) return this.isLocked = !0, this.currentTaskId = e, !0; await new Promise((a) => setTimeout(a, 100)); } return !1; } releaseLock(e) { this.currentTaskId === e && (this.isLocked = !1, this.currentTaskId = null); } generateTaskId() { return `${this.instanceId}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } emitSignal(e) { const t = this.signalListeners.get(e); t && (t.forEach((r) => { this.resolveTask(r); }), this.signalListeners.delete(e)); } // 대기 중인 태스크들을 처리하는 메서드 async processPendingTasks() { if (!(this.isProcessingPending || this.pendingTaskQueue.length === 0)) { this.isProcessingPending = !0; try { for (; this.pendingTaskQueue.length > 0; ) { const e = this.pendingTaskQueue[0]; if (e.status === "COMPLETED" || e.status === "FAILED" || e.status === "ROLLEDBACK") { this.pendingTaskQueue.shift(); continue; } if (e.status === "MANUAL_PENDING" || e.status === "SIGNAL_PENDING" || e.status === "PROCESSING" || e.status === "PENDING") break; } } finally { this.isProcessingPending = !1; } } } // 모든 대기 중인 태스크가 완료될 때까지 대기 async waitForPendingTasks() { return new Promise((e) => { const t = () => { this.pendingTaskQueue.filter( (s) => s.status === "MANUAL_PENDING" || s.status === "SIGNAL_PENDING" ).length === 0 ? e() : setTimeout(t, 100); }; t(); }); } // 태스크 상태 변경 시 대기 큐 처리 async onTaskStatusChange(e, t) { (t === "COMPLETED" || t === "FAILED" || t === "ROLLEDBACK") && (this.pendingTaskQueue = this.pendingTaskQueue.filter((r) => r.id !== e), await this.processPendingTasks()); } async addTask(e, t = {}) { const r = t.id || this.generateTaskId(); return new Promise((s, a) => { this.taskQueue = this.taskQueue.then(async () => { try { const { control: o, validate: c, rollback: h, dependencies: l = [], delay: m } = t, d = new AbortController(), u = { id: r, execute: e, timestamp: Date.now(), retryCount: 0, status: "PENDING", dependencies: l, instanceId: this.instanceId, validate: c, rollback: h, control: o, abortController: d }; this.tasks.set(u.id, u), this.pendingTaskQueue.length > 0 && (this.pendingTaskQueue.push(u), await this.waitForPendingTasks(), this.pendingTaskQueue = this.pendingTaskQueue.filter((L) => L.id !== u.id)); try { if (!await this.acquireLock(u.id)) throw u.status = "FAILED", new Error("FAILED"); try { u.status = "PROCESSING"; for (const w of u.dependencies) { const k = this.tasks.get(w); if (!k || k.status !== "COMPLETED") throw u.status = "FAILED", new Error("FAILED"); } if (u.validate && !await u.validate()) throw u.status = "FAILED", new Error("FAILED"); m && m > 0 && await new Promise((w) => setTimeout(w, m)); const N = await u.execute(u.abortController); if (u.abortController.signal.aborted) { u.status = "COMPLETED", await this.onTaskStatusChange(u.id, "COMPLETED"), s({ success: !0, result: void 0, taskId: u.id, timestamp: Date.now(), instanceId: this.instanceId }); return; } if (t.control) { const w = t.control; if (w.delay && w.delay > 0 && await new Promise((k) => setTimeout(k, w.delay)), w.manual) { u.status = "MANUAL_PENDING", u.manualResolver = { resolve: s, reject: a, result: N }, this.pendingTaskQueue.push(u), await this.onTaskStatusChange(u.id, "MANUAL_PENDING"); return; } if (w.signal) { u.status = "SIGNAL_PENDING", u.manualResolver = { resolve: s, reject: a, result: N }, this.signalListeners.has(w.signal) || this.signalListeners.set(w.signal, /* @__PURE__ */ new Set()), this.signalListeners.get(w.signal).add(u.id), this.pendingTaskQueue.push(u), await this.onTaskStatusChange(u.id, "SIGNAL_PENDING"); return; } if (w.condition && !await w.condition()) { u.status = "MANUAL_PENDING", u.manualResolver = { resolve: s, reject: a, result: N }, this.pendingTaskQueue.push(u), await this.onTaskStatusChange(u.id, "MANUAL_PENDING"); return; } } u.status = "COMPLETED", await this.onTaskStatusChange(u.id, "COMPLETED"), s({ success: !0, result: N, taskId: u.id, timestamp: Date.now(), instanceId: this.instanceId }); } catch (N) { if (u.status = "FAILED", u.rollback) try { await u.rollback(), u.status = "ROLLEDBACK"; } catch { } throw await this.onTaskStatusChange(u.id, u.status), N; } finally { this.releaseLock(u.id); } } catch (L) { a(L); } } catch (o) { a(o); } }).catch(a); }); } async resolveTask(e) { const t = this.tasks.get(e); if (!t || t.status !== "MANUAL_PENDING") return !1; if (t.manualResolver) { if (t.control?.condition && !await t.control.condition()) return !1; t.status = "COMPLETED"; const r = t.manualResolver; return r.resolve({ success: !0, result: r.result, taskId: t.id, timestamp: Date.now(), instanceId: this.instanceId }), delete t.manualResolver, await this.onTaskStatusChange(e, "COMPLETED"), !0; } return !1; } async resolveAllPending() { const e = Array.from(this.tasks.values()).filter( (t) => ["PENDING", "MANUAL_PENDING", "SIGNAL_PENDING"].includes(t.status) ); await Promise.all(e.map((t) => this.resolveTask(t.id))); } } const q = new Xt(), Pt = (n) => { let e; const t = /* @__PURE__ */ new Set(), r = (l, m) => { const d = typeof l == "function" ? l(e) : l; if (!Object.is(d, e)) { const u = e; e = m ?? (typeof d != "object" || d === null) ? d : Object.assign({}, e, d), t.forEach((P) => P(e, u)); } }, s = () => e, c = { setState: r, getState: s, getInitialState: () => h, subscribe: (l) => (t.add(l), () => t.delete(l)) }, h = e = n(r, s, c); return c; }, Kt = ((n) => n ? Pt(n) : Pt), Vt = (n) => n; function zt(n, e = Vt) { const t = nt.useSyncExternalStore( n.subscribe, nt.useCallback(() => e(n.getState()), [n, e]), nt.useCallback(() => e(n.getInitialState()), [n, e]) ); return nt.useDebugValue(t), t; } const Tt = (n) => { const e = Kt(n), t = (r) => zt(e, r); return Object.assign(t, e), t; }, st = ((n) => n ? Tt(n) : Tt), Y = st((n) => ({ index: -1, histories: [], addHistory: (e) => n((t) => ({ index: t.index + 1, histories: t.histories.concat(e) })), replaceHistory: (e) => n((t) => (t.histories.splice(e, 1), { index: t.index - 1, histories: t.histories })), popHistory: (e) => n((t) => ({ index: t.index - 1, histories: t.histories.filter((r, s) => s !== e) })) })), j = st((n) => ({ status: "IDLE", setStatus: (e) => n({ status: e }) })); function Wt() { return z(() => { const n = async (e) => { const t = e.state?.id; (await q.addTask( async (r) => { const s = e.state?.index, a = e.state?.status, o = e.state?.params, c = e.state?.transitionName, h = e.state?.layoutId, l = j.getState().setStatus, { index: m, addHistory: d, popHistory: u } = Y.getState(), P = s < m, L = a === "PUSHING" && s > m, N = a === "REPLACING" && s > m, w = window.location.pathname; if (!P && !L && !N) { r.abort(); return; } return P ? l("POPPING") : L ? (l("PUSHING"), d({ id: t, pathname: w, params: o, transitionName: c, layoutId: h })) : N && (l("REPLACING"), d({ id: t, pathname: w, params: o, transitionName: c, layoutId: h })), async () => { P && u(s + 1), l("COMPLETED"); }; }, { id: t, control: { manual: !0 } } )).result?.(); }; return window.addEventListener("popstate", n), () => { window.removeEventListener("popstate", n); }; }, []), null; } const xt = dt({}), Nt = dt(() => { }); function Jt(n, e) { switch (e.type) { case "SET": return e.params; default: return n; } } const kt = dt({ id: "", isActive: !1, isRoot: !0, isPrev: !1, zIndex: 0, pathname: "", params: {}, transitionName: "none", prevTransitionName: "none", layoutId: null }); function tt() { return pt(kt); } function Zt({ children: n }) { const { isActive: e, params: t } = tt(), [r, s] = Ht(Jt, t); return z(() => { const a = async (o) => { o.state?.step && await q.addTask(async () => { s({ type: "SET", params: o.state?.params || {} }); }); }; return e && window.addEventListener("popstate", a), () => { window.removeEventListener("popstate", a); }; }, [e, s]), /* @__PURE__ */ D(Nt.Provider, { value: s, children: /* @__PURE__ */ D(xt.Provider, { value: r, children: n }) }); } function te({ children: n }) { const e = Y((r) => r.index), t = Y((r) => r.histories); return t.map( (r) => It.toArray(n).filter( (s) => V.pathToRegexp(s.props.path).regexp.test( r.pathname ) ) ).map(([r], s) => /* @__PURE__ */ D( kt.Provider, { value: { id: t[s].id, isActive: s === e, isRoot: s === 0, isPrev: s < e - 1, zIndex: s, pathname: t[s].pathname, params: t[s].params, transitionName: t[e].transitionName, prevTransitionName: t[e - 1]?.transitionName, layoutId: t[s].layoutId }, children: /* @__PURE__ */ D(Zt, { children: r }) }, t[s].id )); } function ee({ name: n, initial: e, enter: t, exit: r, options: s }) { return { name: n, initial: e, variants: { "IDLE-true": t, "IDLE-false": t, "PUSHING-false": r, "PUSHING-true": t, "REPLACING-false": r, "REPLACING-true": t, "POPPING-false": t, "POPPING-true": t, "COMPLETED-false": r, "COMPLETED-true": t }, ...s }; } const ne = ee({ name: "overlay", initial: { opacity: 0, backgroundColor: "rgba(0, 0, 0, 0)" }, enter: { value: { opacity: 0, backgroundColor: "rgba(0, 0, 0, 0.3)" }, options: { duration: 0.3 } }, exit: { value: { opacity: 1, backgroundColor: "rgba(0, 0, 0, 0.3)" }, options: { duration: 0.3 } }, options: { onSwipeStart: (n, { animate: e, prevDecorator: t }) => e( t, { opacity: n ? 1 : 0 }, { duration: 0.3 } ), onSwipe: (n, e, { animate: t, prevDecorator: r }) => t( r, { opacity: Math.max(0, 1 - e / 100) }, { duration: 0 } ), onSwipeEnd: (n, { animate: e, prevDecorator: t }) => e( t, { opacity: n ? 0 : 1 }, { duration: 0.3 } ) } }), ht = /* @__PURE__ */ new Map([["overlay", ne]]), ut = st((n) => ({ defaultTransitionName: "cupertino", setDefaultTransitionName: (e) => n({ defaultTransitionName: e }) })); function rt({ name: n, initial: e, idle: t, enter: r, enterBack: s, exit: a, exitBack: o, options: c }) { return { name: n, initial: e, variants: { "IDLE-true": t, "IDLE-false": t, "PUSHING-false": a, "PUSHING-true": r, "REPLACING-false": a, "REPLACING-true": r, "POPPING-false": o, "POPPING-true": s, "COMPLETED-false": a, "COMPLETED-true": r }, ...c }; } const se = rt({ name: "cupertino", initial: { x: "100%" }, idle: { value: { x: 0 }, options: { duration: 0 } }, enter: { value: { x: 0 }, options: { duration: 0.3, ease: [0.32, 0.72, 0, 1] } }, enterBack: { value: { x: "100%" }, options: { duration: 0.3, ease: [0.32, 0.72, 0, 1] } }, exit: { value: { x: -100 }, options: { duration: 0.3, ease: [0.32, 0.72, 0, 1] } }, exitBack: { value: { x: 0 }, options: { duration: 0.3, ease: [0.32, 0.72, 0, 1] } }, options: { decoratorName: "overlay", swipeDirection: "x", onSwipeStart: async () => !0, onSwipe: (n, e, { animate: t, currentScreen: r, prevScreen: s, onProgress: a }) => { const { offset: o } = e, c = o.x, h = ft(c, [0, window.innerWidth], [0, 100]); return a?.(!0, h), t( r, { x: Math.max(0, c) }, { duration: 0 } ), t( s, { x: -100 + h }, { duration: 0 } ), h; }, onSwipeEnd: async (n, e, { animate: t, currentScreen: r, prevScreen: s, onStart: a }) => { const { offset: o, velocity: c } = e, l = o.x > 50 || c.x > 20; return a?.(l), await Promise.all([ t( r, { x: l ? "100%" : 0 }, { duration: 0.3, ease: [0.32, 0.72, 0, 1] } ), t( s, { x: l ? 0 : -100 }, { duration: 0.3, ease: [0.32, 0.72, 0, 1] } ) ]), l; } } }), re = rt({ name: "layout", initial: { opacity: 0.97 }, idle: { value: { opacity: 1 }, options: { duration: 0.3 } }, enter: { value: { opacity: 1 }, options: { duration: 0.3 } }, enterBack: { value: { opacity: 0.97 }, options: { duration: 0.3 } }, exit: { value: { opacity: 0.97 }, options: { duration: 0.3 } }, exitBack: { value: { opacity: 1 }, options: { duration: 0.3 } }, options: { decoratorName: "overlay", swipeDirection: "y", onSwipeStart: async () => !0, onSwipe: (n, e, { animate: t, currentScreen: r, onProgress: s }) => { const { offset: a } = e, o = a.y, c = Math.max(0, Math.min(56, o)), h = ft(c, [0, 56], [1, 0.96]), l = Math.max(0, o - 56), m = Math.min(1, l / 160), d = Math.sqrt(m) * 12, u = Math.max(0, c + d), P = Math.min(56, u); return s?.(!0, 100), t( r, { y: u, opacity: h }, { duration: 0 } ), P; }, onSwipeEnd: async (n, e, { animate: t, currentScreen: r, prevScreen: s, onStart: a }) => { const { offset: o, velocity: c } = e, l = o.y > 56 || c.y > 20; return a?.(l), await Promise.all([ t( r, { y: l ? "100%" : 0, opacity: l ? 0.96 : 1 }, { duration: 0.3 } ), t( s, { y: 0, opacity: l ? 1 : 0.97 }, { duration: 0.3 } ) ]), l; } } }), ae = rt({ name: "material", initial: { y: "100%", opacity: 0.96 }, idle: { value: { y: 0, opacity: 1 }, options: { duration: 0 } }, enter: { value: { y: 0, opacity: 1 }, options: { duration: 0.24, ease: [0, 0, 0.2, 1] } }, enterBack: { value: { y: "100%", opacity: 0.96 }, options: { duration: 0.22, ease: [0.4, 0, 1, 1] } }, exit: { value: { y: -56, opacity: 0.96 }, options: { duration: 0.22, ease: [0.4, 0, 1, 1] } }, exitBack: { value: { y: 0, opacity: 1 }, options: { duration: 0.24, ease: [0, 0, 0.2, 1] } }, options: { swipeDirection: "y", onSwipeStart: async () => !0, onSwipe: (n, e, { animate: t, currentScreen: r, prevScreen: s, onProgress: a }) => { const { offset: o } = e, c = o.y, h = Math.max(0, Math.min(56, c)), l = ft(h, [0, 56], [1, 0.96]), m = Math.max(0, c - 56), d = Math.min(1, m / 160), u = Math.sqrt(d) * 12, P = Math.max(0, h + u), L = Math.min(56, P); return a?.(!0, L), t( r, { y: P, opacity: l }, { duration: 0 } ), t( s, { y: -56 + L, opacity: L / 56 }, { duration: 0 } ), L; }, onSwipeEnd: async (n, e, { animate: t, currentScreen: r, prevScreen: s, onStart: a }) => { const { offset: o, velocity: c } = e, l = o.y > 56 || c.y > 20; return a?.(l), await Promise.all([ t( r, { y: l ? "100%" : 0, opacity: l ? 0.96 : 1 }, { duration: l ? 0.22 : 0.24, ease: l ? [0.4, 0, 1, 1] : [0, 0, 0.2, 1] } ), t( s, { y: l ? 0 : -56, opacity: l ? 1 : 0.96 }, { duration: l ? 0.22 : 0.24, ease: l ? [0, 0, 0.2, 1] : [0.4, 0, 1, 1] } ) ]), l; } } }), oe = rt({ name: "none", initial: {}, idle: { value: {}, options: { duration: 0 } }, enter: { value: {}, options: { duration: 0 } }, enterBack: { value: {}, options: { duration: 0 } }, exit: { value: {}, options: { duration: 0 } }, exitBack: { value: {}, options: { duration: 0 } } }), et = /* @__PURE__ */ new Map([ ["none", oe], ["cupertino", se], ["material", ae], ["layout", re] ]), ie = (() => { const n = /* @__PURE__ */ Object.create(null), e = Object.prototype.hasOwnProperty; for (const t of et.values()) { const r = t.variants["IDLE-true"].value; for (const s in r) e.call(r, s) && (n[s] = r[s]); } return n; })(); function ye({ children: n, initPath: e = "/", defaultTransitionName: t = "cupertino", transitions: r = [], decorators: s = [] }) { const a = St() ? e || "/" : window.location.pathname, o = St() ? a.split("?")[1] || "" : window.location.search; return ut.setState({ defaultTransitionName: t }), Y.setState({ index: 0, histories: [ { id: "root", pathname: a, params: Bt( It.toArray(n).map((c) => c.props.path).flat(), a, o ), transitionName: t, layoutId: null } ] }), z(() => { window.history.state?.index || window.history.replaceState( { id: "root", index: 0, status: "IDLE", params: {}, transitionName: t, layoutId: null }, "", window.location.pathname ); }, [t]), z(() => { r.forEach((c) => et.set(c.name, c)); }, [r]), z(() => { s.forEach((c) => ht.set(c.name, c)); }, [s]), /* @__PURE__ */ ct( "div", { style: { position: "fixed", top: 0, left: 0, width: "100%", height: "100%" }, children: [ /* @__PURE__ */ D(Wt, {}), /* @__PURE__ */ D(te, { children: n }) ] } ); } function ge({ element: n }) { return n; } function me() { return { push: async (r, s, a = {}) => { const { status: o, setStatus: c } = j.getState(); if (o !== "COMPLETED" && o !== "IDLE") return; const { index: h, addHistory: l } = Y.getState(), m = ut.getState().defaultTransitionName, { transitionName: d = m, layoutId: u = null } = a, P = q.generateTaskId(); (await q.addTask( async () => { c("PUSHING"); const L = V.compile(r), N = Object.fromEntries( Object.entries(s).map(([R, A]) => [R, String(A)]) ), w = L(N), k = V.parse(r).tokens.filter((R) => R.type === "param").map((R) => R.name), F = Object.fromEntries( Object.entries(s).filter(([R]) => !k.includes(R)) ), Q = new URLSearchParams(F).toString(), U = `${w}${Q ? `?${Q}` : ""}`; return window.history.pushState( { id: P, index: h + 1, status: "PUSHING", params: s, transitionName: d, layoutId: u }, "", U ), l({ id: P, pathname: w, params: s, transitionName: d, layoutId: u }), () => { c("COMPLETED"); }; }, { id: P, control: { manual: !0 } } )).result?.(); }, replace: async (r, s, a = {}) => { const { status: o, setStatus: c } = j.getState(); if (o !== "COMPLETED" && o !== "IDLE") return; const { index: h, addHistory: l } = Y.getState(), m = Y.getState().replaceHistory, d = ut.getState().defaultTransitionName, { transitionName: u = d, layoutId: P = null } = a, L = q.generateTaskId(); (await q.addTask( async () => { c("REPLACING"); const N = V.compile(r), w = Object.fromEntries( Object.entries(s).map(([A, i]) => [A, String(i)]) ), k = N(w), F = V.parse(r).tokens.filter((A) => A.type === "param").map((A) => A.name), Q = Object.fromEntries( Object.entries(s).filter(([A]) => !F.includes(A)) ), U = new URLSearchParams(Q).toString(), R = `${k}${U ? `?${U}` : ""}`; return window.history.replaceState( { id: L, index: h, status: "REPLACING", params: s, transitionName: u, layoutId: P }, "", R ), l({ id: L, pathname: k, params: s, transitionName: u, layoutId: P }), async () => { m(h), c("COMPLETED"); }; }, { id: L, control: { manual: !0 } } )).result?.(); }, pop: () => { const r = j.getState().status; r !== "COMPLETED" && r !== "IDLE" || window.history.back(); } }; } function Ee() { const n = pt(Nt); return { pushStep: async (s) => { const a = j.getState().status; a !== "COMPLETED" && a !== "IDLE" || (await q.addTask(async () => { const o = new URLSearchParams(s).toString(), c = `${window.location.pathname}${o ? `?${o}` : ""}`; return window.history.state?.step || window.history.replaceState( { ...window.history.state, step: !0 }, "", window.location.pathname ), window.history.pushState( { ...window.history.state, step: !0, params: s }, "", c ), async () => n({ type: "SET", params: s }); })).result?.(); }, replaceStep: async (s) => { const a = j.getState().status; a !== "COMPLETED" && a !== "IDLE" || (await q.addTask(async () => { const o = new URLSearchParams(s).toString(), c = `${window.location.pathname}${o ? `?${o}` : ""}`; return window.history.replaceState( { ...window.history.state, step: !0, params: s }, "", c ), async () => n({ type: "SET", params: s }); })).result?.(); }, popStep: () => { const s = j.getState().status; s !== "COMPLETED" && s !== "IDLE" || window.history.back(); } }; } function we() { return pt(xt); } function Se({ name: n, initial: e, idle: t, pushOnEnter: r, pushOnExit: s, replaceOnEnter: a, replaceOnExit: o, popOnEnter: c, popOnExit: h, completedOnExit: l, completedOnEnter: m, options: d }) { return { name: n, initial: e, variants: { "IDLE-true": t, "IDLE-false": t, "PUSHING-false": s, "PUSHING-true": r, "REPLACING-false": o, "REPLACING-true": a, "POPPING-false": h, "POPPING-true": c, "COMPLETED-false": l, "COMPLETED-true": m }, ...d }; } function Pe({ name: n, initial: e, idle: t, pushOnEnter: r, pushOnExit: s, replaceOnEnter: a, replaceOnExit: o, popOnEnter: c, popOnExit: h, completedOnEnter: l, completedOnExit: m, options: d }) { return { name: n, initial: e, variants: { "IDLE-true": t, "IDLE-false": t, "PUSHING-false": s, "PUSHING-true": r, "REPLACING-false": o, "REPLACING-true": a, "POPPING-false": h, "POPPING-true": c, "COMPLETED-false": m, "COMPLETED-true": l }, ...d }; } const ce = { then() { } }; function ue({ freeze: n, children: e }) { if (n) throw ce; return e; } function Mt({ freeze: n, children: e, placeholder: t }) { return /* @__PURE__ */ D(_t, { fallback: t, children: /* @__PURE__ */ D(ue, { freeze: n, children: e }) }); } function vt(n, e) { const { direction: t = "x", markerSelector: r = "[data-swipe-at-edge]", depthLimit: s = 24, verifyByScroll: a = !1 } = e ?? {}, o = le(n); if (!o) return { element: null, hasMarker: !1 }; const c = o.closest?.(r); if (c instanceof HTMLElement && lt(c, t) && (!a || Dt(c, t))) return { element: c, hasMarker: !0 }; let h = o, l = 0; for (; h && h !== document.body && l < s; ) { if (lt(h, t) && (!a || Dt(h, t))) return { element: h, hasMarker: !1 }; h = h.parentElement, l++; } return { element: null, hasMarker: !1 }; } function le(n) { if (!n) return null; const e = n, t = typeof e.composedPath == "function" ? e.composedPath() : void 0; if (t && t.length) { for (const r of t) if (r instanceof HTMLElement) return r; } return n; } function lt(n, e) { return e === "y" ? n.scrollHeight - n.clientHeight > 1 : n.scrollWidth - n.clientWidth > 1; } function Dt(n, e) { if (!lt(n, e)) return !1; if (e === "y") { const t = n.scrollTop; if (n.scrollTop = t + 1, n.scrollTop !== t) return n.scrollTop = t, !0; n.scrollTop = t - 1; const s = n.scrollTop !== t; return n.scrollTop = t, s; } else { const t = n.scrollLeft; if (n.scrollLeft = t + 1, n.scrollLeft !== t) return n.scrollLeft = t, !0; n.scrollLeft = t - 1; const s = n.scrollLeft !== t; return n.scrollLeft = t, s; } } function de({ children: n, ref: e, ...t }) { const { isActive: r, transitionName: s } = tt(), [a, o] = Lt(); jt(e, () => a.current); const c = j((u) => u.status), h = et.get(s), { decoratorName: l } = h, { initial: m, variants: d } = ht.get(l); return z(() => { if (!a.current) return; const { value: u, options: P } = d[`${c}-${r}`]; o(a.current, u, P); }, [c, r, o, d, a]), /* @__PURE__ */ D( J.div, { ref: a, initial: m, style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", pointerEvents: "none", ...t.style }, "data-decorator": !0 } ); } const Z = st((n) => ({ dragStatus: "IDLE", replaceTransitionStatus: "IDLE", setDragStatus: (e) => n({ dragStatus: e }), setReplaceTransitionStatus: (e) => n({ replaceTransitionStatus: e }) })); function Ct({ children: n, statusBarHeight: e, statusBarColor: t, systemNavigationBarHeight: r, systemNavigationBarColor: s, appBar: a, navigationBar: o, hideStatusBar: c, hideSystemNavigationBar: h, ...l }) { const [m, d] = Lt(), { id: u, isActive: P, isRoot: L, transitionName: N, prevTransitionName: w } = tt(), k = Ft(), F = j((v) => v.status), Q = Z((v) => v.dragStatus), U = Z.getState().setDragStatus, R = Z.getState().setReplaceTransitionStatus, A = et.get(N), { variants: i, initial: y, swipeDirection: g, decoratorName: E } = A, p = ht.get(E), [f, I] = mt(0), [T, O] = mt(0), S = H(null), M = H(null), x = H(null), C = H(null), b = H(!1), W = H(!1), B = H({ element: null, hasMarker: !1 }), X = H({ element: null, hasMarker: !1 }), yt = H(0), gt = H(0), at = H(null), ot = H(null), bt = async (v, G) => { if (!g) return; const $ = S.current?.previousSibling; M.current = $?.querySelector("[data-screen]"), C.current = $?.querySelector("[data-decorator]"); const K = await A?.onSwipeStart(v, G, { animate: d, currentScreen: m.current, prevScreen: M.current, dragControls: k, onStart: (it) => p?.onSwipeStart?.(it, { animate: d, currentDecorator: x.current, prevDecorator: C.current }) }); U(K ? "PENDING" : "IDLE"); }, At = (v, G) => { !g || Q !== "PENDING" || A?.onSwipe(v, G, { animate: d, currentScreen: m.current, prevScreen: M.current, dragControls: k, onProgress: ($, K) => p?.onSwipe?.($, K, { animate: d, currentDecorator: x.current, prevDecorator: C.current }) }); }, Rt = async (v, G) => { if (!g || Q !== "PENDING") return; await A?.onSwipeEnd(v, G, { animate: d, currentScreen: m.current, prevScreen: M.current, onStart: (K) => p?.onSwipeEnd?.(K, { animate: d, currentDecorator: x.current, prevDecorator: C.current }) }) ? window.history.back() : U("IDLE"); }, Ot = (v) => { if (!(!L && P && F === "COMPLETED" && Q === "IDLE" && !!g)) return; B.current = vt(v.target, { direction: "x", verifyByScroll: !0 }), X.current = vt(v.target, { direction: "y", verifyByScroll: !0 }), yt.current = v.clientX, gt.current = v.clientY, (!B.current.element && !X.current.element || B.current.element || X.current.element) && (b.current = !0); }, Gt = (v) => { const G = !B.current.element && !X.current.element; if (b.current && G) b.current = !1, W.current = !0, k.start(v); else if (b.current && !G) { const $ = v.clientX - yt.current, K = v.clientY - gt.current, it = X.current.element && X.current.element.scrollTop <= 0 && X.current.hasMarker, Ut = B.current.element && B.current.element.scrollLeft <= 0 && B.current.hasMarker; (g === "y" && (it || B.current.element) && K > 0 && Math.abs($) < 4 || g === "x" && (Ut || X.current.element) && $ > 0 && Math.abs(K) < 4) && (b.current = !1, W.current = !0, k.start(v)); } }, $t = () => { b.current = !1, W.current = !1; }; return z(() => { const v = m.current; if (!v) return; const G = ($) => { W.current && $.preventDefault(), $.target?.dataset.swipeAtEdgeBar === "true" && $.preventDefault(); }; return v.addEventListener("touchmove", G, { passive: !1 }), () => { v.removeEventListener("touchmove", G); }; }, [m]), z(() => { m.current && (async () => { const { value: v, options: G } = i[`${F}-${P}`]; !P && F === "REPLACING" && w !== N && (R("PENDING"), await d(m.current, ie, { duration: 0.1 })), P && F === "COMPLETED" && (U("IDLE"), R("IDLE")), await d(m.current, v, G), await q.resolveTask(u); })(); }, [ F, P, u, w, N, d, m, i, U, R ]), Et(() => { at.current && I(at.current.offsetHeight); }, [a]), Et(() => { ot.current && O(ot.current.offsetHeight); }, [o]), /* @__PURE__ */ ct( J.div, { ref: S, style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", display: "flex", flexDirection: "column", boxSizing: "border-box", isolation: "isolate", contain: "strict", overscrollBehavior: "contain" }, children: [ /* @__PURE__ */ D( "div", { "data-swipe-at-edge-bar": !0, style: { position: "absolute", top: 0, left: 0, width: 8, height: "100%", zIndex: 1 } } ), a && /* @__PURE__ */ D( J.div, { ref: at, style: { position: "absolute", top: c ? 0 : e, left: 0, width: "100%" }, children: a } ), /* @__PURE__ */ ct( J.div, { ref: m, ...l, initial: y, drag: g, dragListener: !1, dragControls: k, onDragStart: bt, onDrag: At, onDragEnd: Rt, onPointerDown: Ot, onPointerMove: Gt, onPointerUp: $t, "data-screen": !0, style: { display: "flex", flexDirection: "column", height: "100%", backgroundColor: "white", touchAction: "none", overflowY: "auto", ...l.style }, children: [ !c && e && /* @__PURE__ */ D( J.div, { animate: { backgroundColor: t }, style: { width: "100%", minHeight: e } } ), a && /* @__PURE__ */ D( "div", { style: { width: "100%", minHeight: f } } ), /* @__PURE__ */ D("div", { style: { display: "flex", flexDirection: "column", flexGrow: 1 }, children: n }), o && /* @__PURE__ */ D( "div", { style: { width: "100%", minHeight: T } } ), !h && r && /* @__PURE__ */ D( J.div, { animate: { backgroundColor: s }, style: { width: "100%", minHeight: r } } ) ] } ), o && /* @__PURE__ */ D( J.div, { ref: ot, style: { position: "absolute", bottom: h ? 0 : r, left: 0, width: "100%" }, children: o } ), p && /* @__PURE__ */ D(de, { ref: x }), /* @__PURE__ */ D( "div", { "data-swipe-at-edge-bar": !0, style: { position: "absolute", top: 0, right: 0, width: 8, height: "100%", zIndex: 1 } } ) ] } ); } function Te({ children: n, ...e }) { const { isActive: t, isPrev: r, zIndex: s } = tt(), a = Y((d) => d.index), o = j((d) => d.status), c = Z((d) => d.dragStatus), h = Z((d) => d.replaceTransitionStatus), m = !t && (o === "COMPLETED" && c === "IDLE") || r && a - 2 <= s && h === "IDLE" || r && a - 2 > s; return /* @__PURE__ */ D(Mt, { freeze: m, children: /* @__PURE__ */ D(Ct, { ...e, children: n }) }); } function ve({ children: n, ...e }) { const { isActive: t, isPrev: r, zIndex: s } = tt(), a = Y((d) => d.index), o = j((d) => d.status), c = Z((d) => d.dragStatus), h = Z((d) => d.replaceTransitionStatus), m = !t && (o === "COMPLETED" && c === "IDLE") || r && a - 2 <= s && h === "IDLE" || r && a - 2 > s; return /* @__PURE__ */ D(Mt, { freeze: m, children: /* @__PURE__ */ D( Ct, { ...e, style: { backgroundColor: "transparent", ...e.style }, children: /* @__PURE__ */ D(Qt, { children: n }) } ) }); } function De({ children: n, ...e }) { const { isActive: t, transitionName: r } = tt(), s = j((o) => o.status), a = et.get(r); return /* @__PURE__ */ D( qt, { transition: a?.variants[`${s}-${t}`]?.options, ...e, children: n } ); } export { De as LayoutConfig, ve as LayoutScreen, ge as Route, ye as Router, Te as Screen, ee as createDecorator, Pe as createRawDecorator, Se as createRawTransition, rt as createTransition, me as useNavigate, we as useParams, tt as useScreen, Ee as useStep };