Commit 3148fc64 authored by tom's avatar tom

public tags styles

parent a86ee441
import { ChakraProvider } from '@chakra-ui/react';
import { GrowthBookProvider } from '@growthbook/growthbook-react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import React from 'react';
......@@ -15,7 +14,7 @@ import { RewardsContextProvider } from 'lib/contexts/rewards';
import { SettingsContextProvider } from 'lib/contexts/settings';
import { SocketProvider } from 'lib/socket/context';
import currentChain from 'lib/web3/currentChain';
import theme from 'theme/theme';
import { Provider as ChakraProvider } from 'toolkit/chakra/provider';
import { port as socketPort } from './utils/socket';
......@@ -72,7 +71,7 @@ const TestApp = ({ children, withSocket, appContext = defaultAppContext, marketp
}));
return (
<ChakraProvider theme={ theme }>
<ChakraProvider>
<QueryClientProvider client={ queryClient }>
<SocketProvider url={ withSocket ? `ws://${ config.app.host }:${ socketPort }` : undefined }>
<AppContextProvider { ...appContext }>
......
......@@ -8,16 +8,30 @@ import IconSvg from 'ui/shared/IconSvg';
import { Skeleton } from './skeleton';
export const LinkExternalIcon = ({ color }: { color?: ChakraLinkProps['color'] }) => (
<IconSvg
name="link_external"
boxSize={ 3 }
verticalAlign="middle"
color={ color ?? 'icon.externalLink' }
_groupHover={{
color: 'inherit',
}}
flexShrink={ 0 }
/>
);
export interface LinkProps extends ChakraLinkProps {
loading?: boolean;
external?: boolean;
scroll?: boolean;
iconColor?: ChakraLinkProps['color'];
noIcon?: boolean;
}
export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
function Link(props, ref) {
const { external, loading, href, children, scroll = true, iconColor, ...rest } = props;
const { external, loading, href, children, scroll = true, iconColor, noIcon, ...rest } = props;
if (external) {
return (
......@@ -27,19 +41,12 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
href={ href }
className="group"
target="_blank"
rel="noopener noreferrer" { ...rest }
rel="noopener noreferrer"
cursor={ href ? 'pointer' : 'default' }
{ ...rest }
>
{ children }
<IconSvg
name="link_external"
boxSize={ 3 }
verticalAlign="middle"
color={ iconColor ?? 'icon.externalLink' }
_groupHover={{
color: 'inherit',
}}
flexShrink={ 0 }
/>
{ !noIcon && <LinkExternalIcon color={ iconColor }/> }
</ChakraLink>
</Skeleton>
);
......@@ -47,7 +54,7 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
return (
<Skeleton loading={ loading } asChild>
<ChakraLink asChild ref={ ref } { ...rest }>
<ChakraLink asChild ref={ ref } cursor={ href ? 'pointer' : 'default' } { ...rest }>
{ href ? <NextLink href={ href as NextLinkProps['href'] } scroll={ scroll }>{ children }</NextLink> : <span>{ children }</span> }
</ChakraLink>
</Skeleton>
......
......@@ -8,6 +8,7 @@ import { Skeleton } from './skeleton';
export interface TagProps extends ChakraTag.RootProps {
startElement?: React.ReactNode;
endElement?: React.ReactNode;
endElementProps?: ChakraTag.EndElementProps;
onClose?: VoidFunction;
closable?: boolean;
truncated?: boolean;
......@@ -19,6 +20,7 @@ export const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
const {
startElement,
endElement,
endElementProps,
onClose,
closable = Boolean(onClose),
children,
......@@ -41,7 +43,7 @@ export const Tag = React.forwardRef<HTMLSpanElement, TagProps>(
) }
{ labelElement }
{ endElement && (
<ChakraTag.EndElement>{ endElement }</ChakraTag.EndElement>
<ChakraTag.EndElement { ...endElementProps }>{ endElement }</ChakraTag.EndElement>
) }
{ closable && (
<ChakraTag.EndElement>
......
......@@ -4,10 +4,16 @@ import type { ExcludeUndefined } from 'types/utils';
const colors: ExcludeUndefined<ThemingConfig['tokens']>['colors'] = {
green: {
'50': { value: '#F0FFF4' },
'100': { value: '#C6F6D5' },
'200': { value: '#9AE6B4' },
'300': { value: '#68D391' },
'400': { value: '#48BB78' },
'500': { value: '#38A169' },
'600': { value: '#25855A' },
'700': { value: '#276749' },
'800': { value: '#22543D' },
'900': { value: '#1C4532' },
},
blue: {
'50': { value: '#EBF8FF' },
......@@ -22,11 +28,40 @@ const colors: ExcludeUndefined<ThemingConfig['tokens']>['colors'] = {
'900': { value: '#1A365D' },
},
red: {
'500': { value: '#E53E3E' },
'50': { value: '#FFF5F5' },
'100': { value: '#FED7D7' },
'200': { value: '#FEB2B2' },
'300': { value: '#FC8181' },
'400': { value: '#F56565' },
'500': { value: '#E53E3E' },
'600': { value: '#C53030' },
'700': { value: '#9B2C2C' },
'800': { value: '#822727' },
'900': { value: '#63171B' },
},
orange: {
'50': { value: '#FFFAF0' },
'100': { value: '#FEEBCB' },
'200': { value: '#FBD38D' },
'300': { value: '#F6AD55' },
'400': { value: '#ED8936' },
'500': { value: '#DD6B20' },
'600': { value: '#C05621' },
'700': { value: '#9C4221' },
'800': { value: '#7B341E' },
'900': { value: '#652B19' },
},
yellow: {
'50': { value: '#FFFFF0' },
'100': { value: '#FEFCBF' },
'200': { value: '#FAF089' },
'300': { value: '#F6E05E' },
'400': { value: '#ECC94B' },
'500': { value: '#D69E2E' },
'600': { value: '#B7791F' },
'700': { value: '#975A16' },
'800': { value: '#744210' },
'900': { value: '#5F370E' },
},
gray: {
'50': { value: '#F7FAFC' },
......@@ -40,8 +75,68 @@ const colors: ExcludeUndefined<ThemingConfig['tokens']>['colors'] = {
'800': { value: '#1A202C' },
'900': { value: '#171923' },
},
teal: {
'50': { value: '#E6FFFA' },
'100': { value: '#B2F5EA' },
'200': { value: '#81E6D9' },
'300': { value: '#4FD1C5' },
'400': { value: '#38B2AC' },
'500': { value: '#319795' },
'600': { value: '#2C7A7B' },
'700': { value: '#285E61' },
'800': { value: '#234E52' },
'900': { value: '#1D4044' },
},
cyan: {
'50': { value: '#EDFDFD' },
'100': { value: '#C4F1F9' },
'200': { value: '#9DECF9' },
'300': { value: '#76E4F7' },
'400': { value: '#0BC5EA' },
'500': { value: '#00B5D8' },
'600': { value: '#00A3C4' },
'700': { value: '#0987A0' },
'800': { value: '#086F83' },
'900': { value: '#065666' },
},
purple: {
'50': { value: '#FAF5FF' },
'100': { value: '#E9D8FD' },
'200': { value: '#D6BCFA' },
'300': { value: '#B794F4' },
'400': { value: '#9F7AEA' },
'500': { value: '#805AD5' },
'600': { value: '#6B46C1' },
'700': { value: '#553C9A' },
'800': { value: '#44337A' },
'900': { value: '#322659' },
},
pink: {
'50': { value: '#FFF5F7' },
'100': { value: '#FED7E2' },
'200': { value: '#FBB6CE' },
'300': { value: '#F687B3' },
'400': { value: '#ED64A6' },
'500': { value: '#D53F8C' },
'600': { value: '#B83280' },
'700': { value: '#97266D' },
'800': { value: '#702459' },
'900': { value: '#521B41' },
},
black: { value: '#101112' },
white: { value: '#ffffff' },
whiteAlpha: {
'50': { value: 'RGBA(16, 17, 18, 0.04)' },
'100': { value: 'RGBA(16, 17, 18, 0.06)' },
'200': { value: 'RGBA(16, 17, 18, 0.08)' },
'300': { value: 'RGBA(16, 17, 18, 0.16)' },
'400': { value: 'RGBA(16, 17, 18, 0.24)' },
'500': { value: 'RGBA(16, 17, 18, 0.36)' },
'600': { value: 'RGBA(16, 17, 18, 0.48)' },
'700': { value: 'RGBA(16, 17, 18, 0.64)' },
'800': { value: 'RGBA(16, 17, 18, 0.80)' },
'900': { value: 'RGBA(16, 17, 18, 0.92)' },
},
blackAlpha: {
'50': { value: 'RGBA(16, 17, 18, 0.04)' },
'100': { value: 'RGBA(16, 17, 18, 0.06)' },
......@@ -54,6 +149,7 @@ const colors: ExcludeUndefined<ThemingConfig['tokens']>['colors'] = {
'800': { value: 'RGBA(16, 17, 18, 0.80)' },
'900': { value: 'RGBA(16, 17, 18, 0.92)' },
},
// BRAND COLORS
github: { value: '#171923' },
telegram: { value: '#2775CA' },
linkedin: { value: '#1564BA' },
......
......@@ -321,6 +321,10 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
tag: {
root: {
subtle: {
bg: { value: { _light: '{colors.blackAlpha.50}', _dark: '{colors.whiteAlpha.100}' } },
fg: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
},
clickable: {
bg: { value: { _light: '{colors.gray.100}', _dark: '{colors.gray.800}' } },
fg: { value: { _light: '{colors.blackAlpha.800}', _dark: '{colors.whiteAlpha.800}' } },
},
......
......@@ -38,6 +38,9 @@ export const recipe = defineSlotRecipe({
},
startElement: {
flexShrink: 0,
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
boxSize: 'var(--tag-element-size)',
ms: 'var(--tag-element-offset)',
'&:has([data-scope=avatar])': {
......@@ -48,6 +51,9 @@ export const recipe = defineSlotRecipe({
},
endElement: {
flexShrink: 0,
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
boxSize: 'var(--tag-element-size)',
me: 'var(--tag-element-offset)',
_icon: { boxSize: '100%' },
......@@ -66,8 +72,8 @@ export const recipe = defineSlotRecipe({
minH: '6',
gap: '1',
'--tag-avatar-size': 'spacing.4',
'--tag-element-size': 'spacing.4',
'--tag-element-offset': '-2px',
'--tag-element-size': 'spacing.3',
'--tag-element-offset': '0px',
},
label: {
textStyle: 'sm',
......@@ -85,6 +91,19 @@ export const recipe = defineSlotRecipe({
},
},
},
clickable: {
root: {
cursor: 'pointer',
bgColor: 'tag.root.clickable.bg',
color: 'tag.root.clickable.fg',
'&:not([data-loading], [aria-busy=true])': {
bgColor: 'tag.root.clickable.bg',
},
_hover: {
opacity: 0.76,
},
},
},
},
},
......
......@@ -3,7 +3,6 @@ import React from 'react';
import { route } from 'nextjs-routes';
import config from 'configs/app';
import { Badge } from 'toolkit/chakra/badge';
import { Link } from 'toolkit/chakra/link';
import { Tag } from 'toolkit/chakra/tag';
import { Tooltip } from 'toolkit/chakra/tooltip';
......@@ -26,9 +25,9 @@ const BlockCeloEpochTag = ({ blockQuery }: Props) => {
undefined;
const content = epochBlockNumber ? (
<Link href={ route({ pathname: '/block/[height_or_hash]', query: { height_or_hash: String(epochBlockNumber) } }) }>
<Tag>Epoch #{ blockQuery.data.celo.epoch_number }</Tag>
<Tag variant="clickable">Epoch #{ blockQuery.data.celo.epoch_number }</Tag>
</Link>
) : <Badge>Epoch #{ blockQuery.data.celo.epoch_number }</Badge>;
) : <Tag>Epoch #{ blockQuery.data.celo.epoch_number }</Tag>;
return (
<Tooltip
......
import { Button, Image, Text, useColorModeValue, chakra } from '@chakra-ui/react';
import { Text, chakra } from '@chakra-ui/react';
import React from 'react';
import type { AddressMetadataTagFormatted } from 'types/client/addressMetadata';
......@@ -7,8 +7,8 @@ import { route } from 'nextjs-routes';
import config from 'configs/app';
import * as mixpanel from 'lib/mixpanel/index';
import LinkExternal from '../links/LinkExternal';
import { Image } from 'toolkit/chakra/image';
import { Link } from 'toolkit/chakra/link';
type Props = {
data: NonNullable<AddressMetadataTagFormatted['meta']>;
......@@ -18,9 +18,6 @@ type Props = {
};
const AppActionButton = ({ data, className, txHash, source }: Props) => {
const defaultTextColor = useColorModeValue('blue.600', 'blue.300');
const defaultBg = useColorModeValue('gray.100', 'gray.700');
const { appID, textColor, bgColor, appActionButtonText, appLogoURL, appMarketplaceURL } = data;
const actionURL = appMarketplaceURL?.replace('{chainId}', config.chain.id || '').replace('{txHash}', txHash || '');
......@@ -47,44 +44,29 @@ const AppActionButton = ({ data, className, txHash, source }: Props) => {
mr={ 2 }
/>
) }
<Text fontSize="sm" fontWeight="500" color="currentColor">
<Text textStyle="sm" fontWeight="500" color="currentColor">
{ appActionButtonText }
</Text>
</>
);
return appID ? (
<Button
className={ className }
as="a"
href={ route({ pathname: '/apps/[id]', query: { id: appID, action: 'connect', ...(actionURL ? { url: actionURL } : {}) } }) }
onClick={ handleClick }
display="flex"
size="sm"
px={ 2 }
color={ textColor || defaultTextColor }
bg={ bgColor || defaultBg }
_hover={{ bg: bgColor, opacity: 0.9 }}
_active={{ bg: bgColor, opacity: 0.9 }}
>
{ content }
</Button>
) : (
<LinkExternal
const isExternal = !appID;
return (
<Link
className={ className }
href={ actionURL }
href={ isExternal ? actionURL : route({ pathname: '/apps/[id]', query: { id: appID, action: 'connect', ...(actionURL ? { url: actionURL } : {}) } }) }
external={ isExternal }
onClick={ handleClick }
variant="subtle"
display="flex"
px={ 2 }
variant="underlaid"
iconColor={ textColor }
color={ textColor }
bg={ bgColor }
_hover={{ color: textColor }}
_active={{ color: textColor }}
_hover={{ color: textColor, opacity: textColor || bgColor ? 0.9 : 1 }}
_active={{ color: textColor, opacity: textColor || bgColor ? 0.9 : 1 }}
>
{ content }
</LinkExternal>
</Link>
);
};
......
import type { ResponsiveValue } from '@chakra-ui/react';
import { chakra, Image, Tag } from '@chakra-ui/react';
import type { HTMLChakraProps } from '@chakra-ui/react';
import { chakra } from '@chakra-ui/react';
import React from 'react';
import type { EntityTag as TEntityTag } from './types';
import Skeleton from 'ui/shared/chakra/Skeleton';
import * as mixpanel from 'lib/mixpanel/index';
import { Image } from 'toolkit/chakra/image';
import { Link, LinkExternalIcon } from 'toolkit/chakra/link';
import { Skeleton } from 'toolkit/chakra/skeleton';
import { Tag } from 'toolkit/chakra/tag';
import IconSvg from 'ui/shared/IconSvg';
import TruncatedValue from 'ui/shared/TruncatedValue';
import EntityTagLink from './EntityTagLink';
import EntityTagPopover from './EntityTagPopover';
import EntityTagTooltip from './EntityTagTooltip';
import { getTagLinkParams } from './utils';
interface Props {
interface Props extends HTMLChakraProps<'span'> {
data: TEntityTag;
isLoading?: boolean;
maxW?: ResponsiveValue<string>;
noLink?: boolean;
}
const EntityTag = ({ data, isLoading, maxW, noLink }: Props) => {
const EntityTag = ({ data, isLoading, noLink, ...rest }: Props) => {
const linkParams = !noLink ? getTagLinkParams(data) : undefined;
const hasLink = Boolean(linkParams);
const iconColor = data.meta?.textColor ?? 'gray.400';
const handleLinkClick = React.useCallback(() => {
if (!linkParams?.href) {
return;
}
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, {
Type: 'Address tag',
Info: data.slug,
URL: linkParams.href,
});
}, [ linkParams?.href, data.slug ]);
if (isLoading) {
return <Skeleton borderRadius="sm" w="100px" h="24px"/>;
return <Skeleton loading borderRadius="sm" w="100px" h="24px"/>;
}
const hasLink = !noLink && Boolean(getTagLinkParams(data));
const iconColor = data.meta?.textColor ?? 'gray.400';
const name = (() => {
if (data.meta?.warpcastHandle) {
return `@${ data.meta.warpcastHandle }`;
......@@ -38,11 +52,19 @@ const EntityTag = ({ data, isLoading, maxW, noLink }: Props) => {
const icon = (() => {
if (data.meta?.tagIcon) {
return <Image boxSize={ 3 } mr={ 1 } flexShrink={ 0 } src={ data.meta.tagIcon } alt={ `${ data.name } icon` }/>;
return <Image boxSize={ 3 } src={ data.meta.tagIcon } alt={ `${ data.name } icon` }/>;
}
if (data.tagType === 'name') {
return <IconSvg name="publictags_slim" boxSize={ 3 } mr={ 1 } flexShrink={ 0 } color={ iconColor }/>;
return <IconSvg name="publictags_slim" boxSize={ 3 } color={ iconColor }/>;
}
return null;
})();
const prefix = (() => {
if (data.meta?.tagIcon) {
return null;
}
if (data.tagType === 'protocol' || data.tagType === 'generic') {
......@@ -53,24 +75,23 @@ const EntityTag = ({ data, isLoading, maxW, noLink }: Props) => {
})();
return (
<EntityTagPopover data={ data }>
<Tag
display="flex"
alignItems="center"
minW={ 0 }
w="fit-content"
maxW={ maxW }
bg={ data.meta?.bgColor }
color={ data.meta?.textColor }
colorScheme={ hasLink ? 'gray-blue' : 'gray' }
_hover={ hasLink ? { opacity: 0.76 } : undefined }
>
<EntityTagLink data={ data } noLink={ noLink }>
{ icon }
<TruncatedValue value={ name } tooltipPlacement="top"/>
</EntityTagLink>
</Tag>
</EntityTagPopover>
<EntityTagTooltip data={ data }>
<Link external={ linkParams?.type === 'external' } href={ linkParams?.href } onClick={ handleLinkClick } noIcon>
<Tag
bg={ data.meta?.bgColor }
color={ data.meta?.textColor }
startElement={ icon }
truncated
endElement={ linkParams?.type === 'external' ? <LinkExternalIcon color={ iconColor }/> : null }
endElementProps={ linkParams?.type === 'external' ? { ml: -1 } : undefined }
_hover={ hasLink ? { opacity: 0.76 } : undefined }
variant={ hasLink ? 'clickable' : 'subtle' }
{ ...rest }
>
{ prefix }{ name }
</Tag>
</Link>
</EntityTagTooltip>
);
};
......
import React from 'react';
import type { EntityTag } from './types';
import * as mixpanel from 'lib/mixpanel/index';
import LinkExternal from 'ui/shared/links/LinkExternal';
import LinkInternal from 'ui/shared/links/LinkInternal';
import { getTagLinkParams } from './utils';
interface Props {
data: EntityTag;
children: React.ReactNode;
noLink?: boolean;
}
const EntityTagLink = ({ data, children, noLink }: Props) => {
const linkParams = !noLink ? getTagLinkParams(data) : undefined;
const handleLinkClick = React.useCallback(() => {
if (!linkParams?.href) {
return;
}
mixpanel.logEvent(mixpanel.EventTypes.PAGE_WIDGET, {
Type: 'Address tag',
Info: data.slug,
URL: linkParams.href,
});
}, [ linkParams?.href, data.slug ]);
const linkProps = {
color: 'inherit',
display: 'inline-flex',
overflow: 'hidden',
_hover: { textDecor: 'none', color: 'inherit' },
onClick: handleLinkClick,
};
if (linkParams?.type === 'internal') {
return (
<LinkInternal
{ ...linkProps }
href={ linkParams.href }
>
{ children }
</LinkInternal>
);
}
if (linkParams?.type === 'external') {
return (
<LinkExternal
{ ...linkProps }
href={ linkParams.href }
iconColor={ data.meta?.textColor }
>
{ children }
</LinkExternal>
);
}
// eslint-disable-next-line react/jsx-no-useless-fragment
return <>{ children }</>;
};
export default React.memo(EntityTagLink);
import { chakra, Image, Flex, PopoverArrow, PopoverBody, PopoverContent, PopoverTrigger, useColorModeValue, DarkMode } from '@chakra-ui/react';
import { chakra, Flex } from '@chakra-ui/react';
import React from 'react';
import type { EntityTag } from './types';
import makePrettyLink from 'lib/makePrettyLink';
import * as mixpanel from 'lib/mixpanel/index';
import Popover from 'ui/shared/chakra/Popover';
import LinkExternal from 'ui/shared/links/LinkExternal';
import { Image } from 'toolkit/chakra/image';
import { Link } from 'toolkit/chakra/link';
import { Tooltip } from 'toolkit/chakra/tooltip';
interface Props {
data: EntityTag;
children: React.ReactNode;
}
const EntityTagPopover = ({ data, children }: Props) => {
const bgColor = useColorModeValue('gray.700', 'gray.900');
const EntityTagTooltip = ({ data, children }: Props) => {
const link = makePrettyLink(data.meta?.tooltipUrl);
const hasPopover = Boolean(data.meta?.tooltipIcon || data.meta?.tooltipTitle || data.meta?.tooltipDescription || data.meta?.tooltipUrl);
......@@ -35,28 +35,24 @@ const EntityTagPopover = ({ data, children }: Props) => {
return <>{ children }</>;
}
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.url } onClick={ handleLinkClick }>{ link.domain }</Link> }
</Flex>
);
return (
<Popover trigger="hover" isLazy gutter={ 8 }>
<PopoverTrigger>
{ children }
</PopoverTrigger>
<PopoverContent bgColor={ bgColor } borderRadius="sm" maxW="280px" w="fit-content">
<PopoverArrow bgColor={ bgColor }/>
<DarkMode>
<PopoverBody color="white" p={ 2 } fontSize="sm" display="flex" flexDir="column" rowGap={ 2 }>
{ (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 && <LinkExternal href={ link.url } onClick={ handleLinkClick }>{ link.domain }</LinkExternal> }
</PopoverBody>
</DarkMode>
</PopoverContent>
</Popover>
<Tooltip content={ content } interactive>
{ children }
</Tooltip>
);
};
export default React.memo(EntityTagPopover);
export default React.memo(EntityTagTooltip);
import { Box, Flex, PopoverBody, PopoverContent, PopoverTrigger, chakra } from '@chakra-ui/react';
import { Box, Flex, chakra } from '@chakra-ui/react';
import React from 'react';
import type { EntityTag as TEntityTag } from './types';
import config from 'configs/app';
import useIsMobile from 'lib/hooks/useIsMobile';
import Popover from 'ui/shared/chakra/Popover';
import Tag from 'ui/shared/chakra/Tag';
import { Badge } from 'toolkit/chakra/badge';
import { PopoverBody, PopoverContent, PopoverRoot, PopoverTrigger } from 'toolkit/chakra/popover';
import EntityTag from './EntityTag';
......@@ -39,20 +39,20 @@ const EntityTags = ({ tags, className, isLoading }: Props) => {
<>
{ tags.slice(0, visibleNum).map((tag) => <EntityTag key={ tag.slug } data={ tag } isLoading={ isLoading } maxW={ tagMaxW }/>) }
{ metaSuitesPlaceholder }
<Popover trigger="click" placement="bottom-start" isLazy>
<PopoverRoot>
<PopoverTrigger>
<Tag isLoading={ isLoading } cursor="pointer" as="button" _hover={{ color: 'link_hovered' }}>
<Badge loading={ isLoading } cursor="pointer" as="button" _hover={{ color: 'link.primary.hover' }}>
+{ tags.length - visibleNum }
</Tag>
</Badge>
</PopoverTrigger>
<PopoverContent maxW="300px" w="auto">
<PopoverBody >
<PopoverContent maxW="300px">
<PopoverBody>
<Flex columnGap={ 2 } rowGap={ 2 } flexWrap="wrap">
{ tags.slice(visibleNum).map((tag) => <EntityTag key={ tag.slug } data={ tag }/>) }
</Flex>
</PopoverBody>
</PopoverContent>
</Popover>
</PopoverRoot>
</>
);
}
......
import React from 'react';
import * as addressMetadataMock from 'mocks/metadata/address';
import { Tag } from 'toolkit/chakra/tag';
import EntityTag from 'ui/shared/EntityTags/EntityTag';
import { Section, Container, SectionHeader, SamplesStack, Sample } from './parts';
import { Section, Container, SectionHeader, SamplesStack, Sample, SectionSubHeader } from './parts';
const TagsShowcase = () => {
// TODO @tom2drum CELO tags, public tags, filtered tags
// TODO @tom2drum filtered tags
return (
<Container value="tags">
<Section>
<SectionHeader>Variant</SectionHeader>
<SamplesStack>
<Sample label="variant: ???">
<Sample label="variant: subtle">
<Tag>My tag</Tag>
</Sample>
<Sample label="variant: clickable">
<Tag variant="clickable">My tag</Tag>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Truncated</SectionHeader>
<SamplesStack>
<Sample label="truncated: true">
<Tag maxW="150px" truncated>Very very very very very looooooonggggg text</Tag>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Loading</SectionHeader>
<SamplesStack>
<Sample label="loading: true">
<Tag loading>My tag</Tag>
<Tag maxW="150px" truncated loading>Very very very very very looooooonggggg text</Tag>
</Sample>
<Sample label="loading: false">
<Tag>My tag</Tag>
<Tag maxW="150px" truncated>Very very very very very looooooonggggg text</Tag>
</Sample>
</SamplesStack>
</Section>
<Section>
<SectionHeader>Examples</SectionHeader>
<SectionSubHeader>Public tags</SectionSubHeader>
<SamplesStack>
<Sample>
<EntityTag data={ addressMetadataMock.nameTag }/>
<EntityTag data={ addressMetadataMock.customNameTag }/>
<EntityTag data={ addressMetadataMock.warpcastTag }/>
<EntityTag data={ addressMetadataMock.genericTag }/>
<EntityTag data={ addressMetadataMock.protocolTag }/>
<EntityTag data={ addressMetadataMock.infoTagWithLink } maxW="150px"/>
<EntityTag data={ addressMetadataMock.tagWithTooltip }/>
<EntityTag data={ addressMetadataMock.nameTag } isLoading/>
</Sample>
</SamplesStack>
<SectionSubHeader>Filter tags</SectionSubHeader>
<span>TODO</span>
</Section>
</Container>
);
};
......
......@@ -9,7 +9,6 @@ import { NOVES_TRANSLATE } from 'stubs/noves/NovesTranslate';
import { TX_INTERPRETATION } from 'stubs/txInterpretation';
import { Link } from 'toolkit/chakra/link';
import AccountActionsMenu from 'ui/shared/AccountActionsMenu/AccountActionsMenu';
// TODO @tom2drum fix app action button
import AppActionButton from 'ui/shared/AppActionButton/AppActionButton';
import useAppActionData from 'ui/shared/AppActionButton/useAppActionData';
import { TX_ACTIONS_BLOCK_ID } from 'ui/shared/DetailsActionsWrapper';
......@@ -138,9 +137,9 @@ const TxSubHeading = ({ hash, hasTag, txQuery }: Props) => {
mt={{ base: 3, lg: 0 }}
>
{ !hasTag && <AccountActionsMenu isLoading={ isLoading }/> }
{ /* { appActionData && (
{ appActionData && (
<AppActionButton data={ appActionData } txHash={ hash } source="Txn"/>
) } */ }
) }
<NetworkExplorers type="tx" pathParam={ hash } ml={{ base: 0, lg: 'auto' }}/>
</Flex>
</Box>
......
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