Commit 944773f0 authored by tom goriunov's avatar tom goriunov Committed by GitHub

update icon styles for tokens, contract and more (#1204)

* update border radius for token logos and contract icon

* update gaps between icons and text

* update NFT icon and create entity

* update screenshots
parent 2c525b73
<svg viewBox="0 0 20 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.392 1.45c.252-.288.592-.45.948-.45h8.038a.63.63 0 0 1 .474.225L17.54 6.61a.83.83 0 0 1 .196.544v12.308c0 .408-.141.799-.393 1.087-.25.289-.592.451-.947.451H4.34c-.356 0-.696-.162-.948-.45A1.661 1.661 0 0 1 3 19.461V2.538c0-.408.141-.799.392-1.087Zm.948 1.088h6.87v4.497c0 .388.315.702.702.702h4.485v11.725H4.34V2.538Zm8.274.59 2.791 3.205h-2.791V3.128ZM6.5 11a.5.5 0 0 0 0 1h7.2a.5.5 0 0 0 0-1H6.5ZM6 13.9a.5.5 0 0 1 .5-.5h7.2a.5.5 0 1 1 0 1H6.5a.5.5 0 0 1-.5-.5Zm4.5 2.1a.5.5 0 0 0 0 1h3.2a.5.5 0 0 0 0-1h-3.2Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.28 1.352A1.408 1.408 0 0 1 4.34.85h8.038a.78.78 0 0 1 .587.276l4.689 5.385a.98.98 0 0 1 .233.642v12.308c0 .442-.153.869-.43 1.187a1.408 1.408 0 0 1-1.06.502H4.34c-.403 0-.783-.184-1.06-.502a1.811 1.811 0 0 1-.43-1.187V2.538c0-.442.153-.869.43-1.186Zm1.06-.202c-.308 0-.61.14-.834.399a1.511 1.511 0 0 0-.356.99V19.46c0 .375.13.73.356.99.225.258.526.399.834.399h12.057c.309 0 .61-.14.834-.4.226-.259.356-.614.356-.989V7.153a.68.68 0 0 0-.16-.445L12.74 1.323a.48.48 0 0 0-.36-.173H4.34Zm7.02 1.238v4.647c0 .304.248.551.552.551h4.635v12.025H4.19V2.388h7.17Zm-6.87.3v16.623h11.757V7.886h-4.335a.852.852 0 0 1-.852-.851V2.688H4.49Zm7.974.039 3.27 3.756h-3.27V2.727Zm.3.801v2.655h2.312l-2.312-2.655ZM6.5 11.15a.35.35 0 1 0 0 .7h7.2a.35.35 0 1 0 0-.7H6.5Zm-.65.35a.65.65 0 0 1 .65-.65h7.2a.65.65 0 1 1 0 1.3H6.5a.65.65 0 0 1-.65-.65Zm0 2.4a.65.65 0 0 1 .65-.65h7.2a.65.65 0 1 1 0 1.3H6.5a.65.65 0 0 1-.65-.65Zm.65-.35a.35.35 0 1 0 0 .7h7.2a.35.35 0 1 0 0-.7H6.5Zm4 2.6a.35.35 0 1 0 0 .7h3.2a.35.35 0 1 0 0-.7h-3.2Zm-.65.35a.65.65 0 0 1 .65-.65h3.2a.65.65 0 1 1 0 1.3h-3.2a.65.65 0 0 1-.65-.65Z" fill="currentColor"/>
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.392.45C3.644.163 3.984 0 4.34 0h8.038a.63.63 0 0 1 .474.225L17.54 5.61a.83.83 0 0 1 .196.544v12.308c0 .408-.141.799-.393 1.087-.25.289-.592.451-.947.451H4.34c-.356 0-.696-.162-.948-.45A1.661 1.661 0 0 1 3 18.461V1.538c0-.408.141-.799.392-1.087Zm.948 1.088h6.87v4.497c0 .388.315.702.702.702h4.485v11.725H4.34V1.538Zm8.274.59 2.791 3.205h-2.791V2.128ZM6.5 10a.5.5 0 0 0 0 1h7.2a.5.5 0 0 0 0-1H6.5ZM6 12.9a.5.5 0 0 1 .5-.5h7.2a.5.5 0 1 1 0 1H6.5a.5.5 0 0 1-.5-.5Zm4.5 2.1a.5.5 0 0 0 0 1h3.2a.5.5 0 0 0 0-1h-3.2Z" fill="currentColor"/>
</svg>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.868 1.55a.377.377 0 0 0-.378 0L3.188 6.363A.377.377 0 0 0 3 6.69v9.622c0 .135.072.26.188.327l8.302 4.811a.377.377 0 0 0 .378 0l8.302-4.811a.377.377 0 0 0 .188-.327V6.69a.377.377 0 0 0-.188-.327l-8.302-4.811ZM3.755 16.095V6.906l7.924-4.592 7.925 4.592v9.188l-7.925 4.592-7.924-4.592ZM8.66 6.972a.377.377 0 0 0-.754 0v6.354l-1.53-4.587a.377.377 0 0 0-.734.12v5.66a.377.377 0 0 0 .754 0v-3.335l1.529 4.586a.377.377 0 0 0 .735-.12V6.973Zm2.824-2.448a.377.377 0 0 1 .386-.003l2.262 1.32a.377.377 0 0 1-.38.652l-2.07-1.208-1.89 1.145v4.693h2.265a.377.377 0 0 1 0 .754H9.792v4.906a.377.377 0 0 1-.754 0V6.217c0-.132.069-.254.182-.323l2.264-1.37Zm3.195 2.06a.377.377 0 0 1 .515-.141l2.333 1.333a.377.377 0 1 1-.375.655l-.567-.324v7.544a.377.377 0 1 1-.755 0V7.676l-1.01-.578a.377.377 0 0 1-.141-.515Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.24.061a.502.502 0 0 0-.48 0L1.238 5.835A.449.449 0 0 0 1 6.226v11.548c0 .161.09.31.238.391L11.76 23.94a.502.502 0 0 0 .48 0l10.522-5.774a.45.45 0 0 0 .238-.391V6.226a.45.45 0 0 0-.238-.391L12.24.06ZM1.957 17.513V6.487L12 .977l10.044 5.51v11.026L12 23.023l-10.043-5.51ZM8.174 6.566a.466.466 0 0 0-.478-.453.466.466 0 0 0-.479.453v7.625L5.28 8.687a.481.481 0 0 0-.53-.304.461.461 0 0 0-.402.447v6.793c0 .25.214.453.478.453a.466.466 0 0 0 .478-.453V11.62l1.938 5.503c.074.211.299.34.53.304a.461.461 0 0 0 .402-.447V6.566Zm3.578-2.938a.501.501 0 0 1 .49-.003l2.866 1.585a.44.44 0 0 1 .172.619.493.493 0 0 1-.654.163l-2.622-1.45L9.61 5.916v5.631h2.87c.263 0 .478.203.478.453s-.215.453-.479.453h-2.87v5.887c0 .25-.213.452-.478.452a.466.466 0 0 1-.478-.452V5.66c0-.158.088-.305.23-.387l2.87-1.645Zm4.05 2.472a.493.493 0 0 1 .652-.168l2.957 1.6c.23.123.31.4.178.617a.493.493 0 0 1-.652.169l-.72-.39v9.053c0 .25-.214.453-.478.453a.466.466 0 0 1-.478-.453v-9.57l-1.281-.693a.44.44 0 0 1-.178-.618Z" fill="currentColor"/>
</svg>
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.283 14.602a1.13 1.13 0 0 1 1.231-1.024c.62.057 1.081.608 1.024 1.231a7.455 7.455 0 0 1-7.465 6.79c-4.143 0-7.513-3.357-7.513-7.482V9.883c0-4.126 3.37-7.483 7.513-7.483 3.84 0 7.125 2.981 7.48 6.79a1.132 1.132 0 1 1-2.255.208c-.247-2.653-2.542-4.734-5.225-4.734-2.89 0-5.245 2.343-5.245 5.219v4.234c0 2.879 2.351 5.218 5.245 5.218 2.677 0 4.966-2.077 5.21-4.733ZM8.763 9a3.447 3.447 0 0 1 3.32-2.55c1.562 0 2.93 1.05 3.32 2.559a1.135 1.135 0 0 1-.81 1.382 1.135 1.135 0 0 1-1.382-.81 1.165 1.165 0 0 0-1.132-.867c-.527 0-.99.358-1.129.873a1.133 1.133 0 0 1-1.385.8 1.132 1.132 0 0 1-.801-1.387Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.283 14.602a1.13 1.13 0 0 1 1.231-1.024c.62.057 1.081.608 1.024 1.231a7.455 7.455 0 0 1-7.465 6.79c-4.143 0-7.513-3.357-7.513-7.482V9.883c0-4.126 3.37-7.483 7.513-7.483 3.84 0 7.125 2.981 7.48 6.79a1.132 1.132 0 1 1-2.255.208c-.247-2.653-2.542-4.734-5.225-4.734-2.89 0-5.245 2.343-5.245 5.219v4.234c0 2.879 2.351 5.218 5.245 5.218 2.677 0 4.966-2.077 5.21-4.733ZM8.763 9a3.447 3.447 0 0 1 3.32-2.55c1.562 0 2.93 1.05 3.32 2.559a1.135 1.135 0 0 1-.81 1.382 1.135 1.135 0 0 1-1.382-.81 1.165 1.165 0 0 0-1.132-.867c-.527 0-.99.358-1.129.873a1.133 1.133 0 0 1-1.385.8A1.132 1.132 0 0 1 8.764 9Z" fill="currentColor"/>
</svg>
......@@ -228,6 +228,7 @@ const AddressTokenTransfers = ({ scrollRef, overloadCount = OVERLOAD_COUNT }: Pr
name: '',
icon_url: '',
symbol: '',
type: 'ERC-20' as const,
}), [ tokenFilter ]);
const tokenFilterComponent = tokenFilter && (
......
......@@ -30,7 +30,7 @@ const AddressCoinBalanceListItem = (props: Props) => {
<Skeleton isLoaded={ !props.isLoading }>
<Stat flexGrow="0">
<StatHelpText display="flex" mb={ 0 } alignItems="center">
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/>
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' } mr={ 2 }/>
<Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }>
{ deltaBn.dp(8).toFormat() }
</Text>
......
......@@ -56,7 +56,7 @@ const AddressCoinBalanceTableItem = (props: Props) => {
<Skeleton isLoaded={ !props.isLoading }>
<Stat flexGrow="0" lineHeight={ 5 }>
<StatHelpText display="flex" mb={ 0 } alignItems="center">
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' }/>
<StatArrow type={ isPositiveDelta ? 'increase' : 'decrease' } mr={ 2 }/>
<Text as="span" color={ isPositiveDelta ? 'green.500' : 'red.500' } fontWeight={ 600 }>
{ deltaBn.dp(8).toFormat() }
</Text>
......
import { Box, Flex, Link, Text, useColorModeValue, Skeleton } from '@chakra-ui/react';
import { Box, Flex, Text, Link, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import type { AddressTokenBalance } from 'types/api/address';
import { route } from 'nextjs-routes';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import NftMedia from 'ui/shared/nft/NftMedia';
import TruncatedTextTooltip from 'ui/shared/TruncatedTextTooltip';
type Props = AddressTokenBalance & { isLoading: boolean };
......@@ -35,20 +35,7 @@ const NFTItem = ({ token, token_id: tokenId, token_instance: tokenInstance, isLo
{ tokenId && (
<Flex mb={ 2 } ml={ 1 }>
<Text whiteSpace="pre" variant="secondary">ID# </Text>
<TruncatedTextTooltip label={ tokenId }>
<Skeleton isLoaded={ !isLoading } overflow="hidden" h="20px">
<Link
w="100%"
display="inline-block"
whiteSpace="nowrap"
textOverflow="ellipsis"
overflow="hidden"
href={ tokenInstanceLink }
>
{ tokenId }
</Link>
</Skeleton>
</TruncatedTextTooltip>
<NftEntity hash={ token.address } id={ tokenId } isLoading={ isLoading } noIcon/>
</Flex>
) }
<TokenEntity
......
......@@ -315,7 +315,7 @@ const BlockDetails = ({ query }: Props) => {
isLoading={ isPlaceholderData }
>
<Icon as={ flameIcon } boxSize={ 5 } color="gray.500" isLoading={ isPlaceholderData }/>
<Skeleton isLoaded={ !isPlaceholderData } ml={ 1 }>
<Skeleton isLoaded={ !isPlaceholderData } ml={ 2 }>
{ burntFees.dividedBy(WEI).toFixed() } { config.chain.currency.symbol }
</Skeleton>
{ !txFees.isEqualTo(ZERO) && (
......
......@@ -103,7 +103,7 @@ const BlocksListItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
<Flex columnGap={ 4 } mt={ 2 }>
<Flex>
<Icon as={ flameIcon } boxSize={ 5 } color="gray.500" isLoading={ isLoading }/>
<Skeleton isLoaded={ !isLoading } display="inline-block" color="text_secondary" ml={ 1 }>
<Skeleton isLoaded={ !isLoading } display="inline-block" color="text_secondary" ml={ 2 }>
<span>{ burntFees.div(WEI).toFixed() }</span>
</Skeleton>
</Flex>
......
......@@ -111,7 +111,7 @@ const BlocksTableItem = ({ data, isLoading, enableTimeIncrement }: Props) => {
</Td>
{ !config.features.rollup.isEnabled && !config.UI.views.block.hiddenFields?.burnt_fees && (
<Td fontSize="sm">
<Flex alignItems="center" columnGap={ 1 }>
<Flex alignItems="center" columnGap={ 2 }>
<Icon as={ flameIcon } boxSize={ 5 } color={ burntFeesIconColor } isLoading={ isLoading }/>
<Skeleton isLoaded={ !isLoading } display="inline-block">
{ burntFees.dividedBy(WEI).toFixed(8) }
......
......@@ -32,6 +32,7 @@ const nativeTokenData = {
icon_url: '',
symbol: '',
address: '',
type: 'ERC-20' as const,
};
const coinPriceIndicator: TChainIndicator<'homepage_chart_market'> = {
......
......@@ -50,7 +50,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading }: Props) => {
return (
<Flex alignItems="center" overflow="hidden">
<TokenEntity.Icon token={ data } isLoading={ isLoading }/>
<TokenEntity.Icon token={{ ...data, type: data.token_type }} isLoading={ isLoading }/>
<LinkInternal
href={ route({ pathname: '/token/[hash]', query: { hash: data.address } }) }
fontWeight={ 700 }
......
......@@ -51,7 +51,7 @@ const SearchResultTableItem = ({ data, searchTerm, isLoading }: Props) => {
<>
<Td fontSize="sm">
<Flex alignItems="center">
<TokenEntity.Icon token={ data } isLoading={ isLoading }/>
<TokenEntity.Icon token={{ ...data, type: data.token_type }} isLoading={ isLoading }/>
<LinkInternal
href={ route({ pathname: '/token/[hash]', query: { hash: data.address } }) }
fontWeight={ 700 }
......
......@@ -9,12 +9,12 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Icon from 'ui/shared/chakra/Icon';
import Tag from 'ui/shared/chakra/Tag';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import InOutTag from 'ui/shared/InOutTag';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
type Props = TokenTransfer & {
......@@ -66,7 +66,7 @@ const TokenTransferListItem = ({
<TxAdditionalInfo hash={ txHash } isMobile isLoading={ isLoading }/>
) }
</Flex>
{ 'token_id' in total && <TokenTransferNft hash={ token.address } id={ total.token_id } isLoading={ isLoading }/> }
{ 'token_id' in total && <NftEntity hash={ token.address } id={ total.token_id } isLoading={ isLoading }/> }
{ showTxInfo && txHash && (
<Flex justifyContent="space-between" alignItems="center" lineHeight="24px" width="100%">
<TxEntity
......
import { Box, chakra, Skeleton } from '@chakra-ui/react';
import React from 'react';
import { route } from 'nextjs-routes';
import nftPlaceholder from 'icons/nft_shield.svg';
import Icon from 'ui/shared/chakra/Icon';
import HashStringShorten from 'ui/shared/HashStringShorten';
import HashStringShortenDynamic from 'ui/shared/HashStringShortenDynamic';
import LinkInternal from 'ui/shared/LinkInternal';
interface Props {
hash: string;
id: string;
className?: string;
isDisabled?: boolean;
truncation?: 'dynamic' | 'constant';
isLoading?: boolean;
}
const TokenTransferNft = ({ hash, id, className, isDisabled, isLoading, truncation = 'dynamic' }: Props) => {
const Component = isDisabled || isLoading ? Box : LinkInternal;
return (
<Component
href={ isDisabled ? undefined : route({ pathname: '/token/[hash]/instance/[id]', query: { hash, id } }) }
overflow="hidden"
whiteSpace="nowrap"
display="flex"
alignItems="center"
w="100%"
className={ className }
>
<Icon as={ nftPlaceholder } boxSize="30px" color="inherit" isLoading={ isLoading } borderRadius="base"/>
<Skeleton isLoaded={ !isLoading } maxW="calc(100% - 34px)" ml={ 1 }>
{ truncation === 'constant' ? <HashStringShorten hash={ id }/> : <HashStringShortenDynamic hash={ id } fontWeight={ 500 }/> }
</Skeleton>
</Component>
);
};
export default React.memo(chakra(TokenTransferNft));
......@@ -7,11 +7,11 @@ import type { TokenTransfer } from 'types/api/tokenTransfer';
import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Tag from 'ui/shared/chakra/Tag';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import InOutTag from 'ui/shared/InOutTag';
import { getTokenTransferTypeText } from 'ui/shared/TokenTransfer/helpers';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import TxAdditionalInfo from 'ui/txs/TxAdditionalInfo';
type Props = TokenTransfer & {
......@@ -59,7 +59,7 @@ const TokenTransferTableItem = ({
</Flex>
</Td>
<Td>
{ 'token_id' in total && <TokenTransferNft hash={ token.address } id={ total.token_id } isLoading={ isLoading }/> }
{ 'token_id' in total && <NftEntity hash={ token.address } id={ total.token_id } isLoading={ isLoading }/> }
</Td>
{ showTxInfo && txHash && (
<Td>
......
......@@ -17,7 +17,7 @@ const Utilization = ({ className, value, colorScheme = 'green', isLoading }: Pro
const color = colorScheme === 'gray' ? colorGrayScheme : 'green.500';
return (
<Flex className={ className } alignItems="center" columnGap="10px">
<Flex className={ className } alignItems="center" columnGap={ 2 }>
<Skeleton isLoaded={ !isLoading } w={ `${ WIDTH }px` } h="4px" borderRadius="full" overflow="hidden">
<Box bg={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') } h="100%">
<Box bg={ color } w={ valueString } h="100%"/>
......
import { test, expect } from '@playwright/experimental-ct-react';
import React from 'react';
import TestApp from 'playwright/TestApp';
import NftEntity from './NftEntity';
const iconSizes = [ 'md', 'lg' ];
const hash = '0xd789a607CEac2f0E14867de4EB15b15C9FFB5859';
test.use({ viewport: { width: 180, height: 30 } });
test.describe('icon sizes', () => {
iconSizes.forEach((size) => {
test(size, async({ mount }) => {
const component = await mount(
<TestApp>
<NftEntity
hash={ hash }
id={ 1042 }
iconSize={ size }
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
});
});
test('loading', async({ mount }) => {
const component = await mount(
<TestApp>
<NftEntity
hash={ hash }
id={ 1042 }
isLoading
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
test('long id', async({ mount }) => {
const component = await mount(
<TestApp>
<NftEntity
hash={ hash }
id={ 1794350723452223 }
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
test('customization', async({ mount }) => {
const component = await mount(
<TestApp>
<NftEntity
hash={ hash }
id={ 1042 }
p={ 3 }
borderWidth="1px"
borderColor="blue.700"
/>
</TestApp>,
);
await expect(component).toHaveScreenshot();
});
import type { As } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import _omit from 'lodash/omit';
import React from 'react';
import { route } from 'nextjs-routes';
import nftPlaceholder from 'icons/nft_shield.svg';
import * as EntityBase from 'ui/shared/entities/base/components';
import TruncatedValue from 'ui/shared/TruncatedValue';
const Container = EntityBase.Container;
type IconProps = Pick<EntityProps, 'isLoading' | 'noIcon' | 'iconSize'> & {
asProp?: As;
};
const Icon = (props: IconProps) => {
if (props.noIcon) {
return null;
}
return (
<EntityBase.Icon
{ ...props }
iconSize={ props.iconSize ?? 'lg' }
asProp={ props.asProp ?? nftPlaceholder }
/>
);
};
type LinkProps = EntityBase.LinkBaseProps & Pick<EntityProps, 'hash' | 'id'>;
const Link = chakra((props: LinkProps) => {
const defaultHref = route({ pathname: '/token/[hash]/instance/[id]', query: { hash: props.hash, id: props.id } });
return (
<EntityBase.Link
{ ...props }
href={ props.href ?? defaultHref }
>
{ props.children }
</EntityBase.Link>
);
});
type ContentProps = Omit<EntityBase.ContentBaseProps, 'text'> & Pick<EntityProps, 'id'>;
const Content = chakra((props: ContentProps) => {
return (
<TruncatedValue
isLoading={ props.isLoading }
value={ props.id }
/>
);
});
export interface EntityProps extends EntityBase.EntityBaseProps {
hash: string;
id: string;
}
const NftEntity = (props: EntityProps) => {
const linkProps = _omit(props, [ 'className' ]);
const partsProps = _omit(props, [ 'className', 'onClick' ]);
return (
<Container className={ props.className } w="100%">
<Icon { ...partsProps }/>
<Link { ...linkProps }>
<Content { ...partsProps }/>
</Link>
</Container>
);
};
export default React.memo(chakra(NftEntity));
export {
Container,
Link,
Icon,
Content,
};
......@@ -52,6 +52,7 @@ const Icon = (props: IconProps) => {
return (
<Image
{ ...styles }
borderRadius={ props.token.type === 'ERC-20' ? 'full' : 'base' }
className={ props.className }
src={ props.token.icon_url ?? undefined }
alt={ `${ props.token.name || 'token' } logo` }
......@@ -134,7 +135,7 @@ const Copy = (props: CopyProps) => {
const Container = EntityBase.Container;
export interface EntityProps extends EntityBase.EntityBaseProps {
token: Pick<TokenInfo, 'address' | 'icon_url' | 'name' | 'symbol'>;
token: Pick<TokenInfo, 'address' | 'icon_url' | 'name' | 'symbol' | 'type'>;
noSymbol?: boolean;
jointSymbol?: boolean;
onlySymbol?: boolean;
......
......@@ -12,7 +12,7 @@ const FooterLinkItem = ({ icon, iconSize, text, url }: Props) => {
return (
<Link href={ url } display="flex" alignItems="center" h="30px" variant="secondary" target="_blank" fontSize="xs">
{ icon && (
<Center minW={ 6 } mr="6px">
<Center minW={ 6 } mr={ 2 }>
<Icon boxSize={ iconSize || 5 } as={ icon }/>
</Center>
) }
......
......@@ -16,7 +16,7 @@ interface Props {
}
const SearchBarSuggestToken = ({ data, isMobile, searchTerm }: Props) => {
const icon = <TokenEntity.Icon token={ data }/>;
const icon = <TokenEntity.Icon token={{ ...data, type: data.token_type }}/>;
const verifiedIcon = <Icon as={ verifiedToken } boxSize={ 4 } color="green.500" ml={ 1 }/>;
const name = (
<Text
......
......@@ -9,9 +9,9 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Icon from 'ui/shared/chakra/Icon';
import Tag from 'ui/shared/chakra/Tag';
import AddressEntityWithTokenFilter from 'ui/shared/entities/address/AddressEntityWithTokenFilter';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import TruncatedValue from 'ui/shared/TruncatedValue';
type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean };
......@@ -84,10 +84,10 @@ const TokenTransferListItem = ({
</Flex>
) }
{ 'token_id' in total && (token.type === 'ERC-721' || token.type === 'ERC-1155') && (
<TokenTransferNft
<NftEntity
hash={ token.address }
id={ total.token_id }
isDisabled={ Boolean(tokenId && tokenId === total.token_id) }
noLink={ Boolean(tokenId && tokenId === total.token_id) }
isLoading={ isLoading }
/>
) }
......
......@@ -9,8 +9,8 @@ import useTimeAgoIncrement from 'lib/hooks/useTimeAgoIncrement';
import Icon from 'ui/shared/chakra/Icon';
import Tag from 'ui/shared/chakra/Tag';
import AddressEntityWithTokenFilter from 'ui/shared/entities/address/AddressEntityWithTokenFilter';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
type Props = TokenTransfer & { tokenId?: string; isLoading?: boolean }
......@@ -79,11 +79,10 @@ const TokenTransferTableItem = ({
{ (token.type === 'ERC-721' || token.type === 'ERC-1155') && (
<Td>
{ 'token_id' in total ? (
<TokenTransferNft
<NftEntity
hash={ token.address }
id={ total.token_id }
justifyContent={ token.type === 'ERC-721' ? 'end' : 'start' }
isDisabled={ Boolean(tokenId && tokenId === total.token_id) }
noLink={ Boolean(tokenId && tokenId === total.token_id) }
isLoading={ isLoading }
/>
) : ''
......
import { Flex, Link, Text, Icon, Box } from '@chakra-ui/react';
import { Flex, Text } from '@chakra-ui/react';
import React from 'react';
import type { TokenInfo } from 'types/api/token';
import { route } from 'nextjs-routes';
import nftIcon from 'icons/nft_shield.svg';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import HashStringShorten from 'ui/shared/HashStringShorten';
interface Props {
token: TokenInfo;
......@@ -17,20 +14,24 @@ interface Props {
const NftTokenTransferSnippet = ({ value, token, tokenId }: Props) => {
const num = value === '1' ? '' : value;
const url = route({ pathname: '/token/[hash]/instance/[id]', query: { hash: token.address, id: tokenId } });
return (
<Flex alignItems="center" columnGap={ 3 } rowGap={ 2 } flexWrap={{ base: 'wrap', lg: 'nowrap' }}>
<Text fontWeight={ 500 } as="span">For { num } token ID:</Text>
<Box display="inline-flex" alignItems="center">
<Icon as={ nftIcon } boxSize={ 6 } mr={ 1 }/>
<Link href={ url } fontWeight={ 600 } overflow="hidden">
{ tokenId.length > 8 ? <HashStringShorten hash={ tokenId }/> : tokenId }
</Link>
</Box>
<NftEntity
hash={ token.address }
id={ tokenId }
fontWeight={ 600 }
iconSize="md"
maxW={{ base: '100%', lg: '150px' }}
w="auto"
flexShrink={ 0 }
/>
<TokenEntity
token={ token }
noCopy
w="auto"
flexGrow={ 1 }
/>
</Flex>
);
......
......@@ -187,7 +187,7 @@ const TxDetails = () => {
isLoading={ isPlaceholderData }
>
<Icon as={ clockIcon } boxSize={ 5 } color="gray.500" isLoading={ isPlaceholderData }/>
<Skeleton isLoaded={ !isPlaceholderData } ml={ 1 }>{ dayjs(data.timestamp).fromNow() }</Skeleton>
<Skeleton isLoaded={ !isPlaceholderData } ml={ 2 }>{ dayjs(data.timestamp).fromNow() }</Skeleton>
<TextSeparator/>
<Skeleton isLoaded={ !isPlaceholderData } whiteSpace="normal">{ dayjs(data.timestamp).format('llll') }</Skeleton>
<TextSeparator color="gray.500"/>
......@@ -361,7 +361,7 @@ const TxDetails = () => {
currency={ config.chain.currency.symbol }
exchangeRate={ data.exchange_rate }
flexWrap="wrap"
ml={ 1 }
ml={ 2 }
/>
</DetailsInfoItem>
) }
......
import { Flex, Link, Icon, chakra } from '@chakra-ui/react';
import { Flex, Icon, chakra } from '@chakra-ui/react';
import BigNumber from 'bignumber.js';
import React from 'react';
import type { TxAction, TxActionGeneral } from 'types/api/txAction';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import uniswapIcon from 'icons/uniswap.svg';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
interface Props {
......@@ -122,13 +121,12 @@ const TxDetailsAction = ({ action }: Props) => {
<Flex columnGap={ 1 } rowGap={ 2 } pl={ 3 } flexDirection="column" mt={ 2 }>
{
data.ids.map((id: string) => {
const url = route({ pathname: '/token/[hash]/instance/[id]', query: { hash: data.address, id } });
return (
<Flex key={ data.address + id } whiteSpace="pre-wrap">
<span>1 of </span>
<chakra.span color="text_secondary">Token ID [</chakra.span>
<Link href={ url }>{ id }</Link>
<chakra.span color="text_secondary">]</chakra.span>
<chakra.span flexShrink={ 0 }>1 of </chakra.span>
<chakra.span color="text_secondary" flexShrink={ 0 }>Token ID [</chakra.span>
<NftEntity hash={ data.address } id={ id } noIcon w="min-content"/>
<chakra.span color="text_secondary" flexShrink={ 0 }>]</chakra.span>
</Flex>
);
})
......
import { Flex, Link, useBoolean } from '@chakra-ui/react';
import React from 'react';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
interface Props {
items: Array<{total: { token_id: string} }>;
......@@ -15,12 +15,10 @@ const TxStateTokenIdList = ({ items, tokenAddress, isLoading }: Props) => {
return (
<Flex flexDir="column" rowGap={ 2 }>
{ items.slice(0, isCut ? 3 : items.length).map((item, index) => (
<TokenTransferNft
<NftEntity
key={ index }
hash={ tokenAddress }
id={ item.total.token_id }
w="auto"
truncation="constant"
isLoading={ isLoading }
/>
)) }
......
......@@ -9,8 +9,8 @@ import { ZERO_ADDRESS } from 'lib/consts';
import { nbsp, space } from 'lib/html-entities';
import getNetworkValidatorTitle from 'lib/networks/getNetworkValidatorTitle';
import Tag from 'ui/shared/chakra/Tag';
import NftEntity from 'ui/shared/entities/nft/NftEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import TokenTransferNft from 'ui/shared/TokenTransfer/TokenTransferNft';
import TxStateTokenIdList from './TxStateTokenIdList';
......@@ -114,11 +114,9 @@ export function getStateElements(data: TxStateChange, isLoading?: boolean) {
if (!Array.isArray(data.change)) {
if ('token_id' in data && data.token_id) {
return (
<TokenTransferNft
<NftEntity
hash={ data.token.address }
id={ data.token_id }
w="auto"
truncation="constant"
isLoading={ isLoading }
/>
);
......
......@@ -68,7 +68,7 @@ const VerifiedContractsTableItem = ({ data, isLoading }: Props) => {
</chakra.span>
</Tooltip>
<Tooltip label={ isLoading ? undefined : 'Constructor args' }>
<chakra.span display="inline-block" ml={ 3 }>
<chakra.span display="inline-block" ml={ 2 }>
{ data.has_constructor_args ?
<Icon as={ iconCheck } boxSize={ 6 } color="green.500" cursor="pointer" isLoading={ isLoading }/> :
<Icon as={ iconCross } boxSize={ 6 } color="red.600" cursor="pointer" isLoading={ isLoading }/> }
......
......@@ -15,26 +15,25 @@ import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import * as TokenEntity from 'ui/shared/entities/token/TokenEntity';
const WatchListAddressItem = ({ item, isLoading }: { item: WatchlistAddress; isLoading?: boolean }) => {
const infoItemsPaddingLeft = { base: 1, lg: 8 };
const nativeTokenData = React.useMemo(() => ({
name: config.chain.currency.name || '',
icon_url: '',
symbol: '',
address: '',
type: 'ERC-20' as const,
}), [ ]);
const { usdBn: usdNative } = getCurrencyValue({ value: item.address_balance, accuracy: 2, accuracyUsd: 2, exchangeRate: item.exchange_rate });
return (
<VStack spacing={ 2 } align="stretch" fontWeight={ 500 }>
<VStack spacing={ 3 } align="stretch" fontWeight={ 500 }>
<AddressEntity
address={ item.address }
isLoading={ isLoading }
fontWeight="600"
py="2px"
/>
<Flex fontSize="sm" pl={ infoItemsPaddingLeft } flexWrap="wrap" alignItems="center" rowGap={ 1 }>
<Flex fontSize="sm" pl={ 7 } flexWrap="wrap" alignItems="center" rowGap={ 1 }>
<TokenEntity.Icon
token={ nativeTokenData }
isLoading={ isLoading }
......@@ -51,7 +50,7 @@ const WatchListAddressItem = ({ item, isLoading }: { item: WatchlistAddress; isL
</Skeleton>
</Flex>
{ item.tokens_count && (
<HStack spacing={ 2 } fontSize="sm" pl={ infoItemsPaddingLeft }>
<HStack spacing={ 2 } fontSize="sm" pl={ 7 }>
<Icon as={ TokensIcon } boxSize={ 5 } isLoading={ isLoading } borderRadius="sm"/>
<Skeleton isLoaded={ !isLoading } display="inline-flex">
<span>{ `Tokens:${ nbsp }` + item.tokens_count + (item.tokens_overflow ? '+' : '') }</span>
......@@ -60,7 +59,7 @@ const WatchListAddressItem = ({ item, isLoading }: { item: WatchlistAddress; isL
</HStack>
) }
{ item.tokens_fiat_value && (
<HStack spacing={ 2 } fontSize="sm" pl={ infoItemsPaddingLeft }>
<HStack spacing={ 2 } fontSize="sm" pl={ 7 }>
<Icon boxSize={ 5 } as={ WalletIcon } isLoading={ isLoading }/>
<Skeleton isLoaded={ !isLoading } display="inline-flex">
<Text>{ `Net worth:${ nbsp }` }
......
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