Commit 2aa46b22 authored by tom's avatar tom

remove tooltips inside tooltips

parent 63733aa4
...@@ -290,7 +290,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading, addressFormat }: Pr ...@@ -290,7 +290,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading, addressFormat }: Pr
<Grid templateColumns={ templateCols } alignItems="center" gap={ 2 }> <Grid templateColumns={ templateCols } alignItems="center" gap={ 2 }>
<Skeleton loading={ isLoading } overflow="hidden" display="flex" alignItems="center"> <Skeleton loading={ isLoading } overflow="hidden" display="flex" alignItems="center">
<Text whiteSpace="nowrap" overflow="hidden"> <Text whiteSpace="nowrap" overflow="hidden">
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ hash } noTooltip/>
</Text> </Text>
{ data.is_smart_contract_verified && <IconSvg name="status/success" boxSize="14px" color="green.500" ml={ 1 } flexShrink={ 0 }/> } { data.is_smart_contract_verified && <IconSvg name="status/success" boxSize="14px" color="green.500" ml={ 1 } flexShrink={ 0 }/> }
</Skeleton> </Skeleton>
......
...@@ -10,10 +10,13 @@ export interface Props extends Omit<IconButtonProps, 'type' | 'loading'> { ...@@ -10,10 +10,13 @@ export interface Props extends Omit<IconButtonProps, 'type' | 'loading'> {
text: string; text: string;
type?: 'link' | 'text' | 'share'; type?: 'link' | 'text' | 'share';
isLoading?: boolean; isLoading?: boolean;
// Chakra v3 doesn't support tooltip inside tooltip - https://github.com/chakra-ui/chakra-ui/issues/9939#issuecomment-2817168121
// so we disable the copy tooltip manually when the button is inside a tooltip
noTooltip?: boolean;
} }
const CopyToClipboard = (props: Props) => { const CopyToClipboard = (props: Props) => {
const { text, type = 'text', isLoading, onClick, boxSize = 5, ...rest } = props; const { text, type = 'text', isLoading, onClick, boxSize = 5, noTooltip, ...rest } = props;
const { hasCopied, copy, disclosure } = useClipboard(text); const { hasCopied, copy, disclosure } = useClipboard(text);
...@@ -23,18 +26,6 @@ const CopyToClipboard = (props: Props) => { ...@@ -23,18 +26,6 @@ const CopyToClipboard = (props: Props) => {
onClick?.(event); onClick?.(event);
}, [ onClick, copy ]); }, [ onClick, copy ]);
const tooltipContent = (() => {
if (hasCopied) {
return 'Copied';
}
if (type === 'link') {
return 'Copy link to clipboard';
}
return 'Copy to clipboard';
})();
const iconName = (() => { const iconName = (() => {
switch (type) { switch (type) {
case 'link': case 'link':
...@@ -46,14 +37,7 @@ const CopyToClipboard = (props: Props) => { ...@@ -46,14 +37,7 @@ const CopyToClipboard = (props: Props) => {
} }
})(); })();
return ( const button = (
<Tooltip
content={ tooltipContent }
contentProps={{ zIndex: 'tooltip2' }}
open={ disclosure.open }
onOpenChange={ disclosure.onOpenChange }
closeOnPointerDown={ false }
>
<IconButton <IconButton
aria-label="copy" aria-label="copy"
boxSize={ boxSize } boxSize={ boxSize }
...@@ -67,6 +51,33 @@ const CopyToClipboard = (props: Props) => { ...@@ -67,6 +51,33 @@ const CopyToClipboard = (props: Props) => {
> >
<IconSvg name={ iconName }/> <IconSvg name={ iconName }/>
</IconButton> </IconButton>
);
if (noTooltip) {
return button;
}
const tooltipContent = (() => {
if (hasCopied) {
return 'Copied';
}
if (type === 'link') {
return 'Copy link to clipboard';
}
return 'Copy to clipboard';
})();
return (
<Tooltip
content={ tooltipContent }
contentProps={{ zIndex: 'tooltip2' }}
open={ disclosure.open }
onOpenChange={ disclosure.onOpenChange }
closeOnPointerDown={ false }
>
{ button }
</Tooltip> </Tooltip>
); );
}; };
......
...@@ -6,20 +6,26 @@ import { Tooltip } from 'toolkit/chakra/tooltip'; ...@@ -6,20 +6,26 @@ import { Tooltip } from 'toolkit/chakra/tooltip';
interface Props { interface Props {
hash: string; hash: string;
isTooltipDisabled?: boolean; noTooltip?: boolean;
type?: 'long' | 'short'; type?: 'long' | 'short';
as?: React.ElementType; as?: React.ElementType;
} }
const HashStringShorten = ({ hash, isTooltipDisabled, as = 'span', type }: Props) => { const HashStringShorten = ({ hash, noTooltip, as = 'span', type }: Props) => {
const charNumber = type === 'long' ? 16 : 8; const charNumber = type === 'long' ? 16 : 8;
if (hash.length <= charNumber) { if (hash.length <= charNumber) {
return <chakra.span as={ as }>{ hash }</chakra.span>; return <chakra.span as={ as }>{ hash }</chakra.span>;
} }
const content = <chakra.span as={ as }>{ shortenString(hash, charNumber) }</chakra.span>;
if (noTooltip) {
return content;
}
return ( return (
<Tooltip content={ hash } disabled={ isTooltipDisabled }> <Tooltip content={ hash } disabled={ noTooltip }>
<chakra.span as={ as }>{ shortenString(hash, charNumber) }</chakra.span> { content }
</Tooltip> </Tooltip>
); );
}; };
......
...@@ -23,12 +23,12 @@ const HEAD_MIN_LENGTH = 4; ...@@ -23,12 +23,12 @@ const HEAD_MIN_LENGTH = 4;
interface Props { interface Props {
hash: string; hash: string;
fontWeight?: string | number; fontWeight?: string | number;
isTooltipDisabled?: boolean; noTooltip?: boolean;
tailLength?: number; tailLength?: number;
as?: React.ElementType; as?: React.ElementType;
} }
const HashStringShortenDynamic = ({ hash, fontWeight = '400', isTooltipDisabled, tailLength = TAIL_LENGTH, as = 'span' }: Props) => { const HashStringShortenDynamic = ({ hash, fontWeight = '400', noTooltip, tailLength = TAIL_LENGTH, as = 'span' }: Props) => {
const elementRef = useRef<HTMLSpanElement>(null); const elementRef = useRef<HTMLSpanElement>(null);
const [ displayedString, setDisplayedString ] = React.useState(hash); const [ displayedString, setDisplayedString ] = React.useState(hash);
...@@ -93,11 +93,10 @@ const HashStringShortenDynamic = ({ hash, fontWeight = '400', isTooltipDisabled, ...@@ -93,11 +93,10 @@ const HashStringShortenDynamic = ({ hash, fontWeight = '400', isTooltipDisabled,
const content = <chakra.span ref={ elementRef } as={ as }>{ displayedString }</chakra.span>; const content = <chakra.span ref={ elementRef } as={ as }>{ displayedString }</chakra.span>;
const isTruncated = hash.length !== displayedString.length; const isTruncated = hash.length !== displayedString.length;
if (isTruncated) { if (isTruncated && !noTooltip) {
return ( return (
<Tooltip <Tooltip
content={ hash } content={ hash }
disabled={ isTooltipDisabled }
contentProps={{ maxW: { base: 'calc(100vw - 8px)', lg: '400px' } }} contentProps={{ maxW: { base: 'calc(100vw - 8px)', lg: '400px' } }}
> >
{ content } { content }
......
...@@ -25,7 +25,14 @@ const AddressEntityContentProxy = (props: ContentProps) => { ...@@ -25,7 +25,14 @@ const AddressEntityContentProxy = (props: ContentProps) => {
Proxy contract Proxy contract
{ props.address.name ? ` (${ props.address.name })` : '' } { props.address.name ? ` (${ props.address.name })` : '' }
</Box> </Box>
<AddressEntity address={{ hash: props.address.hash, filecoin: props.address.filecoin }} noLink noIcon noHighlight justifyContent="center"/> <AddressEntity
address={{ hash: props.address.hash, filecoin: props.address.filecoin }}
noLink
noIcon
noHighlight
noTooltip
justifyContent="center"
/>
<Box fontWeight={ 600 } mt={ 2 }> <Box fontWeight={ 600 } mt={ 2 }>
Implementation{ implementations.length > 1 ? 's' : '' } Implementation{ implementations.length > 1 ? 's' : '' }
{ implementationName ? ` (${ implementationName })` : '' } { implementationName ? ` (${ implementationName })` : '' }
...@@ -38,10 +45,10 @@ const AddressEntityContentProxy = (props: ContentProps) => { ...@@ -38,10 +45,10 @@ const AddressEntityContentProxy = (props: ContentProps) => {
noLink noLink
noIcon noIcon
noHighlight noHighlight
noTooltip
minW={ `calc((100% - ${ colNum - 1 } * 12px) / ${ colNum })` } minW={ `calc((100% - ${ colNum - 1 } * 12px) / ${ colNum })` }
flex={ 1 } flex={ 1 }
justifyContent={ colNum === 1 ? 'center' : undefined } justifyContent={ colNum === 1 ? 'center' : undefined }
isTooltipDisabled
/> />
)) } )) }
</Flex> </Flex>
...@@ -55,7 +62,7 @@ const AddressEntityContentProxy = (props: ContentProps) => { ...@@ -55,7 +62,7 @@ const AddressEntityContentProxy = (props: ContentProps) => {
{ ...props } { ...props }
truncation={ nameTag || implementationName || props.address.name ? 'tail' : props.truncation } truncation={ nameTag || implementationName || props.address.name ? 'tail' : props.truncation }
text={ nameTag || implementationName || props.address.name || props.altHash || props.address.hash } text={ nameTag || implementationName || props.address.name || props.altHash || props.address.hash }
isTooltipDisabled noTooltip
/> />
</Box> </Box>
</Tooltip> </Tooltip>
......
...@@ -23,7 +23,7 @@ export interface EntityBaseProps { ...@@ -23,7 +23,7 @@ export interface EntityBaseProps {
icon?: EntityIconProps; icon?: EntityIconProps;
isExternal?: boolean; isExternal?: boolean;
isLoading?: boolean; isLoading?: boolean;
isTooltipDisabled?: boolean; noTooltip?: boolean;
noCopy?: boolean; noCopy?: boolean;
noIcon?: boolean; noIcon?: boolean;
noLink?: boolean; noLink?: boolean;
...@@ -112,12 +112,12 @@ const Icon = ({ isLoading, noIcon, variant, name, color, borderRadius, marginRig ...@@ -112,12 +112,12 @@ const Icon = ({ isLoading, noIcon, variant, name, color, borderRadius, marginRig
); );
}; };
export interface ContentBaseProps extends Pick<EntityBaseProps, 'className' | 'isLoading' | 'truncation' | 'tailLength' | 'isTooltipDisabled' | 'variant'> { export interface ContentBaseProps extends Pick<EntityBaseProps, 'className' | 'isLoading' | 'truncation' | 'tailLength' | 'noTooltip' | 'variant'> {
asProp?: React.ElementType; asProp?: React.ElementType;
text: string; text: string;
} }
const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dynamic', tailLength, isTooltipDisabled, variant }: ContentBaseProps) => { const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dynamic', tailLength, noTooltip, variant }: ContentBaseProps) => {
const styles = getContentProps(variant); const styles = getContentProps(variant);
if (truncation === 'tail') { if (truncation === 'tail') {
...@@ -139,7 +139,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna ...@@ -139,7 +139,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
hash={ text } hash={ text }
as={ asProp } as={ asProp }
type="long" type="long"
isTooltipDisabled={ isTooltipDisabled } noTooltip={ noTooltip }
/> />
); );
case 'constant': case 'constant':
...@@ -147,7 +147,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna ...@@ -147,7 +147,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
<HashStringShorten <HashStringShorten
hash={ text } hash={ text }
as={ asProp } as={ asProp }
isTooltipDisabled={ isTooltipDisabled } noTooltip={ noTooltip }
/> />
); );
case 'dynamic': case 'dynamic':
...@@ -156,7 +156,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna ...@@ -156,7 +156,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
hash={ text } hash={ text }
as={ asProp } as={ asProp }
tailLength={ tailLength } tailLength={ tailLength }
isTooltipDisabled={ isTooltipDisabled } noTooltip={ noTooltip }
/> />
); );
case 'none': case 'none':
...@@ -178,7 +178,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna ...@@ -178,7 +178,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
); );
}); });
export type CopyBaseProps = Pick<CopyToClipboardProps, 'isLoading' | 'text'> & Pick<EntityBaseProps, 'noCopy'>; export type CopyBaseProps = Pick<CopyToClipboardProps, 'isLoading' | 'text'> & Pick<EntityBaseProps, 'noCopy' | 'noTooltip'>;
const Copy = ({ noCopy, ...props }: CopyBaseProps) => { const Copy = ({ noCopy, ...props }: CopyBaseProps) => {
if (noCopy) { if (noCopy) {
......
...@@ -80,7 +80,7 @@ const SearchBarSuggest = ({ onClick, onClear }: Props) => { ...@@ -80,7 +80,7 @@ const SearchBarSuggest = ({ onClick, onClear }: Props) => {
> >
{ kw.startsWith('0x') ? ( { kw.startsWith('0x') ? (
<Box overflow="hidden" whiteSpace="nowrap"> <Box overflow="hidden" whiteSpace="nowrap">
<HashStringShortenDynamic hash={ kw } isTooltipDisabled/> <HashStringShortenDynamic hash={ kw } noTooltip/>
</Box> </Box>
) : ) :
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis">{ kw }</Text> <Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis">{ kw }</Text>
......
...@@ -55,7 +55,7 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm, addressFormat }: ...@@ -55,7 +55,7 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm, addressFormat }:
const tagEl = data.type === 'metadata_tag' ? ( const tagEl = data.type === 'metadata_tag' ? (
<SearchResultEntityTag metadata={ data.metadata } searchTerm={ searchTerm } ml={{ base: 0, lg: 'auto' }}/> <SearchResultEntityTag metadata={ data.metadata } searchTerm={ searchTerm } ml={{ base: 0, lg: 'auto' }}/>
) : null; ) : null;
const addressEl = <HashStringShortenDynamic hash={ hash } isTooltipDisabled/>; const addressEl = <HashStringShortenDynamic hash={ hash } noTooltip/>;
if (isMobile) { if (isMobile) {
return ( return (
......
...@@ -12,7 +12,7 @@ const SearchBarSuggestBlob = ({ data }: ItemsProps<SearchResultBlob>) => { ...@@ -12,7 +12,7 @@ const SearchBarSuggestBlob = ({ data }: ItemsProps<SearchResultBlob>) => {
<Flex alignItems="center" minW={ 0 }> <Flex alignItems="center" minW={ 0 }>
<BlobEntity.Icon/> <BlobEntity.Icon/>
<chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }> <chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }>
<HashStringShortenDynamic hash={ data.blob_hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.blob_hash } noTooltip/>
</chakra.mark> </chakra.mark>
</Flex> </Flex>
); );
......
...@@ -33,7 +33,7 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: ItemsProps<Search ...@@ -33,7 +33,7 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: ItemsProps<Search
as={ shouldHighlightHash ? 'mark' : 'span' } as={ shouldHighlightHash ? 'mark' : 'span' }
display="block" display="block"
> >
<HashStringShortenDynamic hash={ data.block_hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.block_hash } noTooltip/>
</Text> </Text>
) : null; ) : null;
const date = !isFutureBlock ? dayjs(data.timestamp).format('llll') : undefined; const date = !isFutureBlock ? dayjs(data.timestamp).format('llll') : undefined;
......
...@@ -32,7 +32,7 @@ const SearchBarSuggestDomain = ({ data, isMobile, searchTerm, addressFormat }: I ...@@ -32,7 +32,7 @@ const SearchBarSuggestDomain = ({ data, isMobile, searchTerm, addressFormat }: I
whiteSpace="nowrap" whiteSpace="nowrap"
color="text.secondary" color="text.secondary"
> >
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ hash } noTooltip/>
</Text> </Text>
); );
......
...@@ -30,7 +30,7 @@ const SearchBarSuggestLabel = ({ data, isMobile, searchTerm, addressFormat }: It ...@@ -30,7 +30,7 @@ const SearchBarSuggestLabel = ({ data, isMobile, searchTerm, addressFormat }: It
whiteSpace="nowrap" whiteSpace="nowrap"
color="text.secondary" color="text.secondary"
> >
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ hash } noTooltip/>
</Text> </Text>
); );
......
...@@ -30,7 +30,7 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm, addressFormat }: It ...@@ -30,7 +30,7 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm, addressFormat }: It
const address = ( const address = (
<Text color="text.secondary" whiteSpace="nowrap" overflow="hidden"> <Text color="text.secondary" whiteSpace="nowrap" overflow="hidden">
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ hash } noTooltip/>
</Text> </Text>
); );
......
...@@ -12,7 +12,7 @@ const SearchBarSuggestTx = ({ data, isMobile }: ItemsProps<SearchResultTx>) => { ...@@ -12,7 +12,7 @@ const SearchBarSuggestTx = ({ data, isMobile }: ItemsProps<SearchResultTx>) => {
const icon = <TxEntity.Icon/>; const icon = <TxEntity.Icon/>;
const hash = ( const hash = (
<chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }> <chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }>
<HashStringShortenDynamic hash={ data.transaction_hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.transaction_hash } noTooltip/>
</chakra.mark> </chakra.mark>
); );
const date = dayjs(data.timestamp).format('llll'); const date = dayjs(data.timestamp).format('llll');
......
...@@ -12,7 +12,7 @@ const SearchBarSuggestUserOp = ({ data, isMobile }: ItemsProps<SearchResultUserO ...@@ -12,7 +12,7 @@ const SearchBarSuggestUserOp = ({ data, isMobile }: ItemsProps<SearchResultUserO
const icon = <UserOpEntity.Icon/>; const icon = <UserOpEntity.Icon/>;
const hash = ( const hash = (
<chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }> <chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }>
<HashStringShortenDynamic hash={ data.user_operation_hash } isTooltipDisabled/> <HashStringShortenDynamic hash={ data.user_operation_hash } noTooltip/>
</chakra.mark> </chakra.mark>
); );
const date = dayjs(data.timestamp).format('llll'); const date = dayjs(data.timestamp).format('llll');
......
...@@ -51,11 +51,11 @@ const UserProfileContentWallet = ({ onClose, className }: Props) => { ...@@ -51,11 +51,11 @@ const UserProfileContentWallet = ({ onClose, className }: Props) => {
<AddressEntity <AddressEntity
address={{ hash: web3AccountWithDomain.address, ens_domain_name: web3AccountWithDomain.domain }} address={{ hash: web3AccountWithDomain.address, ens_domain_name: web3AccountWithDomain.domain }}
isLoading={ web3AccountWithDomain.isLoading } isLoading={ web3AccountWithDomain.isLoading }
isTooltipDisabled
truncation="dynamic" truncation="dynamic"
fontSize="sm" fontSize="sm"
fontWeight={ 500 } fontWeight={ 500 }
noAltHash noAltHash
noTooltip
onClick={ handleAddressClick } onClick={ handleAddressClick }
/> />
{ web3Wallet.isReconnecting ? <Spinner size="sm" m="2px" flexShrink={ 0 }/> : ( { web3Wallet.isReconnecting ? <Spinner size="sm" m="2px" flexShrink={ 0 }/> : (
......
...@@ -35,7 +35,7 @@ const UserWalletMenuContent = ({ isAutoConnectDisabled, address, domain, isRecon ...@@ -35,7 +35,7 @@ const UserWalletMenuContent = ({ isAutoConnectDisabled, address, domain, isRecon
<Flex alignItems="center" columnGap={ 2 } justifyContent="space-between"> <Flex alignItems="center" columnGap={ 2 } justifyContent="space-between">
<AddressEntity <AddressEntity
address={{ hash: address, ens_domain_name: domain }} address={{ hash: address, ens_domain_name: domain }}
isTooltipDisabled noTooltip
truncation="dynamic" truncation="dynamic"
fontSize="sm" fontSize="sm"
fontWeight={ 700 } fontWeight={ 700 }
......
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