From 6a45bec05f7e1134fa9df8ef3aba30491fa71c73 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Fri, 1 Feb 2019 18:41:13 +0800 Subject: [PATCH 1/9] refactor(module:modal): refactor block scroll strategy close #2612 --- components/modal/nz-modal-config.ts | 7 +- components/modal/nz-modal.component.ts | 127 ++++++++++--------------- 2 files changed, 52 insertions(+), 82 deletions(-) diff --git a/components/modal/nz-modal-config.ts b/components/modal/nz-modal-config.ts index 3514255ba55..db66f7f1751 100644 --- a/components/modal/nz-modal-config.ts +++ b/components/modal/nz-modal-config.ts @@ -9,8 +9,9 @@ export const NZ_MODAL_CONFIG = new InjectionToken('NzModalConfig' factory: () => NZ_MODAL_DEFAULT_CONFIG // Default config }); -//////////// - export interface NzModalConfig { - autoBodyPadding: boolean; // Whether add the padding-right and overflow to body automatically to play smoothly + /** + * @deprecated used {@link BlockScrollStrategy} instead. + */ + autoBodyPadding?: boolean; // Whether add the padding-right and overflow to body automatically to play smoothly } diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index cec078afece..8602a89afa6 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -1,8 +1,11 @@ import { FocusTrap, FocusTrapFactory } from '@angular/cdk/a11y'; -import { Overlay, OverlayRef } from '@angular/cdk/overlay'; + +import { ESCAPE } from '@angular/cdk/keycodes'; +import { BlockScrollStrategy, Overlay, OverlayRef } from '@angular/cdk/overlay'; import { DOCUMENT } from '@angular/common'; import { AfterViewInit, + ChangeDetectionStrategy, Component, ComponentFactoryResolver, ComponentRef, @@ -30,8 +33,6 @@ import { NzMeasureScrollbarService } from '../core/services/nz-measure-scrollbar import { InputBoolean } from '../core/util/convert'; import { NzI18nService } from '../i18n/nz-i18n.service'; - -import { ESCAPE } from '@angular/cdk/keycodes'; import ModalUtil from './modal-util'; import { NzModalConfig, NZ_MODAL_CONFIG, NZ_MODAL_DEFAULT_CONFIG } from './nz-modal-config'; import { NzModalControlService } from './nz-modal-control.service'; @@ -44,41 +45,51 @@ type AnimationState = 'enter' | 'leave' | null; @Component({ selector : 'nz-modal', - templateUrl: './nz-modal.component.html' + templateUrl: './nz-modal.component.html', + changeDetection: ChangeDetectionStrategy.OnPush }) // tslint:disable-next-line:no-any export class NzModalComponent extends NzModalRef implements OnInit, OnChanges, AfterViewInit, OnDestroy, ModalOptions { - private unsubscribe$ = new Subject(); - private previouslyFocusedElement: HTMLElement; - private focusTrap: FocusTrap; - // tslint:disable-next-line:no-any - locale: any = {}; - @Input() nzModalType: ModalType = 'default'; + @Input() @InputBoolean() nzVisible: boolean = false; + @Input() @InputBoolean() nzClosable: boolean = true; + @Input() @InputBoolean() nzMask: boolean = true; + @Input() @InputBoolean() nzMaskClosable: boolean = true; + @Input() @InputBoolean() nzOkLoading: boolean = false; + @Input() @InputBoolean() nzOkDisabled: boolean = false; + @Input() @InputBoolean() nzCancelDisabled: boolean = false; + @Input() @InputBoolean() nzCancelLoading: boolean = false; + @Input() @InputBoolean() nzKeyboard: boolean = true; @Input() nzContent: string | TemplateRef<{}> | Type; // [STATIC] If not specified, will use @Input() nzComponentParams: T; // [STATIC] ONLY avaliable when nzContent is a component @Input() nzFooter: string | TemplateRef<{}> | Array>; // [STATIC] Default Modal ONLY @Input() nzGetContainer: HTMLElement | OverlayRef | (() => HTMLElement | OverlayRef) = () => this.overlay.create(); // [STATIC] - - @Input() @InputBoolean() nzVisible: boolean = false; - @Output() readonly nzVisibleChange = new EventEmitter(); - @Input() nzZIndex: number = 1000; @Input() nzWidth: number | string = 520; @Input() nzWrapClassName: string; @Input() nzClassName: string; @Input() nzStyle: object; - @Input() nzIconType: string = 'question-circle'; // Confirm Modal ONLY @Input() nzTitle: string | TemplateRef<{}>; - @Input() @InputBoolean() nzClosable: boolean = true; - @Input() @InputBoolean() nzMask: boolean = true; - @Input() @InputBoolean() nzMaskClosable: boolean = true; @Input() nzMaskStyle: object; @Input() nzBodyStyle: object; + @Input() nzOkText: string; + @Input() nzCancelText: string; + @Input() nzOkType = 'primary'; + @Input() nzIconType: string = 'question-circle'; // Confirm Modal ONLY + @Input() nzModalType: ModalType = 'default'; + + @Input() @Output() readonly nzOnOk: EventEmitter | OnClickCallback = new EventEmitter(); + @Input() @Output() readonly nzOnCancel: EventEmitter | OnClickCallback = new EventEmitter(); @Output() readonly nzAfterOpen = new EventEmitter(); // Trigger when modal open(visible) after animations @Output() readonly nzAfterClose = new EventEmitter(); // Trigger when modal leave-animation over + @Output() readonly nzVisibleChange = new EventEmitter(); + + @ViewChild('modalContainer') modalContainer: ElementRef; + @ViewChild('bodyContainer', { read: ViewContainerRef }) bodyContainer: ViewContainerRef; + @ViewChild('autoFocusButtonOk', { read: ElementRef }) autoFocusButtonOk: ElementRef; // Only aim to focus the ok button that needs to be auto focused + get afterOpen(): Observable { // Observable alias for nzAfterOpen return this.nzAfterOpen.asObservable(); } @@ -87,34 +98,19 @@ export class NzModalComponent extends NzModalRef impleme return this.nzAfterClose.asObservable(); } - // --- Predefined OK & Cancel buttons - @Input() nzOkText: string; - - get okText(): string { - return this.nzOkText || this.locale.okText; - } - - @Input() nzOkType = 'primary'; - @Input() @InputBoolean() nzOkLoading: boolean = false; - @Input() @Output() readonly nzOnOk: EventEmitter | OnClickCallback = new EventEmitter(); - @ViewChild('autoFocusButtonOk', { read: ElementRef }) autoFocusButtonOk: ElementRef; // Only aim to focus the ok button that needs to be auto focused - @Input() nzCancelText: string; - get cancelText(): string { return this.nzCancelText || this.locale.cancelText; } - @Input() @InputBoolean() nzOkDisabled: boolean = false; - @Input() @InputBoolean() nzCancelDisabled: boolean = false; - @Input() @InputBoolean() nzCancelLoading: boolean = false; - @Input() @Output() readonly nzOnCancel: EventEmitter | OnClickCallback = new EventEmitter(); - @ViewChild('modalContainer') modalContainer: ElementRef; - @ViewChild('bodyContainer', { read: ViewContainerRef }) bodyContainer: ViewContainerRef; - @Input() @InputBoolean() nzKeyboard: boolean = true; + get okText(): string { + return this.nzOkText || this.locale.okText; + } get hidden(): boolean { return !this.nzVisible && !this.animationState; } // Indicate whether this dialog should hidden + + locale: { okText?: string, cancelText?: string } = {}; maskAnimationClassMap: object; modalAnimationClassMap: object; transformOrigin = '0px 0px 0px'; // The origin point that animation based on @@ -122,6 +118,10 @@ export class NzModalComponent extends NzModalRef impleme private contentComponentRef: ComponentRef; // Handle the reference when using nzContent as Component private animationState: AnimationState; // Current animation state private container: HTMLElement | OverlayRef; + private unsubscribe$ = new Subject(); + private previouslyFocusedElement: HTMLElement; + private focusTrap: FocusTrap; + private scrollStrategy: BlockScrollStrategy; constructor( private overlay: Overlay, @@ -139,10 +139,11 @@ export class NzModalComponent extends NzModalRef impleme super(); this.config = this.mergeDefaultConfig(this.config); + this.scrollStrategy = this.overlay.scrollStrategies.block(); } ngOnInit(): void { - this.i18n.localeChange.pipe(takeUntil(this.unsubscribe$)).subscribe(() => this.locale = this.i18n.getLocaleData('Modal')); + this.i18n.localeChange.pipe(takeUntil(this.unsubscribe$)).subscribe(() => this.locale = this.i18n.getLocaleData('Modal') as { okText: string, cancelText: string }); fromEvent(this.document.body, 'keydown').pipe(takeUntil(this.unsubscribe$)).subscribe(e => this.keydownListener(e)); @@ -304,7 +305,7 @@ export class NzModalComponent extends NzModalRef impleme // Do rest things when visible state changed private handleVisibleStateChange(visible: boolean, animation: boolean = true, closeResult?: R): Promise { if (visible) { // Hide scrollbar at the first time when shown up - this.changeBodyOverflow(1); + this.scrollStrategy.enable(); this.savePreviouslyFocusedElement(); this.trapFocus(); } @@ -317,7 +318,7 @@ export class NzModalComponent extends NzModalRef impleme } else { this.nzAfterClose.emit(closeResult); this.restoreFocus(); - this.changeBodyOverflow(); // Show/hide scrollbar when animation is over + this.scrollStrategy.disable(); } }); // .then(() => this.changeBodyOverflow()); @@ -383,21 +384,17 @@ export class NzModalComponent extends NzModalRef impleme private formatModalButtons(buttons: Array>): Array> { return buttons.map((button) => { - const mixedButton = { + return { ...{ - type : 'default', - size : 'default', + type: 'default', + size: 'default', autoLoading: true, - show : true, - loading : false, - disabled : false + show: true, + loading: false, + disabled: false }, ...button }; - - // if (mixedButton.autoLoading) { mixedButton.loading = false; } // Force loading to false when autoLoading=true - - return mixedButton; }); } @@ -431,34 +428,6 @@ export class NzModalComponent extends NzModalRef impleme // } } - /** - * Take care of the body's overflow to decide the existense of scrollbar - * @param plusNum The number that the openModals.length will increase soon - */ - private changeBodyOverflow(plusNum: number = 0): void { - if (this.config.autoBodyPadding) { - const openModals = this.modalControl.openModals; - - if (openModals.length + plusNum > 0) { - if (this.hasBodyScrollBar()) { // Adding padding-right only when body's scrollbar is able to shown up - this.renderer.setStyle(this.document.body, 'padding-right', `${this.nzMeasureScrollbarService.scrollBarWidth}px`); - this.renderer.setStyle(this.document.body, 'overflow', 'hidden'); - } - } else { // NOTE: we need to always remove the padding due to the scroll bar may be disappear by window resizing before modal closed - this.renderer.removeStyle(this.document.body, 'padding-right'); - this.renderer.removeStyle(this.document.body, 'overflow'); - } - } - } - - /** - * Check whether the body element is able to has the scroll bar (if the body content height exceeds the window's height) - * Exceptional Cases: users can show the scroll bar by their own permanently (eg. overflow: scroll) - */ - private hasBodyScrollBar(): boolean { - return this.document.body.scrollHeight > (window.innerHeight || this.document.documentElement.clientHeight); - } - private mergeDefaultConfig(config: NzModalConfig): NzModalConfig { return { ...NZ_MODAL_DEFAULT_CONFIG, ...config }; } From b116e607072c76f051f11665c87c4f1d02dc21a7 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Sat, 2 Feb 2019 11:28:37 +0800 Subject: [PATCH 2/9] docs(module:modal): update docs --- components/modal/doc/index.en-US.md | 12 ------------ components/modal/doc/index.zh-CN.md | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/components/modal/doc/index.en-US.md b/components/modal/doc/index.en-US.md index 00593de81d9..79e53162f0b 100644 --- a/components/modal/doc/index.en-US.md +++ b/components/modal/doc/index.en-US.md @@ -16,18 +16,6 @@ and so on. It is recommended to use the `Component` way to pop up the Modal, so that the component logic of the popup layer can be completely isolated from the outer component, and can be reused at any time. In the popup layer component, you can obtain Modal's component instance by injecting `NzModalRef` to control the behavior of the modal box. -## How To Use - -If you want to modify the global default configuration, you can modify the value of provider `NZ_MODAL_CONFIG`. -(eg, add `{ provide: NZ_MODAL_CONFIG, useValue: { autoBodyPadding: false }}` to `providers` of your module, `NZ_MODAL_CONFIG` can be imported from `ng-zorro-antd`) - -The default global configuration is: -```js -{ - autoBodyPadding: true, // Whether to automatically add "padding" and "overflow" the body to hide the scroll bar -} -``` - ## API ### NzModalService diff --git a/components/modal/doc/index.zh-CN.md b/components/modal/doc/index.zh-CN.md index 29dc69dc02e..c7ac058a3fb 100644 --- a/components/modal/doc/index.zh-CN.md +++ b/components/modal/doc/index.zh-CN.md @@ -17,18 +17,6 @@ title: Modal 在弹出层Component中可以通过依赖注入`NzModalRef`方式直接获取模态框的组件实例,用于控制在弹出层组件中控制模态框行为。 -## 如何使用 - -如果要修改全局默认配置,你可以设置提供商 `NZ_MODAL_CONFIG` 的值来修改。 -(如:在你的模块的`providers`中加入 `{ provide: NZ_MODAL_CONFIG, useValue: { autoBodyPadding: false }}`,`NZ_MODAL_CONFIG` 可以从 `ng-zorro-antd` 中导入) - -默认全局配置为: -```js -{ - autoBodyPadding: true, // 是否自动给body加上padding及overflow来隐藏滚动条 -} -``` - ## API ### NzModalService From f5015eafccc33506bb6672ec07d9b24aa37b06d8 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Sat, 2 Feb 2019 11:58:08 +0800 Subject: [PATCH 3/9] test(module:modal): update cases for scrollbar --- components/modal/nz-modal.component.ts | 3 +- components/modal/nz-modal.spec.ts | 65 +++++++------------------- 2 files changed, 19 insertions(+), 49 deletions(-) diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index 8602a89afa6..2b4081b396d 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -45,8 +45,7 @@ type AnimationState = 'enter' | 'leave' | null; @Component({ selector : 'nz-modal', - templateUrl: './nz-modal.component.html', - changeDetection: ChangeDetectionStrategy.OnPush + templateUrl: './nz-modal.component.html' }) // tslint:disable-next-line:no-any diff --git a/components/modal/nz-modal.spec.ts b/components/modal/nz-modal.spec.ts index 46602526e71..52d8147dba0 100644 --- a/components/modal/nz-modal.spec.ts +++ b/components/modal/nz-modal.spec.ts @@ -17,7 +17,6 @@ import en_US from '../i18n/languages/en_US'; import { NzI18nService } from '../i18n/nz-i18n.service'; import { NzIconTestModule } from '../icon/nz-icon-test.module'; import { CssUnitPipe } from './css-unit.pipe'; -import { NZ_MODAL_CONFIG } from './nz-modal-config'; import { NzModalControlService } from './nz-modal-control.service'; import { NzModalRef } from './nz-modal-ref.class'; import { NzModalComponent } from './nz-modal.component'; @@ -404,6 +403,7 @@ describe('NzModal', () => { fixture = TestBed.createComponent(ModalByServiceComponent); }); afterEach(fakeAsync(() => { // wait all openModals tobe closed to clean up the ModalManager as it is globally static + document.documentElement.classList.remove('cdk-global-scrollblock'); modalService.closeAll(); fixture.detectChanges(); tick(1000); @@ -539,56 +539,27 @@ describe('NzModal', () => { expect(spyCancel).toHaveBeenCalled(); }); - it('should add/remove padding-left depends on current scrollbar (just functions mockup)', () => { - const modalRef = modalService.create(); - const modalInstance = modalRef.getInstance(); - spyOnProperty(window, 'innerHeight').and.returnValue(null); // Disable innerHeight to test another branch - // tslint:disable-next-line:no-string-literal - spyOnProperty(modalInstance['document'].body, 'scrollHeight').and.returnValue(200); - // tslint:disable-next-line:no-string-literal - spyOnProperty(modalInstance['document'].documentElement, 'clientHeight').and.returnValue(100); - // tslint:disable-next-line:no-string-literal - expect(modalInstance['hasBodyScrollBar']()).toBeTruthy(); - - // tslint:disable-next-line:no-string-literal - const spySetStyle = spyOn(modalInstance['renderer'], 'setStyle'); - // tslint:disable-next-line:no-string-literal - modalInstance['changeBodyOverflow'](1); - expect(spySetStyle).toHaveBeenCalled(); - }); - }); -}); + it('should block body scroll', fakeAsync(() => { + console.log(document.documentElement.classList); + const forceScrollElement = document.createElement('div'); + document.body.appendChild(forceScrollElement); + forceScrollElement.style.width = '100px'; + forceScrollElement.style.height = '3000px'; + forceScrollElement.style.background = 'rebeccapurple'; -describe('NzModal with config settled', () => { - let modalService: NzModalService; + const modalRef = modalService.create(); + tick(600); + fixture.detectChanges(); - beforeEach(fakeAsync(() => { - TestBed.configureTestingModule({ - imports: [ NzModalModule ], - providers: [{ - provide: NZ_MODAL_CONFIG, - useValue: { - autoBodyPadding: false // Disable body padding - } - }] - }).compileComponents(); - })); + expect(document.documentElement.classList).toContain('cdk-global-scrollblock'); - beforeEach(inject([ NzModalService ], (ms: NzModalService) => { - modalService = ms; - })); + modalRef.close(); + tick(600); + fixture.detectChanges(); - it('should disable body padding', () => { - const modalInstance = modalService.create().getInstance(); - // Both style operating should not be called - // tslint:disable-next-line:no-string-literal - const setStyle = spyOn(modalInstance['renderer'], 'setStyle'); - // tslint:disable-next-line:no-string-literal - const removeStyle = spyOn(modalInstance['renderer'], 'removeStyle'); - // tslint:disable-next-line:no-string-literal - modalInstance['changeBodyOverflow'](); - expect(setStyle).not.toHaveBeenCalled(); - expect(removeStyle).not.toHaveBeenCalled(); + expect(document.documentElement.classList).not.toContain('cdk-global-scrollblock'); + document.body.removeChild(forceScrollElement); + })); }); }); From 591b1b64f1cbe6ce2b5f8d8573cf57b197e87020 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Sat, 2 Feb 2019 13:29:46 +0800 Subject: [PATCH 4/9] refactor(module:modal): use OnPush change detection close #2643, close #2656 --- components/modal/nz-modal.component.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index 2b4081b396d..e9179147a07 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -6,6 +6,7 @@ import { DOCUMENT } from '@angular/common'; import { AfterViewInit, ChangeDetectionStrategy, + ChangeDetectorRef, Component, ComponentFactoryResolver, ComponentRef, @@ -45,7 +46,8 @@ type AnimationState = 'enter' | 'leave' | null; @Component({ selector : 'nz-modal', - templateUrl: './nz-modal.component.html' + templateUrl: './nz-modal.component.html', + changeDetection: ChangeDetectionStrategy.OnPush }) // tslint:disable-next-line:no-any @@ -132,6 +134,7 @@ export class NzModalComponent extends NzModalRef impleme private nzMeasureScrollbarService: NzMeasureScrollbarService, private modalControl: NzModalControlService, private focusTrapFactory: FocusTrapFactory, + private cdr: ChangeDetectorRef, @Inject(NZ_MODAL_CONFIG) private config: NzModalConfig, @Inject(DOCUMENT) private document: any) { // tslint:disable-line:no-any @@ -142,7 +145,10 @@ export class NzModalComponent extends NzModalRef impleme } ngOnInit(): void { - this.i18n.localeChange.pipe(takeUntil(this.unsubscribe$)).subscribe(() => this.locale = this.i18n.getLocaleData('Modal') as { okText: string, cancelText: string }); + this.i18n.localeChange.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { + this.locale = this.i18n.getLocaleData('Modal') as { okText: string, cancelText: string }; + this.cdr.markForCheck(); + }); fromEvent(this.document.body, 'keydown').pipe(takeUntil(this.unsubscribe$)).subscribe(e => this.keydownListener(e)); @@ -318,9 +324,10 @@ export class NzModalComponent extends NzModalRef impleme this.nzAfterClose.emit(closeResult); this.restoreFocus(); this.scrollStrategy.disable(); + // Mark the for check so it can react if the view container is using OnPush change detection. + this.cdr.markForCheck(); } }); - // .then(() => this.changeBodyOverflow()); } // Lookup a button's property, if the prop is a function, call & then return the result, otherwise, return itself. @@ -422,9 +429,6 @@ export class NzModalComponent extends NzModalRef impleme if (lastPosition) { this.transformOrigin = `${lastPosition.x - modalElement.offsetLeft}px ${lastPosition.y - modalElement.offsetTop}px 0px`; } - // else { - // this.transformOrigin = '0px 0px 0px'; - // } } private mergeDefaultConfig(config: NzModalConfig): NzModalConfig { From 00975f34bac26b1679ffb69b976ec99800ccf752 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Wed, 13 Feb 2019 12:08:38 +0800 Subject: [PATCH 5/9] fix(module:modal, drawer): IE/Edge SVG doesn't support `blur`/`focus` method close #2388 --- components/core/util/is-promise.ts | 4 ++++ components/drawer/nz-drawer.component.ts | 5 ++++- components/modal/nz-modal.component.ts | 9 ++------- 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 components/core/util/is-promise.ts diff --git a/components/core/util/is-promise.ts b/components/core/util/is-promise.ts new file mode 100644 index 00000000000..262245469ba --- /dev/null +++ b/components/core/util/is-promise.ts @@ -0,0 +1,4 @@ +// tslint:disable-next-line:no-any +export function isPromise(obj: any): obj is Promise { + return !!obj && typeof obj.then === 'function' && typeof obj.catch === 'function'; +} diff --git a/components/drawer/nz-drawer.component.ts b/components/drawer/nz-drawer.component.ts index 9ce8a8720b8..1743bee5a8d 100644 --- a/components/drawer/nz-drawer.component.ts +++ b/components/drawer/nz-drawer.component.ts @@ -282,7 +282,10 @@ export class NzDrawerComponent extends NzDrawerRef savePreviouslyFocusedElement(): void { if (this.document && !this.previouslyFocusedElement) { this.previouslyFocusedElement = this.document.activeElement as HTMLElement; - this.previouslyFocusedElement.blur(); + // We need the extra check, because IE's svg element has no blur method. + if (this.previouslyFocusedElement && typeof this.previouslyFocusedElement.blur === 'function') { + this.previouslyFocusedElement.blur(); + } } } diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index e9179147a07..5e97cdb022a 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -33,6 +33,7 @@ import { takeUntil } from 'rxjs/operators'; import { NzMeasureScrollbarService } from '../core/services/nz-measure-scrollbar.service'; import { InputBoolean } from '../core/util/convert'; +import { isPromise } from '../core/util/is-promise'; import { NzI18nService } from '../i18n/nz-i18n.service'; import ModalUtil from './modal-util'; import { NzModalConfig, NZ_MODAL_CONFIG, NZ_MODAL_DEFAULT_CONFIG } from './nz-modal-config'; @@ -374,6 +375,7 @@ export class NzModalComponent extends NzModalRef impleme } else { this.maskAnimationClassMap = this.modalAnimationClassMap = null; } + this.cdr.detectChanges(); } private animateTo(isVisible: boolean): Promise { @@ -438,7 +440,6 @@ export class NzModalComponent extends NzModalRef impleme private savePreviouslyFocusedElement(): void { if (this.document) { this.previouslyFocusedElement = this.document.activeElement as HTMLElement; - this.previouslyFocusedElement.blur(); } } @@ -459,9 +460,3 @@ export class NzModalComponent extends NzModalRef impleme } } } - -//////////// - -function isPromise(obj: {} | void): boolean { - return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof (obj as Promise<{}>).then === 'function' && typeof (obj as Promise<{}>).catch === 'function'; -} From d9b8b4cd86e2efe8de03f201082d4cafaed3b820 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Wed, 13 Feb 2019 16:58:09 +0800 Subject: [PATCH 6/9] fix(module:modal): fix animations --- components/modal/nz-modal.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index 5e97cdb022a..cfb406b1dc1 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -375,7 +375,7 @@ export class NzModalComponent extends NzModalRef impleme } else { this.maskAnimationClassMap = this.modalAnimationClassMap = null; } - this.cdr.detectChanges(); + this.cdr.markForCheck(); } private animateTo(isVisible: boolean): Promise { From d68be0db665ebd72c1cb09f9c2a6de5795a25795 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Wed, 13 Feb 2019 19:26:14 +0800 Subject: [PATCH 7/9] refactor(module:modal): switch to Default change detection --- components/modal/nz-modal.component.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index cfb406b1dc1..19f1e1246f3 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -48,7 +48,8 @@ type AnimationState = 'enter' | 'leave' | null; @Component({ selector : 'nz-modal', templateUrl: './nz-modal.component.html', - changeDetection: ChangeDetectionStrategy.OnPush + // Using OnPush for modal caused footer can not to detect changes. we can fix it when 8.x. + changeDetection: ChangeDetectionStrategy.Default }) // tslint:disable-next-line:no-any @@ -148,7 +149,6 @@ export class NzModalComponent extends NzModalRef impleme ngOnInit(): void { this.i18n.localeChange.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { this.locale = this.i18n.getLocaleData('Modal') as { okText: string, cancelText: string }; - this.cdr.markForCheck(); }); fromEvent(this.document.body, 'keydown').pipe(takeUntil(this.unsubscribe$)).subscribe(e => this.keydownListener(e)); @@ -375,7 +375,6 @@ export class NzModalComponent extends NzModalRef impleme } else { this.maskAnimationClassMap = this.modalAnimationClassMap = null; } - this.cdr.markForCheck(); } private animateTo(isVisible: boolean): Promise { From d0ddca037224308dca8d03559617ac13e1870c78 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Wed, 13 Feb 2019 19:38:14 +0800 Subject: [PATCH 8/9] docs: add temporary use case for IE --- components/drawer/demo/basic-right.ts | 1 + components/modal/demo/basic.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/components/drawer/demo/basic-right.ts b/components/drawer/demo/basic-right.ts index 99331435877..e7987bff350 100755 --- a/components/drawer/demo/basic-right.ts +++ b/components/drawer/demo/basic-right.ts @@ -4,6 +4,7 @@ import { Component } from '@angular/core'; selector: 'nz-demo-drawer-basic-right', template: ` +

Some contents...

Some contents...

diff --git a/components/modal/demo/basic.ts b/components/modal/demo/basic.ts index e0a1be5a128..22a7763b3df 100644 --- a/components/modal/demo/basic.ts +++ b/components/modal/demo/basic.ts @@ -4,6 +4,7 @@ import { Component } from '@angular/core'; selector: 'nz-demo-modal-basic', template: ` +

Content one

Content two

From 1ef10c3930d95534971b776602d84e1a4bcfa397 Mon Sep 17 00:00:00 2001 From: Hsuan Lee Date: Wed, 13 Feb 2019 20:19:09 +0800 Subject: [PATCH 9/9] fix: scrollblock style --- components/core/style/index.less | 2 +- components/drawer/demo/basic-right.ts | 1 - components/modal/demo/basic.ts | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/components/core/style/index.less b/components/core/style/index.less index 5dadbde9cc4..f2e23d1797c 100644 --- a/components/core/style/index.less +++ b/components/core/style/index.less @@ -56,7 +56,7 @@ // https://github.com/angular/material2/issues/15051 body { - overflow-x: unset; + overflow-x: visible; } } diff --git a/components/drawer/demo/basic-right.ts b/components/drawer/demo/basic-right.ts index e7987bff350..99331435877 100755 --- a/components/drawer/demo/basic-right.ts +++ b/components/drawer/demo/basic-right.ts @@ -4,7 +4,6 @@ import { Component } from '@angular/core'; selector: 'nz-demo-drawer-basic-right', template: ` -

Some contents...

Some contents...

diff --git a/components/modal/demo/basic.ts b/components/modal/demo/basic.ts index 22a7763b3df..e0a1be5a128 100644 --- a/components/modal/demo/basic.ts +++ b/components/modal/demo/basic.ts @@ -4,7 +4,6 @@ import { Component } from '@angular/core'; selector: 'nz-demo-modal-basic', template: ` -

Content one

Content two