Commit b8eb137f authored by tom's avatar tom

collapse long tags row

parent 963aaf40
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
<g fill="currentColor" clip-path="url(#explorer_svg__a)">
<path d="M14.192 5.808a.624.624 0 0 0-.64-.15L7.927 7.531a.625.625 0 0 0-.395.395l-1.875 5.625a.625.625 0 0 0 .79.791l5.626-1.875a.626.626 0 0 0 .395-.395l1.875-5.625a.625.625 0 0 0-.151-.64Zm-6.954 6.954L8.62 8.619l2.762 2.762-4.143 1.38Z"/>
<path d="M10 18.75A8.75 8.75 0 1 1 18.75 10 8.76 8.76 0 0 1 10 18.75ZM10 2.5a7.5 7.5 0 1 0 7.5 7.5A7.509 7.509 0 0 0 10 2.5Z"/>
</g>
<defs>
<clipPath id="explorer_svg__a">
<path fill="currentColor" d="M0 0h20v20H0z"/>
</clipPath>
</defs>
</svg>
......@@ -10,6 +10,7 @@ import iconSuccess from 'icons/status/success.svg';
import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext';
import useContractTabs from 'lib/hooks/useContractTabs';
import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString';
import AddressBlocksValidated from 'ui/address/AddressBlocksValidated';
import AddressCoinBalance from 'ui/address/AddressCoinBalance';
......@@ -39,7 +40,7 @@ const TOKEN_TABS = Object.values(tokenTabsByType);
const AddressPageContent = () => {
const router = useRouter();
const isMobile = useIsMobile();
const appProps = useAppContext();
const tabsScrollRef = React.useRef<HTMLDivElement>(null);
......@@ -98,7 +99,7 @@ const AddressPageContent = () => {
addressQuery.data?.token ? { label: 'token', display_name: 'Token' } : undefined,
] }
contentAfter={
<NetworkExplorers type="address" pathParam={ hash } ml="auto"/>
<NetworkExplorers type="address" pathParam={ hash } ml="auto" hideText={ isMobile }/>
}
/>
);
......
......@@ -106,7 +106,6 @@ const BlockPageContent = () => {
title={ `Block #${ blockQuery.data?.height }` }
backLink={ backLink }
contentAfter={ <NetworkExplorers type="block" pathParam={ height } ml={{ base: 'initial', lg: 'auto' }}/> }
withTextAd
/>
) }
{ blockQuery.isLoading ? <SkeletonTabs/> : (
......
......@@ -236,7 +236,7 @@ const TokenPageContent = () => {
tokenQuery.data ? { label: tokenQuery.data?.type, display_name: tokenQuery.data?.type } : undefined,
] }
contentAfter={
<NetworkExplorers type="token" pathParam={ hashString } ml="auto"/>
<NetworkExplorers type="token" pathParam={ hashString } ml="auto" hideText={ isMobile }/>
}
flexGrow={ 1 }
/>
......
......@@ -5,6 +5,7 @@ import type { RoutedTab } from 'ui/shared/Tabs/types';
import useApiQuery from 'lib/api/useApiQuery';
import { useAppContext } from 'lib/appContext';
import useIsMobile from 'lib/hooks/useIsMobile';
import getQueryParamString from 'lib/router/getQueryParamString';
import TextAd from 'ui/shared/ad/TextAd';
import EntityTags from 'ui/shared/EntityTags';
......@@ -31,6 +32,7 @@ const TABS: Array<RoutedTab> = [
const TransactionPageContent = () => {
const router = useRouter();
const appProps = useAppContext();
const isMobile = useIsMobile();
const hash = getQueryParamString(router.query.hash);
......@@ -44,7 +46,7 @@ const TransactionPageContent = () => {
isLoading={ isPlaceholderData }
tagsBefore={ [ data?.tx_tag ? { label: data.tx_tag, display_name: data.tx_tag } : undefined ] }
contentAfter={
<NetworkExplorers type="tx" pathParam={ hash } ml={{ base: 'initial', lg: 'auto' }}/>
<NetworkExplorers type="tx" pathParam={ hash } ml={{ base: 'initial', lg: 'auto' }} hideText={ isMobile && Boolean(data?.tx_tag) }/>
}
/>
);
......
import { Flex, chakra } from '@chakra-ui/react';
import { Flex, chakra, useDisclosure, Popover, PopoverTrigger, PopoverContent, PopoverBody } from '@chakra-ui/react';
import React from 'react';
import type { UserTags } from 'types/api/addressParams';
import useIsMobile from 'lib/hooks/useIsMobile';
import Tag from 'ui/shared/chakra/Tag';
interface TagData {
......@@ -20,6 +21,9 @@ interface Props {
}
const EntityTags = ({ className, data, tagsBefore = [], tagsAfter = [], isLoading, contentAfter }: Props) => {
const isMobile = useIsMobile();
const { isOpen, onToggle, onClose } = useDisclosure();
const tags = [
...tagsBefore,
...(data?.private_tags || []),
......@@ -27,16 +31,55 @@ const EntityTags = ({ className, data, tagsBefore = [], tagsAfter = [], isLoadin
...(data?.watchlist_names || []),
...tagsAfter,
]
.filter(Boolean)
.map((tag) => <Tag key={ tag.label } isLoading={ isLoading }>{ tag.display_name }</Tag>);
.filter(Boolean);
if (tags.length === 0) {
return null;
}
const content = (() => {
if (isMobile && tags.length > 2) {
return (
<>
{
tags
.slice(0, 2)
.map((tag) => (
<Tag key={ tag.label } isLoading={ isLoading } isTruncated maxW={{ base: '115px', lg: 'initial' }}>
{ tag.display_name }
</Tag>
))
}
<Popover isOpen={ isOpen } onClose={ onClose } placement="bottom-start" isLazy>
<PopoverTrigger>
<Tag onClick={ onToggle }>+{ tags.length - 1 }</Tag>
</PopoverTrigger>
<PopoverContent w="240px">
<PopoverBody >
<Flex columnGap={ 2 } rowGap={ 2 } flexWrap="wrap">
{
tags
.slice(2)
.map((tag) => <Tag key={ tag.label }>{ tag.display_name }</Tag>)
}
</Flex>
</PopoverBody>
</PopoverContent>
</Popover>
</>
);
}
return tags.map((tag) => (
<Tag key={ tag.label } isLoading={ isLoading } isTruncated maxW={{ base: '115px', lg: 'initial' }}>
{ tag.display_name }
</Tag>
));
})();
return (
<Flex className={ className } columnGap={ 2 } rowGap={ 2 } flexWrap="wrap" alignItems="center">
{ tags }
{ content }
{ contentAfter }
</Flex>
);
......
......@@ -5,16 +5,17 @@ import type { NetworkExplorer as TNetworkExplorer } from 'types/networks';
import appConfig from 'configs/app/config';
import arrowIcon from 'icons/arrows/east-mini.svg';
import searchIcon from 'icons/search.svg';
import explorerIcon from 'icons/explorer.svg';
import LinkExternal from 'ui/shared/LinkExternal';
interface Props {
className?: string;
type: keyof TNetworkExplorer['paths'];
pathParam: string;
hideText?: boolean;
}
const NetworkExplorers = ({ className, type, pathParam }: Props) => {
const NetworkExplorers = ({ className, type, pathParam, hideText }: Props) => {
const { isOpen, onToggle, onClose } = useDisclosure();
const explorersLinks = appConfig.network.explorers
......@@ -42,8 +43,8 @@ const NetworkExplorers = ({ className, type, pathParam }: Props) => {
px={ 2 }
h="30px"
>
<Icon as={ searchIcon } boxSize={ 4 } mr={ 1 }/>
<span>Explorers</span>
<Icon as={ explorerIcon } boxSize={ 5 } mr={ hideText ? 0 : 1 }/>
{ !hideText && <span>Explorers</span> }
<Icon as={ arrowIcon } transform={ isOpen ? 'rotate(90deg)' : 'rotate(-90deg)' } transitionDuration="faster" boxSize={ 5 } ml={ 1 }/>
</Button>
</PopoverTrigger>
......
......@@ -8,7 +8,7 @@ interface Props extends TagProps {
isLoading?: boolean;
}
const Tag = ({ isLoading, ...props }: Props) => {
const Tag = ({ isLoading, ...props }: Props, ref: React.ForwardedRef<HTMLButtonElement>) => {
if (props.isTruncated && typeof props.children === 'string') {
if (!props.children) {
......@@ -18,16 +18,16 @@ const Tag = ({ isLoading, ...props }: Props) => {
return (
<Skeleton isLoaded={ !isLoading } display="inline-block" borderRadius="sm" maxW="100%">
<TruncatedTextTooltip label={ props.children }>
<ChakraTag { ...props }/>
<ChakraTag { ...props } ref={ ref }/>
</TruncatedTextTooltip>
</Skeleton>
);
}
return (
<Skeleton isLoaded={ !isLoading } display="inline-block" borderRadius="sm" maxW="100%">
<ChakraTag { ...props }/>
<ChakraTag { ...props } ref={ ref }/>
</Skeleton>
);
};
export default React.memo(Tag);
export default React.memo(React.forwardRef(Tag));
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