import { SyntheticEvent } from "react";
import { useNavigate, useRouterContext } from "./Router";
/**
* Wraps a and perform the navigation to href through the router.
*/
interface NavProps {
children: React.ReactNode | React.ReactNode[];
/**
* Optional router navigation target. If omitted, the wrapped anchor href is used.
*/
to?: string;
/**
* A click was intercepted
* @param ev
* @returns
*/
onClick?: (ev: SyntheticEvent) => void;
/**
* If true, use replaceState instead of pushState (no new browser history entry).
* Defaults to true for backward compatibility.
*/
replace?: boolean;
}
export function Nav({ children, to, onClick, replace = true }: NavProps) {
const navigate = useNavigate();
const _onClick = (ev: SyntheticEvent) => {
const link = (ev.target as HTMLElement).closest('a');
const rawHref = link?.getAttribute('href');
const target = to ?? rawHref;
if (link && target) {
ev.stopPropagation();
ev.preventDefault();
navigate(target, { replace });
onClick?.(ev);
}
}
return (
{children}
)
}
/**
* A anchor tag that performs navigation through the router.
*/
interface NavLinkProps {
children: React.ReactNode | React.ReactNode[];
href: string;
className?: string;
/**
* use the root router to navigate
*/
topLevelNav?: boolean;
clearBreadcrumbs?: boolean;
}
export function NavLink({ children, href, className, topLevelNav, clearBreadcrumbs = false }: NavLinkProps) {
const { router } = useRouterContext();
const _onClick = (ev: SyntheticEvent) => {
ev.stopPropagation();
ev.preventDefault();
const actualRouter = topLevelNav ? router.getTopRouter() : router;
actualRouter.navigate(href, { replace: clearBreadcrumbs });
}
return (
{children}
)
}