From 1d5e06cead66924a451874f17c0f4932787f18c2 Mon Sep 17 00:00:00 2001 From: Wilson Zeng Date: Fri, 7 Sep 2018 19:30:48 +0800 Subject: [PATCH] feat(module:modal): support customized modal config (current "autoBodyPadding") (#2006) close #1720 --- components/modal/doc/index.en-US.md | 11 +++++++++ components/modal/doc/index.zh-CN.md | 12 +++++++++ components/modal/nz-modal-config.ts | 16 ++++++++++++ components/modal/nz-modal.component.ts | 28 ++++++++++++++------- components/modal/nz-modal.spec.ts | 34 ++++++++++++++++++++++++++ components/modal/public-api.ts | 1 + 6 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 components/modal/nz-modal-config.ts diff --git a/components/modal/doc/index.en-US.md b/components/modal/doc/index.en-US.md index a0a9d9d4865..29ffa05edb1 100644 --- a/components/modal/doc/index.en-US.md +++ b/components/modal/doc/index.en-US.md @@ -16,6 +16,17 @@ 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 diff --git a/components/modal/doc/index.zh-CN.md b/components/modal/doc/index.zh-CN.md index 66f0639373f..906f06217ab 100644 --- a/components/modal/doc/index.zh-CN.md +++ b/components/modal/doc/index.zh-CN.md @@ -17,6 +17,18 @@ 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 diff --git a/components/modal/nz-modal-config.ts b/components/modal/nz-modal-config.ts new file mode 100644 index 00000000000..3514255ba55 --- /dev/null +++ b/components/modal/nz-modal-config.ts @@ -0,0 +1,16 @@ +import { InjectionToken } from '@angular/core'; + +export const NZ_MODAL_DEFAULT_CONFIG: NzModalConfig = { + autoBodyPadding: true +}; + +export const NZ_MODAL_CONFIG = new InjectionToken('NzModalConfig', { + providedIn: 'root', + 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 +} diff --git a/components/modal/nz-modal.component.ts b/components/modal/nz-modal.component.ts index edceae5d1b0..6fa8474ded2 100644 --- a/components/modal/nz-modal.component.ts +++ b/components/modal/nz-modal.component.ts @@ -31,6 +31,7 @@ import { InputBoolean } from '../core/util/convert'; 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'; import { NzModalControlService } from './nz-modal-control.service'; import { NzModalRef } from './nz-modal-ref.class'; import { ModalButtonOptions, ModalOptions, ModalType, OnClickCallback } from './nz-modal.type'; @@ -128,9 +129,12 @@ export class NzModalComponent extends NzModalRef impleme private viewContainer: ViewContainerRef, private nzMeasureScrollbarService: NzMeasureScrollbarService, private modalControl: NzModalControlService, + @Inject(NZ_MODAL_CONFIG) private config: NzModalConfig, @Inject(DOCUMENT) private document: any) { // tslint:disable-line:no-any super(); + + this.config = this.mergeDefaultConfig(this.config); } ngOnInit(): void { @@ -417,16 +421,18 @@ export class NzModalComponent extends NzModalRef impleme * @param plusNum The number that the openModals.length will increase soon */ private changeBodyOverflow(plusNum: number = 0): void { - 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'); + 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'); } - } 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'); } } @@ -437,6 +443,10 @@ export class NzModalComponent extends NzModalRef impleme 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 }; + } } //////////// diff --git a/components/modal/nz-modal.spec.ts b/components/modal/nz-modal.spec.ts index 4263b99650e..9e4515afef7 100644 --- a/components/modal/nz-modal.spec.ts +++ b/components/modal/nz-modal.spec.ts @@ -14,6 +14,7 @@ import { NzMeasureScrollbarService } from '../core/services/nz-measure-scrollbar import en_US from '../i18n/languages/en_US'; import { NzI18nService } from '../i18n/nz-i18n.service'; 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'; @@ -530,6 +531,39 @@ describe('NzModal', () => { }); }); +describe('NzModal with config settled', () => { + let modalService: NzModalService; + + beforeEach(fakeAsync(() => { + TestBed.configureTestingModule({ + imports: [ NzModalModule ], + providers: [{ + provide: NZ_MODAL_CONFIG, + useValue: { + autoBodyPadding: false // Disable body padding + } + }] + }).compileComponents(); + })); + + beforeEach(inject([ NzModalService ], (ms: NzModalService) => { + modalService = ms; + })); + + 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(); + }); +}); + // ------------------------------------------- // | Testing Components // ------------------------------------------- diff --git a/components/modal/public-api.ts b/components/modal/public-api.ts index e6e1bf6ea2c..b7166d02206 100644 --- a/components/modal/public-api.ts +++ b/components/modal/public-api.ts @@ -2,4 +2,5 @@ export { NzModalComponent } from './nz-modal.component'; export { NzModalRef } from './nz-modal-ref.class'; export { NzModalModule } from './nz-modal.module'; export { NzModalService } from './nz-modal.service'; +export { NZ_MODAL_CONFIG, NzModalConfig } from './nz-modal-config'; export * from './nz-modal.type';