weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
266 lines (256 loc) • 6.28 kB
JSX
/** @jsx createElement */
import { Component, createElement, PropTypes } from 'rax';
import View from 'nuke-view';
import { isWeb, appInfo } from 'nuke-env';
import Text from 'nuke-text';
import Mask from 'nuke-mask';
import Button from 'nuke-button';
import ThemeProvider from 'nuke-theme-provider';
import stylesProvider from '../styles';
import CustomDialogLocales from './locale';
const { connectStyle } = ThemeProvider;
class Dialog extends Component {
constructor(props) {
super(props);
this.show = this.show.bind(this);
this.hide = this.hide.bind(this);
this.onShow = this.onShow.bind(this);
this.onHide = this.onHide.bind(this);
this.wrapPress = this.wrapPress.bind(this);
this.maskTouchMove = this.maskTouchMove.bind(this);
this.contentTouchMove = this.contentTouchMove.bind(this);
this.isIOS = appInfo.platform.toLowerCase() === 'ios';
if (props.type) {
this.isIOS = props.type.toLowerCase() === 'iOS';
}
}
onShow() {
this.props.onShow && this.props.onShow();
}
onHide() {
this.props.onHide && this.props.onHide();
}
hide() {
this.refs.modalMask && this.refs.modalMask.hide();
}
show() {
this.refs.modalMask && this.refs.modalMask.show();
}
wrapPress(e) {
if (isWeb) {
e.stopPropagation();
}
}
fixBody() {
if (isWeb) {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
document.body.style.cssText += `position:fixed;top:-${scrollTop}px;`;
}
}
contentTouchMove(e) {
if (isWeb) {
this.fixBody();
e.stopPropagation();
}
}
maskTouchMove(e) {
if (isWeb) {
this.fixBody();
}
}
getHeader() {
const { title, themeStyle: styles } = this.props;
if (title) {
if (typeof title === 'string') {
return (
<Text
fixedFont
style={[styles.title, this.isIOS ? null : styles['md-title']]}
>
{title}
</Text>
);
}
return title;
}
return null;
}
cancel(e, btnPressCb) {
const { onCancel } = this.props;
if (btnPressCb) {
btnPressCb.call(this, e);
} else {
this.refs.modalMask.hide();
onCancel && onCancel();
}
}
confirm(e, btnPressCb) {
const { onConfirm } = this.props;
if (btnPressCb) {
btnPressCb.call(this, e);
} else {
this.refs.modalMask.hide();
onConfirm && onConfirm();
}
}
getFooter() {
const {
showCancelButton,
showConfirmButton,
confirmButtonStyle,
cancelButtonStyle,
footerStyle,
themeStyle: styles,
} = this.props;
let footerDom = [];
const locale = this.getLocale();
const btnStyles = this.isIOS ? styles.btn : styles['md-btn'];
const footerStyles = Object.assign(
{},
styles.footer,
this.isIOS ? null : styles['md-footer'],
footerStyle
);
let cancelDom;
let confirmDom;
if (!showConfirmButton && !showCancelButton) return null;
if (showCancelButton) {
cancelDom = (
<Button
rect
fixedFont
style={Object.assign(
{},
btnStyles,
this.isIOS ? null : styles['md-btn-weak'],
showConfirmButton ? styles['btn-left'] : null,
this.isIOS && showConfirmButton ? null : styles['md-btn-left'],
cancelButtonStyle
)}
type="normal"
onPress={(e) => {
this.cancel(e, null);
}}
>
{locale.cancel}
</Button>
);
}
if (showConfirmButton) {
confirmDom = (
<Button
rect
style={[
btnStyles,
showCancelButton ? styles['btn-right'] : null,
confirmButtonStyle,
]}
type="normal"
onPress={(e) => {
this.confirm(e, null);
}}
>
{locale.confirm}
</Button>
);
}
footerDom = (
<View role="footer" style={footerStyles}>
{cancelDom}
{confirmDom}
</View>
);
return footerDom;
}
getLocale() {
const { locale = {} } = this.props;
const localeName = 'en';
return Object.assign(
{},
CustomDialogLocales[localeName] || CustomDialogLocales.en,
locale
);
}
getContent() {
const { content, themeStyle: styles, children } = this.props;
if (children) {
return children;
}
if (content) {
if (typeof content === 'string') {
return (
<Text
fixedFont
style={[styles.content, this.isIOS ? null : styles['md-content']]}
>
{content}
</Text>
);
}
return content;
}
return null;
}
render() {
const {
contentStyle = {},
maskClosable,
renderMask,
style,
} = this.props;
const styles = this.props.themeStyle;
const dialogContent = (
<View
data-role="dialogmain"
style={[
styles.main,
this.isIOS ? null : styles['md-main'],
contentStyle,
]}
onClick={this.wrapPress}
onTouchmove={this.contentTouchMove}
>
{this.getHeader()}
{this.getContent()}
{this.getFooter()}
</View>
);
return renderMask ? (
<Mask
defaultVisible={false}
onShow={this.onShow}
onHide={this.onHide}
ref="modalMask"
animate={false}
noPress
style={[styles.mask, isWeb ? styles.maskWeb : {}, style]}
maskClosable={maskClosable}
onTouchmove={this.maskTouchMove}
>
{dialogContent}
</Mask>
) : (
dialogContent
);
}
}
Dialog.defaultProps = {
onHide: () => { },
onShow: () => { },
maskClosable: true,
contentStyle: {},
children: null,
showCancelButton: false,
showConfirmButton: false,
renderMask: true,
};
Dialog.propTypes = {
onHide: PropTypes.func,
onShow: PropTypes.func,
renderMask: PropTypes.boolean,
children: PropTypes.any,
contentStyle: PropTypes.any,
};
Dialog.displayName = 'Dialog';
const StyledDialog = connectStyle(stylesProvider)(Dialog);
export default StyledDialog;