UNPKG

react-vt-router

Version:

A tiny React router with View Transitions using native Web APIs.

11 lines (10 loc) 20.1 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t,e=require("react"),r={exports:{}},n={};var o,a,i={}; /** * @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. */function s(){return o||(o=1,"production"!==process.env.NODE_ENV&&function(){function t(e){if(null==e)return null;if("function"==typeof e)return e.$$typeof===S?null:e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case m:return"Fragment";case y:return"Profiler";case p:return"StrictMode";case g:return"Suspense";case x:return"SuspenseList";case k:return"Activity"}if("object"==typeof e)switch("number"==typeof e.tag&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case h:return"Portal";case w:return(e.displayName||"Context")+".Provider";case v:return(e._context.displayName||"Context")+".Consumer";case b:var r=e.render;return(e=e.displayName)||(e=""!==(e=r.displayName||r.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case R:return null!==(r=e.displayName||null)?r:t(e.type)||"Memo";case _:r=e._payload,e=e._init;try{return t(e(r))}catch(t){}}return null}function r(t){return""+t}function n(t){try{r(t);var e=!1}catch(t){e=!0}if(e){var n=(e=console).error,o="function"==typeof Symbol&&Symbol.toStringTag&&t[Symbol.toStringTag]||t.constructor.name||"Object";return n.call(e,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",o),r(t)}}function o(e){if(e===m)return"<>";if("object"==typeof e&&null!==e&&e.$$typeof===_)return"<...>";try{var r=t(e);return r?"<"+r+">":"<...>"}catch(t){return"<...>"}}function a(){return Error("react-stack-top-frame")}function s(){var e=t(this.type);return L[e]||(L[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.")),void 0!==(e=this.props.ref)?e:null}function c(e,r,o,a,i,c,f,h){var m,p=r.children;if(void 0!==p)if(a)if(E(p)){for(a=0;a<p.length;a++)l(p[a]);Object.freeze&&Object.freeze(p)}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 l(p);if(j.call(r,"key")){p=t(e);var y=Object.keys(r).filter(function(t){return"key"!==t});a=0<y.length?"{key: someKey, "+y.join(": ..., ")+": ...}":"{key: someKey}",C[p+a]||(y=0<y.length?"{"+y.join(": ..., ")+": ...}":"{}",console.error('A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',a,p,y,p),C[p+a]=!0)}if(p=null,void 0!==o&&(n(o),p=""+o),function(t){if(j.call(t,"key")){var e=Object.getOwnPropertyDescriptor(t,"key").get;if(e&&e.isReactWarning)return!1}return void 0!==t.key}(r)&&(n(r.key),p=""+r.key),"key"in r)for(var v in o={},r)"key"!==v&&(o[v]=r[v]);else o=r;return p&&function(t,e){function r(){u||(u=!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)",e))}r.isReactWarning=!0,Object.defineProperty(t,"key",{get:r,configurable:!0})}(o,"function"==typeof e?e.displayName||e.name||"Unknown":e),function(t,e,r,n,o,a,i,c){return r=a.ref,t={$$typeof:d,type:t,key:e,props:a,_owner:o},null!==(void 0!==r?r:null)?Object.defineProperty(t,"ref",{enumerable:!1,get:s}):Object.defineProperty(t,"ref",{enumerable:!1,value:null}),t._store={},Object.defineProperty(t._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(t,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(t,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:i}),Object.defineProperty(t,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:c}),Object.freeze&&(Object.freeze(t.props),Object.freeze(t)),t}(e,p,c,0,null===(m=P.A)?null:m.getOwner(),o,f,h)}function l(t){"object"==typeof t&&null!==t&&t.$$typeof===d&&t._store&&(t._store.validated=1)}var u,f=e,d=Symbol.for("react.transitional.element"),h=Symbol.for("react.portal"),m=Symbol.for("react.fragment"),p=Symbol.for("react.strict_mode"),y=Symbol.for("react.profiler"),v=Symbol.for("react.consumer"),w=Symbol.for("react.context"),b=Symbol.for("react.forward_ref"),g=Symbol.for("react.suspense"),x=Symbol.for("react.suspense_list"),R=Symbol.for("react.memo"),_=Symbol.for("react.lazy"),k=Symbol.for("react.activity"),S=Symbol.for("react.client.reference"),P=f.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,j=Object.prototype.hasOwnProperty,E=Array.isArray,T=console.createTask?console.createTask:function(){return null},L={},O=(f={react_stack_bottom_frame:function(t){return t()}}).react_stack_bottom_frame.bind(f,a)(),N=T(o(a)),C={};i.Fragment=m,i.jsx=function(t,e,r,n,a){var i=1e4>P.recentlyCreatedOwnerStacks++;return c(t,e,r,!1,0,a,i?Error("react-stack-top-frame"):O,i?T(o(t)):N)},i.jsxs=function(t,e,r,n,a){var i=1e4>P.recentlyCreatedOwnerStacks++;return c(t,e,r,!0,0,a,i?Error("react-stack-top-frame"):O,i?T(o(t)):N)}}()),i}var c=(a||(a=1,"production"===process.env.NODE_ENV?r.exports=function(){if(t)return n;t=1;var e=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function o(t,r,n){var o=null;if(void 0!==n&&(o=""+n),void 0!==r.key&&(o=""+r.key),"key"in r)for(var a in n={},r)"key"!==a&&(n[a]=r[a]);else n=r;return r=n.ref,{$$typeof:e,type:t,key:o,ref:void 0!==r?r:null,props:n}}return n.Fragment=r,n.jsx=o,n.jsxs=o,n}():r.exports=s()),r.exports);let l=0;const u=t=>t.replace(/\/+$/,"")||"/",f=(t,e)=>u(`${"/"===t?"":t}/${e}`),d=(t,e)=>new URL(t,window.location.href),h=()=>{try{if(!0===(window.__REACT_VT_ROUTER_FORCE_STRING__??window.__TINY_ROUTER_FORCE_STRING__))return!1}catch{}return"function"==typeof window.URLPattern};function m(t,e="data-vt"){if(void 0!==t)return"boolean"==typeof t?!!t&&{}:"string"==typeof t?{name:t,attribute:e}:{attribute:e,...t}}const p=(t,e)=>{let r=t.startsWith("/")?t:`/${t}`;if("/*"===r)r="/:__splat(.*)";else if(r.endsWith("/*")){const t=r.slice(0,-2).replace(/\/+$/,"");r=(""===t?"/":t)+"/:__splat(.*)"}return r},y=(t,e)=>e?t:t.toLowerCase();function v(...t){try{(window.__REACT_VT_ROUTER_DEBUG__??window.__TINY_ROUTER_DEBUG__)&&console.log(...t)}catch{}}let w=!1;async function b(t,e){!function(){if(w)return;const t=document.createElement("style");t.setAttribute("data-react-vt-router","vt-presets"),t.textContent='\n/* react-vt-router: built-in view-transition presets */\nhtml[data-vt], html[data-vt]::view-transition-new(root), html[data-vt]::view-transition-old(root) { view-transition-name: root; }\n\n@keyframes art-fade-in { from { opacity: 0.01 } to { opacity: 1 } }\n@keyframes art-fade-out { from { opacity: 1 } to { opacity: 0.01 } }\nhtml[data-vt="fade"]::view-transition-new(root) { animation: art-fade-in 250ms ease-out both; }\nhtml[data-vt="fade"]::view-transition-old(root) { animation: art-fade-out 250ms ease-in both; }\n\n@keyframes art-slide-in { from { transform: translateX(100%); opacity: .01 } to { transform: translateX(0); opacity: 1 } }\n@keyframes art-slide-out { from { transform: translateX(0); opacity: 1 } to { transform: translateX(-20%); opacity: .01 } }\nhtml[data-vt="slide"] { overflow-x: clip; }\nhtml[data-vt="slide"]::view-transition-new(root) { animation: art-slide-in 500ms cubic-bezier(.2,.8,.2,1) both; }\nhtml[data-vt="slide"]::view-transition-old(root) { animation: art-slide-out 500ms cubic-bezier(.2,.8,.2,1) both; }\n\n@keyframes art-slide-left-in { from { transform: translateX(-100%); opacity: .01 } to { transform: translateX(0); opacity: 1 } }\n@keyframes art-slide-left-out { from { transform: translateX(0); opacity: 1 } to { transform: translateX(20%); opacity: .01 } }\nhtml[data-vt="slide-left"] { overflow-x: clip; }\nhtml[data-vt="slide-left"]::view-transition-new(root) { animation: art-slide-left-in 500ms cubic-bezier(.2,.8,.2,1) both; }\nhtml[data-vt="slide-left"]::view-transition-old(root) { animation: art-slide-left-out 500ms cubic-bezier(.2,.8,.2,1) both; }\n\n@keyframes art-slide-right-in { from { transform: translateX(100%); opacity: .01 } to { transform: translateX(0); opacity: 1 } }\n@keyframes art-slide-right-out { from { transform: translateX(0); opacity: 1 } to { transform: translateX(-100%); opacity: .01 } }\nhtml[data-vt="slide-right"] { overflow-x: clip; }\nhtml[data-vt="slide-right"]::view-transition-new(root) { animation: art-slide-right-in 500ms cubic-bezier(.2,.8,.2,1) both; }\nhtml[data-vt="slide-right"]::view-transition-old(root) { animation: art-slide-right-out 500ms cubic-bezier(.2,.8,.2,1) both; }\n\n@keyframes art-zoom-in { from { transform: scale(.96); opacity: .01 } to { transform: scale(1); opacity: 1 } }\n@keyframes art-zoom-out { from { transform: scale(1); opacity: 1 } to { transform: scale(1.04); opacity: .01 } }\nhtml[data-vt="zoom"]::view-transition-new(root) { animation: art-zoom-in 300ms ease-out both; }\nhtml[data-vt="zoom"]::view-transition-old(root) { animation: art-zoom-out 300ms ease-in both; }\n\n@media (prefers-reduced-motion: reduce) { html[data-vt]::view-transition-new(root), html[data-vt]::view-transition-old(root) { animation: none !important; }}',document.head.appendChild(t),w=!0}();const r=e?.attribute||"data-vt",n=document.documentElement,o=()=>{e?.name&&n.setAttribute(r,String(e.name)),e?.className&&n.classList.add(e.className)},a=()=>{e?.name&&n.removeAttribute(r),e?.className&&n.classList.remove(e.className)};if(e?.onStart?.(),"function"==typeof document.startViewTransition)try{o();const r=document.startViewTransition(t);Promise.resolve(r?.ready).then(()=>e?.onReady?.()).catch(()=>{});try{await(r?.finished)}finally{a(),e?.onFinished?.()}return}catch{}o();try{t()}finally{a(),e?.onFinished?.()}}const g=e.createContext(null),x=e.createContext(null),R=e.createContext(void 0);let _=0;const k=()=>"r"+ ++_;function S(t,e,r="/"){const n=[];for(const o of t){const t=k(),a=o.index?"":o.path??"",i=o.index?u(r):a.startsWith("/")?u(a):u(f(r,a||""));o.caseSensitive;let s=null;if(h()){const t=p(i);try{s=new(0,window.URLPattern)({pathname:t})}catch{s=null}}const c={...o,id:t,fullPath:i,pattern:s,parent:e,children:void 0};o.children?.length&&(c.children=S(o.children,c,i)),n.push(c)}return n}function P(t,e){const r=e.pathname||"/";try{v("[react-vt-router] matchRoutes start",{url:e.toString(),pathnameRaw:r,supportsURLPattern:h()})}catch{}const n=(t,o)=>{for(const a of t){const t=a.caseSensitive,i=y(r,t);let s=!1,c={};try{v("[react-vt-router] try node",{fullPath:a.fullPath,index:!!a.index,hasChildren:!(!a.children||!a.children.length)})}catch{}if(a.index){const e=y(a.fullPath,t);s=i===e;try{v("[react-vt-router] index check",{expected:e,pathname:i,isMatch:s})}catch{}}else if(a.pattern)try{if(a.children?.length){let r=a.__deepPattern;if(!r&&h())try{const t=window.URLPattern,e="/"===a.fullPath?"/*":`${a.fullPath}/*`;r=new t({pathname:p(e,a.caseSensitive)}),a.__deepPattern=r}catch{}const n=new URL(e.toString());t||(n.pathname=n.pathname.toLowerCase());try{const t=a.pattern.exec(n);t&&(s=!0,c={...t.pathname.groups})}catch{}if(!s&&r)try{const t=r.exec(n);if(t){s=!0;const e=t.pathname.groups||{},{__splat:r,...n}=e;c=n}}catch{}try{v("[react-vt-router] pattern parent",{fullPath:a.fullPath,exactTried:!0,deepTried:!!r,isMatch:s,params:c})}catch{}if(!s){const e=y(a.fullPath,t);s=i===e||i.startsWith("/"===e?"/":e+"/");try{v("[react-vt-router] string parent fallback",{full:e,pathname:i,isMatch:s})}catch{}}}else{const r=new URL(e.toString());t||(r.pathname=r.pathname.toLowerCase());try{const t=a.pattern.exec(r);t&&(s=!0,c={...t.pathname.groups})}catch{}if(!s){const e=y(a.fullPath,t);s=i===e;try{v("[react-vt-router] string leaf fallback",{full:e,pathname:i,isMatch:s})}catch{}}}}catch{}else{const e=y(a.fullPath,t);if(a.children?.length){s=i===e||i.startsWith("/"===e?"/":e+"/");try{v("[react-vt-router] no-pattern parent fallback",{full:e,pathname:i,isMatch:s})}catch{}}else{s=i===e;try{v("[react-vt-router] no-pattern leaf fallback",{full:e,pathname:i,isMatch:s})}catch{}}}if(!s)continue;const l=[...o,{route:a,params:c}];try{v("[react-vt-router] matched",{fullPath:a.fullPath,params:c,depth:l.length})}catch{}if(a.children?.length){const t=n(a.children,l);if(t)return t;continue}return l}return null};return n(t,[])}function j(t){return{pathname:window.location.pathname,search:window.location.search,hash:window.location.hash,state:t??window.history.state?.usr??null,key:"k"+ ++l}}function E({children:t,enableNavigationAPI:r=!1,defaultViewTransition:n}){const[o,a]=e.useState(()=>j()),i=e.useRef(o.state);e.useEffect(()=>{i.current=o.state},[o.state]),e.useEffect(()=>{const t=()=>{const t=j();try{v("[react-vt-router] popstate",t)}catch{}const e=m(n);!1!==e?b(()=>a(t),e||void 0):a(t)},e=()=>{const t=j();try{v("[react-vt-router] hashchange",t)}catch{}const e=m(n);!1!==e?b(()=>a(t),e||void 0):a(t)};return window.addEventListener("popstate",t),window.addEventListener("hashchange",e),()=>{window.removeEventListener("popstate",t),window.removeEventListener("hashchange",e)}},[n]),e.useEffect(()=>{if(!r)return;const t=window.navigation;if(!t?.addEventListener)return;const e=t=>{if(!t.canIntercept)return;new URL(t.destination.url).origin===window.location.origin&&t.intercept({handler:()=>{b(()=>{a(j(t.info?.state)),!1!==t.info?.scroll&&window.scrollTo({top:0,behavior:"auto"})},m(n)||void 0)}})};return t.addEventListener("navigate",e),()=>t.removeEventListener("navigate",e)},[r]);const s=e.useCallback((t,e={})=>{const{replace:r,state:o,viewTransition:i=n??!0,scroll:s="auto"}=e;if("number"==typeof t)return void window.history.go(t);const c=d(t);if(c.origin!==window.location.origin)return void(window.location.href=c.toString());const l=new URL(window.location.href);if(l.pathname===c.pathname&&l.search===c.search&&l.hash===c.hash){try{v("[react-vt-router] navigate no-op (same URL)",c.toString())}catch{}return}const u=()=>{try{v("[react-vt-router] navigate",{to:c.toString(),replace:r,state:o,scroll:s,viewTransition:i})}catch{}r?window.history.replaceState({usr:o??null},"",c):window.history.pushState({usr:o??null},"",c);const t=j(o);try{v("[react-vt-router] location set",t)}catch{}a(t),window.scrollTo({top:0,behavior:s})},f=m(i);!1!==f?b(u,f||void 0):u()},[n]),l=e.useMemo(()=>{const t=(t,e)=>s(t,e);return t.back=()=>t(-1),t.forward=()=>t(1),t.go=e=>t(e),t},[s]),u=e.useMemo(()=>({location:o,navigate:l}),[o,l]);return c.jsx(g.Provider,{value:u,children:t})}function T(){const t=e.useContext(g);if(!t)throw new Error("useRouterState must be used within <BrowserRouter>");return{location:t.location}}function L(){return T().location}function O(){const t=e.useContext(g);if(!t)throw new Error("useNavigate must be used within <BrowserRouter>");return t.navigate}function N(){const t=e.useContext(x);if(!t)return{};return e.useMemo(()=>t.matches.reduce((t,e)=>Object.assign(t,e.params),{}),[t.matches])}function C(){const{location:t}=T(),r=O(),n=e.useCallback((t,e)=>{let n;n=t instanceof URLSearchParams?t:"string"==typeof t||Array.isArray(t)?new URLSearchParams(t):new URLSearchParams(Object.entries(t));const o=new URL(window.location.href);o.search=n.toString(),r(o.toString(),{replace:e?.replace})},[r]);return[e.useMemo(()=>new URLSearchParams(t.search),[t.search]),n]}function U(t){return null}function M(t){const r=[];e.Children.forEach(t,t=>{if(!e.isValidElement(t))return;const n=t.type,o=n===U||!0===n?.$$reactVtRouterRoute||"ReactVtRouterRoute"===n?.displayName,a=t.props;if(!o&&!(a&&"object"==typeof a&&("path"in a||"index"in a)))return;const i=t.props,s={path:i.path,index:i.index,caseSensitive:i.caseSensitive,element:i.redirectTo?c.jsx(X,{to:i.redirectTo,replace:!0}):i.element};i.children&&(s.children=M(i.children)),r.push(s)});try{v("[react-vt-router] createRoutesFromChildren:",r)}catch{}return r}function $({children:t}){const{location:r}=T(),n=e.useMemo(()=>M(t),[t]),o=e.useMemo(()=>S(n),[n]),a=e.useMemo(()=>new URL(window.location.href),[r.key]),i=e.useMemo(()=>P(o,a),[o,a]);try{v("[react-vt-router] Routes snapshot",{location:r,url:a.toString(),routes:n,compiled:o.map(t=>({id:t.id,fullPath:t.fullPath,index:t.index,children:!(!t.children||!t.children.length)})),matches:i})}catch{}return i?c.jsx(x.Provider,{value:{matches:i,index:0},children:c.jsx(A,{})}):null}function A(){const t=e.useContext(x);if(!t)return null;const{matches:r,index:n}=t,o=r[n];if(!o)return null;const a=c.jsx(x.Provider,{value:{matches:r,index:n+1},children:c.jsx(z,{})}),i=o.route.element;return i?c.jsx(x.Provider,{value:{matches:r,index:n+1},children:c.jsx(c.Fragment,{children:i})}):a}function z(t){const r=e.useContext(x);if(!r)return null;const{matches:n,index:o}=r,a=n[o];if(!a)return null;const i=a.route.element;return i?c.jsx(R.Provider,{value:t?.context,children:c.jsx(x.Provider,{value:{matches:n,index:o+1},children:c.jsx(c.Fragment,{children:i})})}):c.jsx(R.Provider,{value:t?.context,children:c.jsx(x.Provider,{value:{matches:n,index:o+1},children:c.jsx(z,{})})})}function F({to:t,replace:r,onClick:n,target:o,rel:a,viewTransition:i,scroll:s,...l}){const u=O(),f=e.useMemo(()=>d(t).toString(),[t]);return c.jsx("a",{...l,href:f,onClick:t=>{if(n&&n(t),!t.defaultPrevented&&!(o&&"_self"!==o||0!==t.button||t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)){try{if(new URL(f).origin!==window.location.origin)return}catch{return}t.preventDefault();try{v("[react-vt-router] Link intercept",{href:f,replace:r,viewTransition:i,scroll:s})}catch{}u(f,{replace:r,viewTransition:i,scroll:s})}},target:o,rel:a})}function X({to:t,replace:r,state:n,viewTransition:o=!0}){const a=O();return e.useEffect(()=>{a(t,{replace:r,state:n,viewTransition:o})},[a,t,r,n,o]),null}function W(t){const{location:r}=T(),n=e.useMemo(()=>S(t),[t]),o=e.useMemo(()=>new URL(window.location.href),[r.key]),a=e.useMemo(()=>P(n,o),[n,o]);return a?c.jsx(x.Provider,{value:{matches:a,index:0},children:c.jsx(A,{})}):null}function V(t){return M(t)}function I(t){const{location:r}=T(),n=e.useMemo(()=>new URL(window.location.href),[r.key]);if(h())try{const e=window.URLPattern,r=p(t),o=new e({pathname:r}).exec(n);if(o){return{params:o.pathname.groups||{},pathname:n.pathname,pattern:t}}}catch{}const o=t.endsWith("/*")?t.slice(0,-2):t,a=n.pathname;return a===o||t.endsWith("/*")&&(a===o||a.startsWith(o+"/"))?{params:{},pathname:a,pattern:t}:null}function D({className:t,style:e,end:r,...n}){const o=G(n.to),a=L(),i=u(o),s=u(a.pathname),l=r?s===i:s===i||s.startsWith(i+"/"),f="function"==typeof t?t({isActive:l,isPending:!1}):t,d="function"==typeof e?e({isActive:l,isPending:!1}):e;return c.jsx(F,{...n,className:f,style:d})}function B(){return e.useContext(R)}function K({context:t}){const r=e.useContext(x);if(!r)return null;const{matches:n,index:o}=r,a=n[o];if(!a)return null;const i=a.route.element;return c.jsx(R.Provider,{value:t,children:c.jsx(x.Provider,{value:{matches:n,index:o+1},children:i??c.jsx(K,{})})})}function G(t){return e.useMemo(()=>d(t).pathname+d(t).search+d(t).hash,[t])}U.$$reactVtRouterRoute=!0,U.displayName="ReactVtRouterRoute";var Y={BrowserRouter:E,Routes:$,Route:U,Link:F,NavLink:D,Navigate:X,Outlet:z,OutletWithContext:K,useNavigate:O,useLocation:L,useParams:N,useSearchParams:C,useMatch:I,useOutletContext:B,useRoutes:W,createRoutesFromElements:V};exports.BrowserRouter=E,exports.Link=F,exports.NavLink=D,exports.Navigate=X,exports.Outlet=z,exports.OutletWithContext=K,exports.Route=U,exports.Routes=$,exports.createRoutesFromElements=V,exports.default=Y,exports.useLocation=L,exports.useMatch=I,exports.useNavigate=O,exports.useOutletContext=B,exports.useParams=N,exports.useResolvedPath=G,exports.useRouterState=T,exports.useRoutes=W,exports.useSearchParams=C;