fix(tooltip): tooltip stays open on fast movement (#4482)

* fix(components): fix  tooltip staying open, add keys, fix AnimatePresence

* chore(changeset) add changeset for tooltip retention fix

* chore(changeset) update changeset text based on codebrabbit feedback

* chore(changeset): update changset message

* fix(tooltip): lint

* chore(changeset): update package name

* fix(tooltip): change LazyMotion level, specify keys

* Merge branch 'canary' into pr/4482

* chore(tooltip): clean up code structure

* Merge branch 'canary' into pr/4482

---------

Co-authored-by: աӄա <wingkwong.code@gmail.com>
This commit is contained in:
Connor Elsea 2025-04-04 09:07:19 -05:00 committed by GitHub
parent 51a0808824
commit 1aab518086
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 52 additions and 33 deletions

View File

@ -0,0 +1,5 @@
---
"@heroui/tooltip": patch
---
fix tooltip staying open on fast movement issue (#4301)

View File

@ -62,39 +62,44 @@ const Tooltip = forwardRef<"div", TooltipProps>((props, ref) => {
const {ref: tooltipRef, id, style, ...otherTooltipProps} = getTooltipProps();
const animatedContent = (
<div ref={tooltipRef} id={id} style={style}>
<LazyMotion features={domAnimation}>
<m.div
animate="enter"
exit="exit"
initial="exit"
variants={TRANSITION_VARIANTS.scaleSpring}
{...mergeProps(motionProps, otherTooltipProps)}
style={{
...getTransformOrigins(placement),
}}
>
<Component {...getTooltipContentProps()}>{content}</Component>
</m.div>
</LazyMotion>
<div key={`${id}-tooltip-content`} ref={tooltipRef} id={id} style={style}>
<m.div
key={`${id}-tooltip-inner`}
animate="enter"
exit="exit"
initial="exit"
variants={TRANSITION_VARIANTS.scaleSpring}
{...mergeProps(motionProps, otherTooltipProps)}
style={{
...getTransformOrigins(placement),
}}
>
<Component {...getTooltipContentProps()}>{content}</Component>
</m.div>
</div>
);
return (
<>
{trigger}
{disableAnimation && isOpen ? (
<OverlayContainer portalContainer={portalContainer}>
<div ref={tooltipRef} id={id} style={style} {...otherTooltipProps}>
<Component {...getTooltipContentProps()}>{content}</Component>
</div>
</OverlayContainer>
{disableAnimation ? (
isOpen && (
<OverlayContainer portalContainer={portalContainer}>
<div ref={tooltipRef} id={id} style={style} {...otherTooltipProps}>
<Component {...getTooltipContentProps()}>{content}</Component>
</div>
</OverlayContainer>
)
) : (
<AnimatePresence>
{isOpen ? (
<OverlayContainer portalContainer={portalContainer}>{animatedContent}</OverlayContainer>
) : null}
</AnimatePresence>
<LazyMotion features={domAnimation}>
<AnimatePresence>
{isOpen && (
<OverlayContainer portalContainer={portalContainer}>
{animatedContent}
</OverlayContainer>
)}
</AnimatePresence>
</LazyMotion>
)}
</>
);

View File

@ -157,13 +157,22 @@ const OffsetTemplate = (args: TooltipProps) => (
);
const MultipleTemplate = (args: TooltipProps) => (
<div className="flex gap-2">
<Tooltip {...args} content="Tooltip 1" delay={1000}>
<Button>Hover me (delay 1000ms)</Button>
</Tooltip>
<Tooltip {...args} content="Tooltip 2">
<Button>Then hover me</Button>
</Tooltip>
<div className="flex flex-col gap-5">
<div className="flex gap-2">
<Tooltip {...args} content="Tooltip 1" delay={1000}>
<Button>Hover me (delay 1000ms)</Button>
</Tooltip>
<Tooltip {...args} content="Tooltip 2">
<Button>Then hover me</Button>
</Tooltip>
</div>
<div className="grid grid-cols-3 gap-2">
{Array.from({length: 21}).map((_, index) => (
<Tooltip {...args} key={index} closeDelay={0} content={`Tooltip ${index}`} openDelay={0}>
<Button>Hover me</Button>
</Tooltip>
))}
</div>
</div>
);