fix: animations for menu
This commit is contained in:
parent
ab83bf0990
commit
b868c0a7a4
3 changed files with 74 additions and 22 deletions
|
|
@ -6,7 +6,7 @@ type MegaMenuProps = {
|
||||||
bibleText: string,
|
bibleText: string,
|
||||||
bibleBook: string,
|
bibleBook: string,
|
||||||
groups: ItemGroupProps[],
|
groups: ItemGroupProps[],
|
||||||
onClick?: () => void
|
onItemClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemProps = {
|
type ItemProps = {
|
||||||
|
|
@ -14,16 +14,18 @@ type ItemProps = {
|
||||||
description: string
|
description: string
|
||||||
icon?: string
|
icon?: string
|
||||||
href: string
|
href: string
|
||||||
|
onClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
type ItemGroupProps = {
|
type ItemGroupProps = {
|
||||||
title: string,
|
title: string,
|
||||||
items: ItemProps[]
|
items: ItemProps[]
|
||||||
|
onItemClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const Item = ({href, title, description, icon}: ItemProps) => {
|
const Item = ({href, title, description, icon, onClick}: ItemProps) => {
|
||||||
return (
|
return (
|
||||||
<Link href={href} className={styles.item}>
|
<Link href={href} className={styles.item} onClick={onClick}>
|
||||||
{icon &&
|
{icon &&
|
||||||
<div className={styles.itemIcon}>
|
<div className={styles.itemIcon}>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -40,20 +42,26 @@ const Item = ({href, title, description, icon}: ItemProps) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ItemGroup = ({title, items}: ItemGroupProps) => {
|
const ItemGroup = ({title, items, onItemClick}: ItemGroupProps) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.itemGroup}>
|
<div className={styles.itemGroup}>
|
||||||
<div className={styles.groupTitle}>{title}</div>
|
<div className={styles.groupTitle}>{title}</div>
|
||||||
<div className={styles.itemGroupContent}>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MegaMenu = ({ bibleText, bibleBook, groups, onClick }: MegaMenuProps) => {
|
export const MegaMenu = ({ bibleText, bibleBook, groups, onItemClick }: MegaMenuProps) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.menu} onClick={onClick}>
|
<div className={styles.menu}>
|
||||||
<div className={styles.bibleText}>
|
<div className={styles.bibleText}>
|
||||||
<div className={faustina.className}>
|
<div className={faustina.className}>
|
||||||
{bibleText}
|
{bibleText}
|
||||||
|
|
@ -63,7 +71,13 @@ export const MegaMenu = ({ bibleText, bibleBook, groups, onClick }: MegaMenuProp
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -6,38 +6,62 @@ import Image from 'next/image'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import {Menu as MenuType, MenuItem as MenuItemType} from "./menu.types"
|
import {Menu as MenuType, MenuItem as MenuItemType} from "./menu.types"
|
||||||
import { Logo } from '@/components/Logo/Logo'
|
import { Logo } from '@/components/Logo/Logo'
|
||||||
import { useState } from 'react'
|
import { useCallback, useState } from 'react'
|
||||||
import { MegaMenu } from '@/components/MegaMenu/MegaMenu'
|
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({
|
const className = classNames({
|
||||||
[styles.menuLink]: display === "normal",
|
[styles.menuLink]: display === "normal",
|
||||||
[styles.button]: display === "button"
|
[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 (
|
return (
|
||||||
<>
|
<span
|
||||||
<a className={className} href={href} onClick={() => setDisplayMegaMenu(!displayMegaMenu)}>
|
className={styles.menuItem}
|
||||||
|
onMouseEnter={() => setIsActive(true)}
|
||||||
|
onMouseLeave={() => setIsActive(false)}
|
||||||
|
>
|
||||||
|
<a className={className} href={href}>
|
||||||
{text}
|
{text}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{megaMenu && displayMegaMenu &&
|
{megaMenu &&
|
||||||
<div className={styles.megaMenu}>
|
<div
|
||||||
<MegaMenu bibleText={megaMenu.text.quote} bibleBook={megaMenu.text.source} groups={megaMenu.groups} />
|
className={classNames({
|
||||||
|
[styles.megaMenu]: true,
|
||||||
|
[styles.megaMenuActive]: isActive
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<MegaMenu
|
||||||
|
bibleText={megaMenu.text.quote}
|
||||||
|
bibleBook={megaMenu.text.source}
|
||||||
|
groups={megaMenu.groups}
|
||||||
|
onItemClick={itemClicked}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</>
|
</span>
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MenuItemsProps = {
|
type MenuItemsProps = {
|
||||||
items: MenuItemType[]
|
items: MenuItemType[]
|
||||||
|
onItemClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const MenuItems = ({items}: MenuItemsProps) => {
|
const MenuItems = ({items, onItemClick}: MenuItemsProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{items.map(item =>
|
{items.map(item =>
|
||||||
|
|
@ -47,6 +71,7 @@ const MenuItems = ({items}: MenuItemsProps) => {
|
||||||
href={item.href}
|
href={item.href}
|
||||||
display={item.display}
|
display={item.display}
|
||||||
megaMenu={item.megaMenu}
|
megaMenu={item.megaMenu}
|
||||||
|
onItemClick={onItemClick}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
@ -77,11 +102,17 @@ export const Menu = ({menu}: MenuProps) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classNames(styles.itemsLeft, {[styles.hide]: !displayMenuMobile})}>
|
<div className={classNames(styles.itemsLeft, {[styles.hide]: !displayMenuMobile})}>
|
||||||
<MenuItems items={menu.leftItems} />
|
<MenuItems
|
||||||
|
items={menu.leftItems}
|
||||||
|
onItemClick={() => setDisplayMenuMobile(false)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classNames(styles.itemsRight, {[styles.hide]: !displayMenuMobile})}>
|
<div className={classNames(styles.itemsRight, {[styles.hide]: !displayMenuMobile})}>
|
||||||
<MenuItems items={menu.rightItems} />
|
<MenuItems
|
||||||
|
items={menu.rightItems}
|
||||||
|
onItemClick={() => setDisplayMenuMobile(false)}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,17 @@
|
||||||
|
|
||||||
.megaMenu {
|
.megaMenu {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 76px;
|
top: 62px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 8;
|
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) {
|
@media screen and (max-width: 800px) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue