Skip to content

Commit

Permalink
feat(module:drawer): support pressing ESC to close drawer (NG-ZORRO#3488
Browse files Browse the repository at this point in the history
)
  • Loading branch information
hsuanxyz authored and Ricbet committed Apr 9, 2020
1 parent c303b71 commit ceb23d9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
29 changes: 19 additions & 10 deletions components/drawer/nz-drawer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import { ESCAPE } from '@angular/cdk/keycodes';
import { DOCUMENT } from '@angular/common';
import {
AfterViewInit,
Expand All @@ -30,12 +31,13 @@ import {
} from '@angular/core';

import { FocusTrap, FocusTrapFactory } from '@angular/cdk/a11y';
import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
import { Overlay, OverlayConfig, OverlayKeyboardDispatcher, OverlayRef } from '@angular/cdk/overlay';
import { CdkPortalOutlet, ComponentPortal, PortalInjector, TemplatePortal } from '@angular/cdk/portal';

import { Observable, Subject } from 'rxjs';

import { toCssPixel, InputBoolean } from 'ng-zorro-antd/core';
import { takeUntil } from 'rxjs/operators';
import { NzDrawerOptionsOfComponent, NzDrawerPlacement } from './nz-drawer-options';
import { NzDrawerRef } from './nz-drawer-ref';

Expand Down Expand Up @@ -83,6 +85,7 @@ export class NzDrawerComponent<T = any, R = any, D = any> extends NzDrawerRef<R>
@ViewChild('contentTemplate') contentTemplate: TemplateRef<{}>;
@ViewChild(CdkPortalOutlet) bodyPortalOutlet: CdkPortalOutlet;

destroy$ = new Subject<void>();
previouslyFocusedElement: HTMLElement;
nzContentParams: D; // only service
overlayRef: OverlayRef | null;
Expand Down Expand Up @@ -162,7 +165,8 @@ export class NzDrawerComponent<T = any, R = any, D = any> extends NzDrawerRef<R>
private injector: Injector,
private changeDetectorRef: ChangeDetectorRef,
private focusTrapFactory: FocusTrapFactory,
private viewContainerRef: ViewContainerRef
private viewContainerRef: ViewContainerRef,
private overlayKeyboardDispatcher: OverlayKeyboardDispatcher
) {
super();
}
Expand All @@ -185,21 +189,17 @@ export class NzDrawerComponent<T = any, R = any, D = any> extends NzDrawerRef<R>
ngOnChanges(changes: SimpleChanges): void {
if (changes.hasOwnProperty('nzVisible')) {
const value = changes.nzVisible.currentValue;
this.updateOverlayStyle();
if (value) {
this.updateBodyOverflow();
this.savePreviouslyFocusedElement();
this.trapFocus();
this.open();
} else {
setTimeout(() => {
this.updateBodyOverflow();
this.restoreFocus();
}, this.getAnimationDuration());
this.close();
}
}
}

ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
this.disposeOverlay();
}

Expand All @@ -210,6 +210,7 @@ export class NzDrawerComponent<T = any, R = any, D = any> extends NzDrawerRef<R>
close(result?: R): void {
this.isOpen = false;
this.updateOverlayStyle();
this.overlayKeyboardDispatcher.remove(this.overlayRef!);
this.changeDetectorRef.detectChanges();
setTimeout(() => {
this.updateBodyOverflow();
Expand All @@ -221,6 +222,7 @@ export class NzDrawerComponent<T = any, R = any, D = any> extends NzDrawerRef<R>

open(): void {
this.isOpen = true;
this.overlayKeyboardDispatcher.add(this.overlayRef!);
this.updateOverlayStyle();
this.updateBodyOverflow();
this.savePreviouslyFocusedElement();
Expand Down Expand Up @@ -261,6 +263,13 @@ export class NzDrawerComponent<T = any, R = any, D = any> extends NzDrawerRef<R>

if (this.overlayRef && !this.overlayRef.hasAttached()) {
this.overlayRef.attach(this.portal);
this.overlayRef!.keydownEvents()
.pipe(takeUntil(this.destroy$))
.subscribe((event: KeyboardEvent) => {
if (event.keyCode === ESCAPE && this.isOpen) {
this.nzOnClose.emit();
}
});
}
}

Expand Down
11 changes: 11 additions & 0 deletions components/drawer/nz-drawer.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { ESCAPE } from '@angular/cdk/keycodes';
import { Component, Input, TemplateRef, ViewChild } from '@angular/core';

import { async, fakeAsync, inject, tick, ComponentFixture, TestBed } from '@angular/core/testing';

import { OverlayContainer } from '@angular/cdk/overlay';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { dispatchKeyboardEvent } from 'ng-zorro-antd';
import { NzDrawerRef } from './nz-drawer-ref';
import { NzDrawerComponent } from './nz-drawer.component';
import { NzDrawerModule } from './nz-drawer.module';
Expand Down Expand Up @@ -109,6 +111,15 @@ describe('NzDrawerComponent', () => {
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
});

it('should be closed when ESC keydown', () => {
component.open();
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
dispatchKeyboardEvent(document.body, 'keydown', ESCAPE);
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(false);
});

it('should close when click mask', () => {
component.maskClosable = true;
component.open();
Expand Down

0 comments on commit ceb23d9

Please sign in to comment.