ng-ytl-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
279 lines (248 loc) • 8.35 kB
text/typescript
import {
Component,
ElementRef,
HostListener,
Input,
OnDestroy,
OnInit,
TemplateRef,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import { NzLocaleService } from '../locale/index';
import { toBoolean } from '../util/convert';
import nzGlobalMonitor from '../util/nz-global-monitor';
import { NzModalSubject } from './nz-modal-subject.service';
interface Position {
x: number;
y: number;
}
export class NzConfirmComponent implements OnInit, OnDestroy {
private _maskClosable = true;
_confirmLoading = false;
_visible = false;
_prefixCls = 'ant-modal';
_prefixConfirmCls = 'ant-confirm';
_maskClassMap;
_bodyClassMap;
_bodyStyleMap;
_width = '416px';
_zIndex = 1000;
_iconTypeCls = 'anticon anticon-question-circle';
_title = '';
_titleTpl: TemplateRef<void>;
_content = '';
_contentTpl: TemplateRef<void>;
_okText = this._locale.translate('Modal.understood');
_cancelText = '';
_animationStatus = '';
_customClass = '';
_typeCls = `${this._prefixConfirmCls}-confirm`;
private contentEl: ElementRef;
set nzVisible(value: boolean) {
const visible = toBoolean(value);
if (this._visible === visible) {
return;
}
if (visible) {
this.anmiateFade('enter');
this.subject.next('onShow');
// 每次触发点击事件的时候,通过全局监听的类,记录下点击的位置,计算动画的origin
setTimeout(() => {
this.setStyles({
x: nzGlobalMonitor.lastClickPos.x || 0,
y: nzGlobalMonitor.lastClickPos.y || 0
});
}, 10);
} else {
this.anmiateFade('leave');
this.subject.next('onHide');
}
this._visible = visible;
// 设置全局的overflow样式
nzGlobalMonitor.setDocumentOverflowHidden(visible);
}
get nzVisible(): boolean {
return this._visible;
}
set nzWidth(value: number | string) {
this._width = typeof value === 'number' ? value + 'px' : value;
}
set nzClass(value: string) {
this._customClass = value;
}
set nzZIndex(value: number) {
this._zIndex = value;
}
set nzTitle(value: string | TemplateRef<void>) {
// TODO: should guard for string instead, all types are theoretically structural
if (value instanceof TemplateRef) {
this._titleTpl = value;
} else {
this._title = value;
}
}
set nzContent(value: string | TemplateRef<void>) {
if (value instanceof TemplateRef) {
this._contentTpl = value;
} else {
this._content = value;
}
}
set nzMaskClosable(value: boolean) {
this._maskClosable = toBoolean(value);
}
set nzOkText(value: string) {
this._okText = value;
}
set nzCancelText(value: string) {
this._cancelText = value;
}
set nzIconType(value: string) {
if (value) {
this._iconTypeCls = `anticon anticon-${value}`;
}
}
set nzConfirmType(value: string) {
if (value) {
this._typeCls = `${this._prefixConfirmCls}-${value}`;
}
}
set nzConfirmLoading(value: boolean) {
this._confirmLoading = toBoolean(value);
}
onEsc(e: KeyboardEvent): void {
if (this._maskClosable) {
this.subject.next('onCancel');
}
}
onEnter(e: KeyboardEvent): void {
this.subject.next('onOk');
}
setStyles(origin?: { x: number, y: number }): void {
const el = this.contentEl.nativeElement;
const transformOrigin = origin ? `${origin.x - el.offsetLeft}px ${origin.y - el.offsetTop}px 0px` : '';
this._bodyStyleMap = {
'width' : this._width,
'transform-origin': transformOrigin
};
}
setClassMap(): void {
this._maskClassMap = {
[`${this._prefixCls}-mask`] : true,
[`${this._prefixCls}-mask-hidden`]: !this._visible && !this._animationStatus,
'fade-enter' : this._animationStatus === 'enter',
'fade-enter-active' : this._animationStatus === 'enter',
'fade-leave' : this._animationStatus === 'leave',
'fade-leave-active' : this._animationStatus === 'leave'
};
this._bodyClassMap = {
[this._prefixCls] : true,
[this._prefixConfirmCls]: true,
[this._typeCls] : true,
'zoom-enter' : this._animationStatus === 'enter',
'zoom-enter-active' : this._animationStatus === 'enter',
'zoom-leave' : this._animationStatus === 'leave',
'zoom-leave-active' : this._animationStatus === 'leave'
};
}
anmiateFade(status: string): void {
this._animationStatus = status;
this.setClassMap();
setTimeout(_ => {
this._animationStatus = '';
this.setClassMap();
this.subject.next(status === 'enter' ? 'onShown' : 'onHidden');
// modal打开后,默认焦点设置到modal上
if (status === 'enter') {
this.contentEl.nativeElement.parentNode.focus();
}
}, 200);
}
closeFromMask(e: MouseEvent): void {
if (this._maskClosable && (e.target as HTMLElement).getAttribute('role') === 'dialog') {
this.subject.next('onCancel');
}
}
constructor(public subject: NzModalSubject, private _locale: NzLocaleService) {
}
// 通过createComponent方法创建component时,ngOnInit不会被触发
ngOnInit(): void {
this.setClassMap();
this.setStyles();
}
ngOnDestroy(): void {
if (this._visible) {
nzGlobalMonitor.setDocumentOverflowHidden(false);
}
this.subject.next('onDestroy');
this.subject.unsubscribe();
this.subject = null;
}
}