@@ -235,6 +235,7 @@ export class TooltipTriggerState {
235235 #hasPointerMoveOpened = $state ( false ) ;
236236 readonly #isDisabled = $derived . by ( ( ) => this . opts . disabled . current || this . root . disabled ) ;
237237 domContext : DOMContext ;
238+ #transitCheckTimeout: number | null = null ;
238239
239240 constructor ( opts : TooltipTriggerStateOpts , root : TooltipRootState ) {
240241 this . opts = opts ;
@@ -243,6 +244,13 @@ export class TooltipTriggerState {
243244 this . attachment = attachRef ( this . opts . ref , ( v ) => ( this . root . triggerNode = v ) ) ;
244245 }
245246
247+ #clearTransitCheck = ( ) => {
248+ if ( this . #transitCheckTimeout !== null ) {
249+ clearTimeout ( this . #transitCheckTimeout) ;
250+ this . #transitCheckTimeout = null ;
251+ }
252+ } ;
253+
246254 handlePointerUp = ( ) => {
247255 this . #isPointerDown. current = false ;
248256 } ;
@@ -265,19 +273,44 @@ export class TooltipTriggerState {
265273 ) ;
266274 } ;
267275
276+ #onpointerenter: PointerEventHandler < HTMLElement > = ( e ) => {
277+ if ( this . #isDisabled) return ;
278+ if ( e . pointerType === "touch" ) return ;
279+
280+ // if in transit, wait briefly to see if user is actually heading to old content or staying here
281+ if ( this . root . provider . isPointerInTransit . current ) {
282+ this . #clearTransitCheck( ) ;
283+ this . #transitCheckTimeout = window . setTimeout ( ( ) => {
284+ // if still in transit after delay, user is likely staying on this trigger
285+ if ( this . root . provider . isPointerInTransit . current ) {
286+ this . root . provider . isPointerInTransit . current = false ;
287+ this . root . onTriggerEnter ( ) ;
288+ this . #hasPointerMoveOpened = true ;
289+ }
290+ } , 250 ) ;
291+ return ;
292+ }
293+
294+ this . root . onTriggerEnter ( ) ;
295+ this . #hasPointerMoveOpened = true ;
296+ } ;
297+
268298 #onpointermove: PointerEventHandler < HTMLElement > = ( e ) => {
269299 if ( this . #isDisabled) return ;
270300 if ( e . pointerType === "touch" ) return ;
271301 if ( this . #hasPointerMoveOpened) return ;
272302
273- if ( this . root . provider . isPointerInTransit . current ) return ;
303+ // moving within trigger means we're definitely not in transit anymore
304+ this . #clearTransitCheck( ) ;
305+ this . root . provider . isPointerInTransit . current = false ;
274306
275307 this . root . onTriggerEnter ( ) ;
276308 this . #hasPointerMoveOpened = true ;
277309 } ;
278310
279311 #onpointerleave: PointerEventHandler < HTMLElement > = ( ) => {
280312 if ( this . #isDisabled) return ;
313+ this . #clearTransitCheck( ) ;
281314 this . root . onTriggerLeave ( ) ;
282315 this . #hasPointerMoveOpened = false ;
283316 } ;
@@ -314,6 +347,7 @@ export class TooltipTriggerState {
314347 disabled : this . opts . disabled . current ,
315348 onpointerup : this . #onpointerup,
316349 onpointerdown : this . #onpointerdown,
350+ onpointerenter : this . #onpointerenter,
317351 onpointermove : this . #onpointermove,
318352 onpointerleave : this . #onpointerleave,
319353 onfocus : this . #onfocus,
0 commit comments