Commit 1a268894 authored by Max Alekseenko's avatar Max Alekseenko

rebuild dropdown

parent c1de6710
<svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.339 1.271a4.518 4.518 0 0 1 7.66 3.214 4.524 4.524 0 0 1-1.269 3.18l-.012.013-2.111 2.114a4.402 4.402 0 0 1-.115.11c.325-.488.508-1.112.508-1.9 0-.473-.065-.886-.188-1.246l.485-.485a2.524 2.524 0 0 0-1.796-4.27 2.518 2.518 0 0 0-1.767.704L8.528 3.904a1 1 0 1 1-1.41-1.418l1.21-1.205.01-.01Zm-4.825 4.82a4.524 4.524 0 0 0-.122.117L1.281 8.322l-.013.012a4.524 4.524 0 0 0 3.212 7.664 4.518 4.518 0 0 0 3.18-1.27l.012-.011 1.204-1.205a1 1 0 0 0-1.415-1.414l-1.197 1.198A2.518 2.518 0 0 1 2 11.498a2.524 2.524 0 0 1 .702-1.77l.485-.484A3.859 3.859 0 0 1 3 8c0-.793.185-1.42.514-1.91Z" fill="currentColor" fill-opacity=".8"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.45 10.064V9.051h2.474c.06 0 .116-.026.159-.074a.27.27 0 0 0 .065-.179.27.27 0 0 0-.065-.179.213.213 0 0 0-.16-.074H7.125c-.298 0-.584-.133-.795-.37C6.12 7.936 6 7.614 6 7.278c0-.336.118-.658.33-.895.21-.238.496-.371.794-.371h.45V5h.9v1.013h1.124v1.013H7.124a.213.213 0 0 0-.159.074.27.27 0 0 0-.065.179.27.27 0 0 0 .065.179c.043.047.1.074.16.074h1.799c.298 0 .584.133.795.37.21.238.329.56.329.896 0 .336-.119.658-.33.895-.21.238-.496.371-.794.371h-.45v1.013h-.9v-1.013H6.45Z" fill="currentColor" fill-opacity=".8"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.339 1.271a4.518 4.518 0 0 1 7.66 3.214 4.524 4.524 0 0 1-1.269 3.18l-.012.013-2.111 2.114a4.402 4.402 0 0 1-.115.11c.325-.488.508-1.112.508-1.9 0-.473-.065-.886-.188-1.246l.485-.485a2.524 2.524 0 0 0-1.796-4.27 2.518 2.518 0 0 0-1.767.704L8.528 3.904a1 1 0 1 1-1.41-1.418l1.21-1.205.01-.01Zm-4.825 4.82a4.524 4.524 0 0 0-.122.117L1.281 8.322l-.013.012a4.524 4.524 0 0 0 3.212 7.664 4.518 4.518 0 0 0 3.18-1.27l.012-.011 1.204-1.205a1 1 0 0 0-1.415-1.414l-1.197 1.198A2.518 2.518 0 0 1 2 11.498a2.524 2.524 0 0 1 .702-1.77l.485-.484A3.859 3.859 0 0 1 3 8c0-.793.185-1.42.514-1.91Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.45 10.064V9.051h2.474c.06 0 .116-.026.159-.074a.27.27 0 0 0 .065-.179.27.27 0 0 0-.065-.179.213.213 0 0 0-.16-.074H7.125c-.298 0-.584-.133-.795-.37A1.364 1.364 0 0 1 6 7.278c0-.336.118-.658.33-.895a1.06 1.06 0 0 1 .794-.371h.45V5h.9v1.013h1.124v1.013H7.124a.213.213 0 0 0-.159.074.27.27 0 0 0-.065.179.27.27 0 0 0 .065.179c.043.047.1.074.16.074h1.799c.298 0 .584.133.795.37.21.238.329.56.329.896 0 .336-.119.658-.33.895a1.06 1.06 0 0 1-.794.371h-.45v1.013h-.9v-1.013H6.45Z" fill="currentColor"/>
</svg>
import { Button, Box, Menu, MenuButton, MenuList, MenuItem, Flex } from '@chakra-ui/react';
import { Button, Box, Flex, Popover, PopoverTrigger, PopoverContent, PopoverBody, useDisclosure } from '@chakra-ui/react';
import { useRouter } from 'next/router';
import React from 'react';
import type { Route } from 'nextjs-routes';
import { route } from 'nextjs-routes';
import config from 'configs/app';
......@@ -10,15 +11,14 @@ import getPageType from 'lib/mixpanel/getPageType';
import * as mixpanel from 'lib/mixpanel/index';
import IconSvg from 'ui/shared/IconSvg';
import DeFiDropdownItem from './DeFiDropdownItem';
const feature = config.features.deFi;
function getHrefAndTarget(feature: { url: string } | { dappId: string }) {
return 'url' in feature ? {
href: feature.url,
target: '_blank',
} : {
href: route({ pathname: '/apps/[id]', query: { id: feature.dappId, action: 'connect' } }),
target: '_self',
function getUrl(feature: { url: string } | { dappId: string }): { url?: string; nextRoute?: Route } {
return {
url: 'url' in feature ? feature.url : undefined,
nextRoute: 'dappId' in feature ? { pathname: '/apps/[id]', query: { id: feature.dappId, action: 'connect' } } : undefined,
};
}
......@@ -26,6 +26,7 @@ const DeFiDropdown = () => {
const router = useRouter();
const source = getPageType(router.pathname);
const isMobile = useIsMobile();
const { isOpen, onToggle, onClose } = useDisclosure();
const handleClick = React.useCallback((content: 'Swap button' | 'Payment link') => {
mixpanel.logEvent(mixpanel.EventTypes.BUTTON_CLICK, { Content: content, Source: source });
......@@ -39,24 +40,20 @@ const DeFiDropdown = () => {
const items = [];
if (feature.swapButton) {
const { href, target } = getHrefAndTarget(feature.swapButton);
items.push({
icon: 'swap' as const,
text: 'Swap',
href,
target,
onClick: () => handleClick('Swap button'),
...getUrl(feature.swapButton),
});
}
if (feature.paymentLink) {
const { href, target } = getHrefAndTarget(feature.paymentLink);
items.push({
icon: 'payment_link' as const,
text: 'Payment link',
href,
target,
onClick: () => handleClick('Payment link'),
...getUrl(feature.paymentLink),
});
}
......@@ -77,37 +74,33 @@ const DeFiDropdown = () => {
};
return items.length > 1 ? (
<Menu>
<MenuButton as={ Button } { ...buttonStyles }>
<Flex alignItems="center">
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy>
<PopoverTrigger>
<Button
onClick={ onToggle }
{ ...buttonStyles }
bgColor={ isOpen ? 'blue.400' : undefined }
_active={{ bgColor: 'blue.400' }}
>
{ !isMobile && 'Blockscout' } DeFi
<IconSvg name="arrows/south-mini" boxSize={ 4 } ml={ 1 }/>
</Flex>
</MenuButton>
<MenuList minWidth="160px" zIndex="popover" overflow="hidden" py={ 4 }>
{ items.map((item, index) => (
<MenuItem
key={ index }
as="a"
href={ item.href }
target={ item.target }
onClick={ item.onClick }
height="48px"
px={ 4 }
fontSize="sm"
fontWeight="500"
>
<IconSvg name={ item.icon } boxSize={ 5 } mr={ 3 }/>
<span>{ item.text }</span>
</MenuItem>
)) }
</MenuList>
</Menu>
</Button>
</PopoverTrigger>
<PopoverContent w="auto">
<PopoverBody >
<Flex flexDirection="column" gap={ 1 }>
{ items.map((item, index) => (
<DeFiDropdownItem key={ index } item={ item }/>
)) }
</Flex>
</PopoverBody>
</PopoverContent>
</Popover>
) : (
<Button
as="a"
href={ items[0].href }
target={ items[0].target }
href={ items[0].nextRoute ? route(items[0].nextRoute) : items[0].url }
target={ items[0].nextRoute ? '_self' : '_blank' }
onClick={ items[0].onClick }
{ ...buttonStyles }
>
......
import { Link, Text, HStack, chakra, shouldForwardProp, useColorModeValue } from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react';
import type { Route } from 'nextjs-routes';
import { route } from 'nextjs-routes';
import type { IconName } from 'ui/shared/IconSvg';
import IconSvg from 'ui/shared/IconSvg';
type Props = {
item: {
icon: IconName;
text: string;
nextRoute?: Route;
url?: string;
onClick: () => void;
};
}
const DeFiDropdownItem = ({ item }: Props) => {
const href = item.nextRoute ? route(item.nextRoute) : item.url;
const content = (
<Link
href={ href }
target={ item.nextRoute ? '_self' : '_blank' }
w="100%"
h="34px"
display="flex"
aria-label={ `${ item.text } link` }
whiteSpace="nowrap"
color={ useColorModeValue('blackAlpha.800', 'gray.400') }
onClick={ item.onClick }
_hover={{
'& *': {
color: 'link_hovered',
},
}}
>
<HStack spacing={ 2 } overflow="hidden">
<IconSvg name={ item.icon } boxSize={ 5 }/>
<Text as="span" fontSize="sm">
<span>{ item.text }</span>
{ !item.nextRoute && <IconSvg name="arrows/north-east" boxSize={ 4 } color="text_secondary" verticalAlign="middle"/> }
</Text>
</HStack>
</Link>
);
return item.nextRoute ? (
<NextLink href={ item.nextRoute } passHref legacyBehavior>
{ content }
</NextLink>
) : content;
};
const DeFiDropdownItemChakra = chakra(DeFiDropdownItem, {
shouldForwardProp: (prop) => {
const isChakraProp = !shouldForwardProp(prop);
if (isChakraProp && prop !== 'px') {
return false;
}
return true;
},
});
export default React.memo(DeFiDropdownItemChakra);
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