From b59fd820068c5ff1d9e7feb0fb1920b921b35acf Mon Sep 17 00:00:00 2001 From: TerryM Date: Thu, 28 May 2026 22:41:23 +0800 Subject: [PATCH] Refine mobile dropdown close behavior --- src/components/FigmaBanner.tsx | 23 +++++++++++++++++++++-- src/layouts/PublicLayout.tsx | 12 ++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/components/FigmaBanner.tsx b/src/components/FigmaBanner.tsx index f5d7072..121aad7 100644 --- a/src/components/FigmaBanner.tsx +++ b/src/components/FigmaBanner.tsx @@ -35,6 +35,7 @@ type BannerApiResponse = { const AUTOPLAY_MS = 3000; const RESUME_AFTER_INTERACTION_MS = 8000; +const publicMenuOpenChangeEvent = "ark:public-menu-open-change"; function bannerLangParam(lang: Lang): string { return langQuery(lang).toLowerCase(); @@ -62,6 +63,7 @@ export function FigmaBanner() { const scrollerRef = useRef(null); const [activeIndex, setActiveIndex] = useState(0); const [autoplayPaused, setAutoplayPaused] = useState(false); + const [publicMenuOpen, setPublicMenuOpen] = useState(false); const resumeTimerRef = useRef(null); const dragStateRef = useRef<{ pointerId: number; @@ -115,6 +117,23 @@ export function FigmaBanner() { [], ); + useEffect(() => { + const handlePublicMenuOpenChange = (event: Event) => { + setPublicMenuOpen(Boolean((event as CustomEvent).detail)); + }; + + window.addEventListener( + publicMenuOpenChangeEvent, + handlePublicMenuOpenChange, + ); + return () => { + window.removeEventListener( + publicMenuOpenChangeEvent, + handlePublicMenuOpenChange, + ); + }; + }, []); + useEffect(() => { const scroller = scrollerRef.current; if (!scroller) return; @@ -132,7 +151,7 @@ export function FigmaBanner() { }, [slides.length]); useEffect(() => { - if (!hasMultiple || autoplayPaused) return; + if (!hasMultiple || autoplayPaused || publicMenuOpen) return; const timer = window.setInterval(() => { setActiveIndex((prev) => { const next = (prev + 1) % slides.length; @@ -141,7 +160,7 @@ export function FigmaBanner() { }); }, AUTOPLAY_MS); return () => window.clearInterval(timer); - }, [hasMultiple, autoplayPaused, slides.length, goTo]); + }, [hasMultiple, autoplayPaused, publicMenuOpen, slides.length, goTo]); const handlePointerDown = (event: ReactPointerEvent) => { if (event.pointerType !== "mouse") return; diff --git a/src/layouts/PublicLayout.tsx b/src/layouts/PublicLayout.tsx index 512ee6b..2086f34 100644 --- a/src/layouts/PublicLayout.tsx +++ b/src/layouts/PublicLayout.tsx @@ -64,6 +64,8 @@ function navClassName(active: boolean) { const dropdownAnimationClass = "animate__animated animate__fadeInDown ark-dropdown-enter"; +const publicMenuOpenChangeEvent = "ark:public-menu-open-change"; + type LanguageDropdownProps = { lang: Lang; setLang: (lang: Lang) => void; @@ -294,6 +296,12 @@ export function PublicLayout() { setMobileSearchOpen(false); }; + useEffect(() => { + window.dispatchEvent( + new CustomEvent(publicMenuOpenChangeEvent, { detail: open }), + ); + }, [open]); + useEffect(() => { if (!open) return; @@ -312,11 +320,11 @@ export function PublicLayout() { document.addEventListener("mousedown", closeOnOutside); document.addEventListener("touchstart", closeOnOutside); - window.addEventListener("scroll", closeOnScroll, true); + window.addEventListener("scroll", closeOnScroll); return () => { document.removeEventListener("mousedown", closeOnOutside); document.removeEventListener("touchstart", closeOnOutside); - window.removeEventListener("scroll", closeOnScroll, true); + window.removeEventListener("scroll", closeOnScroll); }; }, [open]);