fix: animations for menu

This commit is contained in:
Benno Tielen 2024-11-25 11:19:01 +01:00
parent ab83bf0990
commit b868c0a7a4
3 changed files with 74 additions and 22 deletions

View file

@ -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 (
<Link href={href} className={styles.item}>
<Link href={href} className={styles.item} onClick={onClick}>
{icon &&
<div className={styles.itemIcon}>
</div>
@ -40,20 +42,26 @@ const Item = ({href, title, description, icon}: ItemProps) => {
)
}
const ItemGroup = ({title, items}: ItemGroupProps) => {
const ItemGroup = ({title, items, onItemClick}: ItemGroupProps) => {
return (
<div className={styles.itemGroup}>
<div className={styles.groupTitle}>{title}</div>
<div className={styles.itemGroupContent}>
{items.map(item => <Item key={item.title} title={item.title} href={item.href} description={item.description} />)}
{items.map(item => <Item
key={item.title}
title={item.title}
href={item.href}
description={item.description}
onClick={onItemClick}
/>)}
</div>
</div>
)
}
export const MegaMenu = ({ bibleText, bibleBook, groups, onClick }: MegaMenuProps) => {
export const MegaMenu = ({ bibleText, bibleBook, groups, onItemClick }: MegaMenuProps) => {
return (
<div className={styles.menu} onClick={onClick}>
<div className={styles.menu}>
<div className={styles.bibleText}>
<div className={faustina.className}>
{bibleText}
@ -63,7 +71,13 @@ export const MegaMenu = ({ bibleText, bibleBook, groups, onClick }: MegaMenuProp
</div>
</div>
{groups.map(group => <ItemGroup key={group.title} title={group.title} items={group.items} />)}
{groups.map(group =>
<ItemGroup
key={group.title}
title={group.title}
items={group.items}
onItemClick={onItemClick}
/>)}
</div>
)
}

View file

@ -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<boolean>(false);
const itemClicked = useCallback(() => {
setIsActive(false);
if (onItemClick) {
onItemClick();
}
}, [setIsActive, onItemClick]);
return (
<>
<a className={className} href={href} onClick={() => setDisplayMegaMenu(!displayMegaMenu)}>
<span
className={styles.menuItem}
onMouseEnter={() => setIsActive(true)}
onMouseLeave={() => setIsActive(false)}
>
<a className={className} href={href}>
{text}
</a>
{megaMenu && displayMegaMenu &&
<div className={styles.megaMenu}>
<MegaMenu bibleText={megaMenu.text.quote} bibleBook={megaMenu.text.source} groups={megaMenu.groups} />
{megaMenu &&
<div
className={classNames({
[styles.megaMenu]: true,
[styles.megaMenuActive]: isActive
})}
>
<MegaMenu
bibleText={megaMenu.text.quote}
bibleBook={megaMenu.text.source}
groups={megaMenu.groups}
onItemClick={itemClicked}
/>
</div>
}
</>
</span>
)
}
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) => {
</div>
<div className={classNames(styles.itemsLeft, {[styles.hide]: !displayMenuMobile})}>
<MenuItems items={menu.leftItems} />
<MenuItems
items={menu.leftItems}
onItemClick={() => setDisplayMenuMobile(false)}
/>
</div>
<div className={classNames(styles.itemsRight, {[styles.hide]: !displayMenuMobile})}>
<MenuItems items={menu.rightItems} />
<MenuItems
items={menu.rightItems}
onItemClick={() => setDisplayMenuMobile(false)}
/>
</div>
</nav>

View file

@ -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) {