66 lines
1.9 KiB
TypeScript
66 lines
1.9 KiB
TypeScript
'use client'
|
|
|
|
import { useRef, useState } from 'react'
|
|
import Link from 'next/link'
|
|
import { AnimatePresence, motion } from 'framer-motion'
|
|
|
|
export function NavLinks() {
|
|
let [hoveredIndex, setHoveredIndex] = useState<number | null>(null)
|
|
let timeoutRef = useRef<number | null>(null)
|
|
|
|
const handleClick = (e: React.MouseEvent<HTMLAnchorElement>, href: string) => {
|
|
if (href.startsWith('/#')) {
|
|
e.preventDefault();
|
|
const targetId = href.substring(2);
|
|
const targetElement = document.getElementById(targetId);
|
|
|
|
if (targetElement) {
|
|
targetElement.scrollIntoView({
|
|
behavior: 'smooth',
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
return [
|
|
['Technologies', '/#technologies'],
|
|
['Network', '/#network'],
|
|
['How it Works', '/#how-it-works'],
|
|
['Get Started', '/#get-started'],
|
|
].map(([label, href], index) => (
|
|
<Link
|
|
key={label}
|
|
href={href}
|
|
className="relative -mx-3 -my-2 rounded-lg px-3 py-2 text-sm text-white transition-colors delay-150 hover:text-gray-300 hover:delay-0"
|
|
onClick={(e) => handleClick(e, href)}
|
|
onMouseEnter={() => {
|
|
if (timeoutRef.current) {
|
|
window.clearTimeout(timeoutRef.current)
|
|
}
|
|
setHoveredIndex(index)
|
|
}}
|
|
onMouseLeave={() => {
|
|
timeoutRef.current = window.setTimeout(() => {
|
|
setHoveredIndex(null)
|
|
}, 200)
|
|
}}
|
|
>
|
|
<AnimatePresence>
|
|
{hoveredIndex === index && (
|
|
<motion.span
|
|
className="absolute inset-0 rounded-lg bg-white/10"
|
|
layoutId="hoverBackground"
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1, transition: { duration: 0.15 } }}
|
|
exit={{
|
|
opacity: 0,
|
|
transition: { duration: 0.15 },
|
|
}}
|
|
/>
|
|
)}
|
|
</AnimatePresence>
|
|
<span className="relative z-10">{label}</span>
|
|
</Link>
|
|
))
|
|
}
|