Commit c76664de authored by tom goriunov's avatar tom goriunov Committed by GitHub

Public tags cutoff problem (#2048)

* change max width for tag on mobile

* Public tags cutoff problem

Fixes #2007

* fix tests

* update test
parent f92012f4
......@@ -37,7 +37,7 @@ const PublicTagsSubmitResultSuccess = ({ data }: Props) => {
.map((tag) => (
<EntityTag
key={ tag.name }
truncate
maxW={{ base: '100%', lg: '300px' }}
data={{
...tag,
slug: '',
......
......@@ -58,7 +58,7 @@ const PublicTagsSubmitResultWithErrors = ({ data }: Props) => {
{ item.tags.map((tag) => (
<EntityTag
key={ tag.name }
truncate
maxW={{ base: '100%', lg: '300px' }}
data={{ ...tag, slug: '', ordinal: 0 }}
/>
)) }
......
......@@ -29,7 +29,7 @@ test('protocol tag +@dark-mode', async({ render }) => {
});
test('tag with link and long name +@dark-mode', async({ render }) => {
const component = await render(<EntityTag data={ addressMetadataMock.infoTagWithLink } truncate/>);
const component = await render(<EntityTag data={ addressMetadataMock.infoTagWithLink } maxW="300px"/>);
await expect(component).toHaveScreenshot();
});
......
import type { ResponsiveValue } from '@chakra-ui/react';
import { chakra, Image, Skeleton, Tag } from '@chakra-ui/react';
import React from 'react';
......@@ -13,10 +14,10 @@ import { getTagLinkParams } from './utils';
interface Props {
data: TEntityTag;
isLoading?: boolean;
truncate?: boolean;
maxW?: ResponsiveValue<string>;
}
const EntityTag = ({ data, isLoading, truncate }: Props) => {
const EntityTag = ({ data, isLoading, maxW }: Props) => {
if (isLoading) {
return <Skeleton borderRadius="sm" w="100px" h="24px"/>;
......@@ -55,7 +56,8 @@ const EntityTag = ({ data, isLoading, truncate }: Props) => {
display="flex"
alignItems="center"
minW={ 0 }
maxW={ truncate ? { base: '125px', lg: '300px' } : undefined }
w="fit-content"
maxW={ maxW }
bg={ data.meta?.bgColor }
color={ data.meta?.textColor }
colorScheme={ hasLink ? 'gray-blue' : 'gray' }
......
import React from 'react';
import * as addressMetadataMock from 'mocks/metadata/address';
import { test, expect } from 'playwright/lib';
import EntityTags from './EntityTags';
test('mixed name length +@mobile', async({ render }) => {
const data = [
addressMetadataMock.protocolTagWithMeta,
addressMetadataMock.infoTagWithLink,
addressMetadataMock.genericTag,
addressMetadataMock.tagWithTooltip,
];
const component = await render(<EntityTags tags={ data }/>);
await expect(component).toHaveScreenshot();
});
test('one tag with long name +@mobile -@default', async({ render }) => {
const data = [
addressMetadataMock.infoTagWithLink,
];
const component = await render(<EntityTags tags={ data }/>);
await expect(component).toHaveScreenshot();
});
......@@ -28,10 +28,15 @@ const EntityTags = ({ tags, className, isLoading }: Props) => {
}
const content = (() => {
const tagMaxW = {
base: tags.length === 1 ? '100%' : '60%',
lg: '300px',
};
if (tags.length > visibleNum) {
return (
<>
{ tags.slice(0, visibleNum).map((tag) => <EntityTag key={ tag.slug } data={ tag } isLoading={ isLoading } truncate/>) }
{ tags.slice(0, visibleNum).map((tag) => <EntityTag key={ tag.slug } data={ tag } isLoading={ isLoading } maxW={ tagMaxW }/>) }
{ metaSuitesPlaceholder }
<Popover trigger="click" placement="bottom-start" isLazy>
<PopoverTrigger>
......@@ -53,14 +58,14 @@ const EntityTags = ({ tags, className, isLoading }: Props) => {
return (
<>
{ tags.map((tag) => <EntityTag key={ tag.slug } data={ tag } isLoading={ isLoading } truncate/>) }
{ tags.map((tag) => <EntityTag key={ tag.slug } data={ tag } isLoading={ isLoading } maxW={ tagMaxW }/>) }
{ metaSuitesPlaceholder }
</>
);
})();
return (
<Flex className={ className } columnGap={ 2 } rowGap={ 2 } flexWrap="wrap" alignItems="center" flexGrow={ 1 }>
<Flex className={ className } columnGap={ 2 } rowGap={ 2 } flexWrap="nowrap" alignItems="center" flexGrow={ 1 } maxW="100%">
{ content }
</Flex>
);
......
......@@ -8,7 +8,6 @@ import * as TokenEntity from 'ui/shared/entities/token/TokenEntity';
import EntityTags from 'ui/shared/EntityTags/EntityTags';
import formatUserTags from 'ui/shared/EntityTags/formatUserTags';
import IconSvg from 'ui/shared/IconSvg';
import NetworkExplorers from 'ui/shared/NetworkExplorers';
import PageTitle from '../PageTitle';
......@@ -42,7 +41,6 @@ const LongNameAndManyTags = () => {
] }
flexGrow={ 1 }
/>
<NetworkExplorers type="token" pathParam="token-hash" ml="auto"/>
</>
);
......
import type { PlacementWithLogical } from '@chakra-ui/react';
import { Tooltip } from '@chakra-ui/react';
import { Tooltip, useDisclosure } from '@chakra-ui/react';
import debounce from 'lodash/debounce';
import React from 'react';
import useFontFaceObserver from 'use-font-face-observer';
......@@ -15,6 +15,7 @@ interface Props {
const TruncatedTextTooltip = ({ children, label, placement }: Props) => {
const childRef = React.useRef<HTMLElement>(null);
const [ isTruncated, setTruncated ] = React.useState(false);
const { isOpen, onToggle, onOpen, onClose } = useDisclosure();
const isFontFaceLoaded = useFontFaceObserver([
{ family: BODY_TYPEFACE },
......@@ -55,14 +56,36 @@ const TruncatedTextTooltip = ({ children, label, placement }: Props) => {
// and it is not cleared how to manage case with two or more children
const child = React.Children.only(children) as React.ReactElement & {
ref?: React.Ref<React.ReactNode>;
onClick?: () => void;
onMouseEnter?: () => void;
onMouseLeave?: () => void;
};
const handleClick = React.useCallback((event: React.MouseEvent) => {
event.stopPropagation();
onToggle();
}, [ onToggle ]);
const modifiedChildren = React.cloneElement(
child,
{ ref: childRef },
{
ref: childRef,
onClick: handleClick,
onMouseEnter: onOpen,
onMouseLeave: onClose,
},
);
if (isTruncated) {
return <Tooltip label={ label } maxW={{ base: '100vw', lg: '400px' }} placement={ placement }>{ modifiedChildren }</Tooltip>;
return (
<Tooltip
label={ label }
maxW={{ base: '100vw', lg: '400px' }}
placement={ placement }
isOpen={ isOpen }
>
{ modifiedChildren }
</Tooltip>
);
}
return modifiedChildren;
......
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