@@ -146,14 +146,18 @@ export type TooltipProps = React.PropsWithChildren<
146
146
> &
147
147
React . HTMLAttributes < HTMLElement >
148
148
149
- type TriggerPropsType = {
150
- 'aria-describedby' ?: string
151
- 'aria-labelledby' ?: string
152
- 'aria-label' ?: string
153
- onBlur ?: React . FocusEventHandler
154
- onFocus ?: React . FocusEventHandler
155
- onMouseEnter ?: React . MouseEventHandler
156
- onMouseLeave ?: React . MouseEventHandler
149
+ type TriggerPropsType = Pick <
150
+ React . HTMLAttributes < HTMLElement > ,
151
+ | 'aria-describedby'
152
+ | 'aria-labelledby'
153
+ | 'onBlur'
154
+ | 'onTouchEnd'
155
+ | 'onFocus'
156
+ | 'onMouseOverCapture'
157
+ | 'onMouseLeave'
158
+ | 'onTouchCancel'
159
+ | 'onTouchEnd'
160
+ > & {
157
161
ref ?: React . RefObject < HTMLElement >
158
162
}
159
163
@@ -214,7 +218,7 @@ export const Tooltip = React.forwardRef(
214
218
215
219
const [ isPopoverOpen , setIsPopoverOpen ] = useState ( false )
216
220
217
- const timeoutRef = React . useRef < number | null > ( null )
221
+ const openTimeoutRef = React . useRef < number | null > ( null )
218
222
219
223
const { safeSetTimeout, safeClearTimeout} = useSafeTimeout ( )
220
224
@@ -261,6 +265,10 @@ export const Tooltip = React.forwardRef(
261
265
}
262
266
}
263
267
const closeTooltip = ( ) => {
268
+ if ( openTimeoutRef . current ) {
269
+ safeClearTimeout ( openTimeoutRef . current )
270
+ openTimeoutRef . current = null
271
+ }
264
272
try {
265
273
if (
266
274
tooltipElRef . current &&
@@ -365,6 +373,13 @@ export const Tooltip = React.forwardRef(
365
373
closeTooltip ( )
366
374
child . props . onBlur ?.( event )
367
375
} ,
376
+ onTouchEnd : ( event : React . TouchEvent ) => {
377
+ child . props . onTouchEnd ?.( event )
378
+
379
+ // Hide tooltips on tap to essentially disable them on touch devices;
380
+ // this still allows viewing the tooltip on tap-and-hold
381
+ safeSetTimeout ( ( ) => closeTooltip ( ) , 10 )
382
+ } ,
368
383
onFocus : ( event : React . FocusEvent ) => {
369
384
// only show tooltip on :focus-visible, not on :focus
370
385
try {
@@ -377,19 +392,17 @@ export const Tooltip = React.forwardRef(
377
392
openTooltip ( )
378
393
child . props . onFocus ?.( event )
379
394
} ,
380
- onMouseEnter : ( event : React . MouseEvent ) => {
381
- // show tooltip after mosue has been hovering for at least 50ms
395
+ onMouseOverCapture : ( event : React . MouseEvent ) => {
396
+ // We use a `capture` event to ensure this is called first before
397
+ // events that might cancel the opening timeout (like `onTouchEnd`)
398
+ // show tooltip after mouse has been hovering for at least 50ms
382
399
// (prevent showing tooltip when mouse is just passing through)
383
- timeoutRef . current = safeSetTimeout ( ( ) => {
400
+ openTimeoutRef . current = safeSetTimeout ( ( ) => {
384
401
openTooltip ( )
385
402
child . props . onMouseEnter ?.( event )
386
403
} , 50 )
387
404
} ,
388
405
onMouseLeave : ( event : React . MouseEvent ) => {
389
- if ( timeoutRef . current ) {
390
- safeClearTimeout ( timeoutRef . current )
391
- timeoutRef . current = null
392
- }
393
406
closeTooltip ( )
394
407
child . props . onMouseLeave ?.( event )
395
408
} ,
0 commit comments