ant-design/components/modal/Modal.tsx

182 lines
4.5 KiB
TypeScript
Raw Normal View History

2016-09-21 11:54:53 +08:00
import React from 'react';
2016-01-12 17:07:24 +08:00
import Dialog from 'rc-dialog';
import PropTypes from 'prop-types';
2016-06-16 22:34:54 +08:00
import addEventListener from 'rc-util/lib/Dom/addEventListener';
import Button, { ButtonType } from '../button';
2016-01-12 17:07:24 +08:00
let mousePosition;
let mousePositionEventBinded;
export interface ModalProps {
/** 对话框是否可见*/
visible?: boolean;
/** 确定按钮 loading*/
confirmLoading?: boolean;
/** 标题*/
title?: React.ReactNode | string;
/** 是否显示右上角的关闭按钮*/
closable?: boolean;
/** 点击确定回调*/
onOk?: (e: React.MouseEvent<any>) => void;
/** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/
2016-10-19 17:51:33 +08:00
onCancel?: (e: React.MouseEvent<any>) => void;
afterClose?: () => void;
/** 宽度*/
width?: string | number;
/** 底部内容*/
footer?: React.ReactNode;
/** 确认按钮文字*/
okText?: string;
/** 确认按钮类型*/
okType?: ButtonType;
/** 取消按钮文字*/
cancelText?: string;
/** 取消按钮类型*/
cancelType?: ButtonType;
/** 点击蒙层是否允许关闭*/
maskClosable?: boolean;
style?: React.CSSProperties;
wrapClassName?: string;
maskTransitionName?: string;
transitionName?: string;
className?: string;
getContainer?: (instance: React.ReactInstance) => HTMLElement;
}
export interface ModalContext {
antLocale?: {
Modal?: any,
};
}
export interface ModalFuncProps {
visible?: boolean;
title?: React.ReactNode | string;
content?: React.ReactNode | string;
onOk?: (func: Function) => any;
onCancel?: (func: Function) => any;
width?: string | number;
iconClassName?: string;
okText?: string;
okType?: ButtonType;
cancelText?: string;
cancelType?: ButtonType;
iconType?: string;
maskClosable?: boolean;
}
export type ModalFunc = (props: ModalFuncProps) => {
destroy: () => void,
};
export default class Modal extends React.Component<ModalProps, any> {
static info: ModalFunc;
static success: ModalFunc;
static error: ModalFunc;
static warn: ModalFunc;
static warning: ModalFunc;
static confirm: ModalFunc;
static defaultProps = {
prefixCls: 'ant-modal',
width: 520,
transitionName: 'zoom',
2016-04-04 17:38:39 +08:00
maskTransitionName: 'fade',
confirmLoading: false,
visible: false,
okType: 'primary'
2016-07-13 11:14:24 +08:00
};
2016-03-03 17:43:38 +08:00
static propTypes = {
prefixCls: PropTypes.string,
onOk: PropTypes.func,
onCancel: PropTypes.func,
okText: PropTypes.node,
cancelText: PropTypes.node,
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
confirmLoading: PropTypes.bool,
visible: PropTypes.bool,
align: PropTypes.object,
footer: PropTypes.node,
title: PropTypes.node,
closable: PropTypes.bool,
2016-07-13 11:14:24 +08:00
};
static contextTypes = {
antLocale: PropTypes.object,
2016-07-13 11:14:24 +08:00
};
context: ModalContext;
handleCancel = (e) => {
2016-10-24 12:04:26 +08:00
const onCancel = this.props.onCancel;
if (onCancel) {
onCancel(e);
}
}
2016-01-12 17:07:24 +08:00
handleOk = (e) => {
2016-10-24 12:04:26 +08:00
const onOk = this.props.onOk;
if (onOk) {
onOk(e);
2016-10-24 12:04:26 +08:00
}
}
2016-01-12 17:07:24 +08:00
componentDidMount() {
if (mousePositionEventBinded) {
return;
}
// 只有点击事件支持从鼠标位置动画展开
addEventListener(document.documentElement, 'click', (e: MouseEvent) => {
2016-01-12 17:07:24 +08:00
mousePosition = {
x: e.pageX,
2016-05-11 09:32:33 +08:00
y: e.pageY,
2016-01-12 17:07:24 +08:00
};
2016-10-07 18:00:40 +08:00
// 100ms 内发生过点击事件,则从点击位置动画展示
2016-01-12 17:07:24 +08:00
// 否则直接 zoom 展示
// 这样可以兼容非点击方式展开
2016-10-07 18:00:40 +08:00
setTimeout(() => mousePosition = null, 100);
2016-01-12 17:07:24 +08:00
});
mousePositionEventBinded = true;
}
2016-01-12 17:07:24 +08:00
render() {
let { okText, okType, cancelText, cancelType, confirmLoading, footer, visible } = this.props;
2016-03-03 17:43:38 +08:00
2016-03-05 16:39:27 +08:00
if (this.context.antLocale && this.context.antLocale.Modal) {
okText = okText || this.context.antLocale.Modal.okText;
cancelText = cancelText || this.context.antLocale.Modal.cancelText;
2016-03-03 17:43:38 +08:00
}
const defaultFooter = [(
2016-08-29 20:48:47 +08:00
<Button
key="cancel"
type={cancelType}
2016-01-12 17:07:24 +08:00
size="large"
onClick={this.handleCancel}
>
2016-03-07 12:08:52 +08:00
{cancelText || '取消'}
</Button>
), (
2016-08-29 20:48:47 +08:00
<Button
key="confirm"
type={okType}
2016-01-12 17:07:24 +08:00
size="large"
2016-08-29 20:48:47 +08:00
loading={confirmLoading}
onClick={this.handleOk}
>
2016-03-07 12:08:52 +08:00
{okText || '确定'}
</Button>
)];
2016-08-29 20:48:47 +08:00
2016-01-13 22:22:33 +08:00
return (
2016-08-29 20:48:47 +08:00
<Dialog
onClose={this.handleCancel}
footer={footer === undefined ? defaultFooter : footer}
2016-08-29 20:48:47 +08:00
{...this.props}
visible={visible}
mousePosition={mousePosition}
/>
2016-01-13 22:22:33 +08:00
);
2016-01-12 17:07:24 +08:00
}
}