@@ -6,6 +6,7 @@ import { useTooltip } from 'components/TooltipProvider'
6
6
import useIsomorphicLayoutEffect from 'utils/use-isomorphic-layout-effect'
7
7
import { getScrollParent } from 'utils/get-scroll-parent'
8
8
import { computeTooltipPosition } from 'utils/compute-positions'
9
+ import { cssTimeToMs } from 'utils/css-time-to-ms'
9
10
import coreStyles from './core-styles.module.css'
10
11
import styles from './styles.module.css'
11
12
import type {
@@ -67,6 +68,7 @@ const Tooltip = ({
67
68
const tooltipArrowRef = useRef < HTMLElement > ( null )
68
69
const tooltipShowDelayTimerRef = useRef < NodeJS . Timeout | null > ( null )
69
70
const tooltipHideDelayTimerRef = useRef < NodeJS . Timeout | null > ( null )
71
+ const missedTransitionTimerRef = useRef < NodeJS . Timeout | null > ( null )
70
72
const [ actualPlacement , setActualPlacement ] = useState ( place )
71
73
const [ inlineStyles , setInlineStyles ] = useState ( { } )
72
74
const [ inlineArrowStyles , setInlineArrowStyles ] = useState ( { } )
@@ -211,13 +213,28 @@ const Tooltip = ({
211
213
if ( show === wasShowing . current ) {
212
214
return
213
215
}
216
+ if ( missedTransitionTimerRef . current ) {
217
+ clearTimeout ( missedTransitionTimerRef . current )
218
+ }
214
219
wasShowing . current = show
215
220
if ( show ) {
216
221
afterShow ?.( )
217
222
} else {
218
223
/**
219
224
* see `onTransitionEnd` on tooltip wrapper
220
225
*/
226
+ const style = getComputedStyle ( document . body )
227
+ const transitionShowDelay = cssTimeToMs ( style . getPropertyValue ( '--rt-transition-show-delay' ) )
228
+ missedTransitionTimerRef . current = setTimeout ( ( ) => {
229
+ /**
230
+ * if the tooltip switches from `show === true` to `show === false` too fast
231
+ * the transition never runs, so `onTransitionEnd` callback never gets fired
232
+ */
233
+ setRendered ( false )
234
+ setImperativeOptions ( null )
235
+ afterHide ?.( )
236
+ // +25ms just to make sure `onTransitionEnd` (if it gets fired) has time to run
237
+ } , transitionShowDelay + 25 )
221
238
}
222
239
} , [ show ] )
223
240
@@ -811,10 +828,9 @@ const Tooltip = ({
811
828
clickable && coreStyles [ 'clickable' ] ,
812
829
) }
813
830
onTransitionEnd = { ( event : TransitionEvent ) => {
814
- /**
815
- * @warning if `--rt-transition-closing-delay` is set to 0,
816
- * the tooltip will be stuck (but not visible) on the DOM
817
- */
831
+ if ( missedTransitionTimerRef . current ) {
832
+ clearTimeout ( missedTransitionTimerRef . current )
833
+ }
818
834
if ( show || event . propertyName !== 'opacity' ) {
819
835
return
820
836
}
0 commit comments