diff --git a/src/components/AccountDrawer/AuthenticatedHeader.tsx b/src/components/AccountDrawer/AuthenticatedHeader.tsx index d26962e465..6974be95dc 100644 --- a/src/components/AccountDrawer/AuthenticatedHeader.tsx +++ b/src/components/AccountDrawer/AuthenticatedHeader.tsx @@ -40,7 +40,6 @@ const AuthenticatedHeaderWrapper = styled.div` display: flex; flex-direction: column; flex: 1; - overflow: auto; ` const HeaderButton = styled(ThemeButton)` diff --git a/src/components/AccountDrawer/index.tsx b/src/components/AccountDrawer/index.tsx index c264006d8a..b9aaae6fb7 100644 --- a/src/components/AccountDrawer/index.tsx +++ b/src/components/AccountDrawer/index.tsx @@ -1,14 +1,17 @@ import { BrowserEvent, InterfaceEventName } from '@uniswap/analytics-events' import { TraceEvent } from 'analytics' import { ScrollBarStyles } from 'components/Common' +import useDisableScrolling from 'hooks/useDisableScrolling' import { useWindowSize } from 'hooks/useWindowSize' import { atom } from 'jotai' import { useAtomValue, useUpdateAtom } from 'jotai/utils' -import { useCallback, useEffect, useRef } from 'react' +import { useCallback, useEffect, useRef, useState } from 'react' import { ChevronsRight } from 'react-feather' +import { useGesture } from 'react-use-gesture' import styled from 'styled-components/macro' import { BREAKPOINTS, ClickableStyle } from 'theme' import { Z_INDEX } from 'theme/zIndex' +import { isMobile } from 'utils/userAgent' import DefaultMenu from './DefaultMenu' @@ -181,21 +184,53 @@ function AccountDrawer() { } }, [walletDrawerOpen, toggleWalletDrawer]) - // close on escape keypress - useEffect(() => { - const escapeKeyDownHandler = (event: KeyboardEvent) => { - if (event.key === 'Escape' && walletDrawerOpen) { - event.preventDefault() + // useStates for detecting swipe gestures + const [yPosition, setYPosition] = useState(0) + const [dragStartTop, setDragStartTop] = useState(true) + useDisableScrolling(walletDrawerOpen) + + // useGesture hook for detecting swipe gestures + const bind = useGesture({ + // if the drawer is open and the user is dragging down, close the drawer + onDrag: (state) => { + // if the user is dragging up, set dragStartTop to false + if (state.movement[1] < 0) { + setDragStartTop(false) + if (scrollRef.current) { + scrollRef.current.style.overflowY = 'auto' + } + } else if ( + (state.movement[1] > 300 || (state.velocity > 3 && state.direction[1] > 0)) && + walletDrawerOpen && + dragStartTop + ) { toggleWalletDrawer() + } else if (walletDrawerOpen && dragStartTop && state.movement[1] > 0) { + setYPosition(state.movement[1]) + if (scrollRef.current) { + scrollRef.current.style.overflowY = 'hidden' + } } - } - - document.addEventListener('keydown', escapeKeyDownHandler) - - return () => { - document.removeEventListener('keydown', escapeKeyDownHandler) - } - }, [walletDrawerOpen, toggleWalletDrawer]) + }, + // reset the yPosition when the user stops dragging + onDragEnd: (state) => { + setYPosition(0) + if (scrollRef.current) { + scrollRef.current.style.overflowY = 'auto' + } + }, + // set dragStartTop to true if the user starts dragging from the top of the drawer + onDragStart: (state) => { + if (!scrollRef.current?.scrollTop || scrollRef.current?.scrollTop < 30) { + setDragStartTop(true) + } else { + setDragStartTop(false) + if (scrollRef.current) { + scrollRef.current.style.overflowY = 'auto' + } + } + }, + }) return ( @@ -211,7 +246,15 @@ function AccountDrawer() { )} - + {/* id used for child InfiniteScrolls to reference when it has reached the bottom of the component */}