diff --git a/app.tsx b/app.tsx index 787f4b5..c51ef22 100644 --- a/app.tsx +++ b/app.tsx @@ -1,7 +1,33 @@ -import * as ISO from ">able/iso-elements.tsx"; +import {Route, useRoute} from ">able/iso-router.tsx"; -console.log(ISO) +const Tracer =()=> +{ + const {nestedDepth, pathIndex} = useRoute(); + return
Depth: {nestedDepth}, Index:{pathIndex}
+} export default ()=>

App

+ + + +

home page!

+
+ + + + + +

About page!

+
+ + +

more!

+
+
; \ No newline at end of file diff --git a/iso-router.tsx b/iso-router.tsx index d8f9c45..25df41e 100644 --- a/iso-router.tsx +++ b/iso-router.tsx @@ -19,12 +19,13 @@ export const useMeta=(fields:MetaFields)=> } export const Meta =(props:MetaFields)=> { useMeta(props); return null; } + + //////// Router //// Create Signals -export const pageURL = Signal.signal(new URL(globalThis.location.href || "")); +export const pageURL = Signal.signal(new URL(globalThis?.location.href || "")); export const pagePath = Signal.signal([] as string[]); Signal.effect(()=> pagePath.value = pageURL.value.pathname.split("/").filter(part=>part!="")); - //// Add handlers globalThis.addEventListener("click", e=> { @@ -43,33 +44,28 @@ globalThis.addEventListener("click", e=> }) }); globalThis.addEventListener("popstate", _=> pageURL.value = new URL(globalThis.location.href) ); - /// Rendering context type RouteContextData = { /** Current nested depth of the router */ nestedDepth:number, /** Index into the page path to start matching routes */ pathIndex:number, - /** Collection of keys from matched routes ("page/:key/") */ keys: Record + /** Collection of keys from matched routes ("page/:key/") */ keys: Record, + blocked: Signal.Signal } -const context = React.createContext({nestedDepth:0, pathIndex:0, keys:{}} as RouteContextData); -export const useRoute =()=> React.useContext(context); -export const Route =(props:{path:string[], children:React.ReactNode|React.ReactNode[]}):React.JSX.Element|null=> +const context = React.createContext({nestedDepth:0, pathIndex:0, keys:{}, blocked:Signal.signal(false as false|string)} as RouteContextData); +type PathFields = {pathAfter:string[], pathBefore:[], compare:typeof compare} +const compare =(pathA:string[], pathB:string[])=> { - // Match the current page url, with a route. - const {nestedDepth, pathIndex} = React.useContext(context); - const pagePathRange = pagePath.value.slice(pathIndex); - const emptyMatch = !props.path.length && !pagePathRange.length; - const comparisonSize = Math.min(props.path.length, pagePath.value.length); - + const emptyMatch = !pathA.length && !pathB.length; + const comparisonSize = Math.min(pathA.length, pathB.length); if(comparisonSize == 0 && emptyMatch === false) // one of the arrays is empty and one is not { return null; } - const keys = {} as Record; // not doing anything with this currently for(let i=0; i{props.children} + return {comparisonSize, keys}; +}; +export const useRoute =()=> { + const routeContext = React.useContext(context); + const pathFull = pagePath.value; + const pathAfter = pathFull.slice(routeContext.pathIndex); + const pathBefore = pathFull.slice(0, Math.max(0, routeContext.pathIndex-1)); + return { ...routeContext, pathAfter, pathBefore, compare } as PathFields&RouteContextData; +} +export const Route =(props:{path:string[], children:React.ReactNode|React.ReactNode[]}):React.JSX.Element|null=> +{ + const {nestedDepth, pathIndex, pathAfter, compare, keys} = useRoute(); + const check = compare(props.path, pathAfter); + if (check) + { + return {props.children}; + } + else + { + return null; + } } \ No newline at end of file