@yncoder/element-react
Version:
Element UI for React
238 lines (211 loc) • 7.45 kB
JSX
/* @flow */
import * as React from 'react';
import { Component, PropTypes, Transition, View } from '../../libs';
import { cleanScrollBar } from '../table/utils';
import Button from '../button';
import Input from '../input';
import i18n from '../locale';
const typeMap = {
success: 'circle-check',
info: 'information',
warning: 'warning',
error: 'circle-cross'
};
type State = {
visible: boolean,
inputValue?: string,
editorErrorMessage?: string
};
export default class MessageBox extends Component {
state: State;
constructor(props: Object) {
super(props);
this.state = {
visible: false,
inputValue: props.inputValue
};
}
componentDidMount() {
cleanScrollBar()
this.setState({ visible: true });
document.activeElement && document.activeElement.blur()
}
confirmButtonText(): string {
return this.props.confirmButtonText || i18n.t('el.messagebox.confirm');
}
cancelButtonText(): string {
return this.props.cancelButtonText || i18n.t('el.messagebox.cancel');
}
onChange(value: string): void {
this.setState({
inputValue: value
});
this.validate(value);
}
typeClass(): string {
return this.props.type && typeMap[this.props.type] && `el-icon-${typeMap[this.props.type]}`;
}
validate(value: string): boolean {
const { inputPattern, inputValidator, inputErrorMessage } = this.props;
let editorErrorMessage;
if (inputPattern && !inputPattern.test(value)) {
editorErrorMessage = inputErrorMessage || i18n.t('el.messagebox.error');
}
if (typeof inputValidator === 'function') {
const validateResult = inputValidator(value);
if (validateResult === false) {
editorErrorMessage = inputErrorMessage || i18n.t('el.messagebox.error');
}
if (typeof validateResult === 'string') {
editorErrorMessage = validateResult;
}
}
this.setState({ editorErrorMessage });
return !editorErrorMessage;
}
handleAction(action: string): void {
const { modal, promise, showInput } = this.props;
if (modal) {
switch (action) {
case 'cancel':
promise.reject();
break;
case 'confirm':
if (modal === 'prompt') {
if (this.validate(this.state.inputValue || '')) {
if (showInput) {
promise.resolve({ value: this.state.inputValue, action });
} else {
promise.resolve(action);
}
} else {
return;
}
} else {
promise.resolve();
}
break;
default:
break;
}
} else {
promise.resolve(action);
}
this.close();
}
close(): void {
this.setState({
visible: false
});
}
render(): React.DOM {
const { willUnmount, title, showClose, message, showInput, inputPlaceholder, showCancelButton, cancelButtonClass, showConfirmButton, confirmButtonClass, customClass, inputType } = this.props;
const { visible, editorErrorMessage } = this.state;
return (
<div>
<Transition name="v-modal">
<View show={visible}>
<div className="v-modal"></div>
</View>
</Transition>
<div style={{ position: 'absolute' }}>
<Transition
name="msgbox-fade"
onAfterLeave={() => {
willUnmount && willUnmount()
}}
>
<View show={visible}>
<div className={this.classNames('el-message-box__wrapper', customClass)}>
<div className="el-message-box">
{
title && (
<div className="el-message-box__header">
<div className="el-message-box__title">{title}</div>
{
showClose && (
<button type="button" className="el-message-box__headerbtn" aria-label="Close"
onClick={this.handleAction.bind(this, 'cancel')}>
<i className="el-message-box__close el-icon-close" />
</button>
)
}
</div>
)
}
{
message && (
<div className="el-message-box__content">
<div className={this.classNames('el-message-box__status', this.typeClass())} />
<div className="el-message-box__message"
style={{ marginLeft: this.typeClass() ? '50px' : '0' }}>
<div>{message}</div>
</div>
<View show={showInput}>
<div className="el-message-box__input">
<Input
className={this.classNames({
'invalid': editorErrorMessage
})}
type={inputType}
value={this.state.inputValue}
placeholder={inputPlaceholder}
onChange={this.onChange.bind(this)}
/>
<div className="el-message-box__errormsg" style={{
visibility: editorErrorMessage ? 'visible' : 'hidden'
}}>{editorErrorMessage}</div>
</div>
</View>
</div>
)
}
<div className="el-message-box__btns">
<View show={showCancelButton}>
<Button className={cancelButtonClass}
onClick={this.handleAction.bind(this, 'cancel')}>{this.cancelButtonText()}</Button>
</View>
<View show={showConfirmButton}>
<Button className={this.classNames('el-button--primary', confirmButtonClass)}
onClick={this.handleAction.bind(this, 'confirm')}>{this.confirmButtonText()}</Button>
</View>
</div>
</div>
</div>
</View>
</Transition>
</div>
</div>
)
}
}
MessageBox.propTypes = {
modal: PropTypes.oneOf(['alert', 'confirm', 'prompt']),
type: PropTypes.oneOf(['success', 'warning', 'info', 'error']),
title: PropTypes.string,
message: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
showInput: PropTypes.bool,
showClose: PropTypes.bool,
showCancelButton: PropTypes.bool,
showConfirmButton: PropTypes.bool,
confirmButtonText: PropTypes.string,
cancelButtonText: PropTypes.string,
cancelButtonClass: PropTypes.string,
confirmButtonClass: PropTypes.string,
customClass: PropTypes.string,
inputPlaceholder: PropTypes.string,
inputPattern: PropTypes.regex,
inputValidator: PropTypes.func,
inputErrorMessage: PropTypes.string,
inputValue: PropTypes.any,
inputType: PropTypes.string,
promise: PropTypes.object,
onClose: PropTypes.func
}
MessageBox.defaultProps = {
title: '提示',
showInput: false,
showClose: true,
showCancelButton: false,
showConfirmButton: true
}