62 lines
2.2 KiB
TypeScript
62 lines
2.2 KiB
TypeScript
import { CustomRouteObject } from "../configure";
|
|
import { Link, useLocation } from "react-router-dom";
|
|
import { clearMultiplePathSlashes, trimPathOfParameters } from "../utils/StringTransformationUtils";
|
|
|
|
/**
|
|
* @returns Navigation tree elements, require to be used like in example below
|
|
* @example
|
|
* ```tsx
|
|
* <ul className="menu bg-base-200 w-56 h-full">
|
|
* <NavigationTree routes={navigation} />
|
|
* </ul>
|
|
* ```
|
|
*/
|
|
function NavigationTree(props: { routes: CustomRouteObject[] }): React.JSX.Element {
|
|
const locationHook = useLocation(); // Used to highlight active link in navigation tree
|
|
|
|
const GenerateNavigationEntries = (routes: CustomRouteObject[], parentPath?: string): React.ReactNode => {
|
|
return (
|
|
routes.map((route) => {
|
|
// Prepare path for links
|
|
let combinedPath = undefined;
|
|
if (parentPath !== undefined && route.path !== undefined)
|
|
combinedPath = trimPathOfParameters(clearMultiplePathSlashes(`/${parentPath}/${route.path}`));
|
|
else combinedPath = route.path;
|
|
// Does it have children and enabled? Make entry with `/{parent.path}/{route.path}`
|
|
if (route.children && !route.additionalProps.disableInNavbar) {
|
|
return (
|
|
<ul key={route.path}>
|
|
<li key={route.path}>
|
|
<Link to={combinedPath || "/"} className={locationHook.pathname === combinedPath ? "active" : ""}>
|
|
{route.additionalProps.name}
|
|
</Link>
|
|
{route.children ? <ul>{GenerateNavigationEntries(route.children, combinedPath)}</ul> : null}
|
|
</li>
|
|
</ul>
|
|
);
|
|
}
|
|
// Does it have children and not visible? Skip this entry and call this function for children passing path.
|
|
else if (route.children && route.additionalProps.disableInNavbar) {
|
|
return GenerateNavigationEntries(route.children, combinedPath);
|
|
} else if (route.additionalProps.disableInNavbar) {
|
|
return null;
|
|
}
|
|
// Make entry with `/{route.path}`
|
|
else {
|
|
return (
|
|
<li key={route.path}>
|
|
<Link to={combinedPath || "/"} className={locationHook.pathname === combinedPath ? "active" : ""}>
|
|
{route.additionalProps.name}
|
|
</Link>
|
|
</li>
|
|
);
|
|
}
|
|
}) || <>empty navigation tree</>
|
|
);
|
|
};
|
|
|
|
return <div className="h-fit">{GenerateNavigationEntries(props.routes)}</div>;
|
|
}
|
|
|
|
export default NavigationTree;
|