From dcac86c41a3d3ca7510243785a52e7af0ba26769 Mon Sep 17 00:00:00 2001 From: Karolina Kosiorowska Date: Thu, 14 Dec 2023 10:35:04 +0100 Subject: [PATCH] Change the approach to opening modals We should have one modal and change the content in it. --- dapp/src/DApp.tsx | 13 +--- dapp/src/components/ModalOverlay/index.tsx | 40 ---------- dapp/src/components/Modals/BaseModal.tsx | 25 ------- dapp/src/components/Modals/StakeModal.tsx | 18 +++++ .../Modals/StakingOverviewModal.tsx | 26 +++++-- .../components/Overview/PositionDetails.tsx | 22 ++---- dapp/src/components/Staking/index.tsx | 11 --- dapp/src/components/StakingModal/index.tsx | 34 +++++++++ .../src/components/shared/ModalBase/index.tsx | 73 +++++++++++++++++++ dapp/src/contexts/ModalContext.tsx | 45 ------------ dapp/src/contexts/ModalFlowContext.tsx | 19 +++++ dapp/src/contexts/index.tsx | 2 +- dapp/src/hooks/index.ts | 2 +- dapp/src/hooks/useModal.ts | 12 --- dapp/src/hooks/useModalFlowContext.ts | 14 ++++ dapp/src/theme/Drawer.ts | 4 +- dapp/src/theme/Modal.ts | 5 ++ dapp/src/theme/utils/zIndices.ts | 16 +--- 18 files changed, 202 insertions(+), 179 deletions(-) delete mode 100644 dapp/src/components/ModalOverlay/index.tsx delete mode 100644 dapp/src/components/Modals/BaseModal.tsx create mode 100644 dapp/src/components/Modals/StakeModal.tsx delete mode 100644 dapp/src/components/Staking/index.tsx create mode 100644 dapp/src/components/StakingModal/index.tsx create mode 100644 dapp/src/components/shared/ModalBase/index.tsx delete mode 100644 dapp/src/contexts/ModalContext.tsx create mode 100644 dapp/src/contexts/ModalFlowContext.tsx delete mode 100644 dapp/src/hooks/useModal.ts create mode 100644 dapp/src/hooks/useModalFlowContext.ts diff --git a/dapp/src/DApp.tsx b/dapp/src/DApp.tsx index ff0314b10..1566c2e15 100644 --- a/dapp/src/DApp.tsx +++ b/dapp/src/DApp.tsx @@ -5,7 +5,6 @@ import theme from "./theme" import { DocsDrawerContextProvider, LedgerWalletAPIProvider, - ModalContextProvider, SidebarContextProvider, WalletContextProvider, } from "./contexts" @@ -13,7 +12,6 @@ import Header from "./components/Header" import Overview from "./components/Overview" import Sidebar from "./components/Sidebar" import DocsDrawer from "./components/DocsDrawer" -import ModalOverlay from "./components/ModalOverlay" function DApp() { useDetectThemeMode() @@ -26,9 +24,6 @@ function DApp() { - {/* The user has several modals in a flow. - Let's use our own modal overlay to prevent the background flickering effect. */} - ) } @@ -39,11 +34,9 @@ function DAppProviders() { - - - - - + + + diff --git a/dapp/src/components/ModalOverlay/index.tsx b/dapp/src/components/ModalOverlay/index.tsx deleted file mode 100644 index 8a022dee6..000000000 --- a/dapp/src/components/ModalOverlay/index.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { useEffect, useState } from "react" -import { Box } from "@chakra-ui/react" -import { useModal } from "../../hooks" -import { HEADER_HEIGHT } from "../Header" - -const DELAY = 300 - -export default function ModalOverlay() { - const { modalType } = useModal() - const [showOverlay, setShowOverlay] = useState(!modalType) - - useEffect(() => { - const timeout = setTimeout( - () => { - setShowOverlay(!!modalType) - }, - // When the modal opens, we should show the sidebar without delay. - // However, when the modal disappears, the overlay should disappear with some delay. - modalType ? 0 : DELAY, - ) - return () => clearTimeout(timeout) - }, [modalType]) - - return ( - - ) -} diff --git a/dapp/src/components/Modals/BaseModal.tsx b/dapp/src/components/Modals/BaseModal.tsx deleted file mode 100644 index 67905b833..000000000 --- a/dapp/src/components/Modals/BaseModal.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from "react" -import { Modal, ModalCloseButton, ModalContent } from "@chakra-ui/react" -import { HEADER_HEIGHT } from "../Header" -import { useModal, useSidebar } from "../../hooks" - -export default function BaseModal({ children }: { children: React.ReactNode }) { - const { closeModal } = useModal() - const { onClose: closeSidebar } = useSidebar() - - return ( - { - closeSidebar() - closeModal() - }} - > - - - {children} - - - ) -} diff --git a/dapp/src/components/Modals/StakeModal.tsx b/dapp/src/components/Modals/StakeModal.tsx new file mode 100644 index 000000000..ab16f10f7 --- /dev/null +++ b/dapp/src/components/Modals/StakeModal.tsx @@ -0,0 +1,18 @@ +import React from "react" +import { Button, ModalBody, ModalCloseButton } from "@chakra-ui/react" +import { TextMd } from "../Typography" +import { ModalStep } from "../../contexts" + +export default function StakeModal({ goNext }: ModalStep) { + return ( + <> + + + Stake modal + + + + ) +} diff --git a/dapp/src/components/Modals/StakingOverviewModal.tsx b/dapp/src/components/Modals/StakingOverviewModal.tsx index 4b6ccdc89..17815e502 100644 --- a/dapp/src/components/Modals/StakingOverviewModal.tsx +++ b/dapp/src/components/Modals/StakingOverviewModal.tsx @@ -1,11 +1,25 @@ import React from "react" -import { ModalHeader } from "@chakra-ui/react" -import BaseModal from "./BaseModal" +import { + Button, + ModalBody, + ModalCloseButton, + ModalFooter, +} from "@chakra-ui/react" +import { TextMd } from "../Typography" +import { ModalStep } from "../../contexts" -export default function StakingOverviewModal() { +export default function StakingOverviewModal({ goNext }: ModalStep) { return ( - - Staking overview - + <> + + + Staking overview + + + + + ) } diff --git a/dapp/src/components/Overview/PositionDetails.tsx b/dapp/src/components/Overview/PositionDetails.tsx index c64ad99dd..34f4467b4 100644 --- a/dapp/src/components/Overview/PositionDetails.tsx +++ b/dapp/src/components/Overview/PositionDetails.tsx @@ -1,4 +1,4 @@ -import React from "react" +import React, { useState } from "react" import { Text, Button, @@ -12,12 +12,10 @@ import { } from "@chakra-ui/react" import { BITCOIN, USD } from "../../constants" import { Info } from "../../static/icons" -import { useModal, useSidebar } from "../../hooks" -import Staking from "../Staking" +import StakingModal from "../StakingModal" export default function PositionDetails(props: CardProps) { - const { openModal } = useModal() - const { onOpen: openSidebar } = useSidebar() + const [isOpenStakingModal, setIsOpenStakingModal] = useState(false) return ( @@ -38,17 +36,13 @@ export default function PositionDetails(props: CardProps) { {/* TODO: Handle click actions */} - + - + setIsOpenStakingModal(false)} + /> ) } diff --git a/dapp/src/components/Staking/index.tsx b/dapp/src/components/Staking/index.tsx deleted file mode 100644 index b2f6da6ee..000000000 --- a/dapp/src/components/Staking/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from "react" -import { useModal } from "../../hooks" -import StakingOverviewModal from "../Modals/StakingOverviewModal" - -export default function Staking() { - const { modalType } = useModal() - - if (!modalType) return null - - if (modalType === "overview") return -} diff --git a/dapp/src/components/StakingModal/index.tsx b/dapp/src/components/StakingModal/index.tsx new file mode 100644 index 000000000..678c48707 --- /dev/null +++ b/dapp/src/components/StakingModal/index.tsx @@ -0,0 +1,34 @@ +import React from "react" +import { useModalFlowContext } from "../../hooks" +import StakeModal from "../Modals/StakeModal" +import StakingOverviewModal from "../Modals/StakingOverviewModal" +import ModalBase from "../shared/ModalBase" + +function StakingModalSteps() { + const { activeStep, goNext } = useModalFlowContext() + + console.log("activeStep ", activeStep) + + switch (activeStep) { + case "overview": + return + case "stake": + return + default: + return null + } +} + +export default function StakingModal({ + isOpen, + onClose, +}: { + isOpen: boolean + onClose: () => void +}) { + return ( + + + + ) +} diff --git a/dapp/src/components/shared/ModalBase/index.tsx b/dapp/src/components/shared/ModalBase/index.tsx new file mode 100644 index 000000000..8e454c3b5 --- /dev/null +++ b/dapp/src/components/shared/ModalBase/index.tsx @@ -0,0 +1,73 @@ +import React, { useCallback, useEffect, useMemo, useState } from "react" +import { Modal, ModalContent, ModalOverlay } from "@chakra-ui/react" +import { HEADER_HEIGHT } from "../../Header" +import { ModalFlowContext, ModalFlowContextValue } from "../../../contexts" +import { useSidebar } from "../../../hooks" + +export default function ModalBase({ + isOpen, + onClose, + steps, + defaultIndex = 0, + children, +}: { + isOpen: boolean + onClose: () => void + steps: string[] + defaultIndex?: number + children: React.ReactNode +}) { + const { onOpen: openSideBar, onClose: closeSidebar } = useSidebar() + + const [activeStep, setActiveStep] = useState(steps[defaultIndex]) + const [index, setIndex] = useState(defaultIndex) + + const handleGoNext = useCallback(() => { + setIndex((prevIndex) => prevIndex + 1) + }, []) + + const handleClose = useCallback(() => { + onClose() + }, [onClose]) + + useEffect(() => { + if (index >= steps.length) { + handleClose() + } else { + setActiveStep(steps[index]) + } + }, [steps, index, handleClose]) + + useEffect(() => { + if (!isOpen) { + closeSidebar() + + const timeout = setTimeout(() => { + setActiveStep(steps[defaultIndex]) + setIndex(defaultIndex) + }, 100) + return () => clearTimeout(timeout) + } else { + openSideBar() + } + }, [isOpen, steps, defaultIndex, closeSidebar, openSideBar]) + + const contextValue: ModalFlowContextValue = useMemo( + () => ({ + steps, + activeStep, + onClose: handleClose, + goNext: handleGoNext, + }), + [activeStep, steps, handleGoNext, handleClose], + ) + + return ( + + + + {children} + + + ) +} diff --git a/dapp/src/contexts/ModalContext.tsx b/dapp/src/contexts/ModalContext.tsx deleted file mode 100644 index 27bbd37b0..000000000 --- a/dapp/src/contexts/ModalContext.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { createContext, useCallback, useMemo, useState } from "react" - -type ModalType = "overview" - -type ModalContextValue = { - modalType?: ModalType - openModal: (modalType: ModalType) => void - closeModal: () => void -} - -export const ModalContext = createContext({ - openModal: () => {}, - closeModal: () => {}, -}) - -export function ModalContextProvider({ - children, -}: { - children: React.ReactNode -}): React.ReactElement { - const [modalType, setModalType] = useState(undefined) - - const openModal = useCallback((type: ModalType) => { - setModalType(type) - }, []) - - const closeModal = useCallback(() => { - setModalType(undefined) - }, []) - - const contextValue: ModalContextValue = useMemo( - () => ({ - modalType, - openModal, - closeModal, - }), - [modalType, closeModal, openModal], - ) - - return ( - - {children} - - ) -} diff --git a/dapp/src/contexts/ModalFlowContext.tsx b/dapp/src/contexts/ModalFlowContext.tsx new file mode 100644 index 000000000..dac5e8253 --- /dev/null +++ b/dapp/src/contexts/ModalFlowContext.tsx @@ -0,0 +1,19 @@ +import { createContext } from "react" + +export type ModalStep = { + goNext: () => void +} + +export type ModalFlowContextValue = { + activeStep?: string + steps: string[] + onClose: () => void + goNext: () => void +} + +export const ModalFlowContext = createContext({ + activeStep: undefined, + steps: [], + goNext: () => {}, + onClose: () => {}, +}) diff --git a/dapp/src/contexts/index.tsx b/dapp/src/contexts/index.tsx index 944d664cc..6787e1cc6 100644 --- a/dapp/src/contexts/index.tsx +++ b/dapp/src/contexts/index.tsx @@ -2,4 +2,4 @@ export * from "./WalletContext" export * from "./LedgerWalletAPIProvider" export * from "./DocsDrawerContext" export * from "./SidebarContext" -export * from "./ModalContext" +export * from "./ModalFlowContext" diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index b1418a74f..076da9a53 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -4,4 +4,4 @@ export * from "./useRequestEthereumAccount" export * from "./useWalletContext" export * from "./useSidebar" export * from "./useDocsDrawer" -export * from "./useModal" +export * from "./useModalFlowContext" diff --git a/dapp/src/hooks/useModal.ts b/dapp/src/hooks/useModal.ts deleted file mode 100644 index fbf9117fd..000000000 --- a/dapp/src/hooks/useModal.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { useContext } from "react" -import { ModalContext } from "../contexts" - -export function useModal() { - const context = useContext(ModalContext) - - if (!context) { - throw new Error("ModalContext used outside of ModalContext component") - } - - return context -} diff --git a/dapp/src/hooks/useModalFlowContext.ts b/dapp/src/hooks/useModalFlowContext.ts new file mode 100644 index 000000000..48882c561 --- /dev/null +++ b/dapp/src/hooks/useModalFlowContext.ts @@ -0,0 +1,14 @@ +import { useContext } from "react" +import { ModalFlowContext } from "../contexts" + +export function useModalFlowContext() { + const context = useContext(ModalFlowContext) + + if (!context) { + throw new Error( + "ModalFlowContext used outside of ModalFlowContext component", + ) + } + + return context +} diff --git a/dapp/src/theme/Drawer.ts b/dapp/src/theme/Drawer.ts index a46338eef..8a6d8ee24 100644 --- a/dapp/src/theme/Drawer.ts +++ b/dapp/src/theme/Drawer.ts @@ -6,7 +6,9 @@ const Drawer: ComponentSingleStyleConfig = { zIndex: "drawer", }, overlay: { - bg: "gold.300", + bg: "none", + backdropFilter: "auto", + backdropBlur: "8px", }, dialog: { borderTop: "2px", diff --git a/dapp/src/theme/Modal.ts b/dapp/src/theme/Modal.ts index 0d6ceb62c..72b3a7b67 100644 --- a/dapp/src/theme/Modal.ts +++ b/dapp/src/theme/Modal.ts @@ -16,6 +16,11 @@ const Modal: ComponentSingleStyleConfig = { rounded: "100%", bg: "rgba(255, 255, 255, 0.50)", }, + overlay: { + bg: "none", + backdropFilter: "auto", + backdropBlur: "8px", + }, }, } diff --git a/dapp/src/theme/utils/zIndices.ts b/dapp/src/theme/utils/zIndices.ts index b141510db..08df25d44 100644 --- a/dapp/src/theme/utils/zIndices.ts +++ b/dapp/src/theme/utils/zIndices.ts @@ -1,17 +1,7 @@ +import { theme } from "@chakra-ui/react" + export const zIndices = { - hide: -1, - auto: "auto", - base: 0, - docked: 10, - dropdown: 1000, - sticky: 1100, - banner: 1200, - overlay: 1300, - modal: 1400, + ...theme.zIndices, sidebar: 1450, drawer: 1470, - popover: 1500, - skipLink: 1600, - toast: 1700, - tooltip: 1800, }