routeria
Version:
A router package for react
95 lines (94 loc) • 3.8 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useState, isValidElement } from "react";
import { setGuardCallback } from "../hooks/useGuards";
import { useInnerRouteParams } from "../hooks/useRouterParams";
import { useInnerQueryParams } from "../hooks/useQueryParams";
const Router = ({ paths, guards, }) => {
const { setRouterParams, resetRouterParams } = useInnerRouteParams();
const { setQueryParams, resetQueryParams } = useInnerQueryParams();
const [path, setPath] = useState(window.location.pathname);
const [currentGuards, setGuards] = useState(guards || {});
useEffect(() => {
const onLocationChange = () => {
resetRouterParams();
resetQueryParams();
setPath(window.location.pathname);
};
window.addEventListener("popstate", onLocationChange);
return () => window.removeEventListener("popstate", onLocationChange);
}, []);
useEffect(() => {
const manageGuards = (state) => {
const newGuardsState = Object.assign({}, currentGuards);
const currentGuard = newGuardsState[state[0]];
if (Array.isArray(currentGuard)) {
currentGuard[0] = state[1];
}
else {
newGuardsState[state[0]] = state[1];
}
setGuards(newGuardsState);
};
setGuardCallback(manageGuards);
}, [currentGuards]);
const getCurrentRoute = () => {
if (window.location.search)
setQueryParams();
return (basicPath() || pathBreaker() || notFound());
};
const basicPath = () => {
const currentPath = paths[path];
if (isValidElement(currentPath))
return currentPath;
else if (Array.isArray(currentPath))
return checkGuard(currentPath);
return;
};
const pathBreaker = () => {
const nestedLevels = path.split("/");
let currentStage = paths;
for (let i = 1; i < nestedLevels.length; i++) {
const currentPath = `/${nestedLevels[i]}`;
if (currentStage[currentPath]) {
currentStage = setNextNestedStage(currentStage, currentPath);
}
else {
const firstPath = grabFirstPath(currentStage);
if (firstPath && firstPath.slice(0, 2) === "/:") {
setRouterParams(firstPath, nestedLevels[i]);
currentStage = setNextNestedStage(currentStage, firstPath);
}
else
currentStage = currentStage["/*"];
}
}
if (!currentStage)
return;
return ((isValidElement(currentStage["/"])
? currentStage["/"]
: Array.isArray(currentStage["/"]) && checkGuard(currentStage["/"])) ||
(isValidElement(currentStage)
? currentStage
: Array.isArray(currentStage) &&
checkGuard(currentStage)));
};
const setNextNestedStage = (currentStage, currentPath) => currentStage[currentPath];
const grabFirstPath = (currentStage) => {
for (const path in currentStage) {
return path;
}
return;
};
const checkGuard = (currentPath) => {
const currentGuard = currentGuards[currentPath[1]];
if (Array.isArray(currentGuard)) {
return currentGuard[0] ? currentPath[0] : currentGuard[1];
}
else if (currentGuard)
return currentPath[0];
return;
};
const notFound = () => paths["404"];
return _jsx("div", { children: getCurrentRoute() });
};
export default Router;