Added Entry and Exit animation for menu
This commit is contained in:
@@ -6,7 +6,20 @@ import { useMenu } from '@/contexts/MenuContext';
|
||||
import styles from './Header.module.css';
|
||||
|
||||
export default function Header() {
|
||||
const { isMenuOpen, toggleMenu } = useMenu();
|
||||
const { isMenuOpen, closeMenu, openMenu, startClosing, resetClosing } =
|
||||
useMenu();
|
||||
|
||||
const handleMenuToggle = () => {
|
||||
if (isMenuOpen) {
|
||||
startClosing();
|
||||
setTimeout(() => {
|
||||
closeMenu();
|
||||
resetClosing();
|
||||
}, 800);
|
||||
} else {
|
||||
openMenu();
|
||||
}
|
||||
};
|
||||
return (
|
||||
<header className={styles.header}>
|
||||
<div className={styles.inner}>
|
||||
@@ -21,7 +34,7 @@ export default function Header() {
|
||||
</div>
|
||||
<div className={styles.menutoggle}>
|
||||
<button
|
||||
onClick={() => toggleMenu()}
|
||||
onClick={() => handleMenuToggle()}
|
||||
aria-label={isMenuOpen ? 'Close menu' : 'Open menu'}
|
||||
aria-expanded={isMenuOpen}
|
||||
aria-controls="main-menu"
|
||||
|
||||
@@ -75,11 +75,29 @@
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
background-color: var(--grid-bg);
|
||||
clip-path: inset(0 0 100% 0);
|
||||
|
||||
transition: clip-path 0.35s steps(8, end);
|
||||
|
||||
|
||||
&.isOpen {
|
||||
pointer-events: auto;
|
||||
|
||||
transform: translateY(0);
|
||||
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
clip-path: inset(0 0 0 0);
|
||||
}
|
||||
|
||||
&.isClosing {
|
||||
clip-path: inset(0 0 100% 0);
|
||||
transition: clip-path 0.25s steps(6, end);
|
||||
|
||||
&.isOpen {
|
||||
clip-path: inset(0 0 100% 0);
|
||||
transition: clip-path 0.25s steps(6, end);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (--bp-desktop) {
|
||||
|
||||
@@ -16,17 +16,16 @@ interface MenuGridProps {
|
||||
}
|
||||
|
||||
export default function MenuGrid({ navigationData }: MenuGridProps) {
|
||||
const { isMenuOpen, closeMenu } = useMenu();
|
||||
const { isMenuOpen, closeMenu, isClosing, startClosing, resetClosing } =
|
||||
useMenu();
|
||||
const menuRef = React.useRef<HTMLElement>(null);
|
||||
const [isClosing, setIsClosing] = React.useState(false);
|
||||
|
||||
const handleClose = React.useCallback(() => {
|
||||
setIsClosing(true);
|
||||
startClosing();
|
||||
setTimeout(() => {
|
||||
closeMenu();
|
||||
setIsClosing(false);
|
||||
resetClosing();
|
||||
}, 800);
|
||||
}, [closeMenu]);
|
||||
}, [closeMenu, startClosing, resetClosing]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleEscape = (e: KeyboardEvent) => {
|
||||
|
||||
@@ -4,9 +4,11 @@ import React, { useContext, useEffect } from 'react';
|
||||
|
||||
interface MenuContextType {
|
||||
isMenuOpen: boolean;
|
||||
toggleMenu: () => void;
|
||||
isClosing: boolean;
|
||||
closeMenu: () => void;
|
||||
openMenu: () => void;
|
||||
startClosing: () => void;
|
||||
resetClosing: () => void;
|
||||
}
|
||||
|
||||
const MenuContext = React.createContext<MenuContextType | undefined>(undefined);
|
||||
@@ -16,11 +18,13 @@ interface MenuProviderProps {
|
||||
}
|
||||
|
||||
export const MenuProvider = ({ children }: MenuProviderProps) => {
|
||||
const [isMenuOpen, setIsMenuOpen] = React.useState(true);
|
||||
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
|
||||
const [isClosing, setIsClosing] = React.useState(false);
|
||||
|
||||
const toggleMenu = () => setIsMenuOpen(!isMenuOpen);
|
||||
const closeMenu = () => setIsMenuOpen(false);
|
||||
const openMenu = () => setIsMenuOpen(true);
|
||||
const startClosing = () => setIsClosing(true);
|
||||
const resetClosing = () => setIsClosing(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isMenuOpen) {
|
||||
@@ -35,7 +39,14 @@ export const MenuProvider = ({ children }: MenuProviderProps) => {
|
||||
|
||||
return (
|
||||
<MenuContext.Provider
|
||||
value={{ isMenuOpen, toggleMenu, openMenu, closeMenu }}
|
||||
value={{
|
||||
isMenuOpen,
|
||||
openMenu,
|
||||
closeMenu,
|
||||
isClosing,
|
||||
startClosing,
|
||||
resetClosing,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</MenuContext.Provider>
|
||||
|
||||
Reference in New Issue
Block a user