UNPKG

ranui

Version:

A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.

239 lines (238 loc) 6.43 kB
var c = null, r = null, h = null; function P() { return h; } function x(e) { h = e; } function E() { h = null; } function m(e) { const t = {}; return e && new URLSearchParams(e.startsWith("?") ? e.slice(1) : e).forEach((n, a) => { t[a] = n; }), t; } function f(e, t, n) { const a = [], s = e.split("/").map((i) => i.startsWith(":") ? (a.push(i.slice(1)), "([^/]+)") : i === "*" ? "(.*)" : i.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("/"), o = t ? new RegExp(`^${s}$`) : new RegExp(`^${s}(?:/.*)?$`), u = n.match(o); if (!u) return { matched: !1, params: {} }; const d = {}; return a.forEach((i, w) => { d[i] = decodeURIComponent(u[w + 1] ?? ""); }), { matched: !0, params: d }; } function g(e, t) { return e ? `${e.replace(/\/$/, "")}/${t.replace(/^\//, "")}` : t; } function l(e, t = "") { const n = []; for (const a of e) { const s = g(t, a.path); n.push({ path: s, exact: a.exact ?? !1, meta: a.meta }), a.children?.length && n.push(...l(a.children, s)); } return n; } function v() { return typeof document < "u" && "startViewTransition" in document; } function b(e) { v() ? document.startViewTransition(e) : e(); } function p() { typeof document > "u" || r && document.head.contains(r) || (r = document.createElement("style"), r.textContent = "@view-transition { navigation: auto; }", document.head.appendChild(r)); } function _() { r?.remove(), r = null; } function y(e) { return e === !0 || e === "spa" || e === "both"; } function S(e) { return e === "mpa" || e === "both"; } var R = class { _mode; _base; _routes; _flatRoutes; _vtMode; _beforeGuards = []; _afterGuards = []; _changeHandlers = []; _pageSwapHandlers = []; _pageRevealHandlers = []; _components = /* @__PURE__ */ new Set(); _current = null; _mpaActive = !1; constructor(e = {}) { this._mode = e.mode ?? "history", this._base = e.base ?? "", this._routes = e.routes ?? [], this._flatRoutes = l(this._routes), this._vtMode = e.viewTransition, S(this._vtMode) && this._enableMpa(); } get mode() { return this._mode; } get base() { return this._base; } get routes() { return [...this._routes]; } get currentRoute() { return this._current; } matchRoute(e) { const t = this._flatRoutes.find((n) => f(n.path, n.exact, e).matched); return t ? { path: t.path, exact: t.exact, meta: t.meta } : null; } matchParams(e) { for (const t of this._flatRoutes) { const n = f(t.path, t.exact, e); if (n.matched) return n.params; } return {}; } getStaticPaths() { return this._flatRoutes.map((e) => e.path); } _enableMpa() { this._mpaActive || (this._mpaActive = !0, p(), typeof window < "u" && (window.addEventListener("pageswap", this._onPageSwap), window.addEventListener("pagereveal", this._onPageReveal))); } _disableMpa() { this._mpaActive && (this._mpaActive = !1, _(), typeof window < "u" && (window.removeEventListener("pageswap", this._onPageSwap), window.removeEventListener("pagereveal", this._onPageReveal))); } _onPageSwap = (e) => { this._pageSwapHandlers.forEach((t) => t(e)); }; _onPageReveal = (e) => { this._pageRevealHandlers.forEach((t) => t(e)); }; _bind(e) { this._components.add(e); } _unbind(e) { this._components.delete(e); } _buildLocation(e) { const t = e.indexOf("?"), n = t === -1 ? e : e.slice(0, t), a = t === -1 ? "" : e.slice(t + 1); return { path: n || "/", params: {}, query: m(a), fullPath: e || "/" }; } _getCurrentPath() { if (typeof window > "u") return "/"; if (this._mode === "hash") return window.location.hash.slice(1) || "/"; const e = window.location.pathname, t = this._base; return (t && e.startsWith(t) ? e.slice(t.length) || "/" : e) + (window.location.search || ""); } _notify() { const e = this._buildLocation(this._getCurrentPath()); e.params = this.matchParams(e.path); const t = this._current; this._current = e; const n = () => { this._components.forEach((a) => a._syncRoutes()); }; y(this._vtMode) ? b(n) : n(), this._afterGuards.forEach((a) => a(e, t)), this._changeHandlers.forEach((a) => a(e, t)); } async _navigate(e, t) { const n = this._buildLocation(e), a = this._current; for (const s of this._beforeGuards) { const o = await new Promise((u) => { s(n, a, u); }); if (o === !1) return; if (typeof o == "string") return this._navigate(o, t); } if (typeof window < "u") { const s = this._mode === "hash" ? `#${e}` : this._base + e; t ? window.history.replaceState({ path: e }, "", s) : window.history.pushState({ path: e }, "", s); } this._notify(); } push(e) { return this._navigate(e, !1); } replace(e) { return this._navigate(e, !0); } back() { typeof window < "u" && window.history.back(); } forward() { typeof window < "u" && window.history.forward(); } go(e) { typeof window < "u" && window.history.go(e); } destroy() { this._disableMpa(), this._components.clear(); } beforeEach(e) { return this._beforeGuards.push(e), () => { const t = this._beforeGuards.indexOf(e); t !== -1 && this._beforeGuards.splice(t, 1); }; } afterEach(e) { return this._afterGuards.push(e), () => { const t = this._afterGuards.indexOf(e); t !== -1 && this._afterGuards.splice(t, 1); }; } onRouteChange(e) { return this._changeHandlers.push(e), () => { const t = this._changeHandlers.indexOf(e); t !== -1 && this._changeHandlers.splice(t, 1); }; } onPageSwap(e) { return this._pageSwapHandlers.push(e), () => { const t = this._pageSwapHandlers.indexOf(e); t !== -1 && this._pageSwapHandlers.splice(t, 1); }; } onPageReveal(e) { return this._pageRevealHandlers.push(e), () => { const t = this._pageRevealHandlers.indexOf(e); t !== -1 && this._pageRevealHandlers.splice(t, 1); }; } }; function H(e) { c?.destroy(); const t = new R(e); return c = t, t; } function M() { return c; } function G() { return p(), () => _(); } export { R as RouterCore, E as clearSSGPath, H as createRouter, G as enableMpaViewTransitions, P as getSSGPath, f as matchPath, x as setSSGPath, M as useRouter };