diff --git a/src/app/components/overlay/overlay.ts b/src/app/components/overlay/overlay.ts index 3789c336d93..6291b5b124a 100644 --- a/src/app/components/overlay/overlay.ts +++ b/src/app/components/overlay/overlay.ts @@ -3,7 +3,6 @@ import { CommonModule, DOCUMENT } from '@angular/common'; import { AfterContentInit, ChangeDetectionStrategy, - ChangeDetectorRef, Component, ContentChildren, ElementRef, @@ -12,6 +11,7 @@ import { Inject, Input, NgModule, + NgZone, OnDestroy, Output, QueryList, @@ -266,6 +266,8 @@ export class Overlay implements AfterContentInit, OnDestroy { documentResizeListener: any; + private documentKeyboardListener: VoidFunction | null; + private window: Window | null; protected transformOptions: any = { @@ -317,7 +319,7 @@ export class Overlay implements AfterContentInit, OnDestroy { return DomHandler.getTargetElement(this.target, this.el?.nativeElement); } - constructor(@Inject(DOCUMENT) private document: Document, public el: ElementRef, public renderer: Renderer2, private config: PrimeNGConfig, public overlayService: OverlayService, private cd: ChangeDetectorRef) { + constructor(@Inject(DOCUMENT) private document: Document, public el: ElementRef, public renderer: Renderer2, private config: PrimeNGConfig, public overlayService: OverlayService, private zone: NgZone) { this.window = this.document.defaultView; } @@ -435,12 +437,14 @@ export class Overlay implements AfterContentInit, OnDestroy { this.bindScrollListener(); this.bindDocumentClickListener(); this.bindDocumentResizeListener(); + this.bindDocumentKeyboardListener(); } unbindListeners() { this.unbindScrollListener(); this.unbindDocumentClickListener(); this.unbindDocumentResizeListener(); + this.unbindDocumentKeyboardListener(); } bindScrollListener() { @@ -483,7 +487,7 @@ export class Overlay implements AfterContentInit, OnDestroy { bindDocumentResizeListener() { if (!this.documentResizeListener) { - this.documentResizeListener = this.renderer.listen('window', 'resize', (event) => { + this.documentResizeListener = this.renderer.listen(this.window, 'resize', (event) => { const valid = this.listener ? this.listener(event, { type: 'resize', mode: this.overlayMode, valid: !DomHandler.isTouchDevice() }) : !DomHandler.isTouchDevice(); valid && this.hide(event, true); @@ -498,6 +502,35 @@ export class Overlay implements AfterContentInit, OnDestroy { } } + bindDocumentKeyboardListener(): void { + if (this.documentKeyboardListener) { + return; + } + + this.zone.runOutsideAngular(() => { + this.documentKeyboardListener = this.renderer.listen(this.window, 'keydown', (event) => { + if (event.keyCode !== 27) { + return; + } + + const valid = this.listener ? this.listener(event, { type: 'keydown', mode: this.overlayMode, valid: !DomHandler.isTouchDevice() }) : !DomHandler.isTouchDevice(); + + if (valid) { + this.zone.run(() => { + this.hide(event, true); + }); + } + }); + }); + } + + unbindDocumentKeyboardListener(): void { + if (this.documentKeyboardListener) { + this.documentKeyboardListener(); + this.documentKeyboardListener = null; + } + } + ngOnDestroy() { this.hide(this.overlayEl, true);