From 39331a99a25ee949bb9126f6c128b3aa9773f554 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 29 Nov 2024 06:53:04 +0100 Subject: [PATCH 1/8] feat: make mobile navbar close when clicking on header, make it occupy full height --- web/src/layout/Header/MobileHeader.tsx | 50 +++++++++++----------- web/src/layout/Header/navbar/DappList.tsx | 5 +-- web/src/layout/Header/navbar/Explore.tsx | 11 ++--- web/src/layout/Header/navbar/Menu/Help.tsx | 2 +- web/src/layout/Header/navbar/index.tsx | 26 ++++------- 5 files changed, 43 insertions(+), 51 deletions(-) diff --git a/web/src/layout/Header/MobileHeader.tsx b/web/src/layout/Header/MobileHeader.tsx index c8a22877c..31d532fe8 100644 --- a/web/src/layout/Header/MobileHeader.tsx +++ b/web/src/layout/Header/MobileHeader.tsx @@ -1,8 +1,5 @@ -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 { landscapeStyle } from "styles/landscapeStyle"; @@ -37,30 +34,35 @@ const StyledLightButton = styled(LightButton)` } `; -const OpenContext = React.createContext({ - isOpen: false, - toggleIsOpen: () => { - // Placeholder - }, -}); - -export function useOpenContext() { - return useContext(OpenContext); -} +const Overlay = styled.div<{ isOpen: boolean }>` + display: ${({ isOpen }) => (isOpen ? "block" : "none")}; + position: absolute; + top: 0; + width: 100vw; + height: 64px; + z-index: 1; +`; const MobileHeader = () => { - const [isOpen, toggleIsOpen] = useToggle(false); - const containerRef = useRef(null); - useClickAway(containerRef, () => toggleIsOpen(false)); - const memoizedContext = useMemo(() => ({ isOpen, toggleIsOpen }), [isOpen, toggleIsOpen]); + const [isOpen, setIsOpen] = useState(false); + + const handleOpenNavbar = () => { + setIsOpen(true); + }; + + const handleCloseNavbar = () => { + setIsOpen(false); + }; + return ( - - - - - - + + {isOpen ? : null} + + + + ); }; + export default MobileHeader; diff --git a/web/src/layout/Header/navbar/DappList.tsx b/web/src/layout/Header/navbar/DappList.tsx index 9c1db313d..b1c410baf 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 Header = styled.h1` padding-top: 32px; @@ -136,10 +137,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 b3f597dc9..3f990dbb7 100644 --- a/web/src/layout/Header/navbar/Explore.tsx +++ b/web/src/layout/Header/navbar/Explore.tsx @@ -6,8 +6,6 @@ import { Link, useLocation } from "react-router-dom"; import { landscapeStyle } from "styles/landscapeStyle"; import { responsiveSize } from "styles/responsiveSize"; -import { useOpenContext } from "../MobileHeader"; - const Container = styled.div` display: flex; gap: 0px; @@ -59,9 +57,12 @@ const links = [ { to: "/get-pnk", text: "Get PNK" }, ]; -const Explore: React.FC = () => { +interface IExplore { + handleCloseNavbar: () => void; +} + +const Explore: React.FC = ({ handleCloseNavbar }) => { const location = useLocation(); - const { toggleIsOpen } = useOpenContext(); return ( @@ -70,7 +71,7 @@ const Explore: React.FC = () => { {text} diff --git a/web/src/layout/Header/navbar/Menu/Help.tsx b/web/src/layout/Header/navbar/Menu/Help.tsx index 0cc502aca..7c0e9e471 100644 --- a/web/src/layout/Header/navbar/Menu/Help.tsx +++ b/web/src/layout/Header/navbar/Menu/Help.tsx @@ -17,7 +17,7 @@ import { landscapeStyle } from "styles/landscapeStyle"; import Onboarding from "components/Popup/MiniGuides/Onboarding"; -import { IHelp } from ".."; +import { IHelp } from "../index"; import Debug from "../Debug"; const Container = styled.div` diff --git a/web/src/layout/Header/navbar/index.tsx b/web/src/layout/Header/navbar/index.tsx index c47c12601..1bfaffdc2 100644 --- a/web/src/layout/Header/navbar/index.tsx +++ b/web/src/layout/Header/navbar/index.tsx @@ -6,14 +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"; @@ -40,7 +35,7 @@ const Container = styled.div<{ isOpen: boolean }>` top: 0; left: 0; right: 0; - max-height: calc(100vh - 160px); + height: 100%; overflow-y: auto; z-index: 1; background-color: ${({ theme }) => theme.whiteBackground}; @@ -94,28 +89,25 @@ 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); return ( <> - { - toggleIsDappListOpen(); - }} - Icon={KlerosSolutionsIcon} - /> +
- +
From f0d9998eed1dbc66e4fc74ce1b16de692ddeb293 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 29 Nov 2024 07:15:11 +0100 Subject: [PATCH 2/8] fix: bug with overlay in mobile navbar --- web/src/layout/Header/MobileHeader.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/web/src/layout/Header/MobileHeader.tsx b/web/src/layout/Header/MobileHeader.tsx index 31d532fe8..9d7b42ab2 100644 --- a/web/src/layout/Header/MobileHeader.tsx +++ b/web/src/layout/Header/MobileHeader.tsx @@ -2,6 +2,8 @@ import React, { useState } from "react"; import styled, { css } from "styled-components"; import HamburgerIcon from "svgs/header/hamburger.svg"; +import { useLockBodyScroll } from "react-use"; + import { landscapeStyle } from "styles/landscapeStyle"; import LightButton from "components/LightButton"; @@ -34,17 +36,18 @@ const StyledLightButton = styled(LightButton)` } `; -const Overlay = styled.div<{ isOpen: boolean }>` - display: ${({ isOpen }) => (isOpen ? "block" : "none")}; - position: absolute; +const Overlay = styled.div` + position: fixed; top: 0; - width: 100vw; + left: 0; + width: 100%; height: 64px; z-index: 1; `; const MobileHeader = () => { const [isOpen, setIsOpen] = useState(false); + useLockBodyScroll(isOpen); const handleOpenNavbar = () => { setIsOpen(true); @@ -57,7 +60,6 @@ const MobileHeader = () => { return ( {isOpen ? : null} - From b688da16b25e816c0b5e83fe723db09d8cb245f2 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 29 Nov 2024 07:22:21 +0100 Subject: [PATCH 3/8] fix: make the handle close navbar property optional --- web/src/layout/Header/navbar/Explore.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/layout/Header/navbar/Explore.tsx b/web/src/layout/Header/navbar/Explore.tsx index 3f990dbb7..16a3e51e8 100644 --- a/web/src/layout/Header/navbar/Explore.tsx +++ b/web/src/layout/Header/navbar/Explore.tsx @@ -58,7 +58,7 @@ const links = [ ]; interface IExplore { - handleCloseNavbar: () => void; + handleCloseNavbar?: () => void; } const Explore: React.FC = ({ handleCloseNavbar }) => { From 94573d2203ee1878481dfbfcecd8bfae95c953c7 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 29 Nov 2024 07:32:31 +0100 Subject: [PATCH 4/8] chore: tiny feedback, add local time clarification --- web/src/components/DisputeView/DisputeInfo/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/DisputeView/DisputeInfo/index.tsx b/web/src/components/DisputeView/DisputeInfo/index.tsx index 2bf8be948..fb4bcfbbf 100644 --- a/web/src/components/DisputeView/DisputeInfo/index.tsx +++ b/web/src/components/DisputeView/DisputeInfo/index.tsx @@ -95,7 +95,7 @@ const DisputeInfo: React.FC = ({ { icon: CalendarIcon, name: getPeriodPhrase(period ?? 0), - value: !displayAsList ? new Date(date * 1000).toLocaleString() : formatDate(date), + value: !displayAsList ? new Date(date * 1000).toLocaleString() + " (Local Time)" : formatDate(date), display: !isUndefined(period) && !isUndefined(date), style: "grid-column: 2 / 4;", }, From 8625b55f398602ea368d675f72e06dbad7510f15 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 29 Nov 2024 07:36:14 +0100 Subject: [PATCH 5/8] chore: switch to template literal --- web/src/components/DisputeView/DisputeInfo/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/DisputeView/DisputeInfo/index.tsx b/web/src/components/DisputeView/DisputeInfo/index.tsx index fb4bcfbbf..7bf1f48cc 100644 --- a/web/src/components/DisputeView/DisputeInfo/index.tsx +++ b/web/src/components/DisputeView/DisputeInfo/index.tsx @@ -95,7 +95,7 @@ const DisputeInfo: React.FC = ({ { icon: CalendarIcon, name: getPeriodPhrase(period ?? 0), - value: !displayAsList ? new Date(date * 1000).toLocaleString() + " (Local Time)" : formatDate(date), + value: !displayAsList ? `${new Date(date * 1000).toLocaleString()} (Local Time)` : formatDate(date), display: !isUndefined(period) && !isUndefined(date), style: "grid-column: 2 / 4;", }, From 4fadbbb9c061fd6e03c74760b66029612a450570 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:12:21 +0100 Subject: [PATCH 6/8] chore: change enter amount for ? --- .../Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx b/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx index 5c52bf08d..03bb047bb 100644 --- a/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx +++ b/web/src/pages/Courts/CourtDetails/StakePanel/SimulatorPopup/index.tsx @@ -269,7 +269,7 @@ const SimulatorPopup: React.FC = ({ amountToStake, isStaking }) - {!amountToStake || amountToStake === 0 ? "Enter amount" : null} + {!amountToStake || amountToStake === 0 ? "?" : null} {!isUndefined(amountToStake) && amountToStake > 0 && (!isUndefined(item.futureValue) ? item.futureValue : )} From d76ab8c7b86b5c5f0facb49430734d344ec6e841 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 29 Nov 2024 21:41:28 +0100 Subject: [PATCH 7/8] fix: scrolling on some devices in mobile navbar, organize overlay better --- web/src/layout/Header/MobileHeader.tsx | 10 ----- web/src/layout/Header/navbar/index.tsx | 54 +++++++++++++------------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/web/src/layout/Header/MobileHeader.tsx b/web/src/layout/Header/MobileHeader.tsx index 9d7b42ab2..abe65f3b0 100644 --- a/web/src/layout/Header/MobileHeader.tsx +++ b/web/src/layout/Header/MobileHeader.tsx @@ -36,15 +36,6 @@ const StyledLightButton = styled(LightButton)` } `; -const Overlay = styled.div` - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 64px; - z-index: 1; -`; - const MobileHeader = () => { const [isOpen, setIsOpen] = useState(false); useLockBodyScroll(isOpen); @@ -59,7 +50,6 @@ const MobileHeader = () => { return ( - {isOpen ? : null} diff --git a/web/src/layout/Header/navbar/index.tsx b/web/src/layout/Header/navbar/index.tsx index 1bfaffdc2..7b2e05838 100644 --- a/web/src/layout/Header/navbar/index.tsx +++ b/web/src/layout/Header/navbar/index.tsx @@ -8,7 +8,6 @@ import KlerosSolutionsIcon from "svgs/menu-icons/kleros-solutions.svg"; import ConnectWallet from "components/ConnectWallet"; import LightButton from "components/LightButton"; -import { Overlay } from "components/Overlay"; import DappList from "./DappList"; import Explore from "./Explore"; import Menu from "./Menu"; @@ -26,20 +25,15 @@ 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; - height: 100%; + height: 92%; overflow-y: auto; z-index: 1; background-color: ${({ theme }) => theme.whiteBackground}; - border: 1px solid ${({ theme }) => theme.stroke}; box-shadow: 0px 2px 3px ${({ theme }) => theme.defaultShadow}; transform-origin: top; transform: scaleY(${({ isOpen }) => (isOpen ? "1" : "0")}); @@ -76,6 +70,15 @@ const PopupContainer = styled.div` background-color: ${({ theme }) => theme.blackLowOpacity}; `; +const Overlay = styled.div` + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 64px; + z-index: 1; +`; + export interface ISettings { toggleIsSettingsOpen: () => void; initialTab?: number; @@ -102,26 +105,25 @@ const NavBar: React.FC = ({ isOpen, handleCloseNavbar }) => { return ( <> + {isOpen ? : null} - - - -
- -
- - - {isConnected && ( - - - - )} - -
- -
- - + + +
+ +
+ + + {isConnected && ( + + + + )} + +
+ +
+ {(isDappListOpen || isHelpOpen || isSettingsOpen) && ( From df8539d302790934b3a28eff44b720967df96885 Mon Sep 17 00:00:00 2001 From: kemuru <102478601+kemuru@users.noreply.github.com> Date: Fri, 6 Dec 2024 22:13:03 +0100 Subject: [PATCH 8/8] fix: closing behavior and little closing animation --- .../DisputeView/DisputeInfo/index.tsx | 2 +- web/src/components/LightButton.tsx | 4 +- web/src/layout/Header/DesktopHeader.tsx | 8 +-- web/src/layout/Header/navbar/index.tsx | 54 ++++++++++++++----- 4 files changed, 44 insertions(+), 24 deletions(-) diff --git a/web/src/components/DisputeView/DisputeInfo/index.tsx b/web/src/components/DisputeView/DisputeInfo/index.tsx index 46c8747f0..ceb42580f 100644 --- a/web/src/components/DisputeView/DisputeInfo/index.tsx +++ b/web/src/components/DisputeView/DisputeInfo/index.tsx @@ -95,7 +95,7 @@ const DisputeInfo: React.FC = ({ { icon: CalendarIcon, name: getPeriodPhrase(period ?? 0), - value: !displayAsList ? `${new Date(date * 1000).toLocaleString()} (Local Time)` : formatDate(date), + value: !displayAsList ? new Date(date * 1000).toLocaleString() : formatDate(date), display: !isUndefined(period) && !isUndefined(date), style: "grid-column: 2 / 4;", }, 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/navbar/index.tsx b/web/src/layout/Header/navbar/index.tsx index 7729e97ae..202809456 100644 --- a/web/src/layout/Header/navbar/index.tsx +++ b/web/src/layout/Header/navbar/index.tsx @@ -31,7 +31,7 @@ const Container = styled.div<{ isOpen: boolean }>` top: 0; left: 0; right: 0; - height: 92%; + height: 76%; overflow-y: auto; z-index: 1; background-color: ${({ theme }) => theme.whiteBackground}; @@ -61,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; @@ -69,15 +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 StyledOverlay = styled.div` +const NavbarOverlay = styled.div<{ hasPopupOpen: boolean; isClosing: boolean }>` position: fixed; top: 0; left: 0; width: 100%; height: 64px; - z-index: 1; + z-index: ${({ hasPopupOpen, isClosing }) => (hasPopupOpen || isClosing ? -1 : 1)}; +`; + +const StyledOverlay = styled(Overlay)` + top: unset; `; export interface ISettings { @@ -103,19 +109,35 @@ const NavBar: React.FC = ({ isOpen, handleCloseNavbar }) => { const [isDappListOpen, toggleIsDappListOpen] = useToggle(false); const [isHelpOpen, toggleIsHelpOpen] = useToggle(false); const [isSettingsOpen, toggleIsSettingsOpen] = useToggle(false); + 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 ? : null} + {isOpen && } { - toggleIsDappListOpen(); - }} + onClick={() => handleOpenPopup(toggleIsDappListOpen)} Icon={KlerosSolutionsIcon} />
@@ -130,16 +152,20 @@ const NavBar: React.FC = ({ isOpen, handleCloseNavbar }) => { )}
- + handleOpenPopup(toggleIsHelpOpen)} + toggleIsSettingsOpen={() => handleOpenPopup(toggleIsSettingsOpen)} + isMobileNavbar={true} + />
- {(isDappListOpen || isHelpOpen || isSettingsOpen) && ( - - {isDappListOpen && } - {isHelpOpen && } - {isSettingsOpen && } + {hasPopupOpen && ( + isClosing && handleClosePopup()}> + {isDappListOpen && } + {isHelpOpen && } + {isSettingsOpen && } )}