Skip to content

Commit

Permalink
polished menu animations
Browse files Browse the repository at this point in the history
  • Loading branch information
chlebektomas committed Nov 13, 2024
1 parent 2c6115c commit 58f4f83
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
20 changes: 20 additions & 0 deletions storefront/components/Basic/Animations/AnimateNavigationMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TIDs } from 'cypress/tids';
import { HTMLMotionProps, m } from 'framer-motion';
import { fadeAnimation } from 'utils/animations/animationVariants';

export const AnimateNavigationMenu: FC<
HTMLMotionProps<'div'> & { tid?: TIDs; keyName?: string; disableAnimation: boolean }
> = ({ children, className, keyName, tid, disableAnimation, ...props }) => (
<m.div
key={keyName}
animate="visible"
className={className}
exit="hidden"
initial="hidden"
tid={tid}
variants={disableAnimation ? undefined : fadeAnimation}
{...props}
>
{children}
</m.div>
);
29 changes: 27 additions & 2 deletions storefront/components/Layout/Header/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { NavigationItem } from './NavigationItem';
import { TypeCategoriesByColumnFragment } from 'graphql/requests/navigation/fragments/CategoriesByColumnsFragment.generated';
import { useState } from 'react';
import { PageType } from 'store/slices/createPageLoadingStateSlice';

export type NavigationProps = {
Expand All @@ -8,10 +9,34 @@ export type NavigationProps = {
};

export const Navigation: FC<NavigationProps> = ({ navigation, skeletonType }) => {
const [isFirstHover, setIsFirstHover] = useState(false);
const [isAnimationDisabled, setIsAnimationDisabled] = useState(false);

const handleAnimations = () => {
if (!isFirstHover) {
setIsFirstHover(true);

return;
}

setIsAnimationDisabled(true);
};

const handleEnableAnimation = () => {
setIsAnimationDisabled(false);
setIsFirstHover(false);
};

return (
<ul className="relative hidden w-full lg:flex">
<ul className="relative hidden w-full lg:flex" onMouseLeave={handleEnableAnimation}>
{navigation.map((navigationItem, index) => (
<NavigationItem key={index} navigationItem={navigationItem} skeletonType={skeletonType} />
<NavigationItem
key={index}
handleAnimations={handleAnimations}
isAnimationDisabled={isAnimationDisabled}
navigationItem={navigationItem}
skeletonType={skeletonType}
/>
))}
</ul>
);
Expand Down
29 changes: 23 additions & 6 deletions storefront/components/Layout/Header/Navigation/NavigationItem.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AnimateCollapseDiv } from 'components/Basic/Animations/AnimateCollapseDiv';
import { AnimateNavigationMenu } from 'components/Basic/Animations/AnimateNavigationMenu';
import { ExtendedNextLink } from 'components/Basic/ExtendedNextLink/ExtendedNextLink';
import { ArrowIcon } from 'components/Basic/Icon/ArrowIcon';
import { NavigationItemColumn } from 'components/Layout/Header/Navigation/NavigationItemColumn';
Expand All @@ -12,15 +12,29 @@ import { useDebounce } from 'utils/useDebounce';
type NavigationItemProps = {
navigationItem: TypeCategoriesByColumnFragment;
skeletonType?: PageType;
isAnimationDisabled: boolean;
handleAnimations: () => void;
};

export const NavigationItem: FC<NavigationItemProps> = ({ navigationItem, skeletonType }) => {
export const NavigationItem: FC<NavigationItemProps> = ({
navigationItem,
skeletonType,
isAnimationDisabled,
handleAnimations,
}) => {
const [isMenuOpened, setIsMenuOpened] = useState(false);
const hasChildren = !!navigationItem.categoriesByColumns.length;
const isMenuOpenedDelayed = useDebounce(isMenuOpened, 200);
const isMenuOpenedDelayed = useDebounce(isMenuOpened && true, 200);

return (
<li className="group" onMouseEnter={() => setIsMenuOpened(true)} onMouseLeave={() => setIsMenuOpened(false)}>
<li
className="group"
onMouseLeave={() => setIsMenuOpened(false)}
onMouseEnter={() => {
setIsMenuOpened(true);
handleAnimations();
}}
>
<ExtendedNextLink
href={navigationItem.link}
skeletonType={skeletonType}
Expand Down Expand Up @@ -53,14 +67,17 @@ export const NavigationItem: FC<NavigationItemProps> = ({ navigationItem, skelet

<AnimatePresence initial={false}>
{hasChildren && isMenuOpenedDelayed && (
<AnimateCollapseDiv className="absolute left-0 right-0 z-menu !grid grid-cols-4 gap-11 bg-background px-10 shadow-md">
<AnimateNavigationMenu
className="absolute left-0 right-0 z-menu !grid grid-cols-4 gap-11 bg-background px-10 shadow-md"
disableAnimation={isAnimationDisabled}
>
<NavigationItemColumn
className="py-12"
columnCategories={navigationItem.categoriesByColumns}
skeletonType={skeletonType}
onLinkClick={() => setIsMenuOpened(false)}
/>
</AnimateCollapseDiv>
</AnimateNavigationMenu>
)}
</AnimatePresence>
</li>
Expand Down

0 comments on commit 58f4f83

Please sign in to comment.