From b868c0a7a4fe2e8048125f50bce3af1d1271d2e9 Mon Sep 17 00:00:00 2001 From: Benno Tielen Date: Mon, 25 Nov 2024 11:19:01 +0100 Subject: [PATCH] fix: animations for menu --- src/components/MegaMenu/MegaMenu.tsx | 30 ++++++++++---- src/components/Menu/Menu.tsx | 57 ++++++++++++++++++++------ src/components/Menu/styles.module.scss | 9 +++- 3 files changed, 74 insertions(+), 22 deletions(-) diff --git a/src/components/MegaMenu/MegaMenu.tsx b/src/components/MegaMenu/MegaMenu.tsx index 822ed69..f268386 100644 --- a/src/components/MegaMenu/MegaMenu.tsx +++ b/src/components/MegaMenu/MegaMenu.tsx @@ -6,7 +6,7 @@ type MegaMenuProps = { bibleText: string, bibleBook: string, groups: ItemGroupProps[], - onClick?: () => void + onItemClick?: () => void } type ItemProps = { @@ -14,16 +14,18 @@ type ItemProps = { description: string icon?: string href: string + onClick?: () => void } type ItemGroupProps = { title: string, items: ItemProps[] + onItemClick?: () => void } -const Item = ({href, title, description, icon}: ItemProps) => { +const Item = ({href, title, description, icon, onClick}: ItemProps) => { return ( - + {icon &&
@@ -40,20 +42,26 @@ const Item = ({href, title, description, icon}: ItemProps) => { ) } -const ItemGroup = ({title, items}: ItemGroupProps) => { +const ItemGroup = ({title, items, onItemClick}: ItemGroupProps) => { return (
{title}
- {items.map(item => )} + {items.map(item => )}
) } -export const MegaMenu = ({ bibleText, bibleBook, groups, onClick }: MegaMenuProps) => { +export const MegaMenu = ({ bibleText, bibleBook, groups, onItemClick }: MegaMenuProps) => { return ( -
+
{bibleText} @@ -63,7 +71,13 @@ export const MegaMenu = ({ bibleText, bibleBook, groups, onClick }: MegaMenuProp
- {groups.map(group => )} + {groups.map(group => + )}
) } \ No newline at end of file diff --git a/src/components/Menu/Menu.tsx b/src/components/Menu/Menu.tsx index bae6f08..10a3c01 100644 --- a/src/components/Menu/Menu.tsx +++ b/src/components/Menu/Menu.tsx @@ -6,38 +6,62 @@ import Image from 'next/image' import classNames from 'classnames' import {Menu as MenuType, MenuItem as MenuItemType} from "./menu.types" import { Logo } from '@/components/Logo/Logo' -import { useState } from 'react' +import { useCallback, useState } from 'react' import { MegaMenu } from '@/components/MegaMenu/MegaMenu' -const MenuItem = ({text, href, display = "normal", megaMenu}: MenuItemType) => { +type MenuItemProps = MenuItemType & { + onItemClick?: () => void +} + +const MenuItem = ({text, href, display = "normal", megaMenu, onItemClick}: MenuItemProps) => { const className = classNames({ [styles.menuLink]: display === "normal", [styles.button]: display === "button" }); - const [displayMegaMenu, setDisplayMegaMenu] = useState(false) + const [isActive, setIsActive] = useState(false); + const itemClicked = useCallback(() => { + setIsActive(false); + if (onItemClick) { + onItemClick(); + } + }, [setIsActive, onItemClick]); return ( - <> - setDisplayMegaMenu(!displayMegaMenu)}> + setIsActive(true)} + onMouseLeave={() => setIsActive(false)} + > + {text} - {megaMenu && displayMegaMenu && -
- + {megaMenu && +
+
} - - + ) } type MenuItemsProps = { items: MenuItemType[] + onItemClick?: () => void } -const MenuItems = ({items}: MenuItemsProps) => { +const MenuItems = ({items, onItemClick}: MenuItemsProps) => { return ( <> {items.map(item => @@ -47,6 +71,7 @@ const MenuItems = ({items}: MenuItemsProps) => { href={item.href} display={item.display} megaMenu={item.megaMenu} + onItemClick={onItemClick} /> )} @@ -77,11 +102,17 @@ export const Menu = ({menu}: MenuProps) => {
- + setDisplayMenuMobile(false)} + />
- + setDisplayMenuMobile(false)} + />
diff --git a/src/components/Menu/styles.module.scss b/src/components/Menu/styles.module.scss index 4b31936..c77d429 100644 --- a/src/components/Menu/styles.module.scss +++ b/src/components/Menu/styles.module.scss @@ -64,10 +64,17 @@ .megaMenu { position: fixed; - top: 76px; + top: 62px; left: 0; width: 100%; z-index: 8; + max-height: 0; + overflow: hidden; + transition: max-height 0.3s ease-in-out; +} + +.megaMenuActive { + max-height: 1000px; } @media screen and (max-width: 800px) {