Skip to content

Commit e685cfc

Browse files
fixed accessibility labels and scrolling
1 parent e689afa commit e685cfc

1 file changed

Lines changed: 36 additions & 81 deletions

File tree

src/components/Navbar.tsx

Lines changed: 36 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
1-
import { NavLink, Link, useLocation, useNavigate } from "react-router-dom";
2-
import { useState, useContext } from "react";
1+
import { NavLink, Link, useLocation } from "react-router-dom";
2+
import { useState, useContext, useEffect } from "react";
33
import { ThemeContext } from "../context/ThemeContext";
44
import { Moon, Sun, Menu, X, UserPlus } from 'lucide-react';
55

66
const Navbar: React.FC = () => {
77
const [isOpen, setIsOpen] = useState<boolean>(false);
88
const themeContext = useContext(ThemeContext);
9-
const location = useLocation();
10-
const navigate = useNavigate();
9+
const { hash } = useLocation();
1110

12-
if (!themeContext) return null;
13-
const { toggleTheme, mode } = themeContext;
14-
15-
// Helper function for smooth scrolling
16-
const scrollToFeatures = (e: React.MouseEvent) => {
17-
e.preventDefault();
18-
19-
// If not on the home page, navigate home first, then scroll
20-
if (location.pathname !== "/") {
21-
navigate("/");
22-
// Small timeout to allow the home page to load before scrolling
23-
setTimeout(() => {
24-
const element = document.getElementById("features");
25-
element?.scrollIntoView({ behavior: "smooth" });
26-
}, 100);
27-
} else {
28-
// If already on home page, just scroll
11+
// Fix 1: Bot-demanded "Hash-driven" scroll (replaces the timeout)
12+
useEffect(() => {
13+
if (hash === "#features") {
2914
const element = document.getElementById("features");
30-
element?.scrollIntoView({ behavior: "smooth" });
15+
if (element) {
16+
element.scrollIntoView({ behavior: "smooth" });
17+
}
3118
}
32-
setIsOpen(false); // Close mobile menu if open
33-
};
19+
}, [hash]);
20+
21+
if (!themeContext) return null;
22+
const { toggleTheme, mode } = themeContext;
3423

3524
const navLinkStyles = ({ isActive }: { isActive: boolean }) =>
3625
`px-5 py-2 rounded-full text-lg font-semibold transition-all duration-300
@@ -44,71 +33,60 @@ const Navbar: React.FC = () => {
4433
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
4534
<div className="flex justify-between items-center h-20">
4635

47-
{/* 1. Logo Section */}
36+
{/* Logo Section */}
4837
<Link to="/" className="flex items-center shrink-0 group transition-all active:scale-95">
4938
<div className="relative">
50-
<img
51-
src="/crl-icon.png"
52-
alt="CRL Icon"
53-
className="h-10 w-10 mr-3 drop-shadow-md group-hover:rotate-6 transition-transform duration-300"
54-
/>
55-
<div className="absolute -inset-1 bg-blue-400/20 rounded-full blur opacity-0 group-hover:opacity-100 transition-opacity" />
39+
<img src="/crl-icon.png" alt="CRL Icon" className="h-10 w-10 mr-3 drop-shadow-md group-hover:rotate-6 transition-transform" />
5640
</div>
5741
<div className="flex items-center tracking-tight">
5842
<span className="text-2xl font-extrabold text-slate-900 dark:text-white">GitHub</span>
5943
<span className="text-2xl font-extrabold text-blue-600 ml-1">Tracker</span>
6044
</div>
6145
</Link>
6246

63-
{/* 2. Centered Navigation */}
47+
{/* Desktop Nav */}
6448
<div className="hidden lg:flex items-center justify-center flex-1 space-x-1">
6549
<NavLink to="/" className={navLinkStyles}>Home</NavLink>
66-
67-
{/* Features Link - Trigger Scroll */}
68-
<a
69-
href="#features"
70-
onClick={scrollToFeatures}
71-
className="px-5 py-2 rounded-full text-lg font-semibold text-slate-600 dark:text-gray-300 hover:text-blue-500 hover:bg-white/50 dark:hover:bg-gray-800/50 transition-all duration-300"
72-
>
50+
{/* Fix 2: Hash link for Features */}
51+
<Link to="/#features" className="px-5 py-2 rounded-full text-lg font-semibold text-slate-600 dark:text-gray-300 hover:text-blue-500 hover:bg-white/50 dark:hover:bg-gray-800/50 transition-all duration-300">
7352
Features
74-
</a>
75-
53+
</Link>
7654
<NavLink to="/track" className={navLinkStyles}>Tracker</NavLink>
7755
<NavLink to="/contributors" className={navLinkStyles}>Contributors</NavLink>
7856
</div>
7957

80-
{/* 3. Right Side Actions */}
58+
{/* Action Buttons */}
8159
<div className="hidden lg:flex items-center space-x-5">
8260
<div className="h-8 w-[1.5px] bg-indigo-200/60 dark:bg-gray-700 mx-2 rounded-full" />
8361

62+
{/* Fix 3: Accessibility label for Theme Toggle */}
8463
<button
8564
onClick={toggleTheme}
8665
className="p-2.5 rounded-full text-slate-500 dark:text-gray-400 bg-white/40 dark:bg-gray-800/40 hover:bg-white dark:hover:bg-gray-700 hover:text-blue-600 transition-all shadow-sm ring-1 ring-slate-200/50 dark:ring-transparent"
66+
aria-label={mode === 'dark' ? "Switch to light mode" : "Switch to dark mode"}
8767
>
8868
{mode === "dark" ? <Sun className="h-5 w-5" /> : <Moon className="h-5 w-5" />}
8969
</button>
9070

91-
<Link to="/login" className="text-lg font-bold text-slate-700 dark:text-gray-200 hover:text-blue-600 transition-colors px-2">
92-
Login
93-
</Link>
94-
95-
<Link
96-
to="/signup"
97-
className="flex items-center space-x-2 px-7 py-3 text-lg font-bold text-white bg-blue-600 rounded-full hover:bg-blue-700 hover:shadow-[0_0_20px_rgba(37,99,235,0.3)] transition-all active:scale-95"
98-
>
71+
<Link to="/login" className="text-lg font-bold text-slate-700 dark:text-gray-200 hover:text-blue-600 transition-colors px-2">Login</Link>
72+
<Link to="/signup" className="flex items-center space-x-2 px-7 py-3 text-lg font-bold text-white bg-blue-600 rounded-full hover:bg-blue-700 hover:shadow-[0_0_20px_rgba(37,99,235,0.3)] transition-all active:scale-95">
9973
<UserPlus className="h-5 w-5" />
10074
<span>Sign Up</span>
10175
</Link>
10276
</div>
10377

104-
{/* Mobile Toggle */}
78+
{/* Mobile Menu Controls */}
10579
<div className="lg:hidden flex items-center space-x-3">
106-
<button onClick={toggleTheme} className="p-2 text-slate-500 dark:text-gray-400">
80+
<button onClick={toggleTheme} className="p-2 text-slate-500 dark:text-gray-400" aria-label="Toggle light/dark mode">
10781
{mode === "dark" ? <Sun className="h-6 w-6" /> : <Moon className="h-6 w-6" />}
10882
</button>
83+
84+
{/* Fix 4: Accessibility labels and 'expanded' state for Mobile Menu */}
10985
<button
11086
onClick={() => setIsOpen(!isOpen)}
111-
className="p-2.5 rounded-2xl bg-white/80 dark:bg-gray-800 text-slate-900 dark:text-white shadow-sm ring-1 ring-slate-200"
87+
className="p-2.5 rounded-2xl bg-white/80 dark:bg-gray-800 text-slate-900 dark:text-white shadow-sm ring-1 ring-slate-200 dark:ring-transparent transition-all"
88+
aria-label="Toggle navigation menu"
89+
aria-expanded={isOpen}
11290
>
11391
{isOpen ? <X className="h-7 w-7" /> : <Menu className="h-7 w-7" />}
11492
</button>
@@ -117,28 +95,15 @@ const Navbar: React.FC = () => {
11795
</div>
11896

11997
{/* Mobile Drawer */}
120-
<div className={`lg:hidden overflow-hidden transition-all duration-500 ease-in-out bg-white/95 dark:bg-gray-900 ${isOpen ? "max-h-[600px] opacity-100 border-t border-indigo-50" : "max-h-0 opacity-0"}`}>
98+
<div className={`lg:hidden overflow-hidden transition-all duration-500 ease-in-out bg-white/95 dark:bg-gray-900 ${isOpen ? "max-h-[600px] opacity-100 border-t border-indigo-50 shadow-2xl" : "max-h-0 opacity-0"}`}>
12199
<div className="px-5 py-10 space-y-4">
122100
<MobileNavLink to="/" onClick={() => setIsOpen(false)}>Home</MobileNavLink>
123-
124-
{/* Mobile Features Link */}
125-
<button
126-
onClick={scrollToFeatures}
127-
className="block w-full text-left px-6 py-4 rounded-2xl text-xl font-bold text-slate-600 dark:text-gray-400 hover:bg-indigo-50 dark:hover:bg-gray-800 transition-all"
128-
>
129-
Features
130-
</button>
131-
101+
<Link to="/#features" className="block px-6 py-4 rounded-2xl text-xl font-bold text-slate-600 dark:text-gray-400 hover:bg-indigo-50 dark:hover:bg-gray-800" onClick={() => setIsOpen(false)}>Features</Link>
132102
<MobileNavLink to="/track" onClick={() => setIsOpen(false)}>Tracker</MobileNavLink>
133103
<MobileNavLink to="/contributors" onClick={() => setIsOpen(false)}>Contributors</MobileNavLink>
134-
135104
<div className="pt-8 mt-6 border-t border-slate-100 grid grid-cols-2 gap-5">
136-
<Link to="/login" className="flex items-center justify-center py-4 text-lg font-bold text-slate-700 bg-slate-50 rounded-2xl" onClick={() => setIsOpen(false)}>
137-
Login
138-
</Link>
139-
<Link to="/signup" className="flex items-center justify-center py-4 text-lg font-bold text-white bg-blue-600 rounded-2xl shadow-lg" onClick={() => setIsOpen(false)}>
140-
Sign Up
141-
</Link>
105+
<Link to="/login" className="flex items-center justify-center py-4 text-lg font-bold text-slate-700 bg-slate-50 dark:bg-gray-800 rounded-2xl" onClick={() => setIsOpen(false)}>Login</Link>
106+
<Link to="/signup" className="flex items-center justify-center py-4 text-lg font-bold text-white bg-blue-600 rounded-2xl shadow-lg shadow-blue-500/20" onClick={() => setIsOpen(false)}>Sign Up</Link>
142107
</div>
143108
</div>
144109
</div>
@@ -147,17 +112,7 @@ const Navbar: React.FC = () => {
147112
};
148113

149114
const MobileNavLink = ({ to, children, onClick }: { to: string, children: React.ReactNode, onClick: () => void }) => (
150-
<NavLink
151-
to={to}
152-
onClick={onClick}
153-
className={({ isActive }) =>
154-
`block px-6 py-4 rounded-2xl text-xl font-bold transition-all ${
155-
isActive ? "bg-blue-600 text-white shadow-lg" : "text-slate-600 dark:text-gray-400 hover:bg-indigo-50 dark:hover:bg-gray-800"
156-
}`
157-
}
158-
>
159-
{children}
160-
</NavLink>
115+
<NavLink to={to} onClick={onClick} className={({ isActive }) => `block px-6 py-4 rounded-2xl text-xl font-bold transition-all ${isActive ? "bg-blue-600 text-white shadow-lg transform translate-x-2" : "text-slate-600 dark:text-gray-400 hover:bg-indigo-50 hover:translate-x-1"}`}>{children}</NavLink>
161116
);
162117

163118
export default Navbar;

0 commit comments

Comments
 (0)