import type { AnchorHTMLAttributes, MouseEvent } from "react";
import { useEffect, useState } from "react";
/** Change the page without a reload. */
export function navigate(to: string, options: { replace?: boolean } = {}) {
if (to === location.pathname + location.search) return;
history[options.replace ? "replaceState" : "pushState"]({}, "", to);
window.dispatchEvent(new PopStateEvent("popstate"));
window.scrollTo({ top: 0 });
}
/** The current path and query, updated on navigation and Back/Forward. */
export function useLocation() {
const read = () => ({ path: location.pathname, query: new URLSearchParams(location.search) });
const [value, setValue] = useState(read);
useEffect(() => {
const update = () => setValue(read());
window.addEventListener("popstate", update);
return () => window.removeEventListener("popstate", update);
}, []);
return value;
}
export function Link({ to, onClick, ...props }: AnchorHTMLAttributes<HTMLAnchorElement> & { to: string }) {
return (
<a
{...props}
href={to}
onClick={(e: MouseEvent<HTMLAnchorElement>) => {
onClick?.(e);
if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
e.preventDefault();
navigate(to);
}}
/>
);
}