From 37d562f723503531c5dd6d0cd00b955afe74700f Mon Sep 17 00:00:00 2001 From: w3bdesign <45217974+w3bdesign@users.noreply.github.com> Date: Thu, 6 Mar 2025 14:37:32 +0100 Subject: [PATCH 1/2] Disable hamburger while animating --- src/components/Footer/Hamburger.component.tsx | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/components/Footer/Hamburger.component.tsx b/src/components/Footer/Hamburger.component.tsx index 370bb53a2..d752c3398 100644 --- a/src/components/Footer/Hamburger.component.tsx +++ b/src/components/Footer/Hamburger.component.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, useRef } from 'react'; import Link from 'next/link'; import FadeLeftToRight from '@/components/Animations/FadeLeftToRight.component'; @@ -22,34 +22,69 @@ const opacityFull = 'opacity-100 group-hover:opacity-100'; const Hamburger = () => { const [isExpanded, setisExpanded] = useState(false); const [hidden, setHidden] = useState('invisible'); + const [isAnimating, setIsAnimating] = useState(false); + const animationTimeoutRef = useRef(null); useEffect(() => { if (isExpanded) { setHidden(''); + setIsAnimating(true); + + // Clear any existing timeout + if (animationTimeoutRef.current) { + clearTimeout(animationTimeoutRef.current); + } + + // Set a timeout for the animation duration + animationTimeoutRef.current = setTimeout(() => { + setIsAnimating(false); + }, 1000); // Match this with the animation duration } else { - setTimeout(() => { + setIsAnimating(true); + + // Clear any existing timeout + if (animationTimeoutRef.current) { + clearTimeout(animationTimeoutRef.current); + } + + // Set a timeout for the animation duration and hiding + animationTimeoutRef.current = setTimeout(() => { setHidden('invisible'); - }, 1000); + setIsAnimating(false); + }, 1000); // Match this with the animation duration } + + // Cleanup function to clear timeout when component unmounts + return () => { + if (animationTimeoutRef.current) { + clearTimeout(animationTimeoutRef.current); + } + }; }, [isExpanded]); const handleMobileMenuClick = useCallback(() => { + // Prevent clicks during animation + if (isAnimating) { + return; + } + /** * Anti-pattern: setisExpanded(!isExpanded) * Even if your state updates are batched and multiple updates to the enabled/disabled state are made together * each update will rely on the correct previous state so that you always end up with the result you expect. */ setisExpanded((prevExpanded) => !prevExpanded); - }, [setisExpanded]); + }, [setisExpanded, isAnimating]); return (