From 0df379e790353bc70c7c5a3c4927f6fcabb320d8 Mon Sep 17 00:00:00 2001 From: Denny San Date: Tue, 14 May 2024 14:29:56 +0200 Subject: [PATCH 1/4] chore: make menu persistent in dom --- src/components/Menu/Menu.style.ts | 33 +++++- src/components/Menu/Menu.tsx | 4 + src/components/Menu/MenuClickAwayListener.tsx | 27 +++++ src/components/Menu/MenuDesktop.tsx | 97 ++++++++-------- src/components/Menu/MenuItem.style.ts | 1 - src/components/Menu/MenuItem.tsx | 103 ++++++----------- src/components/Menu/MenuItemLabel.tsx | 64 +++++++++++ src/components/Menu/MenuMobile.tsx | 11 +- src/components/Menu/SubMenu.tsx | 108 +++++++----------- .../useDevelopersContent.tsx | 8 +- .../LanguagesSubMenu/useLanguagesContent.tsx | 4 +- src/components/Menus/MainMenu/MainMenu.tsx | 3 +- .../Menus/MainMenu/useMainMenuContent.tsx | 45 ++++++-- .../Navbar/NavbarButtons/NavbarButtons.tsx | 69 ++++++----- src/stores/menu/MenuStore.tsx | 30 ++++- src/types/internal.ts | 3 +- src/types/menu.ts | 1 + 17 files changed, 375 insertions(+), 236 deletions(-) create mode 100644 src/components/Menu/MenuClickAwayListener.tsx create mode 100644 src/components/Menu/MenuItemLabel.tsx diff --git a/src/components/Menu/Menu.style.ts b/src/components/Menu/Menu.style.ts index f23aee6bd..ac2250280 100644 --- a/src/components/Menu/Menu.style.ts +++ b/src/components/Menu/Menu.style.ts @@ -1,6 +1,7 @@ 'use client'; import type { AppBarProps, + BoxProps, CSSObject, LinkProps, ListItemProps, @@ -10,6 +11,7 @@ import type { } from '@mui/material'; import { AppBar, + Box, Drawer, Link, ListItem, @@ -46,13 +48,13 @@ export const MenuList = styled(MuiMenuList, { justifyContent: cardsLayout ? 'center' : 'unset', flexWrap: cardsLayout ? 'wrap' : 'inherit', padding: cardsLayout ? theme.spacing(0, 3) : 0, + outline: 'unset', gap: cardsLayout ? '12px' : 'inherit', '& > :first-of-type': { marginTop: isOpenSubMenu || hasLabel || cardsLayout ? 'inherit' : theme.spacing(1.5), - paddingTop: isOpenSubMenu ? theme.spacing(1.5) : 'inherit', }, - '& > :last-child': { + '& > li:last-of-type': { marginBottom: isOpenSubMenu ? 'inherit' : theme.spacing(3), paddingBottom: isOpenSubMenu ? theme.spacing(1.5) : 'inherit', paddingTop: hasLabel ? 0 : 'inherit', @@ -78,14 +80,16 @@ export const MenuHeaderLabel = styled(Typography)(({ theme }) => ({ export interface MenuPaperProps extends Omit { isMobile?: boolean; + show: boolean; width?: string; component?: ElementType; } export const MenuPaper = styled(Paper, { shouldForwardProp: (prop) => - prop !== 'isMobile' && prop !== 'isWide' && prop !== 'isSubMenu', -})(({ theme, isMobile, width }) => ({ + prop !== 'isMobile' && prop !== 'isWide' && prop !== 'show', +})(({ theme, isMobile, width, show }) => ({ + display: show ? 'block' : 'none', background: theme.palette.surface1.main, padding: 0, marginTop: 0, @@ -99,6 +103,7 @@ export const MenuPaper = styled(Paper, { }8px 16px rgba(0, 0, 0, 0.16)`, borderRadius: '12px 12px 0 0', marginBottom: 0, + maxHeight: `calc( 100vh - ${MENU_LABEL_HEIGHT}px - 12px )`, // viewHeight - navbarHeight - offset overflowY: 'auto', overflowX: 'hidden', @@ -112,6 +117,8 @@ export const MenuPaper = styled(Paper, { height: 32, }, + '.submenu': { paddingBottom: theme.spacing(1.5) }, + [theme.breakpoints.up('sm' as Breakpoint)]: { maxHeight: 'calc( 100vh - 72px - 12px )', }, @@ -138,7 +145,6 @@ export const MenuItemLink = styled(Link, { })(({ theme }) => ({ display: 'flex', justifyContent: 'space-between', - padding: theme.spacing(0, 1.5), height: 48, textDecoration: 'none', color: 'inherit', @@ -193,3 +199,20 @@ export const MenuHeaderAppBar = styled(AppBar)( }, }), ); + +export interface MenuClickAwayBoxProps extends Omit { + open: boolean; +} + +export const MenuClickAwayBox = styled(Box)( + ({ open }) => ({ + display: open ? 'block' : 'none', + position: 'absolute', + left: 0, + width: '100%', + height: '100vh', + top: 0, + zIndex: -1, + backgroundColor: 'transparent', + }), +); diff --git a/src/components/Menu/Menu.tsx b/src/components/Menu/Menu.tsx index a8f30567a..7a516021c 100644 --- a/src/components/Menu/Menu.tsx +++ b/src/components/Menu/Menu.tsx @@ -8,6 +8,7 @@ interface MenuProps { setOpen: (open: boolean, anchorRef: any) => void; cardsLayout?: boolean; styles?: SxProps; + keepMounted?: boolean; open: boolean; children: any; width?: string; @@ -19,6 +20,7 @@ export const Menu = ({ setOpen, cardsLayout, styles, + keepMounted, width, label, isOpenSubMenu, @@ -32,6 +34,7 @@ export const Menu = ({ label={label} open={open} styles={styles} + keepMounted={keepMounted} width={width} cardsLayout={cardsLayout} setOpen={setOpen} @@ -45,6 +48,7 @@ export const Menu = ({ label={label} open={open} styles={styles} + keepMounted={keepMounted} cardsLayout={cardsLayout} setOpen={setOpen} isOpenSubMenu={isOpenSubMenu || false} diff --git a/src/components/Menu/MenuClickAwayListener.tsx b/src/components/Menu/MenuClickAwayListener.tsx new file mode 100644 index 000000000..64f8f1397 --- /dev/null +++ b/src/components/Menu/MenuClickAwayListener.tsx @@ -0,0 +1,27 @@ +import { useMenuStore } from '@/stores/menu/MenuStore'; +import type { PropsWithChildren } from 'react'; +import { MenuClickAwayBox } from './Menu.style'; +interface MenuClickAwayListenerProps { + open: boolean; +} + +export const MenuClickAwayListener: React.FC< + PropsWithChildren +> = ({ open, children }) => { + const { closeAllMenus } = useMenuStore((state) => state); + + return ( + { + event.preventDefault(); + console.log('Click Away Listener', event.target); + event.stopPropagation(); + // closeAllMenus(); + }} + > + {children} + + ); +}; diff --git a/src/components/Menu/MenuDesktop.tsx b/src/components/Menu/MenuDesktop.tsx index 17f77daa3..26d2a1864 100644 --- a/src/components/Menu/MenuDesktop.tsx +++ b/src/components/Menu/MenuDesktop.tsx @@ -2,9 +2,9 @@ import { MenuKeysEnum, MenuMain } from '@/const/menuKeys'; import { useMenuStore } from '@/stores/menu/MenuStore'; import type { SxProps, Theme } from '@mui/material'; import { Fade, Typography } from '@mui/material'; -import ClickAwayListener from '@mui/material/ClickAwayListener'; import type { KeyboardEvent } from 'react'; import { + MenuClickAwayBox, MenuHeaderAppBar, MenuHeaderAppWrapper, MenuList, @@ -17,6 +17,7 @@ interface MenuProps { transformOrigin?: string; cardsLayout?: boolean; styles?: SxProps; + keepMounted?: boolean; setOpen: (open: boolean, anchorRef: any) => void; open: boolean; children: any; @@ -28,6 +29,7 @@ export const MenuDesktop = ({ isOpenSubMenu, setOpen, styles, + keepMounted, transformOrigin, cardsLayout, width, @@ -45,67 +47,70 @@ export const MenuDesktop = ({ } } - return open ? ( - <> + return ( + { + event.preventDefault(); + console.log('Click Away Listener', event.target); + event.stopPropagation(); + closeAllMenus(); + }} + > {({ TransitionProps }) => ( - - { - event.preventDefault(); - closeAllMenus(); - }} + + - - {!!label ? ( - - - - {label} - - - - ) : null} - {children} - - + {!!label ? ( + + + + {label} + + + + ) : null} + {children} + )} - - ) : null; + + ); }; diff --git a/src/components/Menu/MenuItem.style.ts b/src/components/Menu/MenuItem.style.ts index 7d91a0f6e..a9cc1029d 100644 --- a/src/components/Menu/MenuItem.style.ts +++ b/src/components/Menu/MenuItem.style.ts @@ -1,4 +1,3 @@ -'use client'; import type { ListItemProps, MenuItemProps as MUIMenuItemProps, diff --git a/src/components/Menu/MenuItem.tsx b/src/components/Menu/MenuItem.tsx index a1d1a48fb..6b62b44db 100644 --- a/src/components/Menu/MenuItem.tsx +++ b/src/components/Menu/MenuItem.tsx @@ -1,19 +1,15 @@ import { ButtonSecondary } from '@/components/Button/Button.style'; import type { MenuKeysEnum } from '@/const/menuKeys'; -import { - TrackingAction, - TrackingCategory, - TrackingEventParameter, -} from '@/const/trackingKeys'; -import { useUserTracking } from '@/hooks/userTracking/useUserTracking'; -import { useMenuStore } from '@/stores/menu/MenuStore'; -import { EventTrackingTool } from '@/types/userTracking'; -import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import type { Breakpoint, SxProps, Theme } from '@mui/material'; import { Typography, useTheme } from '@mui/material'; import type { JsxElement } from 'typescript'; -import { MenuItemContainer, MenuLabel } from '.'; +import { MenuItemContainer, MenuItemLink } from '.'; +import { MenuItemLabel } from './MenuItemLabel'; +export interface MenuItemLinkType { + url: string; + external?: boolean; +} interface MenuItemProps { open: boolean; showButton: boolean | undefined; @@ -22,12 +18,12 @@ interface MenuItemProps { autoFocus?: boolean; showMoreIcon?: boolean; styles?: SxProps; + link?: MenuItemLinkType; label?: string; onClick?: any; triggerSubMenu?: MenuKeysEnum; prefixIcon?: JSX.Element | string; suffixIcon?: JSX.Element | string; - checkIcon?: boolean; } export const MenuItem = ({ @@ -37,6 +33,7 @@ export const MenuItem = ({ disableRipple, children, showMoreIcon = true, + link, styles, onClick, label, @@ -45,22 +42,9 @@ export const MenuItem = ({ suffixIcon, }: MenuItemProps) => { const theme = useTheme(); - const { trackEvent } = useUserTracking(); - const { setSubMenuState } = useMenuStore((state) => state); - const handleClick = () => { - triggerSubMenu && setSubMenuState(triggerSubMenu); - triggerSubMenu && - trackEvent({ - category: TrackingCategory.MainMenu, - action: TrackingAction.OpenMenu, - label: `open_submenu_${triggerSubMenu.toLowerCase()}`, - data: { [TrackingEventParameter.Menu]: triggerSubMenu }, - disableTrackingTool: [ - EventTrackingTool.ARCx, - EventTrackingTool.Cookie3, - ], - }); + const handleClick = (event: any) => { + event?.stopPropagation(); onClick && onClick(); }; @@ -70,8 +54,9 @@ export const MenuItem = ({ showButton={showButton || false} sx={styles} autoFocus={autoFocus} - onClick={() => { - !children && handleClick(); + onClick={(event) => { + event.stopPropagation(); + !children && handleClick(event); }} > <> @@ -102,48 +87,26 @@ export const MenuItem = ({ {suffixIcon ?? null} )} - {!showButton && ( - <> - - {prefixIcon ?? null} - {label ? ( - - {label} - - ) : null} - - {suffixIcon || showMoreIcon ? ( -
- {suffixIcon ?? null} - {showMoreIcon ? ( - - ) : null} -
- ) : null} - + {!showButton && link?.url && ( + + + + )} + {!showButton && !link?.url && ( + )} diff --git a/src/components/Menu/MenuItemLabel.tsx b/src/components/Menu/MenuItemLabel.tsx new file mode 100644 index 000000000..48cce0455 --- /dev/null +++ b/src/components/Menu/MenuItemLabel.tsx @@ -0,0 +1,64 @@ +import ChevronRightIcon from '@mui/icons-material/ChevronRight'; +import type { Breakpoint } from '@mui/material'; +import { Typography, useTheme } from '@mui/material'; +import { MenuLabel } from '.'; + +interface MenuItemLabelProps { + showMoreIcon?: boolean; + label?: string; + prefixIcon?: JSX.Element | string; + suffixIcon?: JSX.Element | string; +} + +export const MenuItemLabel = ({ + showMoreIcon = true, + label, + prefixIcon, + suffixIcon, +}: MenuItemLabelProps) => { + const theme = useTheme(); + + return ( + <> + + {prefixIcon ?? null} + {label ? ( + + {label} + + ) : null} + + {suffixIcon || showMoreIcon ? ( +
+ {suffixIcon ?? null} + {showMoreIcon ? ( + + ) : null} +
+ ) : null} + + ); +}; diff --git a/src/components/Menu/MenuMobile.tsx b/src/components/Menu/MenuMobile.tsx index 158cc8f87..d36937889 100644 --- a/src/components/Menu/MenuMobile.tsx +++ b/src/components/Menu/MenuMobile.tsx @@ -23,6 +23,7 @@ const paperProps = { interface MenuProps { isOpenSubMenu: boolean; setOpen: (open: boolean, anchorRef: any) => void; + keepMounted?: boolean; cardsLayout?: boolean; styles?: SxProps; label?: string; @@ -34,6 +35,7 @@ export const MenuMobile = ({ open, cardsLayout, label, + keepMounted, styles, isOpenSubMenu, children, @@ -41,8 +43,13 @@ export const MenuMobile = ({ const { openSubMenu, closeAllMenus } = useMenuStore((state) => state); return ( - - + + { event.preventDefault(); diff --git a/src/components/Menu/SubMenu.tsx b/src/components/Menu/SubMenu.tsx index abd1819ce..5e44b705d 100644 --- a/src/components/Menu/SubMenu.tsx +++ b/src/components/Menu/SubMenu.tsx @@ -1,14 +1,7 @@ 'use client'; import type { MenuKeysEnum } from '@/const/menuKeys'; -import { - TrackingAction, - TrackingCategory, - TrackingEventParameter, -} from '@/const/trackingKeys'; -import { useUserTracking } from '@/hooks/userTracking/useUserTracking'; import { useMenuStore } from '@/stores/menu'; import type { MenuListItem } from '@/types/internal'; -import { EventTrackingTool } from '@/types/userTracking'; import { getContrastAlphaColor } from '@/utils/colors'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import CheckIcon from '@mui/icons-material/Check'; @@ -31,10 +24,6 @@ import { interface SubMenuProps { open: boolean; label: string; - suffixIcon?: JSX.Element | string; - prefixIcon?: JSX.Element | string; - checkIcon?: boolean; - url?: string; prevMenu: MenuKeysEnum; subMenuList: MenuListItem[]; triggerSubMenu: MenuKeysEnum; @@ -48,7 +37,6 @@ export const SubMenu = ({ subMenuList, }: SubMenuProps) => { const theme = useTheme(); - const { trackEvent } = useUserTracking(); const menuListRef = useRef(null); const { openSubMenu, setSubMenuState } = useMenuStore((state) => state); @@ -59,24 +47,7 @@ export const SubMenu = ({ } const handleClick = (el: MenuListItem) => { - if (el.triggerSubMenu) { - setSubMenuState(el.triggerSubMenu); - trackEvent({ - category: TrackingCategory.SubMenu, - action: TrackingAction.OpenMenu, - label: `open_submenu_${el.triggerSubMenu.toLowerCase()}`, - data: { - [TrackingEventParameter.Menu]: el.triggerSubMenu, - [TrackingEventParameter.PrevMenu]: prevMenu, - }, - disableTrackingTool: [ - EventTrackingTool.ARCx, - EventTrackingTool.Cookie3, - ], - }); - } else { - typeof el.onClick === 'function' && el.onClick(); - } + el.onClick(); }; const handleBackNavigation = () => { @@ -90,8 +61,9 @@ export const SubMenu = ({ } }, [open, openSubMenu, triggerSubMenu]); - return openSubMenu === triggerSubMenu ? ( + return ( { + onClick={(event) => { + event.stopPropagation(); handleBackNavigation(); }} > @@ -122,42 +95,49 @@ export const SubMenu = ({ {!!subMenuList.length ? ( subMenuList.map((el, index) => - !!el.url ? ( - 0 ? true : false} - onClick={() => { - el.triggerSubMenu - ? setSubMenuState(el.triggerSubMenu) - : el.onClick(); - }} - component="li" + onClick={() => handleClick(el)} key={`${el.label}-${index}`} > - 0 ? true : false} + href={el.link.url} + target={el.link.external ? '_blank' : '_self'} + onClick={(event) => { + event.stopPropagation(); + el.onClick(); + }} + component="li" + key={`${el.label}-${index}`} > - {el.prefixIcon} - - {`${el.label || ' '}`} - - {el.suffixIcon} - - + {el.prefixIcon} + + {`${el.label || ' '}`} + + {el.suffixIcon} + + + ) : ( 0 ? true : false} @@ -202,5 +182,5 @@ export const SubMenu = ({ )} - ) : null; + ); }; diff --git a/src/components/Menus/DevelopersSubMenu/useDevelopersContent.tsx b/src/components/Menus/DevelopersSubMenu/useDevelopersContent.tsx index eb9da5928..d00a45c60 100644 --- a/src/components/Menus/DevelopersSubMenu/useDevelopersContent.tsx +++ b/src/components/Menus/DevelopersSubMenu/useDevelopersContent.tsx @@ -12,7 +12,6 @@ import { import { DOCS_URL, GITHUB_URL } from '@/const/urls'; import { useUserTracking } from '@/hooks/userTracking/useUserTracking'; -import { openInNewTab } from '@/utils/openInNewTab'; import { useTranslation } from 'react-i18next'; export const useDevelopersContent = () => { const { t } = useTranslation(); @@ -51,9 +50,9 @@ export const useDevelopersContent = () => { pageload: true, disableTrackingTool: [EventTrackingTool.Cookie3], }); - openInNewTab(GITHUB_URL); closeAllMenus(); }, + link: { url: GITHUB_URL, external: true }, }, { label: t('navbar.developers.documentation'), @@ -76,9 +75,9 @@ export const useDevelopersContent = () => { pageload: true, disableTrackingTool: [EventTrackingTool.Cookie3], }); - openInNewTab(DOCS_URL); closeAllMenus(); }, + link: { url: DOCS_URL, external: true }, }, { label: t('navbar.navbarMenu.brandAssets'), @@ -95,8 +94,9 @@ export const useDevelopersContent = () => { EventTrackingTool.Cookie3, ], }); - openInNewTab('/jumper_brand_assets.zip'); + closeAllMenus(); }, + link: { url: '/jumper_brand_assets.zip', external: true }, }, ]; }; diff --git a/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx b/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx index ff0e82c5c..d8060ed03 100644 --- a/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx +++ b/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx @@ -38,7 +38,9 @@ export const useLanguagesContent = () => { .map(([language, languageValue]) => ({ label: languageValue.language.value, checkIcon: i18n.language === language, - onClick: () => handleSwitchLanguage(language as LanguageKey), + onClick: () => { + handleSwitchLanguage(language as LanguageKey); + }, })); return languages; diff --git a/src/components/Menus/MainMenu/MainMenu.tsx b/src/components/Menus/MainMenu/MainMenu.tsx index 5fd55fe17..621d8047e 100644 --- a/src/components/Menus/MainMenu/MainMenu.tsx +++ b/src/components/Menus/MainMenu/MainMenu.tsx @@ -17,6 +17,7 @@ export const MainMenu = ({ anchorEl }: MenuProps) => { return ( { autoFocus={index > 0 ? true : false} label={el.label} prefixIcon={el.prefixIcon} + link={el.link} styles={el.styles} children={el.children as unknown as JsxElement} triggerSubMenu={el.triggerSubMenu} @@ -40,7 +42,6 @@ export const MainMenu = ({ anchorEl }: MenuProps) => { open /> ))} - diff --git a/src/components/Menus/MainMenu/useMainMenuContent.tsx b/src/components/Menus/MainMenu/useMainMenuContent.tsx index 90bac8e30..a8f49cd6b 100644 --- a/src/components/Menus/MainMenu/useMainMenuContent.tsx +++ b/src/components/Menus/MainMenu/useMainMenuContent.tsx @@ -11,7 +11,6 @@ import { EXPLORER_URL, JUMPER_LEARN_PATH, JUMPER_LOYALTY_PATH, - JUMPER_MEMECOIN_PATH, X_URL, } from '@/const/urls'; import { useUserTracking } from '@/hooks/userTracking/useUserTracking'; @@ -20,17 +19,15 @@ import { useSettingsStore } from '@/stores/settings'; import { EventTrackingTool } from '@/types/userTracking'; import { appendUTMParametersToLink } from '@/utils/append-utm-params-to-link'; import { getContrastAlphaColor } from '@/utils/colors'; -import { openInNewTab } from '@/utils/openInNewTab'; import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import DeveloperModeIcon from '@mui/icons-material/DeveloperMode'; import LanguageIcon from '@mui/icons-material/Language'; import SchoolIcon from '@mui/icons-material/School'; -import WhatshotIcon from '@mui/icons-material/Whatshot'; import SearchOutlinedIcon from '@mui/icons-material/SearchOutlined'; import XIcon from '@mui/icons-material/X'; import { Typography } from '@mui/material'; import { useTheme } from '@mui/material/styles'; -import { usePathname, useRouter } from 'next/navigation'; +import { useRouter } from 'next/navigation'; import { useTranslation } from 'react-i18next'; import { useThemeSwitchTabs } from './useThemeSwitchTabs'; @@ -39,14 +36,14 @@ export const useMainMenuContent = () => { const { trackPageload, trackEvent } = useUserTracking(); const router = useRouter(); const theme = useTheme(); - const { closeAllMenus } = useMenuStore((state) => state); - const { setSupportModalState } = useMenuStore((state) => state); + const { setSupportModalState, setSubMenuState, closeAllMenus } = useMenuStore( + (state) => state, + ); const themeMode = useSettingsStore((state) => state.themeMode); const explorerUrl = appendUTMParametersToLink(EXPLORER_URL, { utm_campaign: 'jumper_to_explorer', utm_medium: 'menu', }); - const pathname = usePathname(); const themeSwitchTabs = useThemeSwitchTabs(); @@ -124,16 +121,43 @@ export const useMainMenuContent = () => { ), showMoreIcon: true, triggerSubMenu: MenuKeysEnum.Language, + onClick: () => { + setSubMenuState(MenuKeysEnum.Language); + trackEvent({ + category: TrackingCategory.MainMenu, + action: TrackingAction.OpenMenu, + label: `open_submenu_${MenuKeysEnum.Language.toLowerCase()}`, + data: { [TrackingEventParameter.Menu]: MenuKeysEnum.Language }, + disableTrackingTool: [ + EventTrackingTool.ARCx, + EventTrackingTool.Cookie3, + ], + }); + }, }, { label: t('navbar.navbarMenu.developers'), prefixIcon: , triggerSubMenu: MenuKeysEnum.Devs, + onClick: () => { + setSubMenuState(MenuKeysEnum.Devs); + trackEvent({ + category: TrackingCategory.MainMenu, + action: TrackingAction.OpenMenu, + label: `open_submenu_${MenuKeysEnum.Devs.toLowerCase()}`, + data: { [TrackingEventParameter.Menu]: MenuKeysEnum.Devs }, + disableTrackingTool: [ + EventTrackingTool.ARCx, + EventTrackingTool.Cookie3, + ], + }); + }, }, { label: t('navbar.navbarMenu.profile'), prefixIcon: , showMoreIcon: false, + link: { url: '/profile' }, onClick: () => { trackEvent({ category: TrackingCategory.Menu, @@ -153,6 +177,7 @@ export const useMainMenuContent = () => { label: 'Jumper Learn', prefixIcon: , showMoreIcon: false, + link: { url: '/learn' }, onClick: () => { trackEvent({ category: TrackingCategory.Menu, @@ -172,6 +197,7 @@ export const useMainMenuContent = () => { label: t('navbar.navbarMenu.lifiExplorer'), prefixIcon: , showMoreIcon: false, + link: { url: explorerUrl, external: true }, onClick: () => { trackEvent({ category: TrackingCategory.Menu, @@ -190,7 +216,6 @@ export const useMainMenuContent = () => { pageload: true, disableTrackingTool: [EventTrackingTool.Cookie3], }); - openInNewTab(explorerUrl); }, }, { @@ -215,8 +240,8 @@ export const useMainMenuContent = () => { pageload: true, disableTrackingTool: [EventTrackingTool.Cookie3], }); - openInNewTab(X_URL); }, + link: { url: X_URL, external: true }, }, { label: 'Discord', @@ -248,8 +273,8 @@ export const useMainMenuContent = () => { pageload: true, disableTrackingTool: [EventTrackingTool.Cookie3], }); - openInNewTab(DISCORD_URL); }, + link: { url: DISCORD_URL, external: true }, }, { label: t('navbar.navbarMenu.support'), diff --git a/src/components/Navbar/NavbarButtons/NavbarButtons.tsx b/src/components/Navbar/NavbarButtons/NavbarButtons.tsx index 572104f47..8513fa391 100644 --- a/src/components/Navbar/NavbarButtons/NavbarButtons.tsx +++ b/src/components/Navbar/NavbarButtons/NavbarButtons.tsx @@ -20,7 +20,8 @@ export const NavbarButtons = ({ redirectToLearn }: NavbarButtonsProps) => { const mainMenuAnchor = useRef(null); const { trackEvent } = useUserTracking(); - const [openMainMenu, setMainMenuState] = useMenuStore((state) => [ + const [openedMenu, openMainMenu, setMainMenuState] = useMenuStore((state) => [ + state.openedMenu, state.openMainMenu, state.setMainMenuState, ]); @@ -38,36 +39,48 @@ export const NavbarButtons = ({ redirectToLearn }: NavbarButtonsProps) => { event: React.MouseEvent, ) => { event.preventDefault(); - setMainMenuState(!openMainMenu); - trackEvent({ - category: TrackingCategory.Menu, - action: TrackingAction.OpenMenu, - label: 'open_main_menu', - data: { [TrackingEventParameter.Menu]: 'main_menu' }, - disableTrackingTool: [EventTrackingTool.ARCx, EventTrackingTool.Cookie3], - }); + event.stopPropagation(); + const menuOpen = openedMenu(); + setTimeout(() => { + if (menuOpen) { + setMainMenuState(false); + } else { + setMainMenuState(true); + } + trackEvent({ + category: TrackingCategory.Menu, + action: TrackingAction.OpenMenu, + label: 'open_main_menu', + data: { [TrackingEventParameter.Menu]: 'main_menu' }, + disableTrackingTool: [ + EventTrackingTool.ARCx, + EventTrackingTool.Cookie3, + ], + }); + }, 50); }; return ( - - - - handleOnOpenNavbarMainMenu(e)} - > - - + <> + + + handleOnOpenNavbarMainMenu(e)} + > + + + - + ); }; diff --git a/src/stores/menu/MenuStore.tsx b/src/stores/menu/MenuStore.tsx index 1fdd73294..f6c4c1aeb 100644 --- a/src/stores/menu/MenuStore.tsx +++ b/src/stores/menu/MenuStore.tsx @@ -1,6 +1,5 @@ 'use client'; -import type { MenuKeys } from '@/const/menuKeys'; -import { MenuKeysEnum } from '@/const/menuKeys'; +import { MenuKeys, MenuKeysEnum } from '@/const/menuKeys'; import type { EcosystemSelectMenuProps, MenuState, @@ -47,6 +46,19 @@ export const useMenuStore = createWithEqualityFn( return updatedState; }), + openedMenu: () => { + const menuState = get(); + return ( + menuState.openMainMenu || + menuState.openEcosystemSelect.open || + menuState.openSubMenu !== MenuKeys.None || + menuState.openSupportModal || + menuState.openWalletSelectMenu || + menuState.openWalletMenu + ); + // Add your desired functionality here + }, + // Close ALL Navbar Menus closeAllMenus: () => { set({ @@ -64,6 +76,9 @@ export const useMenuStore = createWithEqualityFn( set({ openMainMenu: open, openSubMenu: MenuKeysEnum.None, + openWalletSelectMenu: false, + openWalletMenu: false, + openSupportModal: false, }); }, @@ -72,6 +87,9 @@ export const useMenuStore = createWithEqualityFn( set({ openWalletSelectMenu: open, openSubMenu: MenuKeysEnum.None, + openMainMenu: false, + openWalletMenu: false, + openSupportModal: false, }); }, @@ -80,6 +98,9 @@ export const useMenuStore = createWithEqualityFn( set({ openWalletMenu: open, openSubMenu: MenuKeysEnum.None, + openMainMenu: false, + openWalletSelectMenu: false, + openSupportModal: false, }); }, @@ -89,6 +110,9 @@ export const useMenuStore = createWithEqualityFn( openEcosystemSelect: { open, combinedWallet }, openWalletSelectMenu: false, openSubMenu: MenuKeysEnum.None, + openMainMenu: false, + openWalletMenu: false, + openSupportModal: false, }); }, @@ -114,10 +138,10 @@ export const useMenuStore = createWithEqualityFn( // Toggle support modal setSupportModalState: (open) => { set({ + openSupportModal: open, openMainMenu: false, openWalletSelectMenu: false, openWalletMenu: false, - openSupportModal: open, openSubMenu: MenuKeysEnum.None, }); }, diff --git a/src/types/internal.ts b/src/types/internal.ts index c9fa08863..a9ea48f65 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -1,6 +1,7 @@ import type { ChainId } from '@lifi/sdk'; import type { WidgetConfig, WidgetSubvariant } from '@lifi/widget'; import type { SxProps, Theme } from '@mui/material'; +import type { MenuItemLinkType } from 'src/components/Menu'; import type { Gtag } from './gtag'; declare global { interface Window { @@ -20,7 +21,7 @@ export interface MenuListItem { showMoreIcon?: boolean; styles?: SxProps; checkIcon?: boolean; - url?: string; + link?: MenuItemLinkType; onClick?: any; showButton?: boolean; } diff --git a/src/types/menu.ts b/src/types/menu.ts index 7baace39c..43ed9c6b6 100644 --- a/src/types/menu.ts +++ b/src/types/menu.ts @@ -17,6 +17,7 @@ export interface EcosystemSelectMenuProps { } export type MenuProps = { + openedMenu: () => boolean; openMainMenu: boolean; openWalletSelectMenu: boolean; openWalletMenu: boolean; From e5789f94bcde12deef9a58af0d8d39deb565bf79 Mon Sep 17 00:00:00 2001 From: Denny San Date: Wed, 15 May 2024 10:42:31 +0200 Subject: [PATCH 2/4] chore: fix menus --- src/components/Menu/Menu.style.ts | 6 +- src/components/Menu/Menu.tsx | 1 - src/components/Menu/MenuClickAwayListener.tsx | 12 ++- src/components/Menu/MenuDesktop.tsx | 17 +--- src/components/Menu/MenuMobile.tsx | 78 +++++++++---------- .../Menus/WalletMenu/WalletMenu.tsx | 5 +- .../WalletSelectMenu/WalletSelectMenu.tsx | 16 +++- src/components/Navbar/Navbar.style.tsx | 1 + src/components/Navbar/WalletButton.tsx | 5 +- 9 files changed, 70 insertions(+), 71 deletions(-) diff --git a/src/components/Menu/Menu.style.ts b/src/components/Menu/Menu.style.ts index ac2250280..ded106d2d 100644 --- a/src/components/Menu/Menu.style.ts +++ b/src/components/Menu/Menu.style.ts @@ -70,7 +70,7 @@ export const MenuHeaderLabel = styled(Typography)(({ theme }) => ({ display: 'flex', marginRight: theme.spacing(4.75), flexWrap: 'nowrap', - [theme.breakpoints.up('sm' as Breakpoint)]: { + [theme.breakpoints.up('md' as Breakpoint)]: { maxWidth: 174, marginRight: 0, marginLeft: theme.spacing(0.75), @@ -89,7 +89,7 @@ export const MenuPaper = styled(Paper, { shouldForwardProp: (prop) => prop !== 'isMobile' && prop !== 'isWide' && prop !== 'show', })(({ theme, isMobile, width, show }) => ({ - display: show ? 'block' : 'none', + display: !show ? 'none' : 'block', background: theme.palette.surface1.main, padding: 0, marginTop: 0, @@ -109,6 +109,7 @@ export const MenuPaper = styled(Paper, { overflowX: 'hidden', width: '100%', transformOrigin: 'bottom', + height: '100% !important', transition: 'opacity 307ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 204ms cubic-bezier(0.4, 0, 0.2, 1) 0ms', @@ -210,7 +211,6 @@ export const MenuClickAwayBox = styled(Box)( position: 'absolute', left: 0, width: '100%', - height: '100vh', top: 0, zIndex: -1, backgroundColor: 'transparent', diff --git a/src/components/Menu/Menu.tsx b/src/components/Menu/Menu.tsx index 7a516021c..c7746f272 100644 --- a/src/components/Menu/Menu.tsx +++ b/src/components/Menu/Menu.tsx @@ -50,7 +50,6 @@ export const Menu = ({ styles={styles} keepMounted={keepMounted} cardsLayout={cardsLayout} - setOpen={setOpen} isOpenSubMenu={isOpenSubMenu || false} > {children} diff --git a/src/components/Menu/MenuClickAwayListener.tsx b/src/components/Menu/MenuClickAwayListener.tsx index 64f8f1397..50d4133a0 100644 --- a/src/components/Menu/MenuClickAwayListener.tsx +++ b/src/components/Menu/MenuClickAwayListener.tsx @@ -1,27 +1,31 @@ import { useMenuStore } from '@/stores/menu/MenuStore'; +import type { CSSObject } from '@mui/material'; import type { PropsWithChildren } from 'react'; import { MenuClickAwayBox } from './Menu.style'; interface MenuClickAwayListenerProps { open: boolean; + styles?: CSSObject; } export const MenuClickAwayListener: React.FC< PropsWithChildren -> = ({ open, children }) => { +> = ({ open, children, styles }) => { const { closeAllMenus } = useMenuStore((state) => state); - return ( + return open ? ( { event.preventDefault(); - console.log('Click Away Listener', event.target); event.stopPropagation(); - // closeAllMenus(); + closeAllMenus(); }} > {children} + ) : ( + children ); }; diff --git a/src/components/Menu/MenuDesktop.tsx b/src/components/Menu/MenuDesktop.tsx index 26d2a1864..f3ff4e701 100644 --- a/src/components/Menu/MenuDesktop.tsx +++ b/src/components/Menu/MenuDesktop.tsx @@ -4,13 +4,13 @@ import type { SxProps, Theme } from '@mui/material'; import { Fade, Typography } from '@mui/material'; import type { KeyboardEvent } from 'react'; import { - MenuClickAwayBox, MenuHeaderAppBar, MenuHeaderAppWrapper, MenuList, MenuPaper, MenuPopper, } from './Menu.style'; +import { MenuClickAwayListener } from './MenuClickAwayListener'; interface MenuProps { isOpenSubMenu: boolean; label?: string; @@ -38,7 +38,7 @@ export const MenuDesktop = ({ children, anchorEl, }: MenuProps) => { - const { openSubMenu, closeAllMenus } = useMenuStore((state) => state); + const { openSubMenu } = useMenuStore((state) => state); function handleListKeyDown(event: KeyboardEvent) { if (event.key === 'Tab' || event.key === 'Escape') { @@ -48,16 +48,7 @@ export const MenuDesktop = ({ } return ( - { - event.preventDefault(); - console.log('Click Away Listener', event.target); - event.stopPropagation(); - closeAllMenus(); - }} - > + )} - + ); }; diff --git a/src/components/Menu/MenuMobile.tsx b/src/components/Menu/MenuMobile.tsx index d36937889..9abd7959f 100644 --- a/src/components/Menu/MenuMobile.tsx +++ b/src/components/Menu/MenuMobile.tsx @@ -2,7 +2,6 @@ import { MenuKeysEnum } from '@/const/menuKeys'; import { useMenuStore } from '@/stores/menu'; import type { SxProps, Theme } from '@mui/material'; import { Typography } from '@mui/material'; -import ClickAwayListener from '@mui/material/ClickAwayListener'; import { MenuHeaderAppBar, MenuHeaderAppWrapper, @@ -22,7 +21,6 @@ const paperProps = { interface MenuProps { isOpenSubMenu: boolean; - setOpen: (open: boolean, anchorRef: any) => void; keepMounted?: boolean; cardsLayout?: boolean; styles?: SxProps; @@ -41,54 +39,50 @@ export const MenuMobile = ({ children, }: MenuProps) => { const { openSubMenu, closeAllMenus } = useMenuStore((state) => state); - return ( { + reason === 'backdropClick' && closeAllMenus(); + }} PaperProps={paperProps} keepMounted={keepMounted} + disableScrollLock > - - { - event.preventDefault(); - closeAllMenus(); - }} + + - - {!!label ? ( - - - - {label} - - - - ) : null} - {children} - - + {!!label ? ( + + + + {label} + + + + ) : null} + {children} + ); diff --git a/src/components/Menus/WalletMenu/WalletMenu.tsx b/src/components/Menus/WalletMenu/WalletMenu.tsx index 505783600..c22cd85a1 100644 --- a/src/components/Menus/WalletMenu/WalletMenu.tsx +++ b/src/components/Menus/WalletMenu/WalletMenu.tsx @@ -24,7 +24,6 @@ export const WalletMenu = ({ anchorEl }: WalletMenuProps) => { setWalletMenuState, setSnackbarState, openSubMenu, - closeAllMenus, setWalletSelectMenuState, } = useMenuStore((state) => state); @@ -64,8 +63,8 @@ export const WalletMenu = ({ anchorEl }: WalletMenuProps) => { )} { - closeAllMenus(); + onClick={(event) => { + event.stopPropagation(); setWalletSelectMenuState(true); }} > diff --git a/src/components/Menus/WalletSelectMenu/WalletSelectMenu.tsx b/src/components/Menus/WalletSelectMenu/WalletSelectMenu.tsx index c3af67db5..3ed8b21a3 100644 --- a/src/components/Menus/WalletSelectMenu/WalletSelectMenu.tsx +++ b/src/components/Menus/WalletSelectMenu/WalletSelectMenu.tsx @@ -29,8 +29,12 @@ export const WalletSelectMenu = ({ anchorEl }: MenuProps) => { 0, NUMBER_OF_WALLETS_DISPLAYED, ); - const { openWalletSelectMenu, setWalletSelectMenuState, openSubMenu } = - useMenuStore((state) => state); + const { + openWalletSelectMenu, + setWalletSelectMenuState, + openSubMenu, + setSubMenuState, + } = useMenuStore((state) => state); const menuItemStyles: SxProps = { margin: 0, @@ -128,10 +132,14 @@ export const WalletSelectMenu = ({ anchorEl }: MenuProps) => { openSubMenu === MenuKeysEnum.None && ( + openSubMenu === MenuKeysEnum.None && + setSubMenuState(MenuKeysEnum.WalletSelectMore) + } styles={{ ...menuItemStyles, gridColumn: 'span 3', diff --git a/src/components/Navbar/Navbar.style.tsx b/src/components/Navbar/Navbar.style.tsx index bcf18ac69..d69416758 100644 --- a/src/components/Navbar/Navbar.style.tsx +++ b/src/components/Navbar/Navbar.style.tsx @@ -15,6 +15,7 @@ export const NavbarContainer = styled(AppBar)<{ sticky?: boolean }>( justifyContent: 'space-between', position: 'sticky', top: 0, + minWidth: 416, backdropFilter: 'blur(12px)', boxShadow: 'unset', background: 'transparent', diff --git a/src/components/Navbar/WalletButton.tsx b/src/components/Navbar/WalletButton.tsx index b0150830f..4dbc6a945 100644 --- a/src/components/Navbar/WalletButton.tsx +++ b/src/components/Navbar/WalletButton.tsx @@ -82,7 +82,10 @@ export const WallettButtons = () => { { + event.stopPropagation(); + handleWalletSelectClick(); + }} > Date: Thu, 16 May 2024 14:53:31 +0200 Subject: [PATCH 3/4] fix: typescript errors --- src/components/BackgroundGradient/BackgroundGradient.tsx | 4 ++-- src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx | 2 +- src/components/Navbar/Navbar.tsx | 4 ++-- src/components/Navbar/NavbarTabs/useNavbarTabs.tsx | 2 +- src/components/PoweredBy/PoweredBy.tsx | 4 ++-- src/components/Widgets/Widgets.tsx | 4 +++- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/BackgroundGradient/BackgroundGradient.tsx b/src/components/BackgroundGradient/BackgroundGradient.tsx index 6d3931896..f2817f7b6 100644 --- a/src/components/BackgroundGradient/BackgroundGradient.tsx +++ b/src/components/BackgroundGradient/BackgroundGradient.tsx @@ -1,12 +1,12 @@ 'use client'; import { type CSSObject } from '@mui/material'; +import { usePathname } from 'next/navigation'; import { BackgroundGradientBottomLeft, BackgroundGradientBottomRight, BackgroundGradientContainer, BackgroundGradientTopCenter, } from '.'; -import { usePathname } from 'next/navigation'; import { SirBridgeLot } from '../illustrations/SirBridgeLot'; import { FixBoxWithNoOverflow, MovingBox } from './MovingBox.style'; @@ -17,7 +17,7 @@ interface BackgroundGradientProps { export const BackgroundGradient = ({ styles }: BackgroundGradientProps) => { const pathname = usePathname(); - return !pathname.includes('memecoins') ? ( + return !pathname?.includes('memecoins') ? ( diff --git a/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx b/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx index d8060ed03..3cbb51d2a 100644 --- a/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx +++ b/src/components/Menus/LanguagesSubMenu/useLanguagesContent.tsx @@ -30,7 +30,7 @@ export const useLanguagesContent = () => { }); i18n.changeLanguage(newLanguage); setCookie(cookieName, newLanguage, { path: '/', sameSite: true }); - replaceLocaleInUrl(pathname, newLanguage); + pathname && replaceLocaleInUrl(pathname, newLanguage); }; const languages = Object.entries(supportedLanguages) diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index da2f3b6cd..4f6f01dc3 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -15,8 +15,8 @@ import { export const Navbar = () => { const router = useRouter(); const pathname = usePathname(); - const isLearnPage = pathname.includes(JUMPER_LEARN_PATH); - const isLoyaltyPage = pathname.includes(JUMPER_LOYALTY_PATH); + const isLearnPage = pathname?.includes(JUMPER_LEARN_PATH); + const isLoyaltyPage = pathname?.includes(JUMPER_LOYALTY_PATH); const { setWelcomeScreenClosed } = useWelcomeScreen(); const { closeAllMenus } = useMenuStore((state) => state); const handleClick = () => { diff --git a/src/components/Navbar/NavbarTabs/useNavbarTabs.tsx b/src/components/Navbar/NavbarTabs/useNavbarTabs.tsx index 4ef484ca1..5928f9f60 100644 --- a/src/components/Navbar/NavbarTabs/useNavbarTabs.tsx +++ b/src/components/Navbar/NavbarTabs/useNavbarTabs.tsx @@ -27,7 +27,7 @@ export const useNavbarTabs = ({ navbarPageReload }: useNavbarTabsProps) => { const handleClickTab = (tab: string) => (event: React.MouseEvent) => { window.history.replaceState(null, document.title, `/${tab}`); - replacePathInUrl(pathname, tab); + pathname && replacePathInUrl(pathname, tab); if (navbarPageReload) { router.push(`/${tab}`); } diff --git a/src/components/PoweredBy/PoweredBy.tsx b/src/components/PoweredBy/PoweredBy.tsx index 8edd57527..8953dfd66 100644 --- a/src/components/PoweredBy/PoweredBy.tsx +++ b/src/components/PoweredBy/PoweredBy.tsx @@ -27,7 +27,7 @@ export const PoweredBy = ({ styles }: PoweredByProps) => { const theme = useTheme(); const { trackPageload, trackEvent } = useUserTracking(); const currentPath = usePathname(); - let result = currentPath.substring(0, currentPath.lastIndexOf('/')); + let result = currentPath?.substring(0, currentPath.lastIndexOf('/')); const isArticle = isArticlePage( `${process.env.NEXT_PUBLIC_SITE_URL}/${currentPath}`, ); @@ -36,7 +36,7 @@ export const PoweredBy = ({ styles }: PoweredByProps) => { const isRoot = result === '/' || result === ''; const isThemePage = result === JUMPER_MEMECOIN_PATH; const isApp = Object.values(LinkMap).some((page) => - result.includes(`/${page}`), + result?.includes(`/${page}`), ); const handleClick = () => { diff --git a/src/components/Widgets/Widgets.tsx b/src/components/Widgets/Widgets.tsx index e19e76bd3..ede28ad79 100644 --- a/src/components/Widgets/Widgets.tsx +++ b/src/components/Widgets/Widgets.tsx @@ -62,12 +62,14 @@ export function Widgets({ }, [widgetVariant]); const themeVariant: ThemeVariantType | undefined = useMemo(() => { - if (pathname.includes('memecoins')) { + if (pathname?.includes('memecoins')) { setWelcomeScreenClosed(true); //Todo: review the logic of the tab selection. setActiveTab(-1); return ThemesMap.Memecoins; } + // remove setWelcomeScreenClosed from array to prevent infinite re-rendering + // eslint-disable-next-line react-hooks/exhaustive-deps }, [pathname, setActiveTab]); const getActiveWidget = useCallback(() => { From d57a28bec9dcdd90d293799f9d0d1c5e22f34d93 Mon Sep 17 00:00:00 2001 From: Denny San Date: Tue, 21 May 2024 15:54:48 +0200 Subject: [PATCH 4/4] refactor: use mui clickawaylistener --- src/components/Menu/Menu.style.ts | 18 ----------- src/components/Menu/MenuClickAwayListener.tsx | 31 ------------------- src/components/Menu/MenuDesktop.tsx | 22 ++++++++++--- .../Navbar/NavbarButtons/NavbarButtons.tsx | 29 +++++++---------- 4 files changed, 29 insertions(+), 71 deletions(-) delete mode 100644 src/components/Menu/MenuClickAwayListener.tsx diff --git a/src/components/Menu/Menu.style.ts b/src/components/Menu/Menu.style.ts index ded106d2d..412b58e82 100644 --- a/src/components/Menu/Menu.style.ts +++ b/src/components/Menu/Menu.style.ts @@ -1,7 +1,6 @@ 'use client'; import type { AppBarProps, - BoxProps, CSSObject, LinkProps, ListItemProps, @@ -11,7 +10,6 @@ import type { } from '@mui/material'; import { AppBar, - Box, Drawer, Link, ListItem, @@ -200,19 +198,3 @@ export const MenuHeaderAppBar = styled(AppBar)( }, }), ); - -export interface MenuClickAwayBoxProps extends Omit { - open: boolean; -} - -export const MenuClickAwayBox = styled(Box)( - ({ open }) => ({ - display: open ? 'block' : 'none', - position: 'absolute', - left: 0, - width: '100%', - top: 0, - zIndex: -1, - backgroundColor: 'transparent', - }), -); diff --git a/src/components/Menu/MenuClickAwayListener.tsx b/src/components/Menu/MenuClickAwayListener.tsx deleted file mode 100644 index 50d4133a0..000000000 --- a/src/components/Menu/MenuClickAwayListener.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { useMenuStore } from '@/stores/menu/MenuStore'; -import type { CSSObject } from '@mui/material'; -import type { PropsWithChildren } from 'react'; -import { MenuClickAwayBox } from './Menu.style'; -interface MenuClickAwayListenerProps { - open: boolean; - styles?: CSSObject; -} - -export const MenuClickAwayListener: React.FC< - PropsWithChildren -> = ({ open, children, styles }) => { - const { closeAllMenus } = useMenuStore((state) => state); - - return open ? ( - { - event.preventDefault(); - event.stopPropagation(); - closeAllMenus(); - }} - > - {children} - - ) : ( - children - ); -}; diff --git a/src/components/Menu/MenuDesktop.tsx b/src/components/Menu/MenuDesktop.tsx index f3ff4e701..b009334e1 100644 --- a/src/components/Menu/MenuDesktop.tsx +++ b/src/components/Menu/MenuDesktop.tsx @@ -1,7 +1,7 @@ import { MenuKeysEnum, MenuMain } from '@/const/menuKeys'; import { useMenuStore } from '@/stores/menu/MenuStore'; import type { SxProps, Theme } from '@mui/material'; -import { Fade, Typography } from '@mui/material'; +import { ClickAwayListener, Fade, Typography } from '@mui/material'; import type { KeyboardEvent } from 'react'; import { MenuHeaderAppBar, @@ -10,7 +10,6 @@ import { MenuPaper, MenuPopper, } from './Menu.style'; -import { MenuClickAwayListener } from './MenuClickAwayListener'; interface MenuProps { isOpenSubMenu: boolean; label?: string; @@ -38,7 +37,9 @@ export const MenuDesktop = ({ children, anchorEl, }: MenuProps) => { - const { openSubMenu } = useMenuStore((state) => state); + const { openedMenu, openSubMenu, closeAllMenus } = useMenuStore( + (state) => state, + ); function handleListKeyDown(event: KeyboardEvent) { if (event.key === 'Tab' || event.key === 'Escape') { @@ -48,7 +49,18 @@ export const MenuDesktop = ({ } return ( - + { + console.log('Click Away Listener'); + setTimeout(() => { + event.stopPropagation(); + event.preventDefault(); + open && closeAllMenus(); + }, 150); + }} + > )} - + ); }; diff --git a/src/components/Navbar/NavbarButtons/NavbarButtons.tsx b/src/components/Navbar/NavbarButtons/NavbarButtons.tsx index 8513fa391..5b1d3094e 100644 --- a/src/components/Navbar/NavbarButtons/NavbarButtons.tsx +++ b/src/components/Navbar/NavbarButtons/NavbarButtons.tsx @@ -41,23 +41,18 @@ export const NavbarButtons = ({ redirectToLearn }: NavbarButtonsProps) => { event.preventDefault(); event.stopPropagation(); const menuOpen = openedMenu(); - setTimeout(() => { - if (menuOpen) { - setMainMenuState(false); - } else { - setMainMenuState(true); - } - trackEvent({ - category: TrackingCategory.Menu, - action: TrackingAction.OpenMenu, - label: 'open_main_menu', - data: { [TrackingEventParameter.Menu]: 'main_menu' }, - disableTrackingTool: [ - EventTrackingTool.ARCx, - EventTrackingTool.Cookie3, - ], - }); - }, 50); + if (menuOpen) { + setMainMenuState(false); + } else { + setMainMenuState(true); + } + trackEvent({ + category: TrackingCategory.Menu, + action: TrackingAction.OpenMenu, + label: 'open_main_menu', + data: { [TrackingEventParameter.Menu]: 'main_menu' }, + disableTrackingTool: [EventTrackingTool.ARCx, EventTrackingTool.Cookie3], + }); }; return (