83 lines
2.6 KiB
React
83 lines
2.6 KiB
React
import { useEffect, useState } from "react";
|
|
import "../styles/NavBar.css";
|
|
|
|
const NavBar = () => {
|
|
const [active, setActive] = useState("home-section");
|
|
const [isScrolling, setIsScrolling] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const sections = document.querySelectorAll("section");
|
|
const navHeight = document.querySelector(".navbar")?.offsetHeight + 40 || 120;
|
|
|
|
const handleScroll = () => {
|
|
if (isScrolling) return;
|
|
|
|
let current = "home-section";
|
|
sections.forEach((section) => {
|
|
const sectionTop = section.offsetTop - navHeight;
|
|
if (window.scrollY >= sectionTop) {
|
|
current = section.id;
|
|
}
|
|
});
|
|
|
|
setActive(current);
|
|
};
|
|
|
|
window.addEventListener("scroll", handleScroll);
|
|
handleScroll();
|
|
|
|
return () => {
|
|
window.removeEventListener("scroll", handleScroll);
|
|
};
|
|
}, [isScrolling]);
|
|
|
|
const handleClick = (id) => {
|
|
setActive(id);
|
|
setIsScrolling(true);
|
|
document.getElementById(id)?.scrollIntoView({ behavior: "smooth" });
|
|
setTimeout(() => setIsScrolling(false), 800);
|
|
};
|
|
|
|
|
|
return (
|
|
<nav className="navbar">
|
|
<ul className="nav-list">
|
|
<li>
|
|
<button
|
|
onClick={() => handleClick("home-section")}
|
|
className={`nav-link ${active === "home-section" ? "active" : ""}`}
|
|
>
|
|
Home
|
|
</button>
|
|
</li>
|
|
<li>
|
|
<button
|
|
onClick={() => handleClick("experiences-section")}
|
|
className={`nav-link ${active === "experiences-section" ? "active" : ""}`}
|
|
>
|
|
Experiences
|
|
</button>
|
|
</li>
|
|
<li>
|
|
<button
|
|
onClick={() => handleClick("projects-section")}
|
|
className={`nav-link ${active === "projects-section" ? "active" : ""}`}
|
|
>
|
|
Projects
|
|
</button>
|
|
</li>
|
|
<li>
|
|
<button
|
|
onClick={() => handleClick("skills-section")}
|
|
className={`nav-link ${active === "skills-section" ? "active" : ""}`}
|
|
>
|
|
Skills
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
);
|
|
};
|
|
|
|
export default NavBar;
|