Commit 46508f65 authored by tom's avatar tom

fix user wallet menu

parent 0eb4ffd8
/* eslint-disable no-restricted-imports */
import { Drawer as ChakraDrawer, Portal } from '@chakra-ui/react'; import { Drawer as ChakraDrawer, Portal } from '@chakra-ui/react';
import * as React from 'react'; import * as React from 'react';
...@@ -42,8 +43,14 @@ export const DrawerCloseTrigger = React.forwardRef< ...@@ -42,8 +43,14 @@ export const DrawerCloseTrigger = React.forwardRef<
); );
}); });
const EMPTY_ELEMENT = () => null;
export const DrawerRoot = (props: ChakraDrawer.RootProps) => {
const { initialFocusEl = EMPTY_ELEMENT, ...rest } = props;
return <ChakraDrawer.Root { ...rest } initialFocusEl={ initialFocusEl }/>;
};
export const DrawerTrigger = ChakraDrawer.Trigger; export const DrawerTrigger = ChakraDrawer.Trigger;
export const DrawerRoot = ChakraDrawer.Root;
export const DrawerFooter = ChakraDrawer.Footer; export const DrawerFooter = ChakraDrawer.Footer;
export const DrawerHeader = ChakraDrawer.Header; export const DrawerHeader = ChakraDrawer.Header;
export const DrawerBody = ChakraDrawer.Body; export const DrawerBody = ChakraDrawer.Body;
......
...@@ -10,6 +10,11 @@ export const recipe = defineRecipe({ ...@@ -10,6 +10,11 @@ export const recipe = defineRecipe({
_disabled: { _disabled: {
opacity: 0.2, opacity: 0.2,
}, },
// FIXME have to override the Chakra UI styles for the SVG icon inside the button
// try to find a better solution
'& svg': {
boxSize: 'auto',
},
}, },
variants: { variants: {
visual: { visual: {
......
import { useColorModeValue, useToken, Box, chakra } from '@chakra-ui/react'; import { Box, chakra } from '@chakra-ui/react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import React from 'react'; import React from 'react';
import Skeleton from 'ui/shared/chakra/Skeleton'; import { Skeleton } from 'toolkit/chakra/skeleton';
const Identicon = dynamic<{ bg: string; string: string; size: number }>( const Identicon = dynamic<{ bg: string; string: string; size: number }>(
async() => { async() => {
...@@ -17,26 +17,25 @@ const Identicon = dynamic<{ bg: string; string: string; size: number }>( ...@@ -17,26 +17,25 @@ const Identicon = dynamic<{ bg: string; string: string; size: number }>(
interface Props { interface Props {
className?: string; className?: string;
size: number; iconSize: number;
seed: string; seed: string;
} }
const IdenticonGithub = ({ size, seed }: Props) => { const IdenticonGithub = ({ iconSize, seed }: Props) => {
const bgColor = useToken('colors', useColorModeValue('gray.100', 'white'));
return ( return (
<Box <Box
boxSize={ `${ size * 2 }px` } boxSize={ `${ iconSize * 2 }px` }
transformOrigin="left top" transformOrigin="left top"
transform="scale(0.5)" transform="scale(0.5)"
borderRadius="full" borderRadius="full"
overflow="hidden" overflow="hidden"
bg={{ _light: 'gray.100', _dark: 'white' }}
> >
<Identicon <Identicon
bg={ bgColor } bg="transparent"
string={ seed } string={ seed }
// the displayed size is doubled for retina displays and then scaled down // the displayed size is doubled for retina displays and then scaled down
size={ size * 2 } size={ iconSize * 2 }
/> />
</Box> </Box>
); );
......
import { Box, Image } from '@chakra-ui/react'; import { Box } from '@chakra-ui/react';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
import React from 'react'; import React from 'react';
import config from 'configs/app'; import config from 'configs/app';
import * as cookies from 'lib/cookies'; import * as cookies from 'lib/cookies';
import { Image } from 'toolkit/chakra/image';
import IdenticonGithub from 'ui/shared/IdenticonGithub'; import IdenticonGithub from 'ui/shared/IdenticonGithub';
interface IconProps { interface IconProps {
...@@ -17,7 +18,7 @@ const Icon = dynamic( ...@@ -17,7 +18,7 @@ const Icon = dynamic(
switch (type) { switch (type) {
case 'github': { case 'github': {
return (props: IconProps) => <IdenticonGithub size={ props.size } seed={ props.hash }/>; return (props: IconProps) => <IdenticonGithub iconSize={ props.size } seed={ props.hash }/>;
} }
case 'blockie': { case 'blockie': {
......
...@@ -11,7 +11,7 @@ const NetworkMenu = () => { ...@@ -11,7 +11,7 @@ const NetworkMenu = () => {
return ( return (
<PopoverRoot <PopoverRoot
positioning={{ placement: 'bottom-start' }} positioning={{ placement: 'bottom-start', offset: { mainAxis: 6 } }}
lazyMount lazyMount
open={ menu.open } open={ menu.open }
onOpenChange={ menu.onOpenChange } onOpenChange={ menu.onOpenChange }
......
import type { ButtonProps } from '@chakra-ui/react'; import type { ButtonProps } from '@chakra-ui/react';
import { Button, Box, HStack, Tooltip } from '@chakra-ui/react'; import { Box, HStack } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import useIsMobile from 'lib/hooks/useIsMobile'; import useIsMobile from 'lib/hooks/useIsMobile';
import shortenString from 'lib/shortenString'; import shortenString from 'lib/shortenString';
import { Button } from 'toolkit/chakra/button';
import { Tooltip } from 'toolkit/chakra/tooltip';
import UserIdenticon from '../UserIdenticon'; import UserIdenticon from '../UserIdenticon';
interface Props { interface Props {
size?: ButtonProps['size']; size?: ButtonProps['size'];
variant?: ButtonProps['variant']; visual?: ButtonProps['visual'];
onClick?: () => void;
isPending?: boolean; isPending?: boolean;
isAutoConnectDisabled?: boolean; isAutoConnectDisabled?: boolean;
address?: string; address?: string;
domain?: string; domain?: string;
} }
const UserWalletButton = ({ size, variant, onClick, isPending, isAutoConnectDisabled, address, domain }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => { const UserWalletButton = ({ size, visual, isPending, isAutoConnectDisabled, address, domain }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
...@@ -38,24 +39,20 @@ const UserWalletButton = ({ size, variant, onClick, isPending, isAutoConnectDisa ...@@ -38,24 +39,20 @@ const UserWalletButton = ({ size, variant, onClick, isPending, isAutoConnectDisa
return ( return (
<Tooltip <Tooltip
label={ <span>Connect your wallet<br/>to Blockscout for<br/>full-featured access</span> } content={ <span>Connect your wallet<br/>to Blockscout for<br/>full-featured access</span> }
textAlign="center" disabled={ isMobile || Boolean(address) }
padding={ 2 }
isDisabled={ isMobile || Boolean(address) }
openDelay={ 500 } openDelay={ 500 }
> >
<Button <Button
ref={ ref } ref={ ref }
size={ size } size={ size }
variant={ variant } visual={ visual }
onClick={ onClick }
data-selected={ Boolean(address) } data-selected={ Boolean(address) }
data-warning={ isAutoConnectDisabled } data-warning={ isAutoConnectDisabled }
fontSize="sm" textStyle="sm"
lineHeight={ 5 }
px={ address ? 2.5 : 4 } px={ address ? 2.5 : 4 }
fontWeight={ address ? 700 : 600 } fontWeight={ address ? 700 : 600 }
isLoading={ isPending } loading={ isPending }
loadingText={ isMobile ? undefined : 'Connecting' } loadingText={ isMobile ? undefined : 'Connecting' }
> >
{ content } { content }
......
import { PopoverBody, PopoverContent, PopoverTrigger, useDisclosure, type ButtonProps } from '@chakra-ui/react'; import { type ButtonProps } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useMarketplaceContext } from 'lib/contexts/marketplace'; import { useMarketplaceContext } from 'lib/contexts/marketplace';
import useWeb3AccountWithDomain from 'lib/web3/useAccountWithDomain'; import useWeb3AccountWithDomain from 'lib/web3/useAccountWithDomain';
import useWeb3Wallet from 'lib/web3/useWallet'; import useWeb3Wallet from 'lib/web3/useWallet';
import Popover from 'ui/shared/chakra/Popover'; import { PopoverBody, PopoverContent, PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import UserWalletButton from './UserWalletButton'; import UserWalletButton from './UserWalletButton';
import UserWalletMenuContent from './UserWalletMenuContent'; import UserWalletMenuContent from './UserWalletMenuContent';
interface Props { interface Props {
buttonSize?: ButtonProps['size']; buttonSize?: ButtonProps['size'];
buttonVariant?: ButtonProps['variant']; buttonVisual?: ButtonProps['visual'];
} }
// TODO @tom2drum check this component const UserWalletDesktop = ({ buttonSize, buttonVisual = 'header' }: Props) => {
const UserWalletDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => {
const walletMenu = useDisclosure(); const walletMenu = useDisclosure();
const web3Wallet = useWeb3Wallet({ source: 'Header' }); const web3Wallet = useWeb3Wallet({ source: 'Header' });
...@@ -36,13 +36,25 @@ const UserWalletDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => { ...@@ -36,13 +36,25 @@ const UserWalletDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => {
walletMenu.onClose(); walletMenu.onClose();
}, [ web3Wallet, walletMenu ]); }, [ web3Wallet, walletMenu ]);
const handleOpenChange = React.useCallback(({ open }: { open: boolean }) => {
if (!web3Wallet.isConnected) {
web3Wallet.openModal();
return;
}
if (open) {
walletMenu.onOpen();
} else {
walletMenu.onClose();
}
}, [ walletMenu, web3Wallet ]);
return ( return (
<Popover openDelay={ 300 } placement="bottom-end" isLazy isOpen={ walletMenu.isOpen } onClose={ walletMenu.onClose }> <PopoverRoot positioning={{ placement: 'bottom-end' }} lazyMount open={ walletMenu.open } onOpenChange={ handleOpenChange }>
<PopoverTrigger> <PopoverTrigger>
<UserWalletButton <UserWalletButton
size={ buttonSize } size={ buttonSize }
variant={ buttonVariant } visual={ buttonVisual }
onClick={ web3Wallet.isConnected ? walletMenu.onOpen : web3Wallet.openModal }
address={ web3AccountWithDomain.address } address={ web3AccountWithDomain.address }
domain={ web3AccountWithDomain.domain } domain={ web3AccountWithDomain.domain }
isPending={ isPending } isPending={ isPending }
...@@ -63,7 +75,7 @@ const UserWalletDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => { ...@@ -63,7 +75,7 @@ const UserWalletDesktop = ({ buttonSize, buttonVariant = 'header' }: Props) => {
</PopoverBody> </PopoverBody>
</PopoverContent> </PopoverContent>
) } ) }
</Popover> </PopoverRoot>
); );
}; };
......
import { Box, Button, Flex, IconButton, Spinner, Text } from '@chakra-ui/react'; import { Box, Flex, Spinner, Text } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import delay from 'lib/delay'; import delay from 'lib/delay';
import { Button } from 'toolkit/chakra/button';
import { IconButton } from 'toolkit/chakra/icon-button';
import AddressEntity from 'ui/shared/entities/address/AddressEntity'; import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import IconSvg from 'ui/shared/IconSvg'; import IconSvg from 'ui/shared/IconSvg';
...@@ -41,13 +43,13 @@ const UserWalletMenuContent = ({ isAutoConnectDisabled, address, domain, isRecon ...@@ -41,13 +43,13 @@ const UserWalletMenuContent = ({ isAutoConnectDisabled, address, domain, isRecon
{ isReconnecting ? <Spinner size="sm" m="2px" flexShrink={ 0 }/> : ( { isReconnecting ? <Spinner size="sm" m="2px" flexShrink={ 0 }/> : (
<IconButton <IconButton
aria-label="Open wallet" aria-label="Open wallet"
icon={ <IconSvg name="gear_slim" boxSize={ 5 }/> }
variant="simple"
color="icon_info" color="icon_info"
boxSize={ 5 } boxSize={ 5 }
onClick={ handleOpenWalletClick } onClick={ handleOpenWalletClick }
flexShrink={ 0 } flexShrink={ 0 }
/> >
<IconSvg name="gear_slim" boxSize={ 5 }/>
</IconButton>
) } ) }
</Flex> </Flex>
<Button size="sm" width="full" variant="outline" onClick={ onDisconnect } mt={ 6 }> <Button size="sm" width="full" variant="outline" onClick={ onDisconnect } mt={ 6 }>
......
import { Drawer, DrawerBody, DrawerContent, DrawerOverlay, useDisclosure } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import { useMarketplaceContext } from 'lib/contexts/marketplace'; import { useMarketplaceContext } from 'lib/contexts/marketplace';
import useWeb3AccountWithDomain from 'lib/web3/useAccountWithDomain'; import useWeb3AccountWithDomain from 'lib/web3/useAccountWithDomain';
import useWeb3Wallet from 'lib/web3/useWallet'; import useWeb3Wallet from 'lib/web3/useWallet';
import { DrawerTrigger, DrawerRoot, DrawerBackdrop, DrawerContent, DrawerBody } from 'toolkit/chakra/drawer';
import { useDisclosure } from 'toolkit/hooks/useDisclosure';
import UserWalletButton from './UserWalletButton'; import UserWalletButton from './UserWalletButton';
import UserWalletMenuContent from './UserWalletMenuContent'; import UserWalletMenuContent from './UserWalletMenuContent';
...@@ -29,38 +30,48 @@ const UserWalletMobile = () => { ...@@ -29,38 +30,48 @@ const UserWalletMobile = () => {
walletMenu.onClose(); walletMenu.onClose();
}, [ web3Wallet, walletMenu ]); }, [ web3Wallet, walletMenu ]);
const handleOpenChange = React.useCallback(({ open }: { open: boolean }) => {
if (!web3Wallet.isConnected) {
web3Wallet.openModal();
return;
}
if (open) {
walletMenu.onOpen();
} else {
walletMenu.onClose();
}
}, [ walletMenu, web3Wallet ]);
return ( return (
<> <DrawerRoot
<UserWalletButton open={ walletMenu.open }
variant="header" onOpenChange={ handleOpenChange }
onClick={ web3Wallet.isConnected ? walletMenu.onOpen : web3Wallet.openModal } >
address={ web3AccountWithDomain.address } <DrawerBackdrop/>
domain={ web3AccountWithDomain.domain } <DrawerTrigger>
isPending={ isPending } <UserWalletButton
/> visual="header"
{ web3AccountWithDomain.address && ( address={ web3AccountWithDomain.address }
<Drawer domain={ web3AccountWithDomain.domain }
isOpen={ walletMenu.isOpen } isPending={ isPending }
placement="right" />
onClose={ walletMenu.onClose } </DrawerTrigger>
autoFocus={ false } <DrawerContent maxWidth="300px">
> <DrawerBody p={ 6 }>
<DrawerOverlay/> { web3AccountWithDomain.address && (
<DrawerContent maxWidth="300px"> <UserWalletMenuContent
<DrawerBody p={ 6 }> address={ web3AccountWithDomain.address }
<UserWalletMenuContent domain={ web3AccountWithDomain.domain }
address={ web3AccountWithDomain.address } isAutoConnectDisabled={ isAutoConnectDisabled }
domain={ web3AccountWithDomain.domain } isReconnecting={ web3Wallet.isReconnecting }
isAutoConnectDisabled={ isAutoConnectDisabled } onOpenWallet={ handleOpenWalletClick }
isReconnecting={ web3Wallet.isReconnecting } onDisconnect={ handleDisconnectClick }
onOpenWallet={ handleOpenWalletClick } />
onDisconnect={ handleDisconnectClick } ) }
/> </DrawerBody>
</DrawerBody> </DrawerContent>
</DrawerContent> </DrawerRoot>
</Drawer>
) }
</>
); );
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment