UNPKG

weex-nuke

Version:

基于 Rax 、Weex 的高性能组件体系 ~~

266 lines (256 loc) 6.28 kB
/** @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;