Skip to content

Commit 0059251

Browse files
authoredApr 1, 2025··
fix: consistent delayed tooltip group behavior (#1683)
1 parent d94afb5 commit 0059251

File tree

3 files changed

+19
-10
lines changed

3 files changed

+19
-10
lines changed
 

‎src/core/primitives/tooltip/tooltip.tsx

+19-8
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ export const Tooltip = forwardRef(function Tooltip(
184184
const tooltipId = useId()
185185
const [isOpen, setIsOpen] = useDelayedState(false)
186186
const delayGroupContext = useTooltipDelayGroup()
187+
const {setIsGroupActive, setOpenTooltipId} = delayGroupContext || {}
187188
const showTooltip = isOpen || delayGroupContext?.openTooltipId === tooltipId
188189

189190
const isInsideGroup = delayGroupContext !== null
@@ -200,15 +201,15 @@ export const Tooltip = forwardRef(function Tooltip(
200201
if (open) {
201202
const groupedOpenDelay = immediate ? 0 : openDelay
202203

203-
delayGroupContext.setIsGroupActive(open, groupedOpenDelay)
204-
delayGroupContext.setOpenTooltipId(tooltipId, groupedOpenDelay)
204+
setIsGroupActive?.(open, groupedOpenDelay)
205+
setOpenTooltipId?.(tooltipId, groupedOpenDelay)
205206
} else {
206207
const minimumGroupDeactivateDelay = 200 // We should provide some delay to allow the user to reach the next tooltip.
207208
const groupDeactivateDelay =
208209
closeDelay > minimumGroupDeactivateDelay ? closeDelay : minimumGroupDeactivateDelay
209210

210-
delayGroupContext.setIsGroupActive(open, groupDeactivateDelay)
211-
delayGroupContext.setOpenTooltipId(null, immediate ? 0 : closeDelay)
211+
setIsGroupActive?.(open, groupDeactivateDelay)
212+
setOpenTooltipId?.(null, immediate ? 0 : closeDelay)
212213
}
213214
} else {
214215
const standaloneDelay = immediate ? 0 : open ? openDelay : closeDelay
@@ -217,7 +218,15 @@ export const Tooltip = forwardRef(function Tooltip(
217218
setIsOpen(open, standaloneDelay)
218219
}
219220
},
220-
[isInsideGroup, delayGroupContext, openDelay, tooltipId, closeDelay, setIsOpen],
221+
[
222+
isInsideGroup,
223+
openDelay,
224+
setIsGroupActive,
225+
setOpenTooltipId,
226+
tooltipId,
227+
closeDelay,
228+
setIsOpen,
229+
],
221230
)
222231

223232
const handleBlur = useCallback(
@@ -264,7 +273,7 @@ export const Tooltip = forwardRef(function Tooltip(
264273
)
265274

266275
// Handle closing the tooltip when the mouse leaves the referenceElement
267-
useCloseOnMouseLeave({handleIsOpenChange, referenceElement, showTooltip})
276+
useCloseOnMouseLeave({handleIsOpenChange, referenceElement, showTooltip, isInsideGroup})
268277

269278
// Close when `disabled` changes to `true`
270279
useEffect(() => {
@@ -416,10 +425,12 @@ function useCloseOnMouseLeave({
416425
handleIsOpenChange,
417426
referenceElement,
418427
showTooltip,
428+
isInsideGroup,
419429
}: {
420430
handleIsOpenChange: (open: boolean, immediate?: boolean) => void
421431
referenceElement: HTMLElement | null
422432
showTooltip: boolean
433+
isInsideGroup: boolean
423434
}) {
424435
// Since we don't want the `mouseevent` events to be attached and removed if the `referenceElement` is changed
425436
// we use a "effect event" (https://19.react.dev/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events)
@@ -441,7 +452,7 @@ function useCloseOnMouseLeave({
441452
// necessary, because the tooltip might not always close as it should (e.g. when clicking
442453
// the reference element triggers a CPU-heavy operation.)
443454
useEffect(() => {
444-
if (!showTooltip) return
455+
if (!showTooltip || isInsideGroup) return
445456

446457
const handleMouseMove = (event: MouseEvent) => {
447458
onMouseMove(event.target, () => window.removeEventListener('mousemove', handleMouseMove))
@@ -450,5 +461,5 @@ function useCloseOnMouseLeave({
450461
window.addEventListener('mousemove', handleMouseMove)
451462

452463
return () => window.removeEventListener('mousemove', handleMouseMove)
453-
}, [showTooltip])
464+
}, [isInsideGroup, showTooltip])
454465
}

‎src/core/primitives/tooltip/tooltipDelayGroup/tooltipDelayGroupProvider.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export function TooltipDelayGroupProvider(
3939

4040
const value: TooltipDelayGroupContextValue = useMemo(
4141
() => ({
42-
isGroupActive: isGroupActive,
4342
setIsGroupActive: setIsGroupActive,
4443
openTooltipId: openTooltipId,
4544
setOpenTooltipId: setOpenTooltipId,

‎src/core/primitives/tooltip/tooltipDelayGroup/types.ts

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* @beta
33
*/
44
export interface TooltipDelayGroupContextValue {
5-
isGroupActive: boolean
65
setIsGroupActive: (nextState: React.SetStateAction<boolean>, delay?: number | undefined) => void
76
setOpenTooltipId: (nextId: string | null, delay?: number | undefined) => void
87
openDelay: number

0 commit comments

Comments
 (0)
Please sign in to comment.