Skip to content

Commit 0d4baa6

Browse files
committed
fix: added SmoothScroll effect and applied it in root layout (while fixing navbar)
1 parent ff3bd77 commit 0d4baa6

File tree

4 files changed

+71
-38
lines changed

4 files changed

+71
-38
lines changed

src/app/layout.tsx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { detailsForMetadata } from "./config";
66
import Footer from "@/components/Footer";
77
import Navbar from "@/components/Navbar";
88
import { cn } from "@/lib/utils";
9+
import { SmoothScrollProvider } from "@/components/SmoothScrollProvider";
910

1011
const inter = Inter({ subsets: ['latin'] })
1112
const spaceMono = Space_Mono({
@@ -51,11 +52,7 @@ export const metadata: Metadata = {
5152
verification: { google: "Wwciyzq9ANfCqyfI9hjLic5BhSc30awKaJPxbWCm5mc" }
5253
};
5354

54-
export default function RootLayout({
55-
children,
56-
}: {
57-
children: React.ReactNode;
58-
}) {
55+
export default function RootLayout({ children, }: { children: React.ReactNode; }) {
5956
// ${inter.className}
6057
return (
6158
<html lang="en" className={`${inter.className} ${spaceMono.variable}`} suppressHydrationWarning>
@@ -66,13 +63,15 @@ export default function RootLayout({
6663
)}
6764
suppressHydrationWarning
6865
>
69-
<div className="flex flex-col min-h-screen">
70-
<Providers>
71-
<Navbar />
72-
<div className="flex-grow mx-auto max-w-full px-4 sm:px-12 md:px-16 lg:max-w-5xl xl:max-w-6xl 2xl:max-w-7xl">{children}</div>
73-
<Footer />
74-
</Providers>
75-
</div>
66+
<SmoothScrollProvider offset={90}>
67+
<div className="flex flex-col min-h-screen">
68+
<Providers>
69+
<Navbar />
70+
<div className="flex-grow mx-auto max-w-full px-4 sm:px-12 md:px-16 lg:max-w-5xl xl:max-w-6xl 2xl:max-w-7xl">{children}</div>
71+
<Footer />
72+
</Providers>
73+
</div>
74+
</SmoothScrollProvider>
7675
</body>
7776
</html>
7877
);

src/components/Navbar.tsx

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,11 @@ const Navbar = () => {
88
return (
99
<header className="sticky top-0 z-50 py-6 backdrop-blur-xl">
1010
<nav className="flex items-center justify-between mx-auto max-w-full px-4 sm:px-12 md:px-16 lg:max-w-5xl xl:max-w-6xl 2xl:max-w-7xl">
11-
<ul className="flex gap-4 sm:gap-8" onClick={
12-
(event: React.SyntheticEvent) => {
13-
event.preventDefault();
14-
const target = event.target as HTMLAnchorElement;
15-
const id = target.getAttribute('href');
16-
if (id !== "#") {
17-
const element = document.getElementById(String(id?.replace('#', '')));
18-
const y = element && element.getBoundingClientRect().top + window.scrollY - 100;
19-
if (y !== null) {
20-
window.scrollTo({top: y, behavior: 'smooth'});
21-
} else {
22-
element?.scrollIntoView({
23-
behavior: 'smooth'
24-
});
25-
}
26-
} else {
27-
window.scrollTo({
28-
top: 0,
29-
behavior: 'smooth'
30-
});
31-
}
32-
}
33-
}>
34-
<li><a href="#" className="hover:underline hover:underline-offset-4">home</a></li>
35-
<li><a href="#experience" className="hover:underline hover:underline-offset-4">experience</a></li>
11+
<ul className="flex gap-4 sm:gap-8">
12+
<li><a href="/" className="hover:underline hover:underline-offset-4">home</a></li>
13+
<li><a href="/#experience" className="hover:underline hover:underline-offset-4">experience</a></li>
3614
{/* <li><a href="#education" className="hover:underline hover:underline-offset-4">education</a></li> */}
37-
<li><a href="#projects" className="hover:underline hover:underline-offset-4">projects</a></li>
15+
<li><a href="/#projects" className="hover:underline hover:underline-offset-4">projects</a></li>
3816
</ul>
3917
<div className="flex gap-0 sm:gap-4">
4018
<ThemeSwitch />
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use client'
2+
3+
import { useSmoothScroll } from '@/hooks/useSmoothScroll'
4+
5+
export function SmoothScrollProvider({ children, offset = 0 }: { children: React.ReactNode, offset?: number }) {
6+
useSmoothScroll(offset)
7+
return <>{children}</>
8+
}

src/hooks/useSmoothScroll.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use client'
2+
3+
import { useEffect, useCallback } from 'react'
4+
import { useRouter, usePathname } from 'next/navigation'
5+
6+
export function useSmoothScroll(offset = 0) {
7+
const router = useRouter()
8+
const pathname = usePathname()
9+
10+
const scrollToElement = useCallback((hash: string) => {
11+
const targetElement = document.getElementById(hash.substring(1))
12+
if (targetElement) {
13+
const yPosition = targetElement.getBoundingClientRect().top + window.pageYOffset - offset
14+
window.scrollTo({ top: yPosition, behavior: 'smooth' })
15+
}
16+
}, [offset])
17+
18+
useEffect(() => {
19+
if (window.location.hash) {
20+
scrollToElement(window.location.hash)
21+
}
22+
}, [pathname, scrollToElement])
23+
24+
useEffect(() => {
25+
const handleClick = (e: MouseEvent) => {
26+
const target = e.target as HTMLElement
27+
const anchor = target.closest('a')
28+
if (!anchor) return
29+
30+
const href = anchor.getAttribute('href')
31+
if (!href) return
32+
33+
const url = new URL(href, window.location.origin)
34+
35+
if (url.pathname === pathname && url.hash) {
36+
e.preventDefault()
37+
scrollToElement(url.hash)
38+
window.history.pushState(null, '', url.hash)
39+
} else if (url.pathname !== pathname && url.hash) {
40+
e.preventDefault()
41+
router.push(href)
42+
}
43+
}
44+
45+
document.addEventListener('click', handleClick)
46+
return () => document.removeEventListener('click', handleClick)
47+
}, [pathname, router, scrollToElement])
48+
}

0 commit comments

Comments
 (0)