diff --git a/app/layout.tsx b/app/layout.tsx
index 5d1e493..f550c96 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -2,8 +2,7 @@ import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Nav from "@/components/nav";
-import Transitions from "@/components/page-transitions/context";
-import Animate from "@/components/page-transitions/animate";
+import Transitions, { Animate } from "@/components/transitions";
const inter = Inter({ subsets: ["latin"] });
@@ -19,10 +18,10 @@ export default function RootLayout({
}>) {
return (
-
-
+
+
- {children}
+ {children}
;
-
-const Link = (props: Props) => {
- const { navigate } = useNavigationTransition();
- return (
- {
- e.preventDefault();
- const href = e.currentTarget.getAttribute("href");
- if (href) navigate(href);
- }}
- />
- );
-};
-
-export default Link;
diff --git a/components/nav.tsx b/components/nav.tsx
index 99fa181..7bda209 100644
--- a/components/nav.tsx
+++ b/components/nav.tsx
@@ -1,4 +1,4 @@
-import Link from "./link";
+import Link from "next/link";
export default function Nav() {
return (
diff --git a/components/page-transitions/animate.tsx b/components/page-transitions/animate.tsx
deleted file mode 100644
index 66deed6..0000000
--- a/components/page-transitions/animate.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-"use client";
-
-import { PropsWithChildren } from "react";
-import { DELAY, useNavigationTransition } from "./context";
-import { AnimatePresence, motion } from "framer-motion";
-
-export default function Animate({ children }: PropsWithChildren) {
- const { pending } = useNavigationTransition();
- return (
-
- {!pending && (
-
- {children}
-
- )}
-
- );
-}
diff --git a/components/page-transitions/context.tsx b/components/page-transitions/context.tsx
deleted file mode 100644
index 5ae57f8..0000000
--- a/components/page-transitions/context.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-"use client";
-
-import { useRouter } from "next/navigation";
-import { PropsWithChildren, createContext, use, useTransition } from "react";
-
-export const DELAY = 500;
-
-const sleep = (ms: number) =>
- new Promise((resolve) => setTimeout(() => resolve(), ms));
-const noop = () => {};
-
-type TransitionContext = {
- pending: boolean;
- navigate: (url: string) => void;
-};
-const Context = createContext({
- pending: false,
- navigate: noop,
-});
-export const useNavigationTransition = () => use(Context);
-
-export default function Transitions({ children }: PropsWithChildren) {
- const [pending, start] = useTransition();
- const router = useRouter();
- const navigate = (href: string) => {
- start(async () => {
- await Promise.all([router.push(href), sleep(DELAY)]);
- });
- };
-
- return (
-
- {children}
-
- );
-}
diff --git a/components/transitions.tsx b/components/transitions.tsx
new file mode 100644
index 0000000..ed0f0d5
--- /dev/null
+++ b/components/transitions.tsx
@@ -0,0 +1,87 @@
+"use client";
+
+import { AnimatePresence, motion } from "framer-motion";
+import { useRouter } from "next/navigation";
+import {
+ createContext,
+ MouseEventHandler,
+ PropsWithChildren,
+ use,
+ useTransition,
+} from "react";
+
+export const DELAY = 1000;
+
+const sleep = (ms: number) =>
+ new Promise((resolve) => setTimeout(() => resolve(), ms));
+const noop = () => {};
+
+type TransitionContext = {
+ pending: boolean;
+ navigate: (url: string) => void;
+};
+const Context = createContext({
+ pending: false,
+ navigate: noop,
+});
+export const usePageTransition = () => use(Context);
+export const usePageTransitionHandler = () => {
+ const { navigate } = usePageTransition();
+ const onClick: MouseEventHandler = (e) => {
+ e.preventDefault();
+ const href = e.currentTarget.getAttribute("href");
+ if (href) navigate(href);
+ };
+
+ return onClick;
+};
+
+type Props = PropsWithChildren<{
+ className?: string;
+}>;
+
+export default function Transitions({ children, className }: Props) {
+ const [pending, start] = useTransition();
+ const router = useRouter();
+ const navigate = (href: string) => {
+ start(async () => {
+ router.push(href);
+ await sleep(DELAY);
+ });
+ };
+
+ const onClick: MouseEventHandler = (e) => {
+ const a = (e.target as Element).closest("a");
+ if (a) {
+ e.preventDefault();
+ const href = a.getAttribute("href");
+ if (href) navigate(href);
+ }
+ };
+
+ return (
+
+
+ {children}
+
+
+ );
+}
+
+export function Animate({ children, className }: Props) {
+ const { pending } = usePageTransition();
+ return (
+
+ {!pending && (
+
+ {children}
+
+ )}
+
+ );
+}