Reputation: 55
I am using the Angular CDK overlay to show a modal drawer on my page. I am also using the Angular CDK Overlay for tooltips. It's possible that I may have a control in my drawer with a tooltip. The drawer allows the user to close it by pressing Escape.
My issue is if I have the drawer open and the tooltip showing and I press Escape. The drawer closes but the tooltip remains visible.
This StackBlitz demonstrates the issue (open the drawer, hover to show the tooltip, and press the Escape key).
https://stackblitz.com/edit/angular-material-datepicker-sfpsg7?file=src%2Fapp%2Fapp.component.ts
How can I resolve this?
Upvotes: 2
Views: 474
Reputation: 57886
Two way to solve this problem.
exportAs
and then call the close method manually.import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<button (click)="drawer.open()">Open Drawer</button>
<pro-drawer #drawer headerText="User Information" (dismissRequested)="drawer.close(); toolTip.hideTooltip();">
<button style="margin: 150px 0 0 50px;" #toolTip="proTooltip" proTooltip="This is tooltip text">Hover for tooltip</button>
</pro-drawer>
`,
})
export class AppComponent {}
import {
ComponentRef,
Directive,
ElementRef,
HostListener,
Input,
OnDestroy,
TemplateRef,
} from '@angular/core';
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { ProTooltipComponent } from './pro-tooltip.component';
@Directive({
selector: '[proTooltip]',
exportAs: 'proTooltip',
})
export class ProTooltipDirective implements OnDestroy {
@Input('proTooltip') text = '';
private overlayRef: OverlayRef;
private tooltipVisible: boolean = false;
constructor(private overlay: Overlay, private elementRef: ElementRef) {}
ngOnDestroy() {
this.hideTooltip();
}
@HostListener('mouseenter')
onMouseEnter() {
this.showTooltip();
}
@HostListener('mouseleave')
onMouseLeave() {
this.hideTooltip();
}
private showTooltip() {
if (
!this.tooltipVisible &&
!this.overlayRef &&
(!!this.text || !!this.template)
) {
this.overlayRef = this.overlay.create({
positionStrategy: this.overlay
.position()
.flexibleConnectedTo(this.elementRef)
.withPositions([
{
panelClass: 'tooltip-location-top',
originX: 'center',
originY: 'top',
overlayX: 'center',
overlayY: 'bottom',
},
]),
});
const tooltipRef: ComponentRef<ProTooltipComponent> =
this.overlayRef.attach(new ComponentPortal(ProTooltipComponent));
tooltipRef.instance.text = this.text;
this.tooltipVisible = true;
}
}
private hideTooltip() {
if (this.tooltipVisible && this.overlayRef) {
this.overlayRef.detach();
if (this.overlayRef) {
this.overlayRef.dispose();
this.overlayRef = null;
}
this.tooltipVisible = false;
}
}
}
Hostlistener
and trigger the close on press of escape button.import {
ComponentRef,
Directive,
ElementRef,
HostListener,
Input,
OnDestroy,
TemplateRef,
} from '@angular/core';
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { ProTooltipComponent } from './pro-tooltip.component';
@Directive({
selector: '[proTooltip]',
})
export class ProTooltipDirective implements OnDestroy {
@Input('proTooltip') text = '';
private overlayRef: OverlayRef;
private tooltipVisible: boolean = false;
constructor(private overlay: Overlay, private elementRef: ElementRef) {}
ngOnDestroy() {
this.hideTooltip();
}
@HostListener('mouseenter')
onMouseEnter() {
this.showTooltip();
}
@HostListener('mouseleave')
onMouseLeave() {
this.hideTooltip();
}
@HostListener('window:keydown.escape')
onEscape() {
console.log('window.keydown.escape');
this.hideTooltip();
}
private showTooltip() {
if (
!this.tooltipVisible &&
!this.overlayRef &&
(!!this.text || !!this.template)
) {
this.overlayRef = this.overlay.create({
positionStrategy: this.overlay
.position()
.flexibleConnectedTo(this.elementRef)
.withPositions([
{
panelClass: 'tooltip-location-top',
originX: 'center',
originY: 'top',
overlayX: 'center',
overlayY: 'bottom',
},
]),
});
const tooltipRef: ComponentRef<ProTooltipComponent> =
this.overlayRef.attach(new ComponentPortal(ProTooltipComponent));
tooltipRef.instance.text = this.text;
this.tooltipVisible = true;
}
}
private hideTooltip() {
if (this.tooltipVisible && this.overlayRef) {
this.overlayRef.detach();
if (this.overlayRef) {
this.overlayRef.dispose();
this.overlayRef = null;
}
this.tooltipVisible = false;
}
}
}
Upvotes: 1