Skip to content

Commit

Permalink
feat(module:modal): support use directive to define the footer (#3036)
Browse files Browse the repository at this point in the history
* feat(module:modal): support use directive to define the footer

close #3035

* docs(module:modal): add custom footer demo

* test(module:modal): add test

* test(module:modal): add test

* fix(module:modal): fix type

* test(module:modal): fix test

* chore: rebase master

* chore: rebase master

* test(module:modal): fix test

* test(module:modal): fix test
  • Loading branch information
hsuanxyz authored and Wendell committed Jul 19, 2019
1 parent 3a3b33a commit f022a0f
Show file tree
Hide file tree
Showing 16 changed files with 267 additions and 9 deletions.
2 changes: 1 addition & 1 deletion components/modal/demo/confirm.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
order: 3
order: 4
title:
zh-CN: 确认对话框
en-US: Confirmation modal dialog
Expand Down
14 changes: 14 additions & 0 deletions components/modal/demo/footer2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
order: 3
title:
zh-CN: 自定义页脚(2)
en-US: Customized Footer(2)
---

## zh-CN

使用 `nzModalFooter` 指令自定义了页脚的按钮。

## en-US

use `nzModalFooter` directive to customized footer button bar.
87 changes: 87 additions & 0 deletions components/modal/demo/footer2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* entryComponents: NzModalCustomFooterComponent */

import { Component } from '@angular/core';
import { NzModalService, NzModalRef } from 'ng-zorro-antd';

@Component({
selector: 'nz-demo-modal-footer2',
template: `
<button nz-button nzType="primary" (click)="showModal1()">
<span>In Template</span>
</button>
<br>
<br>
<button nz-button nzType="primary" (click)="showModal2()">
<span>In Component</span>
</button>
<nz-modal [(nzVisible)]="isVisible" nzTitle="Custom Modal Title" (nzOnCancel)="handleCancel()">
<div>
<p>Modal Content</p>
<p>Modal Content</p>
<p>Modal Content</p>
<p>Modal Content</p>
<p>Modal Content</p>
</div>
<div *nzModalFooter>
<span>Modal Footer: </span>
<button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
<button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
</div>
</nz-modal>
`,
styles: []
})
export class NzDemoModalFooter2Component {
isVisible = false;
isConfirmLoading = false;

constructor(private modalService: NzModalService) { }

showModal1(): void {
this.isVisible = true;
}

showModal2(): void {
this.modalService.create({
nzTitle: 'Modal Title',
nzContent: NzModalCustomFooterComponent
});
}

handleOk(): void {
this.isConfirmLoading = true;
setTimeout(() => {
this.isVisible = false;
this.isConfirmLoading = false;
}, 3000);
}

handleCancel(): void {
this.isVisible = false;
}
}

@Component({
selector: 'nz-modal-custom-footer-component',
template: `
<div>
<p>Modal Content</p>
<p>Modal Content</p>
<p>Modal Content</p>
<p>Modal Content</p>
<p>Modal Content</p>
</div>
<div *nzModalFooter>
<button nz-button nzType="default" (click)="destroyModal()">Custom Callback</button>
<button nz-button nzType="primary" (click)="destroyModal()">Custom Submit</button>
</div>
`
})
export class NzModalCustomFooterComponent {

constructor(private modal: NzModalRef) { }

destroyModal(): void {
this.modal.destroy();
}
}
2 changes: 1 addition & 1 deletion components/modal/demo/info.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
order: 5
order: 6
title:
zh-CN: 信息提示
en-US: Information modal dialog
Expand Down
2 changes: 1 addition & 1 deletion components/modal/demo/locale.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
order: 6
order: 7
title:
zh-CN: 国际化
en-US: Internationalization
Expand Down
2 changes: 1 addition & 1 deletion components/modal/demo/manual.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
order: 7
order: 8
title:
zh-CN: 手动移除
en-US: Manual to destroy
Expand Down
2 changes: 1 addition & 1 deletion components/modal/demo/position.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
order: 8
order: 9
title:
zh-CN: 自定义位置
en-US: To customize the position of modal
Expand Down
2 changes: 1 addition & 1 deletion components/modal/demo/service.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
order: 9
order: 10
title:
zh-CN: 服务方式创建
en-US: Modal's service
Expand Down
18 changes: 18 additions & 0 deletions components/modal/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,21 @@ nzFooter: [{
```
The above configuration items can also be changed in real-time to trigger the button behavior change.
### [nzModalFooter]
Another way to customize the footer button.
```html
<div *nzModalFooter>
<button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
<button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
</div>

<!-- or -->

<ng-template [nzModalFooter]>
<button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
<button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
</ng-template>
```
18 changes: 18 additions & 0 deletions components/modal/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,21 @@ nzFooter: [{
```
以上配置项也可在运行态实时改变,来触发按钮行为改变。
### [nzModalFooter]
另一种自定义页脚按钮的方式。
```html
<div *nzModalFooter>
<button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
<button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
</div>

<!-- or -->

<ng-template [nzModalFooter]>
<button nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
<button nz-button nzType="primary" (click)="handleOk()" [nzLoading]="isConfirmLoading">Custom Submit</button>
</ng-template>
```
84 changes: 84 additions & 0 deletions components/modal/nz-modal-footer.directive.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { OverlayContainer } from '@angular/cdk/overlay';
import { Component } from '@angular/core';
import { async, fakeAsync, inject, tick, ComponentFixture, TestBed } from '@angular/core/testing';

import { NoopAnimationsModule } from '@angular/platform-browser/animations';

import { NzModalModule } from './nz-modal.module';
import { NzModalService } from './nz-modal.service';

describe('modal footer directive', () => {
let overlayContainer: OverlayContainer;
let overlayContainerElement: HTMLElement;
let fixture: ComponentFixture<TestDirectiveFooterComponent>;
let testComponent: TestDirectiveFooterComponent;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [NzModalModule, NoopAnimationsModule],
declarations: [TestDirectiveFooterComponent],
providers: [NzModalService]
});

TestBed.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(TestDirectiveFooterComponent);
testComponent = fixture.componentInstance;
fixture.detectChanges();
});

beforeEach(inject([OverlayContainer], (oc: OverlayContainer) => {
overlayContainer = oc;
overlayContainerElement = oc.getContainerElement();
}));

afterEach(() => {
overlayContainer.ngOnDestroy();
});

afterEach(fakeAsync(() => {
fixture.detectChanges();
tick(1000);
}));

it('should work with template', () => {
testComponent.showModal();
fixture.detectChanges();
expect(testComponent.isVisible).toBe(true);
const cancelBtn: HTMLButtonElement = overlayContainerElement.querySelector(
'.ant-modal #btn-template'
) as HTMLButtonElement;
expect(cancelBtn).toBeTruthy();
cancelBtn.click();
fixture.detectChanges();
expect(testComponent.isVisible).toBe(false);
});
});

@Component({
template: `
<nz-modal [(nzVisible)]="isVisible" nzTitle="Custom Modal Title" (nzOnCancel)="handleCancel()">
<div>
<p>Modal Content</p>
</div>
<div *nzModalFooter>
<button id="btn-template" nz-button nzType="default" (click)="handleCancel()">Custom Callback</button>
</div>
</nz-modal>
`
})
class TestDirectiveFooterComponent {
isVisible = false;

constructor() {}

handleCancel(): void {
this.isVisible = false;
}

showModal(): void {
this.isVisible = true;
}
}
21 changes: 21 additions & 0 deletions components/modal/nz-modal-footer.directive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @license
* Copyright Alibaba.com All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/

import { Directive, Optional, TemplateRef } from '@angular/core';
import { NzModalRef } from './nz-modal-ref.class';

@Directive({
selector: '[nzModalFooter]'
})
export class NzModalFooterDirective {
constructor(@Optional() private nzModalRef: NzModalRef, public templateRef: TemplateRef<{}>) {
if (this.nzModalRef) {
this.nzModalRef.getInstance().setFooterWithTemplate(this.templateRef);
}
}
}
14 changes: 14 additions & 0 deletions components/modal/nz-modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
Component,
ComponentFactoryResolver,
ComponentRef,
ContentChild,
ElementRef,
EventEmitter,
Inject,
Expand All @@ -43,6 +44,7 @@ import { NzI18nService } from 'ng-zorro-antd/i18n';

import { NzModalConfig, NZ_MODAL_CONFIG } from './nz-modal-config';
import { NzModalControlService } from './nz-modal-control.service';
import { NzModalFooterDirective } from './nz-modal-footer.directive';
import { NzModalRef } from './nz-modal-ref.class';
import { ModalButtonOptions, ModalOptions, ModalType, OnClickCallback } from './nz-modal.type';

Expand Down Expand Up @@ -101,6 +103,13 @@ export class NzModalComponent<T = any, R = any> extends NzModalRef<T, R>
@ViewChild('bodyContainer', { static: false, read: ViewContainerRef }) bodyContainer: ViewContainerRef;
@ViewChild('autoFocusButtonOk', { static: false, read: ElementRef }) autoFocusButtonOk: ElementRef; // Only aim to focus the ok button that needs to be auto focused

@ContentChild(NzModalFooterDirective, { static: false })
set modalFooter(value: NzModalFooterDirective) {
if (value && value.templateRef) {
this.setFooterWithTemplate(value.templateRef);
}
}

get afterOpen(): Observable<void> {
// Observable alias for nzAfterOpen
return this.nzAfterOpen.asObservable();
Expand Down Expand Up @@ -266,6 +275,11 @@ export class NzModalComponent<T = any, R = any> extends NzModalRef<T, R>
clearTimeout(this.timeoutId);
}

setFooterWithTemplate(templateRef: TemplateRef<{}>): void {
this.nzFooter = templateRef;
this.cdr.markForCheck();
}

setOverlayRef(overlayRef: OverlayRef): void {
this.overlayRef = overlayRef;
}
Expand Down
5 changes: 3 additions & 2 deletions components/modal/nz-modal.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { NzIconModule } from 'ng-zorro-antd/icon';

import { CssUnitPipe } from './css-unit.pipe';
import { NzModalControlServiceModule } from './nz-modal-control.service.module';
import { NzModalFooterDirective } from './nz-modal-footer.directive';
import { NzModalComponent } from './nz-modal.component';
import { NzModalServiceModule } from './nz-modal.service.module';

Expand All @@ -31,8 +32,8 @@ import { NzModalServiceModule } from './nz-modal.service.module';
NzModalServiceModule,
NzModalControlServiceModule
],
exports: [NzModalComponent],
declarations: [NzModalComponent, CssUnitPipe],
exports: [NzModalComponent, NzModalFooterDirective],
declarations: [NzModalComponent, NzModalFooterDirective, CssUnitPipe],
entryComponents: [NzModalComponent]
})
export class NzModalModule {}
1 change: 1 addition & 0 deletions components/modal/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

export { NzModalComponent } from './nz-modal.component';
export { NzModalFooterDirective } from './nz-modal-footer.directive';
export { NzModalRef } from './nz-modal-ref.class';
export { NzModalModule } from './nz-modal.module';
export { NzModalService } from './nz-modal.service';
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"stage-release": "ts-node --project scripts/release/tsconfig.json scripts/release/release.ts",
"ng": "ng",
"gulp": "gulp",
"lint": "tslint -c tslint.json 'components/**/!(demo|testing)/!(polyfills).ts' --fix",
"lint": "tslint -c tslint.json 'components/**/!(demo|testing)/!(polyfills).ts'",
"integration-cli": "npm run build:lib && cd integration/angular-cli && npm run integration",
"integration-rollup": "npm run build:lib&& cd integration/rollup && npm run integration",
"integration-webpack": "npm run build:lib && cd integration/webpack && npm run integration",
Expand Down

0 comments on commit f022a0f

Please sign in to comment.