Skip to content

Commit d4ada67

Browse files
committed
Added smooth scroll on nav bar item click.
1 parent 97c023d commit d4ada67

File tree

2 files changed

+60
-52
lines changed

2 files changed

+60
-52
lines changed

client/src/components/Navbar/navbar.tsx

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,64 +12,58 @@ export function Navbar() {
1212
const links = [
1313
{
1414
title: "Home",
15-
icon: (
16-
<IconHome className="h-full w-full text-neutral-500 dark:text-neutral-300" />
17-
),
15+
icon: <IconHome className="h-full w-full text-neutral-500 dark:text-neutral-300" />,
1816
to: "#top", // Scroll to top
1917
},
2018
{
2119
title: "Features",
22-
icon: (
23-
<IconTerminal2 className="h-full w-full text-neutral-500 dark:text-neutral-300" />
24-
),
20+
icon: <IconTerminal2 className="h-full w-full text-neutral-500 dark:text-neutral-300" />,
2521
to: "#features", // Scroll to features section
2622
},
2723
{
2824
title: "FAQs",
29-
icon: (
30-
<IconNewSection className="h-full w-full text-neutral-500 dark:text-neutral-300" />
31-
),
25+
icon: <IconNewSection className="h-full w-full text-neutral-500 dark:text-neutral-300" />,
3226
to: "#help", // Scroll to help section
3327
},
3428
{
3529
title: "DevHub",
36-
icon: (
37-
<img
38-
src="../../../public/logo.png"
39-
width={20}
40-
height={20}
41-
alt="DevHub"
42-
/>
43-
),
30+
icon: <img src="../../../public/logo.png" width={20} height={20} alt="DevHub" />,
4431
to: "#", // No scrolling
4532
},
4633
{
4734
title: "DevMap",
48-
icon: (
49-
<IconExchange className="h-full w-full text-neutral-500 dark:text-neutral-300" />
50-
),
35+
icon: <IconExchange className="h-full w-full text-neutral-500 dark:text-neutral-300" />,
5136
to: "#", // No scrolling
5237
},
5338
{
5439
title: "Discord",
55-
icon: (
56-
<IconBrandDiscord className="h-full w-full text-neutral-500 dark:text-neutral-300" />
57-
),
40+
icon: <IconBrandDiscord className="h-full w-full text-neutral-500 dark:text-neutral-300" />,
5841
to: "https://discord.gg/he8QHEC8WP", // Discord link
5942
},
6043
{
6144
title: "GitHub",
62-
icon: (
63-
<IconBrandGithub className="h-full w-full text-neutral-500 dark:text-neutral-300" />
64-
),
45+
icon: <IconBrandGithub className="h-full w-full text-neutral-500 dark:text-neutral-300" />,
6546
to: "https://github.com/devhub-ai/devhub", // GitHub link
6647
},
6748
];
6849

50+
const handleClick = (event, link) => {
51+
if (link.to.startsWith("#")) {
52+
event.preventDefault();
53+
const targetElement = document.querySelector(link.to);
54+
if (targetElement) {
55+
targetElement.scrollIntoView({ behavior: "smooth" });
56+
}
57+
}
58+
};
59+
6960
return (
7061
<div className="flex items-center justify-center mt-16 w-full">
7162
<FloatingDock
72-
items={links}
63+
items={links.map(link => ({
64+
...link,
65+
onClick: (event) => handleClick(event, link),
66+
}))}
7367
/>
7468
</div>
7569
);

client/src/components/ui/floating-dock.tsx

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -129,34 +129,48 @@ function IconContainer({
129129

130130
const [hovered, setHovered] = useState(false);
131131

132+
const handleClick = (event: React.MouseEvent) => {
133+
if (to.startsWith("#")) {
134+
event.preventDefault();
135+
const targetElement = document.querySelector(to);
136+
if (targetElement) {
137+
targetElement.scrollIntoView({ behavior: "smooth" });
138+
} else {
139+
console.error(`Element not found: ${to}`);
140+
}
141+
} else {
142+
// For external links, allow the default behavior
143+
window.open(to, "_blank"); // Open in a new tab
144+
}
145+
};
146+
132147
return (
133-
<a href={to}> {/* Change here */}
148+
<motion.div
149+
ref={ref}
150+
style={{ width, height }}
151+
onMouseEnter={() => setHovered(true)}
152+
onMouseLeave={() => setHovered(false)}
153+
onClick={handleClick}
154+
className="aspect-square rounded-full bg-gray-200 dark:bg-neutral-800 flex items-center justify-center relative cursor-pointer"
155+
>
156+
<AnimatePresence>
157+
{hovered && (
158+
<motion.div
159+
initial={{ opacity: 0, y: 10, x: "-50%" }}
160+
animate={{ opacity: 1, y: 0, x: "-50%" }}
161+
exit={{ opacity: 0, y: 2, x: "-50%" }}
162+
className="px-2 py-0.5 whitespace-pre rounded-md bg-gray-100 border dark:bg-neutral-800 dark:border-neutral-900 dark:text-white border-gray-200 text-neutral-700 absolute left-1/2 -translate-x-1/2 -top-8 w-fit text-xs"
163+
>
164+
{title}
165+
</motion.div>
166+
)}
167+
</AnimatePresence>
134168
<motion.div
135-
ref={ref}
136-
style={{ width, height }}
137-
onMouseEnter={() => setHovered(true)}
138-
onMouseLeave={() => setHovered(false)}
139-
className="aspect-square rounded-full bg-gray-200 dark:bg-neutral-800 flex items-center justify-center relative"
169+
style={{ width: widthIcon, height: heightIcon }}
170+
className="flex items-center justify-center"
140171
>
141-
<AnimatePresence>
142-
{hovered && (
143-
<motion.div
144-
initial={{ opacity: 0, y: 10, x: "-50%" }}
145-
animate={{ opacity: 1, y: 0, x: "-50%" }}
146-
exit={{ opacity: 0, y: 2, x: "-50%" }}
147-
className="px-2 py-0.5 whitespace-pre rounded-md bg-gray-100 border dark:bg-neutral-800 dark:border-neutral-900 dark:text-white border-gray-200 text-neutral-700 absolute left-1/2 -translate-x-1/2 -top-8 w-fit text-xs"
148-
>
149-
{title}
150-
</motion.div>
151-
)}
152-
</AnimatePresence>
153-
<motion.div
154-
style={{ width: widthIcon, height: heightIcon }}
155-
className="flex items-center justify-center"
156-
>
157-
{icon}
158-
</motion.div>
172+
{icon}
159173
</motion.div>
160-
</a>
174+
</motion.div>
161175
);
162176
}

0 commit comments

Comments
 (0)