Commit 8d48fe74 authored by tom's avatar tom

fix the delay behavior of tooltips

parent 55e0f223
...@@ -35,14 +35,30 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>( ...@@ -35,14 +35,30 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
lazyMount = true, lazyMount = true,
unmountOnExit = true, unmountOnExit = true,
triggerProps, triggerProps,
closeDelay, closeDelay = 100,
openDelay = 100,
interactive,
...rest ...rest
} = props; } = props;
const [ open, setOpen ] = React.useState<boolean>(defaultOpen); const [ open, setOpen ] = React.useState<boolean>(defaultOpen);
const timeoutRef = React.useRef<number | null>(null);
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const triggerRef = useClickAway<HTMLButtonElement>(() => setOpen(false));
const handleClickAway = React.useCallback((event: Event) => {
if (interactive) {
const closest = (event.target as HTMLElement)?.closest('.chakra-tooltip__positioner');
if (closest) {
return;
}
}
timeoutRef.current = window.setTimeout(() => {
setOpen(false);
}, closeDelay);
}, [ closeDelay, interactive ]);
const triggerRef = useClickAway<HTMLButtonElement>(handleClickAway);
const handleOpenChange = React.useCallback((details: { open: boolean }) => { const handleOpenChange = React.useCallback((details: { open: boolean }) => {
setOpen(details.open); setOpen(details.open);
...@@ -50,8 +66,25 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>( ...@@ -50,8 +66,25 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
}, [ onOpenChange ]); }, [ onOpenChange ]);
const handleTriggerClick = React.useCallback(() => { const handleTriggerClick = React.useCallback(() => {
if (timeoutRef.current) {
window.clearTimeout(timeoutRef.current);
}
timeoutRef.current = window.setTimeout(() => {
setOpen((prev) => !prev); setOpen((prev) => !prev);
}, [ ]); }, open ? closeDelay : openDelay);
}, [ open, openDelay, closeDelay ]);
const handleContentClick = React.useCallback((event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
}, []);
React.useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
if (disabled || (disableOnMobile && isMobile)) return children; if (disabled || (disableOnMobile && isMobile)) return children;
...@@ -69,22 +102,23 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>( ...@@ -69,22 +102,23 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
return ( return (
<ChakraTooltip.Root <ChakraTooltip.Root
openDelay={ 100 } openDelay={ openDelay }
// FIXME: chakra closes tooltip too fast, so Playwright is not able to make a screenshot of its content // FIXME: chakra closes tooltip too fast, so Playwright is not able to make a screenshot of its content
// so we need to increase the close delay in Playwright environment // so we need to increase the close delay in Playwright environment
closeDelay={ config.app.isPw ? 10_000 : closeDelay ?? 100 } closeDelay={ config.app.isPw ? 10_000 : closeDelay }
open={ open } open={ open }
onOpenChange={ handleOpenChange } onOpenChange={ handleOpenChange }
closeOnClick={ false } closeOnClick={ false }
closeOnPointerDown={ true } closeOnPointerDown={ false }
variant={ variant } variant={ variant }
lazyMount={ lazyMount } lazyMount={ lazyMount }
unmountOnExit={ unmountOnExit } unmountOnExit={ unmountOnExit }
interactive={ interactive }
{ ...rest } { ...rest }
positioning={ positioning } positioning={ positioning }
> >
<ChakraTooltip.Trigger <ChakraTooltip.Trigger
ref={ triggerRef } ref={ open ? triggerRef : null }
asChild asChild
onClick={ isMobile ? handleTriggerClick : undefined } onClick={ isMobile ? handleTriggerClick : undefined }
{ ...triggerProps } { ...triggerProps }
...@@ -95,6 +129,7 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>( ...@@ -95,6 +129,7 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
<ChakraTooltip.Positioner> <ChakraTooltip.Positioner>
<ChakraTooltip.Content <ChakraTooltip.Content
ref={ ref } ref={ ref }
onClick={ interactive ? handleContentClick : undefined }
{ ...(selected ? { 'data-selected': true } : {}) } { ...(selected ? { 'data-selected': true } : {}) }
{ ...contentProps } { ...contentProps }
> >
......
...@@ -11,7 +11,6 @@ import type { ExcludeUndefined } from 'types/utils'; ...@@ -11,7 +11,6 @@ import type { ExcludeUndefined } from 'types/utils';
import { route } from 'nextjs-routes'; import { route } from 'nextjs-routes';
import config from 'configs/app'; import config from 'configs/app';
import { SECOND } from 'lib/consts';
import dayjs from 'lib/date/dayjs'; import dayjs from 'lib/date/dayjs';
import { Link } from 'toolkit/chakra/link'; import { Link } from 'toolkit/chakra/link';
import type { TooltipProps } from 'toolkit/chakra/tooltip'; import type { TooltipProps } from 'toolkit/chakra/tooltip';
...@@ -71,7 +70,6 @@ const GasInfoTooltip = ({ children, data, dataUpdatedAt, placement }: Props) => ...@@ -71,7 +70,6 @@ const GasInfoTooltip = ({ children, data, dataUpdatedAt, placement }: Props) =>
interactive interactive
showArrow={ false } showArrow={ false }
contentProps={{ p: 4, borderRadius: 'md' }} contentProps={{ p: 4, borderRadius: 'md' }}
closeDelay={ SECOND }
> >
{ children } { children }
</Tooltip> </Tooltip>
......
...@@ -15,7 +15,7 @@ const TooltipShowcase = () => { ...@@ -15,7 +15,7 @@ const TooltipShowcase = () => {
<Tooltip content="Tooltip content"> <Tooltip content="Tooltip content">
<span>Default</span> <span>Default</span>
</Tooltip> </Tooltip>
<Tooltip content="Tooltip content"> <Tooltip content="Tooltip content" interactive>
<Utilization value={ 0.5 }/> <Utilization value={ 0.5 }/>
</Tooltip> </Tooltip>
</Sample> </Sample>
......
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