Skip to content

Commit

Permalink
feat: close and disconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsimao committed Jan 17, 2025
1 parent ea77b03 commit 668640e
Show file tree
Hide file tree
Showing 10 changed files with 242 additions and 110 deletions.
33 changes: 33 additions & 0 deletions apps/evm/src/components/ConnectButton/ConnectButton.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { DrawerClose, hexToRgba } from '@gobob/ui';
import styled from 'styled-components';

type StyledCloseButtonProps = {
$isOpen?: boolean;
};

const StyledCloseButton = styled(DrawerClose)<StyledCloseButtonProps>`
background-color: transparent;
border: 0;
border-top-left-radius: ${({ theme }) => theme.rounded('lg')};
border-bottom-left-radius: ${({ theme }) => theme.rounded('lg')};
width: 3.5rem;
height: 100%;
position: absolute;
left: 0;
top: 0;
bottom: 0;
z-index: -1;
display: flex;
padding-top: ${({ theme }) => theme.spacing('3xl')};
padding-left: ${({ theme }) => theme.spacing('lg')};
transform: ${({ $isOpen }) => ($isOpen ? 'translateX(-95%)' : 'translateX(0%)')};
${({ theme }) => theme.transition('common', 'normal')}
&:hover, &:focus-visible {
background-color: ${({ theme }) => hexToRgba(theme.color('grey-300'), 40)};
transform: ${({ $isOpen }) => $isOpen && 'translateX(-75%)'};
}
`;

export { StyledCloseButton };
31 changes: 23 additions & 8 deletions apps/evm/src/components/ConnectButton/ConnectButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
'use client';

import { useAccount as useSatsAccount } from '@gobob/sats-wagmi';
import { Button, DrawerButton, DrawerContent, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTitle } from '@gobob/ui';
import {
Button,
ChevronDoubleRight,
DrawerButton,
DrawerContent,
DrawerOverlay,
DrawerPortal,
DrawerRoot,
DrawerTitle
} from '@gobob/ui';
import { Trans } from '@lingui/macro';
import { useStore } from '@tanstack/react-store';
import { useState } from 'react';
import { useTheme } from 'styled-components';
import { useMediaQuery } from 'usehooks-ts';
import { useAccount } from 'wagmi';
import { useState } from 'react';

import { Profile } from '../Profile';
import { ProfileTag } from '../ProfileTag';

import { StyledCloseButton } from './ConnectButton.style';

import { useConnectModal } from '@/connect-ui';
import { chainL1, chainL2, isValidChain } from '@/constants';
import { store } from '@/lib/store';
Expand All @@ -20,6 +31,8 @@ const ConnectButton = (): JSX.Element => {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('s'));

const [isProfileDrawerOpen, setProfileDrawerOpen] = useState(false);

const { address: evmAddress, chain } = useAccount();
const { address: btcAddress } = useSatsAccount();

Expand All @@ -29,7 +42,6 @@ const ConnectButton = (): JSX.Element => {
const isReceiveModalOpen = useStore(store, (state) => state.shared.isReceiveModalOpen);
const { isOpen: isConnectModalOpen } = useConnectModal();

const [isOpen, setOpen] = useState(false);
const { open } = useConnectModal();

const isLoggedIn = !!(evmAddress || btcAddress);
Expand All @@ -40,31 +52,34 @@ const ConnectButton = (): JSX.Element => {
};

return (
<Button variant='ghost' onPress={handleConnect}>
<Button style={{ marginLeft: 30 }} variant='ghost' onPress={handleConnect}>
<Trans>Connect Wallet</Trans>
</Button>
);
}

const handleClose = () => setOpen(false);
const handleClose = () => setProfileDrawerOpen(false);

return (
<DrawerRoot
direction={isMobile ? 'bottom' : 'right'}
dismissible={!(isReceiveModalOpen || isConnectModalOpen)}
open={isOpen}
onOpenChange={setOpen}
open={isProfileDrawerOpen}
onOpenChange={setProfileDrawerOpen}
>
<DrawerButton variant='ghost'>
<ProfileTag chain={currentChain} hideAddress={isMobile} size='s' />
</DrawerButton>
<DrawerPortal>
<DrawerOverlay />
<DrawerContent>
<StyledCloseButton $isOpen={isProfileDrawerOpen}>
<ChevronDoubleRight color='grey-50' size='s' />
</StyledCloseButton>
<DrawerTitle hidden>
<Trans>Profile</Trans>
</DrawerTitle>
<Profile currentChain={currentChain} isMobile={isMobile} otherChain={otherChain} onClose={handleClose} />
<Profile currentChain={currentChain} otherChain={otherChain} onClose={handleClose} />
</DrawerContent>
</DrawerPortal>
</DrawerRoot>
Expand Down
108 changes: 56 additions & 52 deletions apps/evm/src/components/Layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { useUserAgent } from '@/user-agent';
const Header = (): JSX.Element => {
const { i18n } = useLingui();

const [isOpen, setOpen] = useState(false);
const [isPopoverOpen, setPopoverOpen] = useState(false);

const theme = useTheme();
const isMobileViewport = useMediaQuery(theme.breakpoints.down('md'));
Expand All @@ -41,57 +41,61 @@ const Header = (): JSX.Element => {

return (
<StyledHeader alignItems='center' elementType='header' justifyContent='space-between'>
<StyledLogoWrapper alignItems='center' gap='md'>
<Sidebar isMobile={isMobile} />
<Logo hidden={isMobile} href={RoutesPath.HOME} />
</StyledLogoWrapper>
<Flex alignItems='center' elementType='header' gap='xl' justifyContent='flex-end'>
<Nav hidden={isMobile}>
<NavItem href={RoutesPath.BRIDGE} size='s'>
<Trans>Bridge</Trans>
</NavItem>
<NavItem href={RoutesPath.APPS} size='s'>
<Trans>Apps</Trans>
</NavItem>
<NavItem href={RoutesPath.STRATEGIES} size='s'>
<Trans>Stake</Trans>
</NavItem>
<NavItem href={RoutesPath.FUSION} size='s'>
<Trans>Fusion</Trans>
</NavItem>
</Nav>
<Popover crossOffset={-50} isOpen={isOpen} onOpenChange={setOpen}>
<PopoverTrigger>
<Button
isIconOnly
aria-label={t(i18n)`Show secondary navigation`}
hidden={isMobile}
size='s'
variant='ghost'
>
<EllipsisHorizontal color='light' size='s' />
</Button>
</PopoverTrigger>
<PopoverContent hidden={isMobile}>
<PopoverBody onClick={() => setOpen(false)}>
<Nav direction='column'>
<NavItem isExternal href={ExternalLinks.TERMS_OF_SERVICE} size='s'>
<Trans>T&Cs</Trans>
</NavItem>
<NavItem isExternal href={ExternalLinks.DOCS} size='s'>
<Trans>Dev</Trans>
</NavItem>
<NavItem isExternal href={ExternalLinks.HOMEPAGE} size='s'>
<Trans>About</Trans>
</NavItem>
<NavItem isExternal href={ExternalLinks.SAFE} size='s'>
<Trans>Multisig</Trans>
</NavItem>
</Nav>
</PopoverBody>
</PopoverContent>
</Popover>
<SocialsGroup hidden={isMobile} variant='ghost' />
<Flex alignItems='center' gap='4xl'>
<StyledLogoWrapper alignItems='center' gap='md'>
<Sidebar isMobile={isMobile} />
<Logo hidden={isMobile} href={RoutesPath.HOME} />
</StyledLogoWrapper>
<Flex alignItems='center' gap='xl'>
<Nav hidden={isMobile}>
<NavItem href={RoutesPath.BRIDGE} size='s'>
<Trans>Bridge</Trans>
</NavItem>
<NavItem href={RoutesPath.APPS} size='s'>
<Trans>Apps</Trans>
</NavItem>
<NavItem href={RoutesPath.STRATEGIES} size='s'>
<Trans>Stake</Trans>
</NavItem>
<NavItem href={RoutesPath.FUSION} size='s'>
<Trans>Fusion</Trans>
</NavItem>
</Nav>
<Popover crossOffset={-50} isOpen={isPopoverOpen} onOpenChange={setPopoverOpen}>
<PopoverTrigger>
<Button
isIconOnly
aria-label={t(i18n)`Show secondary navigation`}
hidden={isMobile}
size='s'
variant='ghost'
>
<EllipsisHorizontal color='light' size='s' />
</Button>
</PopoverTrigger>
<PopoverContent hidden={isMobile}>
<PopoverBody gap='md' onClick={() => setPopoverOpen(false)}>
<Nav direction='column'>
<NavItem isExternal href={ExternalLinks.TERMS_OF_SERVICE} size='s'>
<Trans>T&Cs</Trans>
</NavItem>
<NavItem isExternal href={ExternalLinks.DOCS} size='s'>
<Trans>Dev</Trans>
</NavItem>
<NavItem isExternal href={ExternalLinks.HOMEPAGE} size='s'>
<Trans>About</Trans>
</NavItem>
<NavItem isExternal href={ExternalLinks.SAFE} size='s'>
<Trans>Multisig</Trans>
</NavItem>
</Nav>
<SocialsGroup hidden={isMobile} variant='ghost' />
</PopoverBody>
</PopoverContent>
</Popover>
</Flex>
</Flex>
<Flex alignItems='center' gap='xl'>
<FusionPopover />
<ConnectButton />
</Flex>
Expand Down
2 changes: 1 addition & 1 deletion apps/evm/src/components/Layout/NavItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const NavItem = ({ children, size, isExternal, href, onPress, ...props }: NavIte
const localizedHref = `/${params.lang}${href}`;

return (
<li>
<li style={{ lineHeight: 1 }}>
<StyledNativeNavLink {...props} ref={ref} href={localizedHref} onClick={onPress} onKeyDown={onPress}>
<StyledNavLink
as={Span}
Expand Down
74 changes: 74 additions & 0 deletions apps/evm/src/components/Profile/DisconnectButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use client';

import { Button, Flex, Power, Span } from '@gobob/ui';
import { Trans } from '@lingui/macro';
import { useEffect, useRef, useState } from 'react';

type DisconnectButtonProps = {
onConfirmPress: () => void;
};

const DisconnectButton = ({ onConfirmPress }: DisconnectButtonProps): JSX.Element => {
const [isFocused, setFocused] = useState(false);

const timeoutRef = useRef<ReturnType<typeof setTimeout>>();

useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);

const handleMouseLeave = () => {
timeoutRef.current = setTimeout(() => {
setFocused(false);
timeoutRef.current = undefined;
}, 500);
};

const handlePress = () => {
if (!isFocused) {
return setFocused(true);
}
onConfirmPress();
};

const handleMouseEnter = () => {
if (isFocused && timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = undefined;
}
};

const handleBlur = () => setFocused(false);

return (
<Button
size='s'
variant='ghost'
onBlur={handleBlur}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onPress={handlePress}
>
<Power size='s' />
<Flex
alignItems='center'
elementType='span'
style={{
display: 'grid',
gridTemplateColumns: isFocused ? '1fr' : '0fr',
transition: 'all 200ms ease 0ms'
}}
>
<Span size='s' style={{ overflow: 'hidden', marginLeft: isFocused ? 4 : 0 }}>
<Trans>Disconnect</Trans>
</Span>
</Flex>
</Button>
);
};

export { DisconnectButton };
3 changes: 2 additions & 1 deletion apps/evm/src/components/Profile/Profile.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const StyledWalletCard = styled(Card)`
const StyledTokenListItem = styled(Card)<StyledTokenListItemProps>`
cursor: pointer;
&:hover {
&:hover,
&:focus-visible {
${({ theme }) => theme.list.item.hover}
}
Expand Down
Loading

0 comments on commit 668640e

Please sign in to comment.