diff --git a/src/components/router/Navigate.tsx b/src/components/router/Navigate.tsx new file mode 100644 index 0000000..b67b2f0 --- /dev/null +++ b/src/components/router/Navigate.tsx @@ -0,0 +1,33 @@ +import { useEffect } from "react" +import { type To } from "react-router-dom" + +import { useNavigate, type NavigateOptions } from "../../hooks" + +export type NavigateProps< + Override extends "delta" | "to", + State extends Record = Record, +> = Override extends "delta" + ? { delta: number; to?: undefined } + : { delta?: undefined; to: To } & NavigateOptions + +const Navigate: { + (props: NavigateProps<"delta">): JSX.Element + = Record>( + props: NavigateProps<"to", State>, + ): JSX.Element +} = ({ + delta, + to, + ...options +}: NavigateProps<"delta"> | NavigateProps<"to">) => { + const navigate = useNavigate() + + useEffect(() => { + if (typeof delta === "number") navigate(delta) + else navigate(to, options) + }, [navigate, delta, to, options]) + + return <> +} + +export default Navigate diff --git a/src/components/router/index.tsx b/src/components/router/index.tsx index 4315bf9..3131ff2 100644 --- a/src/components/router/index.tsx +++ b/src/components/router/index.tsx @@ -8,3 +8,5 @@ export * from "./LinkListItem" export { default as LinkListItem } from "./LinkListItem" export * from "./LinkTab" export { default as LinkTab } from "./LinkTab" +export * from "./Navigate" +export { default as Navigate } from "./Navigate" diff --git a/src/hooks/router.tsx b/src/hooks/router.tsx index 7c1e6e0..f6fc359 100644 --- a/src/hooks/router.tsx +++ b/src/hooks/router.tsx @@ -5,7 +5,7 @@ import { useParams as _useParams, useSearchParams as _useSearchParams, type Location, - type NavigateOptions, + type NavigateOptions as _NavigateOptions, type Params, type To, } from "react-router-dom" @@ -21,13 +21,17 @@ import { type TryValidateSyncRT, } from "../utils/schema" +export type NavigateOptions< + State extends Record = Record, +> = Omit<_NavigateOptions, "state"> & { + state?: State & Partial + next?: boolean +} + export type Navigate = { = Record>( to: To, - options?: Omit & { - state?: State & Partial - next?: boolean - }, + options?: NavigateOptions, ): void (delta: number): void }