Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make mobile navbar close when clicking on header, make it occup… #1761

Draft
wants to merge 10 commits into
base: dev
Choose a base branch
from
4 changes: 2 additions & 2 deletions web/src/components/LightButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
8 changes: 1 addition & 7 deletions web/src/layout/Header/DesktopHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,7 @@ const DesktopHeader: React.FC = () => {
<Container>
<LeftSide>
<LightButtonContainer>
<LightButton
text=""
onClick={() => {
toggleIsDappListOpen();
}}
Icon={StyledKlerosSolutionsIcon}
/>
<LightButton text="" onClick={toggleIsDappListOpen} Icon={StyledKlerosSolutionsIcon} />
</LightButtonContainer>
<Logo />
</LeftSide>
Expand Down
42 changes: 18 additions & 24 deletions web/src/layout/Header/MobileHeader.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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 (
<Container ref={containerRef}>
<OpenContext.Provider value={memoizedContext}>
<Logo />
<NavBar />
<StyledLightButton text="" Icon={HamburgerIcon} onClick={toggleIsOpen} />
</OpenContext.Provider>
<Container>
<Logo />
<StyledLightButton text="" Icon={HamburgerIcon} onClick={handleOpenNavbar} />
<NavBar {...{ isOpen, handleCloseNavbar }} />
</Container>
);
};

export default MobileHeader;
5 changes: 1 addition & 4 deletions web/src/layout/Header/navbar/DappList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -134,10 +135,6 @@ const ITEMS = [
},
];

interface IDappList {
toggleIsDappListOpen: () => void;
}

const DappList: React.FC<IDappList> = ({ toggleIsDappListOpen }) => {
const containerRef = useRef(null);
useClickAway(containerRef, () => toggleIsDappListOpen());
Expand Down
8 changes: 3 additions & 5 deletions web/src/layout/Header/navbar/Explore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -61,19 +59,19 @@ const links = [

interface IExplore {
isMobileNavbar?: boolean;
handleCloseNavbar?: () => void;
}

const Explore: React.FC<IExplore> = ({ isMobileNavbar }) => {
const Explore: React.FC<IExplore> = ({ isMobileNavbar, handleCloseNavbar }) => {
const location = useLocation();
const { toggleIsOpen } = useOpenContext();

return (
<Container>
<Title>Explore</Title>
{links.map(({ to, text }) => (
<StyledLink
key={text}
onClick={toggleIsOpen}
onClick={handleCloseNavbar}
isActive={to === "/" ? location.pathname === "/" : location.pathname.split("/")[1] === to.split("/")[1]}
{...{ to, isMobileNavbar }}
>
Expand Down
77 changes: 54 additions & 23 deletions web/src/layout/Header/navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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};
Expand Down Expand Up @@ -69,14 +61,29 @@ const DisconnectWalletButtonContainer = styled.div`
align-items: center;
`;

const PopupContainer = styled.div`
const PopupContainer = styled.div<{ isClosing: boolean }>`
position: fixed;
top: 0;
left: 0;
width: 100%;
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 {
Expand All @@ -92,29 +99,49 @@ export interface IDappList {
toggleIsDappListOpen: () => void;
}

const NavBar: React.FC = () => {
interface INavBar {
isOpen: boolean;
handleCloseNavbar: () => void;
}

const NavBar: React.FC<INavBar> = ({ isOpen, handleCloseNavbar }) => {
kemuru marked this conversation as resolved.
Show resolved Hide resolved
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 && <NavbarOverlay onClick={handleCloseNavbar} {...{ hasPopupOpen, isClosing }} />}
<Wrapper {...{ isOpen }}>
<StyledOverlay>
<Container {...{ isOpen }}>
<LightButton
isMobileNavbar={true}
text="Kleros Solutions"
onClick={() => {
toggleIsDappListOpen();
}}
onClick={() => handleOpenPopup(toggleIsDappListOpen)}
Icon={KlerosSolutionsIcon}
/>
<hr />
<Explore isMobileNavbar={true} />
<Explore isMobileNavbar={true} {...{ handleCloseNavbar }} />
<hr />
<WalletContainer>
<ConnectWallet />
Expand All @@ -125,16 +152,20 @@ const NavBar: React.FC = () => {
)}
</WalletContainer>
<hr />
<Menu {...{ toggleIsHelpOpen, toggleIsSettingsOpen }} isMobileNavbar={true} />
<Menu
toggleIsHelpOpen={() => handleOpenPopup(toggleIsHelpOpen)}
toggleIsSettingsOpen={() => handleOpenPopup(toggleIsSettingsOpen)}
isMobileNavbar={true}
/>
<br />
</Container>
</StyledOverlay>
</Wrapper>
{(isDappListOpen || isHelpOpen || isSettingsOpen) && (
<PopupContainer>
{isDappListOpen && <DappList {...{ toggleIsDappListOpen }} />}
{isHelpOpen && <Help {...{ toggleIsHelpOpen }} />}
{isSettingsOpen && <Settings {...{ toggleIsSettingsOpen }} />}
{hasPopupOpen && (
<PopupContainer {...{ isClosing }} onTransitionEnd={() => isClosing && handleClosePopup()}>
{isDappListOpen && <DappList toggleIsDappListOpen={handleClosePopup} />}
{isHelpOpen && <Help toggleIsHelpOpen={handleClosePopup} />}
{isSettingsOpen && <Settings toggleIsSettingsOpen={handleClosePopup} />}
</PopupContainer>
)}
</>
Expand Down
Loading