From 94cea267c9f49bebcb33c2fe8baede3eb6ce4e34 Mon Sep 17 00:00:00 2001 From: Timothy Armes Date: Wed, 11 Oct 2023 08:36:45 +0200 Subject: [PATCH] Simplify burger handling --- app/[locale]/components/Hamburger.tsx | 24 ++++---- app/[locale]/components/HamburgerMenu.tsx | 57 ++++--------------- app/atoms.ts | 1 + components/Map.tsx | 2 +- components/ScrollToTopButton.tsx | 2 +- hooks/useHamburgerClose.ts | 67 ----------------------- {handlers => utils}/scrollHandlers.ts | 0 7 files changed, 23 insertions(+), 130 deletions(-) delete mode 100644 hooks/useHamburgerClose.ts rename {handlers => utils}/scrollHandlers.ts (100%) diff --git a/app/[locale]/components/Hamburger.tsx b/app/[locale]/components/Hamburger.tsx index cc3b6de..8b37f76 100644 --- a/app/[locale]/components/Hamburger.tsx +++ b/app/[locale]/components/Hamburger.tsx @@ -1,48 +1,44 @@ "use client"; -import { useRef, useState } from "react"; - +import { useAtom } from "jotai"; import { twMerge } from "tailwind-merge"; +import { burgerMenuIsOpenAtom } from "@/app/atoms"; + import HamburgerMenu from "./HamburgerMenu"; const Hamburger = () => { - const [menuVisible, setMenuVisible] = useState(false); - const hamburgerButtonRef = useRef(null); + const [burgerMenuIsOpen, setBurgerMenuIsOpen] = useAtom(burgerMenuIsOpenAtom); + return ( <>
setMenuVisible(!menuVisible)} + onClick={() => setBurgerMenuIsOpen(!burgerMenuIsOpen)} >
- + ); }; diff --git a/app/[locale]/components/HamburgerMenu.tsx b/app/[locale]/components/HamburgerMenu.tsx index d195cb9..cb2a934 100644 --- a/app/[locale]/components/HamburgerMenu.tsx +++ b/app/[locale]/components/HamburgerMenu.tsx @@ -1,69 +1,30 @@ import { Dispatch, RefObject, SetStateAction, useRef, useState } from "react"; +import { useAtom } from "jotai"; import { useTranslations } from "next-intl"; import { twMerge } from "tailwind-merge"; -import useHamburgerClose from "@/hooks/useHamburgerClose"; +import { burgerMenuIsOpenAtom } from "@/app/atoms"; import { Link } from "@/utils/navigation"; -interface HamburgerMenuState { - menuVisible: boolean; - setMenuVisible: Dispatch>; - hamburgerButtonRef: RefObject; -} - -const HamburgerMenu = ({ - menuVisible, - setMenuVisible, - hamburgerButtonRef, -}: HamburgerMenuState) => { +const HamburgerMenu = () => { const t = useTranslations("Nav"); - const [mouseOverMenu, setMouseOverMenu] = useState(false); - const timeoutRef = useRef(); - const menuRef = useRef(null); + const [burgerMenuIsOpen, setBurgerMenuIsOpen] = useAtom(burgerMenuIsOpenAtom); - const menuTimeout = () => { - timeoutRef.current = setTimeout(() => { - setMenuVisible(false); - setMouseOverMenu(false); - }, 4000); - }; - - const handleMouseEnterMenu = () => { - setMouseOverMenu(true); - clearTimeout(timeoutRef.current); - }; - - const handleMouseLeaveMenu = () => { - setMouseOverMenu(false); - clearTimeout(timeoutRef.current); - }; - - useHamburgerClose({ - menuVisible, - setMenuVisible, - menuRef, - hamburgerButtonRef, - mouseOverMenu, - setMouseOverMenu, - timeoutRef, - menuTimeout, - }); + const closeMenu = () => setBurgerMenuIsOpen(false); return (
  • @@ -73,6 +34,7 @@ const HamburgerMenu = ({
  • @@ -82,6 +44,7 @@ const HamburgerMenu = ({
  • diff --git a/app/atoms.ts b/app/atoms.ts index 98e78b6..3807543 100644 --- a/app/atoms.ts +++ b/app/atoms.ts @@ -5,6 +5,7 @@ import { Club, TimeControl, Tournament } from "@/types"; import atomWithDebounce from "@/utils/atomWithDebounce"; import { normalizedContains } from "@/utils/string"; +export const burgerMenuIsOpenAtom = atom(false); export const mapBoundsAtom = atom(null); export const syncVisibleAtom = atom(true); export const searchStringAtom = atom(""); diff --git a/components/Map.tsx b/components/Map.tsx index 7c95170..4edc903 100644 --- a/components/Map.tsx +++ b/components/Map.tsx @@ -220,7 +220,7 @@ export const Map = ({ return (
    -
    {filters}
    + {filters &&
    {filters}
    } { const scrollToTopElementRef = useRef(null); diff --git a/hooks/useHamburgerClose.ts b/hooks/useHamburgerClose.ts deleted file mode 100644 index 4d0f8e4..0000000 --- a/hooks/useHamburgerClose.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Dispatch, RefObject, SetStateAction, useEffect } from "react"; - -interface HamburgerClose { - menuVisible: boolean; - setMenuVisible: Dispatch>; - menuRef: RefObject; - hamburgerButtonRef: RefObject; - mouseOverMenu: boolean; - setMouseOverMenu: Dispatch>; - timeoutRef: RefObject; - menuTimeout: () => void; -} - -const useHamburgerClose = ({ - menuVisible, - setMenuVisible, - menuRef, - hamburgerButtonRef, - mouseOverMenu, - setMouseOverMenu, - timeoutRef, - menuTimeout, -}: HamburgerClose) => { - useEffect(() => { - const handleMouseDownOutsideMenu = (event: MouseEvent) => { - if ( - menuVisible && - menuRef.current && - !menuRef.current.contains(event.target as Node) && - hamburgerButtonRef.current && - !hamburgerButtonRef.current.contains(event.target as Node) - ) { - setMenuVisible(false); - setMouseOverMenu(false); - } - }; - - const handleLinkClick = () => { - setMenuVisible(false); - }; - - document.addEventListener("mousedown", handleMouseDownOutsideMenu); - const links = document.querySelectorAll("a"); - links.forEach((link) => { - link.addEventListener("click", handleLinkClick); - }); - - return () => { - document.removeEventListener("mousedown", handleMouseDownOutsideMenu); - links.forEach((link) => { - link.removeEventListener("click", handleLinkClick); - }); - }; - }, [menuVisible]); - - useEffect(() => { - if (menuVisible && !mouseOverMenu) { - menuTimeout(); - } else { - if (timeoutRef.current) { - clearTimeout(timeoutRef.current); - } - } - }, [mouseOverMenu, menuVisible]); -}; - -export default useHamburgerClose; diff --git a/handlers/scrollHandlers.ts b/utils/scrollHandlers.ts similarity index 100% rename from handlers/scrollHandlers.ts rename to utils/scrollHandlers.ts