diff --git a/web/src/components/LightButton.tsx b/web/src/components/LightButton.tsx index 9e4c579bc..42cece315 100644 --- a/web/src/components/LightButton.tsx +++ b/web/src/components/LightButton.tsx @@ -13,12 +13,12 @@ const StyledButton = styled(Button)<{ isMobileNavbar?: boolean }>` font-weight: 400; } .button-svg { - fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.secondaryText : `${theme.white}BF`)} !important; + fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.secondaryPurple : `${theme.white}BF`)} !important; } &:hover { .button-svg { - fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.primaryText : `${theme.white}`)} !important; + fill: ${({ theme, isMobileNavbar }) => (isMobileNavbar ? theme.secondaryPurple : `${theme.white}`)} !important; } transition: background-color 0.1s; background-color: ${({ theme }) => theme.whiteLowOpacityStrong}; diff --git a/web/src/layout/Header/DesktopHeader.tsx b/web/src/layout/Header/DesktopHeader.tsx index ac17f602f..5821ef78b 100644 --- a/web/src/layout/Header/DesktopHeader.tsx +++ b/web/src/layout/Header/DesktopHeader.tsx @@ -151,13 +151,7 @@ const DesktopHeader: React.FC = () => { - { - toggleIsDappListOpen(); - }} - Icon={StyledKlerosSolutionsIcon} - /> + diff --git a/web/src/layout/Header/MobileHeader.tsx b/web/src/layout/Header/MobileHeader.tsx index 6900ac759..9709b60a9 100644 --- a/web/src/layout/Header/MobileHeader.tsx +++ b/web/src/layout/Header/MobileHeader.tsx @@ -1,10 +1,9 @@ -import React, { useContext, useMemo, useRef } from "react"; +import React, { useState } from "react"; import styled, { css } from "styled-components"; - -import { useClickAway, useToggle } from "react-use"; - import HamburgerIcon from "svgs/header/hamburger.svg"; +import { useLockBodyScroll } from "react-use"; + import { landscapeStyle } from "styles/landscapeStyle"; import LightButton from "components/LightButton"; @@ -33,30 +32,25 @@ const StyledLightButton = styled(LightButton)` } `; -const OpenContext = React.createContext({ - isOpen: false, - toggleIsOpen: () => { - // Placeholder - }, -}); +const MobileHeader = () => { + const [isOpen, setIsOpen] = useState(false); + useLockBodyScroll(isOpen); -export function useOpenContext() { - return useContext(OpenContext); -} + const handleOpenNavbar = () => { + setIsOpen(true); + }; + + const handleCloseNavbar = () => { + setIsOpen(false); + }; -const MobileHeader = () => { - const [isOpen, toggleIsOpen] = useToggle(false); - const containerRef = useRef(null); - useClickAway(containerRef, () => toggleIsOpen(false)); - const memoizedContext = useMemo(() => ({ isOpen, toggleIsOpen }), [isOpen, toggleIsOpen]); return ( - - - - - - + + + + ); }; + export default MobileHeader; diff --git a/web/src/layout/Header/navbar/DappList.tsx b/web/src/layout/Header/navbar/DappList.tsx index c6fa55ec3..32cbb996d 100644 --- a/web/src/layout/Header/navbar/DappList.tsx +++ b/web/src/layout/Header/navbar/DappList.tsx @@ -15,6 +15,7 @@ import { landscapeStyle } from "styles/landscapeStyle"; import { responsiveSize } from "styles/responsiveSize"; import Product from "./Product"; +import { IDappList } from "./index"; const Container = styled.div` display: flex; @@ -134,10 +135,6 @@ const ITEMS = [ }, ]; -interface IDappList { - toggleIsDappListOpen: () => void; -} - const DappList: React.FC = ({ toggleIsDappListOpen }) => { const containerRef = useRef(null); useClickAway(containerRef, () => toggleIsDappListOpen()); diff --git a/web/src/layout/Header/navbar/Explore.tsx b/web/src/layout/Header/navbar/Explore.tsx index fb5209ced..c46b9707f 100644 --- a/web/src/layout/Header/navbar/Explore.tsx +++ b/web/src/layout/Header/navbar/Explore.tsx @@ -4,8 +4,6 @@ import { landscapeStyle } from "styles/landscapeStyle"; import { Link, useLocation } from "react-router-dom"; -import { useOpenContext } from "../MobileHeader"; - const Container = styled.div` display: flex; gap: 0; @@ -61,11 +59,11 @@ const links = [ interface IExplore { isMobileNavbar?: boolean; + handleCloseNavbar?: () => void; } -const Explore: React.FC = ({ isMobileNavbar }) => { +const Explore: React.FC = ({ isMobileNavbar, handleCloseNavbar }) => { const location = useLocation(); - const { toggleIsOpen } = useOpenContext(); return ( @@ -73,7 +71,7 @@ const Explore: React.FC = ({ isMobileNavbar }) => { {links.map(({ to, text }) => ( diff --git a/web/src/layout/Header/navbar/index.tsx b/web/src/layout/Header/navbar/index.tsx index 3480405ff..202809456 100644 --- a/web/src/layout/Header/navbar/index.tsx +++ b/web/src/layout/Header/navbar/index.tsx @@ -6,13 +6,9 @@ import { useAccount } from "wagmi"; import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg"; -import { useLockOverlayScroll } from "hooks/useLockOverlayScroll"; - import ConnectWallet from "components/ConnectWallet"; import LightButton from "components/LightButton"; import { Overlay } from "components/Overlay"; - -import { useOpenContext } from "../MobileHeader"; import DappList from "./DappList"; import Explore from "./Explore"; import Menu from "./Menu"; @@ -30,16 +26,12 @@ const Wrapper = styled.div<{ isOpen: boolean }>` z-index: 1; `; -const StyledOverlay = styled(Overlay)` - top: unset; -`; - const Container = styled.div<{ isOpen: boolean }>` position: absolute; top: 0; left: 0; right: 0; - max-height: calc(100vh - 160px); + height: 76%; overflow-y: auto; z-index: 1; background-color: ${({ theme }) => theme.whiteBackground}; @@ -69,7 +61,7 @@ const DisconnectWalletButtonContainer = styled.div` align-items: center; `; -const PopupContainer = styled.div` +const PopupContainer = styled.div<{ isClosing: boolean }>` position: fixed; top: 0; left: 0; @@ -77,6 +69,21 @@ const PopupContainer = styled.div` height: 100%; z-index: 1; background-color: ${({ theme }) => theme.blackLowOpacity}; + opacity: ${({ isClosing }) => (isClosing ? 0 : 1)}; + transition: opacity 0.2s ease-in-out; +`; + +const NavbarOverlay = styled.div<{ hasPopupOpen: boolean; isClosing: boolean }>` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 64px; + z-index: ${({ hasPopupOpen, isClosing }) => (hasPopupOpen || isClosing ? -1 : 1)}; +`; + +const StyledOverlay = styled(Overlay)` + top: unset; `; export interface ISettings { @@ -92,29 +99,49 @@ export interface IDappList { toggleIsDappListOpen: () => void; } -const NavBar: React.FC = () => { +interface INavBar { + isOpen: boolean; + handleCloseNavbar: () => void; +} + +const NavBar: React.FC = ({ isOpen, handleCloseNavbar }) => { const { isConnected } = useAccount(); const [isDappListOpen, toggleIsDappListOpen] = useToggle(false); const [isHelpOpen, toggleIsHelpOpen] = useToggle(false); const [isSettingsOpen, toggleIsSettingsOpen] = useToggle(false); - const { isOpen } = useOpenContext(); - useLockOverlayScroll(isOpen); + const [isClosing, toggleIsClosing] = useToggle(false); + + const hasPopupOpen = isDappListOpen || isHelpOpen || isSettingsOpen; + + const handleOpenPopup = (toggleFn: () => void) => { + toggleIsClosing(false); + toggleFn(); + }; + + const handleClosePopup = () => { + toggleIsClosing(true); + setTimeout(() => { + if (isDappListOpen) toggleIsDappListOpen(false); + if (isHelpOpen) toggleIsHelpOpen(false); + if (isSettingsOpen) toggleIsSettingsOpen(false); + toggleIsClosing(false); + }, 200); + }; return ( <> + {isOpen && } { - toggleIsDappListOpen(); - }} + onClick={() => handleOpenPopup(toggleIsDappListOpen)} Icon={KlerosSolutionsIcon} />
- +
@@ -125,16 +152,20 @@ const NavBar: React.FC = () => { )}
- + handleOpenPopup(toggleIsHelpOpen)} + toggleIsSettingsOpen={() => handleOpenPopup(toggleIsSettingsOpen)} + isMobileNavbar={true} + />
- {(isDappListOpen || isHelpOpen || isSettingsOpen) && ( - - {isDappListOpen && } - {isHelpOpen && } - {isSettingsOpen && } + {hasPopupOpen && ( + isClosing && handleClosePopup()}> + {isDappListOpen && } + {isHelpOpen && } + {isSettingsOpen && } )}