Skip to content

Commit 3f2a036

Browse files
committed
🎨 Enhanced Responsive Navbar with Animations, Cropping Fixes & Smooth UI Transitions
1 parent ad2e60e commit 3f2a036

File tree

2 files changed

+79
-8
lines changed

2 files changed

+79
-8
lines changed

‎components/Navbar.tsx‎

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import React, { useState } from "react";
1+
"use client";
2+
3+
import React, { useState, useEffect } from "react";
24
import Link from "next/link";
35
import { Menu, X, Slack } from "lucide-react";
46
import Logo from "./Logo";
57
import ThemeToggle from "./ThemeToggle";
68
import GitHubStarButton from "./GitHubStarsButton";
79

810
// constants/contact.ts
9-
export const CONTACT_EMAIL = '[email protected]';
11+
export const CONTACT_EMAIL = "[email protected]";
1012
export const CONTACT_MAILTO = `mailto:${CONTACT_EMAIL}`;
1113

1214
interface NavigationItem {
@@ -17,6 +19,8 @@ interface NavigationItem {
1719

1820
const Navbar: React.FC = () => {
1921
const [isMenuOpen, setIsMenuOpen] = useState(false);
22+
const [activeSection, setActiveSection] = useState<string>("");
23+
const [scrolled, setScrolled] = useState(false);
2024

2125
const navigation: NavigationItem[] = [
2226
{ name: "Features", href: "/#features" },
@@ -28,20 +32,52 @@ const Navbar: React.FC = () => {
2832
external: true,
2933
},
3034
];
35+
3136
const slackLink: NavigationItem = {
3237
name: "Slack",
3338
href: "https://join.slack.com/t/opsimate/shared_invite/zt-39bq3x6et-NrVCZzH7xuBGIXmOjJM7gA",
3439
external: true,
3540
};
36-
// New Contact link
41+
3742
const contactLink: NavigationItem = {
3843
name: "Contact Us",
3944
href: CONTACT_MAILTO,
4045
external: true,
4146
};
4247

48+
// Highlight active section on scroll
49+
useEffect(() => {
50+
const sections = document.querySelectorAll("section[id]");
51+
const observer = new IntersectionObserver(
52+
(entries) => {
53+
entries.forEach((entry) => {
54+
if (entry.isIntersecting) {
55+
setActiveSection(entry.target.id);
56+
}
57+
});
58+
},
59+
{ rootMargin: "-50% 0px -50% 0px" }
60+
);
61+
62+
sections.forEach((section) => observer.observe(section));
63+
return () => sections.forEach((section) => observer.unobserve(section));
64+
}, []);
65+
66+
// Blur effect on scroll
67+
useEffect(() => {
68+
const handleScroll = () => setScrolled(window.scrollY > 20);
69+
window.addEventListener("scroll", handleScroll);
70+
return () => window.removeEventListener("scroll", handleScroll);
71+
}, []);
72+
4373
return (
44-
<nav className="bg-surface-50 dark:bg-surface-950 shadow-sm border-b border-surface-200 dark:border-surface-800 sticky top-0 z-50 transition-colors duration-200">
74+
<nav
75+
className={`sticky top-0 z-50 border-b border-surface-200 dark:border-surface-800 transition-all duration-300 ${
76+
scrolled
77+
? "navbar-blur shadow-md"
78+
: "bg-surface-50 dark:bg-surface-950 shadow-sm"
79+
}`}
80+
>
4581
<div className="container-max">
4682
<div className="flex justify-between items-center py-4">
4783
{/* Logo */}
@@ -55,7 +91,11 @@ const Navbar: React.FC = () => {
5591
<Link
5692
key={item.name}
5793
href={item.href}
58-
className="text-surface-700 dark:text-surface-300 hover:text-primary-500 dark:hover:text-primary-400 font-medium transition-colors duration-200"
94+
className={`nav-link text-surface-700 dark:text-surface-300 hover:text-primary-500 dark:hover:text-primary-400 font-medium ${
95+
activeSection === item.href.replace("/#", "")
96+
? "nav-link-active"
97+
: ""
98+
}`}
5999
{...(item.external && {
60100
target: "_blank",
61101
rel: "noopener noreferrer",
@@ -64,7 +104,9 @@ const Navbar: React.FC = () => {
64104
{item.name}
65105
</Link>
66106
))}
107+
67108
<GitHubStarButton />
109+
68110
<Link
69111
href={slackLink.href}
70112
className="text-surface-700 dark:text-surface-300 hover:text-primary-500 dark:hover:text-primary-400 font-medium transition-colors duration-200 inline-flex items-center gap-2"
@@ -77,13 +119,15 @@ const Navbar: React.FC = () => {
77119
<Slack size={18} aria-hidden="true" />
78120
{slackLink.name}
79121
</Link>
80-
{/* Contact Us button */}
81-
<a
122+
123+
{/* Contact Us button */}
124+
<a
82125
href={contactLink.href}
83126
className="px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors duration-200"
84127
>
85128
{contactLink.name}
86129
</a>
130+
87131
<ThemeToggle />
88132
</div>
89133

@@ -106,7 +150,11 @@ const Navbar: React.FC = () => {
106150
<Link
107151
key={item.name}
108152
href={item.href}
109-
className="text-gray-700 hover:text-blue-600 font-medium transition-colors duration-200 px-2 py-1"
153+
className={`text-gray-700 hover:text-blue-600 font-medium transition-colors duration-200 px-2 py-1 ${
154+
activeSection === item.href.replace("/#", "")
155+
? "text-primary-600 dark:text-primary-400"
156+
: ""
157+
}`}
110158
onClick={() => setIsMenuOpen(false)}
111159
{...(item.external && {
112160
target: "_blank",
@@ -116,6 +164,7 @@ const Navbar: React.FC = () => {
116164
{item.name}
117165
</Link>
118166
))}
167+
119168
{/* Mobile Contact Us link */}
120169
<a
121170
href={contactLink.href}

‎styles/globals.css‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
@layer base {
66
html {
77
scroll-behavior: smooth;
8+
scroll-padding-top: 80px;
89
}
910

1011
body {
@@ -13,6 +14,27 @@
1314
}
1415

1516
@layer components {
17+
.nav-link {
18+
@apply relative transition-all duration-300 ease-in-out;
19+
}
20+
21+
.nav-link::after {
22+
content: "";
23+
@apply absolute left-0 bottom-[-4px] w-0 h-[2px] bg-primary-500 transition-all duration-300;
24+
}
25+
26+
.nav-link-active::after {
27+
@apply w-full;
28+
}
29+
30+
.nav-link-active {
31+
@apply text-primary-600 dark:text-primary-400;
32+
}
33+
34+
.navbar-blur {
35+
@apply bg-surface-50/80 dark:bg-surface-950/80 backdrop-blur-md;
36+
}
37+
1638
.btn-primary {
1739
@apply bg-blue-600 hover:bg-blue-700 dark:bg-surface-200 dark:hover:bg-surface-100 text-white dark:text-surface-900 font-semibold py-3 px-6 rounded-lg transition-colors duration-200 inline-flex items-center gap-2;
1840
}

0 commit comments

Comments
 (0)