diff --git a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip-target.directive.ts b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip-target.directive.ts index 93faf786554..41a53e4e99b 100644 --- a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip-target.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip-target.directive.ts @@ -559,8 +559,6 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen /** * Used when a single tooltip is used for multiple targets. - * If the tooltip is shown for one target and the user interacts with another target, - * the tooltip is instantly hidden for the first target. */ private _checkTooltipForMultipleTargets(): void { if (!this.target.tooltipTarget) { @@ -573,8 +571,10 @@ export class IgxTooltipTargetDirective extends IgxToggleActionDirective implemen this.target.tooltipTarget._removeCloseButtonFromTooltip(); } + // If the tooltip is shown for one target and the user interacts with another target, + // the tooltip is instantly hidden for the first target. clearTimeout(this.target.timeoutId); - this.target.stopAnimations(true); + this.target.forceClose(this._mergedOverlaySettings); this.target.tooltipTarget = this; this._isForceClosed = true; diff --git a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.spec.ts index 0f78506dfbd..e9f39d07c02 100644 --- a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.spec.ts @@ -558,6 +558,31 @@ describe('IgxTooltip', () => { flush(); })); + it('Should position relative to its target when having no close animation - #16288', fakeAsync(() => { + targetOne.positionSettings = targetTwo.positionSettings = { + openAnimation: undefined, + closeAnimation: undefined + }; + fix.detectChanges(); + + hoverElement(buttonOne); + tick(targetOne.showDelay); + + verifyTooltipVisibility(tooltipNativeElement, targetOne, true); + verifyTooltipPosition(tooltipNativeElement, buttonOne, true); + + unhoverElement(buttonOne); + + hoverElement(buttonTwo); + tick(targetTwo.showDelay); + + // Tooltip is visible and positioned relative to buttonTwo + verifyTooltipVisibility(tooltipNativeElement, targetTwo, true); + verifyTooltipPosition(tooltipNativeElement, buttonTwo); + // Tooltip is NOT visible and positioned relative to buttonOne + verifyTooltipPosition(tooltipNativeElement, buttonOne, false); + })); + it('Hovering first target briefly and then hovering second target leads to tooltip showing for second target', fakeAsync(() => { targetOne.showDelay = 600; fix.detectChanges(); diff --git a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts index 92bef088822..60f47c4d759 100644 --- a/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/tooltip/tooltip.directive.ts @@ -3,6 +3,7 @@ import { OnDestroy, inject, DOCUMENT, HostListener, } from '@angular/core'; import { IgxOverlayService } from '../../services/overlay/overlay'; +import { OverlaySettings } from '../../services/overlay/utilities'; import { IgxNavigationService } from '../../core/navigation'; import { IgxToggleDirective } from '../toggle/toggle.directive'; import { IgxTooltipTargetDirective } from './tooltip-target.directive'; @@ -165,29 +166,44 @@ export class IgxTooltipDirective extends IgxToggleDirective implements OnDestroy /** * If there is an animation in progress, this method will reset it to its initial state. - * Optional `force` parameter that ends the animation. + * Allows hovering over the tooltip while an open/close animation is running. + * Stops the animation and immediately shows the tooltip. * * @hidden - * @param force if set to `true`, the animation will be ended. */ - public stopAnimations(force: boolean = false): void { + public stopAnimations(): void { const info = this.overlayService.getOverlayById(this._overlayId); if (!info) return; if (info.openAnimationPlayer) { info.openAnimationPlayer.reset(); - if (force) { - info.openAnimationPlayer.finish(); - info.openAnimationPlayer = null; - } } if (info.closeAnimationPlayer) { info.closeAnimationPlayer.reset(); - if (force) { - info.closeAnimationPlayer.finish(); - info.closeAnimationPlayer = null; - } + } + } + + /** + * If there is a close animation in progress, this method will end it. + * If there is no close animation in progress, this method will close the tooltip with no animation. + * + * @param overlaySettings settings to use for closing the tooltip + * @hidden + */ + public forceClose(overlaySettings: OverlaySettings) { + const info = this.overlayService.getOverlayById(this._overlayId); + const hasCloseAnimation = info ? info.closeAnimationPlayer : false; + + if (hasCloseAnimation) { + info.closeAnimationPlayer.finish(); + info.closeAnimationPlayer.reset(); + info.closeAnimationPlayer = null; + } else if (!this.collapsed) { + const animation = overlaySettings.positionStrategy.settings.closeAnimation; + overlaySettings.positionStrategy.settings.closeAnimation = null; + this.close(); + overlaySettings.positionStrategy.settings.closeAnimation = animation; } }