UNPKG

@web-package/react-widgets-router

Version:

This package is a router that provides transition animations and fully preserves the state of previous elements, offering an experience close to a Web standard API.

2 lines (1 loc) 5.16 kB
import{jsx as e,Fragment as t}from"react/jsx-runtime";import{useRef as n,useLayoutEffect as s,useContext as o,useState as r,useEffect as i,createContext as a}from"react";class l{static get pathname(){return location.pathname}static arrayOf(e){return console.assert("A given path does not exist nothing."!=e),Array.from(e.matchAll(/(?<=\/)[\w-]+(?=\/|$)/g)).map((e=>e[0]))}}function u({route:o,active:r,keepAlive:i,first:a,onDispose:l}){var u;const c=n(r),h=n(null),p=null==o?void 0:o.props.component,d=null==o?void 0:o.props.element,f=null!=d?d:e(p||t,{}),m=null!==(u=null==o?void 0:o.props.keepalive)&&void 0!==u?u:null==i||i,v=()=>{h.current.style.display="none",o&&!m&&l(o.props)};return s((()=>{const e=h.current;if(e&&a&&c.current==r)r||(e.style.display="none");else if(e){c.current=r;const t=getComputedStyle(e),n=t.getPropertyValue("--router-fadein-keyframe").replaceAll('"',""),s=t.getPropertyValue("--router-fadein-duration"),o=t.getPropertyValue("--router-fadeout-keyframe").replaceAll('"',""),i=t.getPropertyValue("--router-fadeout-duration");if(r){if(e.style.display="unset",n)return e.style.animation=`${n} ${s||"0.3s"}`,void(e.onanimationend=null)}else{if(o)return e.style.animation=`${o} ${i||"0.3s"}`,void(e.onanimationend=v);v()}}c.current=r}),[r]),e("route-sliver",{ref:h,children:f})}addEventListener("DOMContentLoaded",(()=>{const e=new CSSStyleSheet;e.insertRule("\n route-sliver {\n position: absolute;\n width: 100%;\n height: 100%;\n }\n "),e.insertRule("\n *:has(> route-sliver) {\n position: relative;\n top: 0px;\n left: 0px;\n }\n "),document.adoptedStyleSheets=[...document.adoptedStyleSheets,e]}));class c{constructor(e){this.location=e,this.consumedPaths=[],this.paths=[],this.paths=l.arrayOf(e)}get first(){return this.paths[0]}get relPath(){return"/"+this.paths.join("/")}get absPath(){return"/"+[...this.consumedPaths,...this.paths].join("/")}get clone(){const e=new c(this.location);return e.paths=this.paths.slice(),e.consumedPaths=this.consumedPaths.slice(),e}consume(){return console.assert(0!=this.paths.length,"Not exists a path that can be consumed."),this.paths[0]&&this.consumedPaths.push(this.paths[0]),this.paths=this.paths.slice(1)}}class h{constructor(){this.listeners=[],window.onpopstate=e=>this.notifyListeners(location.pathname)}static get instance(){var e;return null!==(e=this._instance)&&void 0!==e?e:this._instance=new h}addListener(e){console.assert(!this.listeners.includes(e),"Already exists a given listener in the context."),this.listeners.push(e)}removeListener(e){console.assert(this.listeners.includes(e),"Already not exists a given listener in the context."),this.listeners=this.listeners.filter((t=>t!=e))}notifyListeners(e){this.listeners.forEach((t=>t(e)))}push(e){location.pathname!=e&&(this.notifyListeners(e),history.pushState(null,"",e))}move(e){location.pathname!=e&&(history.replaceState({},"",e),this.notifyListeners(location.pathname))}forward(){history.forward(),this.notifyListeners(location.pathname)}backward(){history.back(),this.notifyListeners(location.pathname)}}function p(){let e=o(d),t=h.instance;if(null==e){const[n,s]=r(window.location.pathname);e=new c(n),i((()=>(t.addListener(s),()=>t.removeListener(s))),[])}return e.clone}const d=a(null);function f({location:s,keepAlive:o,children:i}){const a=n(new Map),c=p(),h=Array.isArray(i)?i:[i],[f,m]=r(0);let v=h.find((e=>l.arrayOf(e.props.path)[0]==c.first&&null==s||l.arrayOf(e.props.path)[0]==l.arrayOf(null!=s?s:"")[0]&&s));if(null!=v||(v=h.find((e=>e.props.default||"*"==e.props.path))),!v)throw new Error("Route corresponding to a given path was not found. Therefore, You need to define a `default` attribute to allow the router to specify a default `Route`.");return 0!=c.paths.length&&c.consume(),a.current.set(v.props.path,{context:c.clone}),e(t,{children:Array.from(a.current).map((([t,n],s)=>{const r=(null==v?void 0:v.props.path)==t,i=h.find((e=>e.props.path==t));return e(d.Provider,{value:n.context.clone,children:e(u,{active:r,first:0==s,route:i,keepAlive:o,onDispose:e=>{a.current.delete(e.path),m(f+1)}})},t)}))})}function m(e){var t;return console.assert(null!=e.element||null!=e.component,"Not exists a given component"),console.assert(null==e.element&&null!=e.component,"Cannot define rendering a component."),console.assert(null!=e.element&&null==e.component,"Cannot define rendering a component."),null!==(t=e.component)&&void 0!==t?t:e.element}var v;function y(e){var t;const n=null!==(t=null==e?void 0:e.context)&&void 0!==t?t:p();return t=>{var s,o,r;const i=null!==(s=null==e?void 0:e.routing)&&void 0!==s?s:v.relative,a=t.startsWith("/")?t.slice(1):t;i==v.absolute?null!==(o=null==e?void 0:e.replace)&&void 0!==o&&o?h.instance.move(t):h.instance.push(t):null!==(r=null==e?void 0:e.replace)&&void 0!==r&&r?h.instance.move("/"+[...n.consumedPaths,a].join("/")):h.instance.push("/"+[...n.consumedPaths,a].join("/"))}}!function(e){e[e.absolute=0]="absolute",e[e.relative=1]="relative"}(v||(v={}));export{m as Route,f as Router,h as RouterBinding,c as RouterContext,p as useLocation,y as useRoute};