Public tags: attributions (#3169)

Resolves #3163
This commit is contained in:
tom goriunov
2025-12-09 13:39:04 +01:00
committed by GitHub
parent 065d2472dc
commit 2e564fad37
7 changed files with 48 additions and 12 deletions
+2
View File
@@ -22,6 +22,8 @@ export default function parseMetaPayload(meta: AddressMetadataTag['meta']): Addr
'tooltipTitle',
'tooltipDescription',
'tooltipUrl',
'tooltipAttribution',
'tooltipAttributionIcon',
'appID',
'appMarketplaceURL',
'appLogoURL',
+2
View File
@@ -62,6 +62,8 @@ export const tagWithTooltip: AddressMetadataTagApi = {
tooltipIcon: 'https://localhost:3100/icon.svg',
tooltipTitle: 'Blockscout team member',
tooltipUrl: 'https://blockscout.com',
tooltipAttribution: 'https://duck.org',
tooltipAttributionIcon: 'https://localhost:3100/icon_sm.svg',
},
};
+2
View File
@@ -27,6 +27,8 @@ export interface AddressMetadataTagApi extends Omit<AddressMetadataTag, 'meta'>
tooltipTitle?: string;
tooltipDescription?: string;
tooltipUrl?: string;
tooltipAttribution?: string;
tooltipAttributionIcon?: string;
appID?: string;
appMarketplaceURL?: string;
appLogoURL?: string;
+1
View File
@@ -44,6 +44,7 @@ test('tag with link and long name +@dark-mode', async({ render }) => {
test('tag with tooltip +@dark-mode', async({ render, page, mockAssetResponse }) => {
await mockAssetResponse(addressMetadataMock.tagWithTooltip.meta?.tooltipIcon as string, './playwright/mocks/image_s.jpg');
await mockAssetResponse(addressMetadataMock.tagWithTooltip.meta?.tooltipAttributionIcon as string, './playwright/mocks/image_md.jpg');
const component = await render(<EntityTag data={ addressMetadataMock.tagWithTooltip }/>);
await component.getByText('BlockscoutHeroes').hover();
await page.getByText('Blockscout team member').waitFor({ state: 'visible' });
+41 -12
View File
@@ -1,4 +1,4 @@
import { chakra, Flex } from '@chakra-ui/react';
import { Box, chakra, Flex, Separator } from '@chakra-ui/react';
import React from 'react';
import type { EntityTag } from './types';
@@ -15,8 +15,23 @@ interface Props {
}
const EntityTagTooltip = ({ data, children }: Props) => {
const hasPopover = Boolean(
data.meta?.tooltipIcon ||
data.meta?.tooltipTitle ||
data.meta?.tooltipDescription ||
data.meta?.tooltipUrl ||
data.meta?.tooltipAttribution,
);
const link = makePrettyLink(data.meta?.tooltipUrl);
const hasPopover = Boolean(data.meta?.tooltipIcon || data.meta?.tooltipTitle || data.meta?.tooltipDescription || data.meta?.tooltipUrl);
const attribution = React.useMemo(() => {
if (!data.meta?.tooltipAttribution) {
return;
}
const link = makePrettyLink(data.meta?.tooltipAttribution);
return link ?? data.meta.tooltipAttribution;
}, [ data.meta?.tooltipAttribution ]);
const handleLinkClick = React.useCallback(() => {
if (!data.meta?.tooltipUrl) {
@@ -36,16 +51,30 @@ const EntityTagTooltip = ({ data, children }: Props) => {
}
const content = (
<Flex textStyle="sm" flexDir="column" rowGap={ 2 } textAlign="left" className="dark">
{ (data.meta?.tooltipIcon || data.meta?.tooltipTitle) && (
<Flex columnGap={ 3 } alignItems="center">
{ data.meta?.tooltipIcon && <Image src={ data.meta.tooltipIcon } boxSize="30px" alt={ `${ data.name } tag logo` }/> }
{ data.meta?.tooltipTitle && <chakra.span fontWeight="600">{ data.meta.tooltipTitle }</chakra.span> }
</Flex>
) }
{ data.meta?.tooltipDescription && <chakra.span>{ data.meta.tooltipDescription }</chakra.span> }
{ link && <Link external href={ link.href } onClick={ handleLinkClick }>{ link.domain }</Link> }
</Flex>
<Box className="dark">
<Flex textStyle="sm" flexDir="column" rowGap={ 2 } textAlign="left" _empty={{ display: 'none' }}>
{ (data.meta?.tooltipIcon || data.meta?.tooltipTitle) && (
<Flex columnGap={ 3 } alignItems="center">
{ data.meta?.tooltipIcon && <Image src={ data.meta.tooltipIcon } boxSize="30px" alt={ `${ data.name } tag logo` }/> }
{ data.meta?.tooltipTitle && <chakra.span fontWeight="600">{ data.meta.tooltipTitle }</chakra.span> }
</Flex>
) }
{ data.meta?.tooltipDescription && <chakra.span>{ data.meta.tooltipDescription }</chakra.span> }
{ link && <Link external href={ link.href } onClick={ handleLinkClick }>{ link.domain }</Link> }
</Flex>
{ attribution ? (
<>
{ (data.meta?.tooltipIcon || data.meta?.tooltipTitle || data.meta?.tooltipDescription || link) && <Separator mt={ 2 } mb={ 1 }/> }
<Flex alignItems="center" color="text.secondary" textStyle="xs">
<chakra.span mr={ 2 }>Source:</chakra.span>
{ data.meta?.tooltipAttributionIcon && <Image src={ data.meta.tooltipAttributionIcon } boxSize={ 4 } mr={ 1 } zIndex={ 1 }/> }
{ typeof attribution === 'string' ?
<chakra.span fontWeight="500">{ attribution }</chakra.span> :
<Link external href={ attribution.href }>{ attribution.domain }</Link> }
</Flex>
</>
) : null }
</Box>
);
return (
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 18 KiB