@@ -19,7 +19,6 @@ import {
1919} from './tooltip-event-controller.js' ;
2020import service from './tooltip-service.js' ;
2121
22- // TODO: Expose events
2322export interface IgcTooltipComponentEventMap {
2423 igcOpening : CustomEvent < Element | null > ;
2524 igcOpened : CustomEvent < Element | null > ;
@@ -60,8 +59,8 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
6059 private _animationPlayer = addAnimationController ( this , this . _containerRef ) ;
6160
6261 private _timeoutId ?: number ;
63- private toBeShown = false ;
64- private toBeHidden = false ;
62+ private _toBeShown = false ;
63+ private _toBeHidden = false ;
6564 private _open = false ;
6665 private _showTriggers = [ 'pointerenter' ] ;
6766 private _hideTriggers = [ 'pointerleave' ] ;
@@ -205,6 +204,8 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
205204
206205 this . _internals = this . attachInternals ( ) ;
207206 this . _internals . role = 'tooltip' ;
207+ this . _internals . ariaAtomic = 'true' ;
208+ this . _internals . ariaLive = 'polite' ;
208209 }
209210
210211 protected override async firstUpdated ( ) {
@@ -255,10 +256,23 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
255256 return this . _animationPlayer . playExclusive ( animation ) ;
256257 }
257258
259+ /**
260+ * Immediately stops any ongoing animation and resets the tooltip state.
261+ *
262+ * This method is used in edge cases when a transition needs to be forcefully interrupted,
263+ * such as when a tooltip is in the middle of showing or hiding and the user suddenly
264+ * triggers the opposite action (e.g., hovers in and out rapidly).
265+ *
266+ * It:
267+ * - Reverts `open` based on whether it was mid-hide or mid-show.
268+ * - Clears internal transition flags (`_toBeShown`, `_toBeHidden`).
269+ * - Stops any active animations, causing `_toggleAnimation()` to return false.
270+ *
271+ */
258272 private async _forceAnimationStop ( ) {
259- this . toBeShown = false ;
260- this . toBeHidden = false ;
261- this . open = ! this . open ;
273+ this . open = this . _toBeHidden ;
274+ this . _toBeShown = false ;
275+ this . _toBeHidden = false ;
262276 this . _animationPlayer . stopAll ( ) ;
263277 }
264278
@@ -276,9 +290,9 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
276290 await this . _setDelay ( this . showDelay ) ;
277291
278292 this . open = true ;
279- this . toBeShown = true ;
293+ this . _toBeShown = true ;
280294 const result = await this . _toggleAnimation ( 'open' ) ;
281- this . toBeShown = false ;
295+ this . _toBeShown = false ;
282296
283297 return result ;
284298 } ;
@@ -289,10 +303,10 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
289303
290304 await this . _setDelay ( this . hideDelay ) ;
291305
292- this . toBeHidden = true ;
306+ this . _toBeHidden = true ;
293307 const result = await this . _toggleAnimation ( 'close' ) ;
294- this . open = false ;
295- this . toBeHidden = false ;
308+ this . open = ! result ;
309+ this . _toBeHidden = false ;
296310
297311 return result ;
298312 } ;
@@ -303,8 +317,7 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
303317 } ;
304318
305319 public showWithEvent = async ( ) => {
306- clearTimeout ( this . _timeoutId ) ;
307- if ( this . toBeHidden ) {
320+ if ( this . _toBeHidden ) {
308321 await this . _forceAnimationStop ( ) ;
309322 return ;
310323 }
@@ -320,8 +333,7 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
320333 } ;
321334
322335 public hideWithEvent = async ( ) => {
323- clearTimeout ( this . _timeoutId ) ;
324- if ( this . toBeShown ) {
336+ if ( this . _toBeShown ) {
325337 await this . _forceAnimationStop ( ) ;
326338 return ;
327339 }
@@ -337,6 +349,7 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
337349 } ;
338350
339351 protected [ showOnTrigger ] = ( ) => {
352+ clearTimeout ( this . _timeoutId ) ;
340353 this . showWithEvent ( ) ;
341354 } ;
342355
@@ -346,12 +359,14 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
346359 if ( related && ( this . contains ( related ) || this . _target ?. contains ( related ) ) )
347360 return ;
348361
349- this . hideWithEvent ( ) ;
362+ clearTimeout ( this . _timeoutId ) ;
363+ this . _timeoutId = setTimeout ( ( ) => this . hideWithEvent ( ) , 180 ) ;
350364 } ;
351365
352366 protected override render ( ) {
353367 return html `
354368 < igc-popover
369+ aria-hidden =${ ! this . open }
355370 .placement =${ this . placement }
356371 .offset=${ this . offset }
357372 .anchor=${ this . _target }
@@ -361,13 +376,7 @@ export default class IgcTooltipComponent extends EventEmitterMixin<
361376 flip
362377 shift
363378 >
364- < div
365- ${ ref ( this . _containerRef ) }
366- part ="base "
367- aria-hidden =${ String ( ! this . open ) }
368- aria-live ="polite"
369- aria-atomic="true"
370- >
379+ < div ${ ref ( this . _containerRef ) } part ="base ">
371380 ${ this . message ? html `${ this . message } ` : html `< slot > </ slot > ` }
372381 ${ this . disableArrow ? nothing : html `< div id ="arrow "> </ div > ` }
373382 </ div >
0 commit comments