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} ) }