mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
remove tooltips inside tooltips
This commit is contained in:
@@ -290,7 +290,7 @@ const SearchResultListItem = ({ data, searchTerm, isLoading, addressFormat }: Pr
|
||||
<Grid templateColumns={ templateCols } alignItems="center" gap={ 2 }>
|
||||
<Skeleton loading={ isLoading } overflow="hidden" display="flex" alignItems="center">
|
||||
<Text whiteSpace="nowrap" overflow="hidden">
|
||||
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ hash } noTooltip/>
|
||||
</Text>
|
||||
{ data.is_smart_contract_verified && <IconSvg name="status/success" boxSize="14px" color="green.500" ml={ 1 } flexShrink={ 0 }/> }
|
||||
</Skeleton>
|
||||
|
||||
@@ -10,10 +10,13 @@ export interface Props extends Omit<IconButtonProps, 'type' | 'loading'> {
|
||||
text: string;
|
||||
type?: 'link' | 'text' | 'share';
|
||||
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 { 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);
|
||||
|
||||
@@ -23,6 +26,37 @@ const CopyToClipboard = (props: Props) => {
|
||||
onClick?.(event);
|
||||
}, [ onClick, copy ]);
|
||||
|
||||
const iconName = (() => {
|
||||
switch (type) {
|
||||
case 'link':
|
||||
return 'link';
|
||||
case 'share':
|
||||
return 'share';
|
||||
default:
|
||||
return 'copy';
|
||||
}
|
||||
})();
|
||||
|
||||
const button = (
|
||||
<IconButton
|
||||
aria-label="copy"
|
||||
boxSize={ boxSize }
|
||||
onClick={ handleClick }
|
||||
ml={ 2 }
|
||||
borderRadius="sm"
|
||||
loadingSkeleton={ isLoading }
|
||||
variant="icon_secondary"
|
||||
size="2xs"
|
||||
{ ...rest }
|
||||
>
|
||||
<IconSvg name={ iconName }/>
|
||||
</IconButton>
|
||||
);
|
||||
|
||||
if (noTooltip) {
|
||||
return button;
|
||||
}
|
||||
|
||||
const tooltipContent = (() => {
|
||||
if (hasCopied) {
|
||||
return 'Copied';
|
||||
@@ -35,17 +69,6 @@ const CopyToClipboard = (props: Props) => {
|
||||
return 'Copy to clipboard';
|
||||
})();
|
||||
|
||||
const iconName = (() => {
|
||||
switch (type) {
|
||||
case 'link':
|
||||
return 'link';
|
||||
case 'share':
|
||||
return 'share';
|
||||
default:
|
||||
return 'copy';
|
||||
}
|
||||
})();
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={ tooltipContent }
|
||||
@@ -54,19 +77,7 @@ const CopyToClipboard = (props: Props) => {
|
||||
onOpenChange={ disclosure.onOpenChange }
|
||||
closeOnPointerDown={ false }
|
||||
>
|
||||
<IconButton
|
||||
aria-label="copy"
|
||||
boxSize={ boxSize }
|
||||
onClick={ handleClick }
|
||||
ml={ 2 }
|
||||
borderRadius="sm"
|
||||
loadingSkeleton={ isLoading }
|
||||
variant="icon_secondary"
|
||||
size="2xs"
|
||||
{ ...rest }
|
||||
>
|
||||
<IconSvg name={ iconName }/>
|
||||
</IconButton>
|
||||
{ button }
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,20 +6,26 @@ import { Tooltip } from 'toolkit/chakra/tooltip';
|
||||
|
||||
interface Props {
|
||||
hash: string;
|
||||
isTooltipDisabled?: boolean;
|
||||
noTooltip?: boolean;
|
||||
type?: 'long' | 'short';
|
||||
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;
|
||||
if (hash.length <= charNumber) {
|
||||
return <chakra.span as={ as }>{ hash }</chakra.span>;
|
||||
}
|
||||
|
||||
const content = <chakra.span as={ as }>{ shortenString(hash, charNumber) }</chakra.span>;
|
||||
|
||||
if (noTooltip) {
|
||||
return content;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip content={ hash } disabled={ isTooltipDisabled }>
|
||||
<chakra.span as={ as }>{ shortenString(hash, charNumber) }</chakra.span>
|
||||
<Tooltip content={ hash } disabled={ noTooltip }>
|
||||
{ content }
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -23,12 +23,12 @@ const HEAD_MIN_LENGTH = 4;
|
||||
interface Props {
|
||||
hash: string;
|
||||
fontWeight?: string | number;
|
||||
isTooltipDisabled?: boolean;
|
||||
noTooltip?: boolean;
|
||||
tailLength?: number;
|
||||
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 [ displayedString, setDisplayedString ] = React.useState(hash);
|
||||
|
||||
@@ -93,11 +93,10 @@ const HashStringShortenDynamic = ({ hash, fontWeight = '400', isTooltipDisabled,
|
||||
const content = <chakra.span ref={ elementRef } as={ as }>{ displayedString }</chakra.span>;
|
||||
const isTruncated = hash.length !== displayedString.length;
|
||||
|
||||
if (isTruncated) {
|
||||
if (isTruncated && !noTooltip) {
|
||||
return (
|
||||
<Tooltip
|
||||
content={ hash }
|
||||
disabled={ isTooltipDisabled }
|
||||
contentProps={{ maxW: { base: 'calc(100vw - 8px)', lg: '400px' } }}
|
||||
>
|
||||
{ content }
|
||||
|
||||
@@ -25,7 +25,14 @@ const AddressEntityContentProxy = (props: ContentProps) => {
|
||||
Proxy contract
|
||||
{ props.address.name ? ` (${ props.address.name })` : '' }
|
||||
</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 }>
|
||||
Implementation{ implementations.length > 1 ? 's' : '' }
|
||||
{ implementationName ? ` (${ implementationName })` : '' }
|
||||
@@ -38,10 +45,10 @@ const AddressEntityContentProxy = (props: ContentProps) => {
|
||||
noLink
|
||||
noIcon
|
||||
noHighlight
|
||||
noTooltip
|
||||
minW={ `calc((100% - ${ colNum - 1 } * 12px) / ${ colNum })` }
|
||||
flex={ 1 }
|
||||
justifyContent={ colNum === 1 ? 'center' : undefined }
|
||||
isTooltipDisabled
|
||||
/>
|
||||
)) }
|
||||
</Flex>
|
||||
@@ -55,7 +62,7 @@ const AddressEntityContentProxy = (props: ContentProps) => {
|
||||
{ ...props }
|
||||
truncation={ nameTag || implementationName || props.address.name ? 'tail' : props.truncation }
|
||||
text={ nameTag || implementationName || props.address.name || props.altHash || props.address.hash }
|
||||
isTooltipDisabled
|
||||
noTooltip
|
||||
/>
|
||||
</Box>
|
||||
</Tooltip>
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface EntityBaseProps {
|
||||
icon?: EntityIconProps;
|
||||
isExternal?: boolean;
|
||||
isLoading?: boolean;
|
||||
isTooltipDisabled?: boolean;
|
||||
noTooltip?: boolean;
|
||||
noCopy?: boolean;
|
||||
noIcon?: boolean;
|
||||
noLink?: boolean;
|
||||
@@ -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;
|
||||
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);
|
||||
|
||||
if (truncation === 'tail') {
|
||||
@@ -139,7 +139,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
|
||||
hash={ text }
|
||||
as={ asProp }
|
||||
type="long"
|
||||
isTooltipDisabled={ isTooltipDisabled }
|
||||
noTooltip={ noTooltip }
|
||||
/>
|
||||
);
|
||||
case 'constant':
|
||||
@@ -147,7 +147,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
|
||||
<HashStringShorten
|
||||
hash={ text }
|
||||
as={ asProp }
|
||||
isTooltipDisabled={ isTooltipDisabled }
|
||||
noTooltip={ noTooltip }
|
||||
/>
|
||||
);
|
||||
case 'dynamic':
|
||||
@@ -156,7 +156,7 @@ const Content = chakra(({ className, isLoading, asProp, text, truncation = 'dyna
|
||||
hash={ text }
|
||||
as={ asProp }
|
||||
tailLength={ tailLength }
|
||||
isTooltipDisabled={ isTooltipDisabled }
|
||||
noTooltip={ noTooltip }
|
||||
/>
|
||||
);
|
||||
case 'none':
|
||||
@@ -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) => {
|
||||
if (noCopy) {
|
||||
|
||||
@@ -80,7 +80,7 @@ const SearchBarSuggest = ({ onClick, onClear }: Props) => {
|
||||
>
|
||||
{ kw.startsWith('0x') ? (
|
||||
<Box overflow="hidden" whiteSpace="nowrap">
|
||||
<HashStringShortenDynamic hash={ kw } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ kw } noTooltip/>
|
||||
</Box>
|
||||
) :
|
||||
<Text overflow="hidden" whiteSpace="nowrap" textOverflow="ellipsis">{ kw }</Text>
|
||||
|
||||
@@ -55,7 +55,7 @@ const SearchBarSuggestAddress = ({ data, isMobile, searchTerm, addressFormat }:
|
||||
const tagEl = data.type === 'metadata_tag' ? (
|
||||
<SearchResultEntityTag metadata={ data.metadata } searchTerm={ searchTerm } ml={{ base: 0, lg: 'auto' }}/>
|
||||
) : null;
|
||||
const addressEl = <HashStringShortenDynamic hash={ hash } isTooltipDisabled/>;
|
||||
const addressEl = <HashStringShortenDynamic hash={ hash } noTooltip/>;
|
||||
|
||||
if (isMobile) {
|
||||
return (
|
||||
|
||||
@@ -12,7 +12,7 @@ const SearchBarSuggestBlob = ({ data }: ItemsProps<SearchResultBlob>) => {
|
||||
<Flex alignItems="center" minW={ 0 }>
|
||||
<BlobEntity.Icon/>
|
||||
<chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }>
|
||||
<HashStringShortenDynamic hash={ data.blob_hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ data.blob_hash } noTooltip/>
|
||||
</chakra.mark>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
@@ -33,7 +33,7 @@ const SearchBarSuggestBlock = ({ data, isMobile, searchTerm }: ItemsProps<Search
|
||||
as={ shouldHighlightHash ? 'mark' : 'span' }
|
||||
display="block"
|
||||
>
|
||||
<HashStringShortenDynamic hash={ data.block_hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ data.block_hash } noTooltip/>
|
||||
</Text>
|
||||
) : null;
|
||||
const date = !isFutureBlock ? dayjs(data.timestamp).format('llll') : undefined;
|
||||
|
||||
@@ -32,7 +32,7 @@ const SearchBarSuggestDomain = ({ data, isMobile, searchTerm, addressFormat }: I
|
||||
whiteSpace="nowrap"
|
||||
color="text.secondary"
|
||||
>
|
||||
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ hash } noTooltip/>
|
||||
</Text>
|
||||
);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ const SearchBarSuggestLabel = ({ data, isMobile, searchTerm, addressFormat }: It
|
||||
whiteSpace="nowrap"
|
||||
color="text.secondary"
|
||||
>
|
||||
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ hash } noTooltip/>
|
||||
</Text>
|
||||
);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ const SearchBarSuggestToken = ({ data, isMobile, searchTerm, addressFormat }: It
|
||||
|
||||
const address = (
|
||||
<Text color="text.secondary" whiteSpace="nowrap" overflow="hidden">
|
||||
<HashStringShortenDynamic hash={ hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ hash } noTooltip/>
|
||||
</Text>
|
||||
);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const SearchBarSuggestTx = ({ data, isMobile }: ItemsProps<SearchResultTx>) => {
|
||||
const icon = <TxEntity.Icon/>;
|
||||
const hash = (
|
||||
<chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }>
|
||||
<HashStringShortenDynamic hash={ data.transaction_hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ data.transaction_hash } noTooltip/>
|
||||
</chakra.mark>
|
||||
);
|
||||
const date = dayjs(data.timestamp).format('llll');
|
||||
|
||||
@@ -12,7 +12,7 @@ const SearchBarSuggestUserOp = ({ data, isMobile }: ItemsProps<SearchResultUserO
|
||||
const icon = <UserOpEntity.Icon/>;
|
||||
const hash = (
|
||||
<chakra.mark overflow="hidden" whiteSpace="nowrap" fontWeight={ 700 }>
|
||||
<HashStringShortenDynamic hash={ data.user_operation_hash } isTooltipDisabled/>
|
||||
<HashStringShortenDynamic hash={ data.user_operation_hash } noTooltip/>
|
||||
</chakra.mark>
|
||||
);
|
||||
const date = dayjs(data.timestamp).format('llll');
|
||||
|
||||
@@ -51,11 +51,11 @@ const UserProfileContentWallet = ({ onClose, className }: Props) => {
|
||||
<AddressEntity
|
||||
address={{ hash: web3AccountWithDomain.address, ens_domain_name: web3AccountWithDomain.domain }}
|
||||
isLoading={ web3AccountWithDomain.isLoading }
|
||||
isTooltipDisabled
|
||||
truncation="dynamic"
|
||||
fontSize="sm"
|
||||
fontWeight={ 500 }
|
||||
noAltHash
|
||||
noTooltip
|
||||
onClick={ handleAddressClick }
|
||||
/>
|
||||
{ web3Wallet.isReconnecting ? <Spinner size="sm" m="2px" flexShrink={ 0 }/> : (
|
||||
|
||||
@@ -35,7 +35,7 @@ const UserWalletMenuContent = ({ isAutoConnectDisabled, address, domain, isRecon
|
||||
<Flex alignItems="center" columnGap={ 2 } justifyContent="space-between">
|
||||
<AddressEntity
|
||||
address={{ hash: address, ens_domain_name: domain }}
|
||||
isTooltipDisabled
|
||||
noTooltip
|
||||
truncation="dynamic"
|
||||
fontSize="sm"
|
||||
fontWeight={ 700 }
|
||||
|
||||
Reference in New Issue
Block a user