mirror of
https://github.com/TheRealOwenRees/echecsfrance.git
synced 2026-07-23 04:26:57 +00:00
Simplify burger handling
This commit is contained in:
@@ -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<HTMLDivElement>(null);
|
||||
const [burgerMenuIsOpen, setBurgerMenuIsOpen] = useAtom(burgerMenuIsOpenAtom);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
ref={hamburgerButtonRef}
|
||||
className="hamburger-button relative z-[99999] space-y-2"
|
||||
data-test="hamburger-button"
|
||||
onClick={() => setMenuVisible(!menuVisible)}
|
||||
onClick={() => setBurgerMenuIsOpen(!burgerMenuIsOpen)}
|
||||
>
|
||||
<div
|
||||
className={twMerge(
|
||||
"h-0.5 w-8 bg-gray-600 transition-all duration-300 ease-in-out dark:bg-white",
|
||||
menuVisible &&
|
||||
burgerMenuIsOpen &&
|
||||
"translate-x-[1px] translate-y-2.5 rotate-45 bg-white",
|
||||
)}
|
||||
></div>
|
||||
<div
|
||||
className={twMerge(
|
||||
"h-0.5 w-8 bg-gray-600 transition-transform duration-300 ease-linear dark:bg-white",
|
||||
menuVisible && "scale-0 bg-white opacity-0",
|
||||
burgerMenuIsOpen && "scale-0 bg-white opacity-0",
|
||||
)}
|
||||
></div>
|
||||
<div
|
||||
className={twMerge(
|
||||
"h-0.5 w-8 bg-gray-600 transition-transform duration-300 ease-in-out dark:bg-white",
|
||||
menuVisible && "-translate-y-2.5 -rotate-45 bg-white",
|
||||
burgerMenuIsOpen && "-translate-y-2.5 -rotate-45 bg-white",
|
||||
)}
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<HamburgerMenu
|
||||
menuVisible={menuVisible}
|
||||
setMenuVisible={setMenuVisible}
|
||||
hamburgerButtonRef={hamburgerButtonRef}
|
||||
/>
|
||||
<HamburgerMenu />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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<SetStateAction<boolean>>;
|
||||
hamburgerButtonRef: RefObject<HTMLDivElement>;
|
||||
}
|
||||
|
||||
const HamburgerMenu = ({
|
||||
menuVisible,
|
||||
setMenuVisible,
|
||||
hamburgerButtonRef,
|
||||
}: HamburgerMenuState) => {
|
||||
const HamburgerMenu = () => {
|
||||
const t = useTranslations("Nav");
|
||||
const [mouseOverMenu, setMouseOverMenu] = useState(false);
|
||||
const timeoutRef = useRef<NodeJS.Timeout | undefined>();
|
||||
const menuRef = useRef<HTMLDivElement>(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 (
|
||||
<div
|
||||
ref={menuRef}
|
||||
className={twMerge(
|
||||
"fixed right-0 top-0 z-[9999] h-[calc(100svh-5rem)] w-full",
|
||||
"fixed right-0 top-0 z-[9999] h-[calc(100svh-3rem)] w-full",
|
||||
"flex items-center justify-center bg-primary-600 transition-transform duration-200 ease-linear dark:bg-gray-600 md:hidden",
|
||||
!menuVisible && "translate-x-full",
|
||||
!burgerMenuIsOpen && "translate-x-full",
|
||||
)}
|
||||
onMouseEnter={handleMouseEnterMenu}
|
||||
onMouseLeave={handleMouseLeaveMenu}
|
||||
>
|
||||
<ul className="list-reset text-white">
|
||||
<li className="py-5 text-center text-xl">
|
||||
<Link
|
||||
onClick={closeMenu}
|
||||
href="/tournaments"
|
||||
className="border-b-2 border-transparent transition-all duration-300 ease-in-out hover:border-white"
|
||||
>
|
||||
@@ -73,6 +34,7 @@ const HamburgerMenu = ({
|
||||
|
||||
<li className="py-5 text-center text-xl">
|
||||
<Link
|
||||
onClick={closeMenu}
|
||||
href="/clubs"
|
||||
className="border-b-2 border-transparent transition-all duration-300 ease-in-out hover:border-white"
|
||||
>
|
||||
@@ -82,6 +44,7 @@ const HamburgerMenu = ({
|
||||
|
||||
<li className="py-5 text-center text-xl">
|
||||
<Link
|
||||
onClick={closeMenu}
|
||||
href="/elo"
|
||||
className="border-b-2 border-transparent transition-all duration-300 ease-in-out hover:border-white"
|
||||
>
|
||||
|
||||
@@ -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<LatLngBounds | null>(null);
|
||||
export const syncVisibleAtom = atom(true);
|
||||
export const searchStringAtom = atom("");
|
||||
|
||||
Reference in New Issue
Block a user