Skip to content

Commit

Permalink
feat(module:drawer): support nzVisible two-way binding (#6013)
Browse files Browse the repository at this point in the history
close #5999
  • Loading branch information
stygian-desolator committed Nov 21, 2020
1 parent b42b51f commit caab8be
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 4 deletions.
4 changes: 2 additions & 2 deletions components/drawer/doc/index.en-US.md
Expand Up @@ -25,7 +25,7 @@ import { NzDrawerModule } from 'ng-zorro-antd/drawer';
| Props | Description | Type | Default | Global Config |
| --- | --- | --- | --- | --- |
| `[nzClosable]` | Whether a close (x) button is visible on top right of the Drawer dialog or not. | `boolean` | `true` |
| `[nzCloseIcon]` | 自定义关闭图标 | `string \| TemplateRef<void> \| null` | `'close'` |
| `[nzCloseIcon]` | Custom close icon | `string \| TemplateRef<void> \| null` | `'close'` |
| `[nzMask]` | Whether to show mask or not. | `boolean` | `true` ||
| `[nzMaskClosable]` | Clicking on the mask (area outside the Drawer) to close the Drawer or not. | `boolean` | `true` ||
| `[nzCloseOnNavigation]` | Whether to close the drawer when the navigation history changes | `boolean` | `true` ||
Expand All @@ -34,7 +34,7 @@ import { NzDrawerModule } from 'ng-zorro-antd/drawer';
| `[nzBodyStyle]` | Body style for drawer body element. Such as height, padding etc. | `object` | `{}` |
| `[nzTitle]` | The title for Drawer. | `string \| TemplateRef<void>` | - |
| `[nzFooter]` | The footer for Drawer. | `string \| TemplateRef<void>` | - |
| `[nzVisible]` | Whether the Drawer dialog is visible or not. | `boolean` | `false` |
| `[nzVisible]` | Whether the Drawer dialog is visible or not, you can use `[(nzVisible)]` two-way binding | `boolean` | `false` |
| `[nzPlacement]` | The placement of the Drawer. | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` |
| `[nzWidth]` | Width of the Drawer dialog, only when placement is `'right'` or `'left'`. | `number \| string` | `256` |
| `[nzHeight]` | Height of the Drawer dialog, only when placement is `'top'` or `'bottom'`. | `number \| string` | `256` |
Expand Down
2 changes: 1 addition & 1 deletion components/drawer/doc/index.zh-CN.md
Expand Up @@ -33,7 +33,7 @@ import { NzDrawerModule } from 'ng-zorro-antd/drawer';
| `[nzBodyStyle]` | Drawer body 样式 | `object` | `{}` |
| `[nzTitle]` | 标题 | `string \| TemplateRef<void>` | - |
| `[nzFooter]` | 抽屉的页脚 | `string \| TemplateRef<void>` | - |
| `[nzVisible]` | Drawer 是否可见 | `boolean` | - |
| `[nzVisible]` | Drawer 是否可见,可以使用 `[(nzVisible)]` 双向绑定 | `boolean` | - |
| `[nzPlacement]` | 抽屉的方向 | `'top' \| 'right' \| 'bottom' \| 'left'` | `'right'` |
| `[nzWidth]` | 宽度, 只在方向为 `'right'``'left'` 时生效 | `number \| string` | `256` |
| `[nzHeight]` | 高度, 只在方向为 `'top'``'bottom'` 时生效 | `number \| string` | `256` |
Expand Down
5 changes: 4 additions & 1 deletion components/drawer/drawer.component.ts
Expand Up @@ -142,11 +142,12 @@ export class NzDrawerComponent<T = NzSafeAny, R = NzSafeAny, D = NzSafeAny>

@Output() readonly nzOnViewInit = new EventEmitter<void>();
@Output() readonly nzOnClose = new EventEmitter<MouseEvent>();
@Output() readonly nzVisibleChange = new EventEmitter<boolean>();

@ViewChild('drawerTemplate', { static: true }) drawerTemplate!: TemplateRef<void>;
@ViewChild(CdkPortalOutlet, { static: false }) bodyPortalOutlet?: CdkPortalOutlet;

destroy$ = new Subject<void>();
private destroy$ = new Subject<void>();
previouslyFocusedElement?: HTMLElement;
placementChanging = false;
placementChangeTimeoutId = -1;
Expand Down Expand Up @@ -290,6 +291,7 @@ export class NzDrawerComponent<T = NzSafeAny, R = NzSafeAny, D = NzSafeAny>

close(result?: R): void {
this.isOpen = false;
this.nzVisibleChange.emit(false);
this.updateOverlayStyle();
this.overlayKeyboardDispatcher.remove(this.overlayRef!);
this.changeDetectorRef.detectChanges();
Expand All @@ -305,6 +307,7 @@ export class NzDrawerComponent<T = NzSafeAny, R = NzSafeAny, D = NzSafeAny>
open(): void {
this.attachOverlay();
this.isOpen = true;
this.nzVisibleChange.emit(true);
this.overlayKeyboardDispatcher.add(this.overlayRef!);
this.updateOverlayStyle();
this.updateBodyOverflow();
Expand Down
34 changes: 34 additions & 0 deletions components/drawer/drawer.spec.ts
Expand Up @@ -56,20 +56,28 @@ describe('NzDrawerComponent', () => {
});

it('should open work', () => {
expect(component.triggerVisible).toHaveBeenCalledTimes(1);
component.open();
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
expect(component.drawerComponent.nzVisible).toBe(true);
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
expect(component.triggerVisible).toHaveBeenCalledWith(true);
});

it('should close work', () => {
expect(component.triggerVisible).toHaveBeenCalledTimes(1);
component.open();
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
expect(component.triggerVisible).toHaveBeenCalledWith(true);
component.close();
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(false);
expect(component.drawerComponent.nzVisible).toBe(false);
expect(component.triggerVisible).toHaveBeenCalledTimes(3);
expect(component.triggerVisible).toHaveBeenCalledWith(false);
});

it('should block scroll', fakeAsync(() => {
Expand All @@ -94,13 +102,18 @@ describe('NzDrawerComponent', () => {
});

it('should closable', () => {
expect(component.triggerVisible).toHaveBeenCalledTimes(1);
component.closable = true;
component.open();
fixture.detectChanges();
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
expect(component.triggerVisible).toHaveBeenCalledWith(true);
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
(overlayContainerElement.querySelector('.ant-drawer .ant-drawer-close') as HTMLElement).click();
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(false);
expect(component.triggerVisible).toHaveBeenCalledTimes(3);
expect(component.triggerVisible).toHaveBeenCalledWith(false);
});

it('should set close icon work', () => {
Expand All @@ -122,44 +135,62 @@ describe('NzDrawerComponent', () => {
});

it('should not close when click mask', () => {
expect(component.triggerVisible).toHaveBeenCalledTimes(1);
component.maskClosable = false;
component.open();
fixture.detectChanges();
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
expect(component.triggerVisible).toHaveBeenCalledWith(true);
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
(overlayContainerElement.querySelector('.ant-drawer .ant-drawer-mask') as HTMLElement).click();
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
});

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

it('should disabled ESC keydown', () => {
expect(component.triggerVisible).toHaveBeenCalledTimes(1);
component.open();
component.drawerComponent.nzKeyboard = false;
fixture.detectChanges();
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
expect(component.triggerVisible).toHaveBeenCalledWith(true);
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(true);
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
component.close();
fixture.detectChanges();
});

it('should close when click mask', () => {
expect(component.triggerVisible).toHaveBeenCalledTimes(1);
component.maskClosable = true;
component.open();
fixture.detectChanges();
expect(component.triggerVisible).toHaveBeenCalledTimes(2);
expect(component.triggerVisible).toHaveBeenCalledWith(true);
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(true);
(overlayContainerElement.querySelector('.ant-drawer .ant-drawer-mask') as HTMLElement).click();
fixture.detectChanges();
expect(overlayContainerElement.querySelector('.ant-drawer')!.classList.contains('ant-drawer-open')).toBe(false);
expect(component.triggerVisible).toHaveBeenCalledTimes(3);
expect(component.triggerVisible).toHaveBeenCalledWith(false);
});

it('should not show mask', () => {
Expand Down Expand Up @@ -551,6 +582,7 @@ describe('NzDrawerService', () => {
[nzOffsetX]="offsetX"
[nzOffsetY]="offsetY"
(nzOnClose)="close()"
(nzVisibleChange)="triggerVisible($event)"
>
<p>Some contents...</p>
<p>Some contents...</p>
Expand All @@ -573,6 +605,8 @@ class NzTestDrawerComponent {
closeIcon?: TemplateRef<void> | string;
offsetX = 0;
offsetY = 0;
triggerVisible = jasmine.createSpy('visibleChange');

@ViewChild('titleTemplate', { static: false }) titleTemplateRef!: TemplateRef<void>;
@ViewChild('closeIconTemplate', { static: false }) closeIconTemplateRef!: TemplateRef<void>;
@ViewChild('customFooter', { static: false }) templateFooter!: TemplateRef<void>;
Expand Down

0 comments on commit caab8be

Please sign in to comment.