@@ -6,6 +6,7 @@ import { useTooltip } from 'components/TooltipProvider'
66import useIsomorphicLayoutEffect from 'utils/use-isomorphic-layout-effect'
77import { getScrollParent } from 'utils/get-scroll-parent'
88import { computeTooltipPosition } from 'utils/compute-positions'
9+ import { cssTimeToMs } from 'utils/css-time-to-ms'
910import coreStyles from './core-styles.module.css'
1011import styles from './styles.module.css'
1112import type {
@@ -67,6 +68,7 @@ const Tooltip = ({
6768 const tooltipArrowRef = useRef < HTMLElement > ( null )
6869 const tooltipShowDelayTimerRef = useRef < NodeJS . Timeout | null > ( null )
6970 const tooltipHideDelayTimerRef = useRef < NodeJS . Timeout | null > ( null )
71+ const missedTransitionTimerRef = useRef < NodeJS . Timeout | null > ( null )
7072 const [ actualPlacement , setActualPlacement ] = useState ( place )
7173 const [ inlineStyles , setInlineStyles ] = useState ( { } )
7274 const [ inlineArrowStyles , setInlineArrowStyles ] = useState ( { } )
@@ -211,13 +213,28 @@ const Tooltip = ({
211213 if ( show === wasShowing . current ) {
212214 return
213215 }
216+ if ( missedTransitionTimerRef . current ) {
217+ clearTimeout ( missedTransitionTimerRef . current )
218+ }
214219 wasShowing . current = show
215220 if ( show ) {
216221 afterShow ?.( )
217222 } else {
218223 /**
219224 * see `onTransitionEnd` on tooltip wrapper
220225 */
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 )
221238 }
222239 } , [ show ] )
223240
@@ -811,10 +828,9 @@ const Tooltip = ({
811828 clickable && coreStyles [ 'clickable' ] ,
812829 ) }
813830 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+ }
818834 if ( show || event . propertyName !== 'opacity' ) {
819835 return
820836 }
0 commit comments