import { useIsMounted } from "@plexswap/hooks"; import throttle from "lodash/throttle"; import React, { useEffect, useMemo, useRef, useState } from "react"; import { styled } from "styled-components"; import { AtomBox } from "../../components/AtomBox"; import BottomNav from "../../components/BottomNav"; import { Box } from "../../components/Box"; import Flex from "../../components/Box/Flex"; import WayaPrice from "../../components/WayaPrice/WayaPrice"; import Footer from "../../components/Footer"; import LangSelector from "../../components/LangSelector/LangSelector"; import MenuItems from "../../components/MenuItems/MenuItems"; import { SubMenuItems } from "../../components/SubMenuItems"; import { useMatchBreakpoints } from "../../contexts"; import Logo from "./components/Logo"; import { MENU_HEIGHT, MOBILE_MENU_HEIGHT, TOP_BANNER_HEIGHT, TOP_BANNER_HEIGHT_MOBILE } from "./config"; import { MenuContext } from "./context"; import { NavProps } from "./types"; const Wrapper = styled.div` position: relative; width: 100%; display: grid; grid-template-rows: auto 1fr; `; const StyledNav = styled.nav` display: flex; justify-content: space-between; align-items: center; width: 100%; height: ${MENU_HEIGHT}px; background-color: ${({ theme }) => theme.nav.background}; border-bottom: 1px solid ${({ theme }) => theme.colors.cardBorder}; transform: translate3d(0, 0, 0); padding-left: 16px; padding-right: 16px; `; const FixedContainer = styled("div").withConfig({ shouldForwardProp: (props) => !["showMenu"].includes(props), })<{ showMenu: boolean; height: number }>` position: fixed; top: ${({ showMenu, height }) => (showMenu ? 0 : `-${height}px`)}; left: 0; transition: top 0.2s; height: ${({ height }) => `${height}px`}; width: 100%; z-index: 20; `; const TopBannerContainer = styled.div<{ height: number }>` height: ${({ height }) => `${height}px`}; min-height: ${({ height }) => `${height}px`}; max-height: ${({ height }) => `${height}px`}; width: 100%; `; const BodyWrapper = styled(Box)` position: relative; display: flex; max-width: 100vw; `; const Inner = styled.div` flex-grow: 1; transition: margin-top 0.2s, margin-left 0.2s cubic-bezier(0.4, 0, 0.2, 1); transform: translate3d(0, 0, 0); max-width: 100%; `; const Menu: React.FC> = ({ linkComponent = "a", banner, rightSide, isDark, toggleTheme, currentLang, setLang, wayaPriceUsd, links, subLinks, footerLinks, activeItem, activeSubItem, langs, buyWayaLabel, buyWayaLink, children, chainId, }) => { const { isMobile } = useMatchBreakpoints(); const isMounted = useIsMounted(); const [showMenu, setShowMenu] = useState(true); const refPrevOffset = useRef(typeof window === "undefined" ? 0 : window.pageYOffset); const topBannerHeight = isMobile ? TOP_BANNER_HEIGHT_MOBILE : TOP_BANNER_HEIGHT; const totalTopMenuHeight = isMounted && banner ? MENU_HEIGHT + topBannerHeight : MENU_HEIGHT; useEffect(() => { const handleScroll = () => { const currentOffset = window.pageYOffset; const isBottomOfPage = window.document.body.clientHeight === currentOffset + window.innerHeight; const isTopOfPage = currentOffset === 0; // Always show the menu when user reach the top if (isTopOfPage) { setShowMenu(true); } // Avoid triggering anything at the bottom because of layout shift else if (!isBottomOfPage) { if (currentOffset < refPrevOffset.current || currentOffset <= totalTopMenuHeight) { // Has scroll up setShowMenu(true); } else { // Has scroll down setShowMenu(false); } } refPrevOffset.current = currentOffset; }; const throttledHandleScroll = throttle(handleScroll, 200); window.addEventListener("scroll", throttledHandleScroll); return () => { window.removeEventListener("scroll", throttledHandleScroll); }; }, [totalTopMenuHeight]); // Find the home link if provided const homeLink = links.find((link) => link.label === "Home"); const subLinksWithoutMobile = useMemo(() => subLinks?.filter((subLink) => !subLink.isMobileOnly), [subLinks]); const subLinksMobileOnly = useMemo(() => subLinks?.filter((subLink) => subLink.isMobileOnly), [subLinks]); const providerValue = useMemo(() => ({ linkComponent }), [linkComponent]); return ( {banner && isMounted && {banner}} {rightSide} {subLinks ? ( {subLinksMobileOnly && subLinksMobileOnly?.length > 0 && ( )} ) : (
)} {children}