reactnativecomponents
Version:
React Native Components
229 lines (228 loc) • 5.9 kB
JavaScript
import * as React from 'react';
import * as PropTypes from 'prop-types';
import * as Animatable from 'react-native-animatable';
import Component from '../AbstractComponent';
import { Keyboard, Text, View, StyleSheet } from 'react-native';
import { createRootView } from '../createRootNode/index';
import { AbstractDialog } from '../Dialog/index';
import Button from '../Button/index';
import { fontSize } from '../styles';
const styles = StyleSheet.create({
mask: {
flex: 1,
justifyContent: 'center',
backgroundColor: 'rgba(0,0,0,.4)'
},
container: {
marginHorizontal: 15,
borderRadius: 10,
borderWidth: 0.1,
minHeight: 100,
overflow: 'hidden'
},
content: {
paddingHorizontal: 10
},
title: {
textAlign: 'center',
fontSize,
padding: 15
},
buttonGroup: {
marginTop: 15,
flexDirection: 'row'
},
buttonStyle: {
flex: 1
},
button: {
borderRadius: 0
}
});
const popupShowAnimation = {
animation: 'slideInUp',
duration: 300
};
const popupHideAnimation = {
animation: 'slideOutDown',
duration: 300
};
class SceneModal extends Component {
constructor(props) {
super(props);
const { showAnimation, scene } = props;
let animation = {};
switch (scene) {
case 'popup':
animation = showAnimation || popupShowAnimation;
break;
default:
break;
}
this.state = {
visible: true,
isShow: true,
animation
};
}
getChildContext() {
return {
destroy: this.handleClose
};
}
handlePress(onPress) {
return () => {
const result = onPress && onPress();
console.log(result, result !== true);
this.handleClose(result);
};
}
handleDismiss() {
const { onDismiss } = this.props;
Keyboard.dismiss();
const result = onDismiss && onDismiss();
this.handleClose(result);
}
handleClose(result) {
if (result !== true) {
const { hideAnimation, scene } = this.props;
let animation;
switch (scene) {
case 'popup':
animation = hideAnimation || popupHideAnimation;
break;
default:
break;
}
this.setState({
animation,
isShow: false
});
// 如果不存在关闭动画,直接销毁组件
if (!animation) {
this.destroy();
}
}
}
handleAnimationEnd() {
if (!this.state.isShow) {
this.destroy();
}
}
destroy() {
this.setState({ visible: false });
this.context.manager.destroy();
}
render() {
const { maskStyle, containerStyle, contentStyle, title, content, buttons } = this.props;
const { animation, visible } = this.state;
return (<AbstractDialog onPress={this.handleDismiss} style={[styles.mask, maskStyle]} visible={visible}>
<Animatable.View {...animation} onAnimationEnd={this.handleAnimationEnd} style={[styles.container, containerStyle]}>
{typeof title === 'string' ? (<Text style={styles.title}>{title}</Text>) : title}
<View style={[styles.content, contentStyle]}>
{typeof content === 'string' ? (<Text>{content}</Text>) : content}
</View>
{buttons && buttons.length > 0 && (<View style={[styles.buttonGroup]}>
{buttons.map(({ onPress, containerStyle, style, ...props }, index) => (<Button {...props} containerStyle={[styles.button, containerStyle]} key={index} onPress={this.handlePress(onPress)} style={[styles.buttonStyle, style]}/>))}
</View>)}
</Animatable.View>
</AbstractDialog>);
}
}
SceneModal.defaultProps = {
buttons: []
};
SceneModal.contextTypes = {
manager: PropTypes.object
};
SceneModal.childContextTypes = {
destroy: PropTypes.func
};
/**
* 情景模态框
*/
function sceneModal(props) {
return createRootView(SceneModal, props);
}
export default (args) => {
return sceneModal(args);
};
/**
* 消息模态框
*/
export function info(args) {
return sceneModal({
...args,
scene: 'info'
});
}
/**
* 成功模态框
*/
export function success(args) {
return sceneModal({
...args,
scene: 'success'
});
}
/**
* 错误模态框
*/
export function error(args) {
return sceneModal({
...args,
scene: 'error'
});
}
/**
* 警告模态框
*/
export function warn(args) {
return sceneModal({
...args,
scene: 'warn'
});
}
/**
* 弹出框,默认有一个确定按钮
* @param {any} ok 按钮children 内容,默认为"确定"
* @param {any} onOk 按钮onPress事件
* @param {{}} args 其他参数
* @returns {RootManager}
*/
export function alert({ ok = '确定', onOk, button, ...args } = {}) {
const buttons = [{
onPress: onOk,
children: ok,
...button
}];
return sceneModal({
...args,
scene: 'alert',
buttons
});
}
/**
*/
export function confirm({ cancel = '取消', ok = '确定', onOk, okButton, onCancel, cancelButton, ...args } = {}) {
const buttons = [{
children: cancel,
onPress: onCancel,
...cancelButton
}, {
children: ok,
onPress: onOk,
...okButton
}];
return sceneModal({
...args,
scene: 'confirm',
buttons
});
}
export function popup(args) {
return sceneModal({
...args,
scene: 'popup'
});
}