Looking to implement a mobile menu with a cool fading effect on the navigation items, but something seems off. The NavLink items all appear simultaneously instead of staggered loading.
Initially, considered using 'delay' instead of 'delayChildren' but that didn't solve the issue.
Check out the mobileNav.tsx code below:
'use client';
import { useState } from "react";
import {AnimatePresence, motion} from "framer-motion";
import NavLink from '@/components/nav/navLink';
const MobileNav = () => {
const [isOpen, setOpen] = useState<boolean>(false);
const handleClick = () => {
setOpen(!isOpen);
};
const menuVariants = {
closed: {
x: '100%',
},
open: {
x: 0,
transition: {
type: 'tween',
duration: 0.3,
},
},
};
const navLinksVariants = {
hidden: {},
visible: {
transition: {
staggerChildren: 0.1,
delayChildren: 0.3,
},
},
exit: {
transition: {
staggerChildren: 0.05,
staggerDirection: -1,
},
},
};
return(
<>
<AnimatePresence>
{isOpen &&
<motion.div className="z-10 w-screen h-screen bg-gray-500 absolute flex flex-col justify-center items-center"
variants={menuVariants}
initial="closed"
animate="open">
<motion.ul
variants={navLinksVariants}
initial="hidden"
animate="visible"
exit="exit">
<NavLink link="#projects">Projects</NavLink>
<NavLink link="#about">About</NavLink>
<NavLink link="#contact">Contact</NavLink>
</motion.ul>
</motion.div>
}
</AnimatePresence>
<button onClick={handleClick} className="p-4 flex flex-col justify-center items-center absolute z-20 lg:hidden">
{!isOpen &&
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-10">
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
}
{isOpen &&
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-10">
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
}
</button>
</>
)
}
export default MobileNav;
And here is the content of navLink.tsx:
'use client';
import { motion } from 'framer-motion';
interface NavLinkProps {
link: string;
children: string;
}
const NavLink: React.FC<NavLinkProps> = ({link, children}) => {
const linkItemVariants = {
hidden: { opacity: 0, y: '50%' },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.5,
ease: "easeOut" // Add ease-out easing function
},
},
exit: {
opacity: 0,
y: '80%',
transition: {
duration: 0.3,
ease: "easeOut" // Add ease-out easing function
}
},
};
return (
<motion.li className="lg:mx-5 sm:mb-5 text-5xl lg:text-lg"
variants={linkItemVariants}
initial="hidden"
animate="visible"
exit="exit">
<a href={link} aria-label={children}>
{children}
</a>
</motion.li>
);
};
export default NavLink;