UNPKG

react-best-router

Version:

In larger React applications, it is usually necessary to use a Router to handle relationships between pages and navigate between them. Are you using other Router libraries? Have you encountered any areas that are not very useful? For example, defining nes

2 lines (1 loc) 5.95 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");const t=e.createContext(null);function r(){const r=e.useContext(t);if(!r)throw"Invalid call outside of Router";return r}function n(e){const t=e.split("/").map(e=>(e||"").trim()),r=t.length,n=t.reduce((e,t,n)=>"."===t||""===t&&0!==n&&n!==r-1?e:".."===t?e.slice(0,-1):[...e,t],[]).join("/");return n.length>1&&"/"===n.at(-1)?n.slice(0,-1):n}function a(e){const t=function(e){const t=[];let r=0,n=e;n=n.replace(/\\\(/,"@@#").replace(/\\\)/,"#@@"),n=n.replace(/(?<S>\/)?:(?<N>[a-z0-9_]+)(?<R>\(.+?\))?(?<M>[*?+])?/gi,(function(e,n="",a="",o="",s=""){const c="*"===s||"+"===s?`(?<${a}>${o||`(${n}[a-z0-9_-]+)`}${s})`:`${n}${s}(?<${a}>${o||"([a-z0-9_-]+)"}${s})`,i=`@@${r++}@@`;return t.push([i,c]),i}));let a=0;n=n.replace(/(?<S>\/)?(?<R>\(.+?\))(?<M>[*?+])?/gi,(function(e,n="",o="",s=""){const c="*"===s||"+"===s?`(?<$${++a}>${o}${s})`:`${n}${s}(?<$${++a}>${o}${s})`,i=`@@${r++}@@`;return t.push([i,c]),i})),n=n.replace(/\?/g,"\\?").replace(/\*/g,"\\*").replace(/\+/g,"\\+").replace(/\./g,"\\.").replace(/\//g,"\\/"),t.forEach(([e,t])=>n=n.replace(e,t)),n=n.replace(/@@#/g,"(").replace(/#@@/g,")");try{return new RegExp(`^${n}$`,"i")}catch(t){throw"Invalid pattern: "+e}}(e);return e=>{const{pathname:r,searchParams:n}=new URL(e,location.origin),a=null==t?void 0:t.exec(decodeURIComponent(r));return{state:!!a,params:(null==a?void 0:a.groups)||{},query:n}}}function o(e,t,r){if(r&&r.prefix===r.pattern){const t=`Invalid nesting '${r.pattern} -> ${e}'`;throw new Error(t)}t=t||function(e){const t=/[.*()[\]?+]/,r=e.split("/"),n=r.slice(0).reverse().findIndex(e=>!t.test(e));return(n>0?r.slice(0,-n):r).join("/")}(e);const o=`/${function(e){let t=e,r="";for(;t;)r=`${t.prefix}/${r}`,t=t.parent;return r}(r)}/${e}`,s=a((c=n(c=o)).length>1&&"/"===c.at(-1)?c.slice(0,-1):c);var c;const i={parent:r,pattern:e,prefix:t,match:s};return i.match=e=>(i.result=s(e),i.result),i}const s=e.createContext(null);function c(){return e.useContext(s)}function i(e){const{pathname:t}=new URL(e,location.origin);return t}function u(e,t,r){return r.startsWith("/")?n(`${i(e)}/${r}`):function(e,t){return n(`${e}/${t}`)}(i(t),r)}function p(t){const{base:a,state:o,driver:s}=r(),i=c();return e.useMemo(()=>{if(!(null==i?void 0:i.result))throw"Invalid call outside of Route";const e=function(e,t){return n("/"+t.slice(e.length)).split("?")[0]}(a,o.path),{params:r,query:c}=i.result;return t&&r&&Object.entries(r).forEach(([e,n])=>{const a=t[e];r[e]=a?a(String(n)):n}),{path:e,params:r,query:c,push:e=>s.push({path:u(a,o.path,e)}),back:()=>s.back(),forward:()=>s.forward(),go:e=>s.go(e),replace:e=>s.replace({path:u(a,o.path,e)})}},[o,i,s])}function l({navRef:t}){const{parser:r}=t||{},n=p(r);return e.useMemo(()=>t&&(t.current=n),[n,t]),e.createElement(e.Fragment)}function h(e){return{parser:e,current:void 0}}function f(t){const{side:n,children:a}=t,s=function(t,r){const n=e.Children.toArray(r).filter(e=>!!e),a=n.filter(e=>e.type===t);return n.length===a.length?a.map(e=>{var t;return null===(t=e.props)||void 0===t?void 0:t.pattern}):[]}(...n),{state:i}=r(),u=c(),p=e.useMemo(()=>s.map(e=>o(e,"",u)),[s.join(":"),i.path,u]);return!p[0]||p.some(e=>e.match(i.path).state)?e.createElement(e.Fragment,null):a}function d(t){const r=p(),{to:n}=t;return e.useEffect(()=>r.push(n),[r,n]),e.createElement(e.Fragment,null)}function v(t){const{pattern:n="/(.*)?",prefix:a,navigator:i}=t,{render:u,children:p,fallback:h,redirect:g}=t,{state:m}=r(),$=c(),w=e.useMemo(()=>o(n,a,$),[n,a,$]),x=w.match(m.path).state;if(!x&&!h)return e.createElement(e.Fragment,null);if(x&&g)return e.createElement(d,{to:g});const E=u?u(p):p;return e.createElement(s.Provider,{value:w},i&&e.createElement(l,{navRef:i}),x?E:h,x&&h&&e.createElement(f,{side:[v,E]},h))}function g(e){return{...e,path:n(e.path)}}function m(){const e=()=>{const{pathname:e,search:t}=location;return{path:`${e}${t}`}};return{current:e,push:e=>{history.pushState(e,e.path,e.path);const t=new PopStateEvent("popstate",{state:e});window.dispatchEvent(t)},replace:e=>{history.replaceState(e,e.path,e.path);const t=new PopStateEvent("popstate",{state:e});window.dispatchEvent(t)},go:e=>history.go(e),back:()=>history.back(),forward:()=>history.forward(),subscribe:t=>{const r=r=>{t(r.state||e())};return window.addEventListener("popstate",r),()=>window.removeEventListener("popstate",r)}}}function $(){const e=()=>({path:location.hash.slice(1)||"/"});return{current:e,push:e=>{location.hash=e.path},replace:e=>{location.hash=e.path},go:e=>history.go(e),back:()=>history.back(),forward:()=>history.forward(),subscribe:t=>{const r=()=>t(e());return window.addEventListener("hashchange",r),()=>window.removeEventListener("hashchange",r)}}}function w(e={path:"/"}){let t,r=[e],n=0;const a=(a,o=!1)=>{a<0&&(a=0),a>r.length-1&&(a=r.length-1),(a!==n||o)&&(n=a,null==t||t(r[n]||e))};return{subscribe:e=>(t=e,()=>t=void 0),current:()=>r[n]||e,replace:e=>{r=r.slice(0,n+1),r[n]=e,a(r.length-1,!0)},push:e=>{r=r.slice(0,n+1),r.push(e),a(r.length-1)},go:e=>a(n+e),back:()=>a(n-1),forward:()=>a(n+1)}}exports.NavigatorForwarder=l,exports.Route=v,exports.Router=function(r){const{driver:n,base:a="/",navigator:o,children:s,render:c,fallback:i}=r,[u,p]=e.useState(()=>g(n.current())),l=e.useMemo(()=>({base:a,state:u,driver:n}),[a,u,n]);return e.useLayoutEffect(()=>n.subscribe(e=>p(g(e))),[n,u]),e.createElement(t.Provider,{value:l},e.createElement(v,{pattern:a+"/(.*)?",prefix:a,render:c,navigator:o,fallback:i},s))},exports.createBrowserDriver=m,exports.createHashDriver=$,exports.createMemoryDriver=w,exports.createNavigatorRef=h,exports.normalizeState=g,exports.useBrowserDriver=function(){return e.useMemo(()=>m(),[])},exports.useHashDriver=function(){return e.useMemo(()=>$(),[])},exports.useMemoryDriver=function(t={path:"/"}){return e.useMemo(()=>w(t),[t])},exports.useNavigator=p,exports.useNavigatorRef=function(t){return e.useMemo(()=>h(t),[t])};