UNPKG

taro-material

Version:

Mini Program components that implement Google's Material Design.

152 lines (133 loc) 3.51 kB
import Taro from '@tarojs/taro' import { View, Text, Image } from '@tarojs/components' import PropTypes from 'prop-types' import classNames from 'classnames' import _isFunction from 'lodash/isFunction' import AtComponent from '../../common/component' import statusImg from './img.json' export default class AtToast extends AtComponent { constructor (props) { super(...arguments) const { isOpened, duration } = props if (isOpened) { this.makeTimer(duration) } this._timer = null this.state = { _isOpened: isOpened } } clearTimmer () { if (this._timer) { clearTimeout(this._timer) this._timer = null } } makeTimer (duration) { if (duration === 0) { return } this._timer = setTimeout(() => { this.close() }, +duration) } close () { const { _isOpened } = this.state if (_isOpened) { this.setState( { _isOpened: false }, this.handleClose ) this.clearTimmer() } } handleClose () { if (_isFunction(this.props.onClose)) { this.props.onClose() } } componentWillReceiveProps (nextProps) { const { isOpened, duration } = nextProps if (!isOpened) { this.close() return } if (!this.state._isOpened) { this.setState({ _isOpened: true }) } else { this.clearTimmer() } this.makeTimer(duration) } handleClick = () => { const { onClick, status } = this.props if (status === 'loading') { return } if (onClick) { return onClick() } this.close() } render () { const { _isOpened } = this.state const { customStyle, text, icon, status, image, hasMask } = this.props const realImg = image || statusImg[status] || null const isRenderIcon = !!(icon && !(image || statusImg[status])) const bodyClass = classNames('toast-body', { 'at-toast__body--custom-image': image, 'toast-body--text': !realImg && !icon, [`at-toast__body--${status}`]: !!status }) const iconClass = classNames('at-icon', { [`at-icon-${icon}`]: icon }) return _isOpened ? ( <View className={classNames('at-toast', this.props.className)}> {hasMask && <View className='at-toast__overlay' />} <View className={bodyClass} style={customStyle} onClick={this.handleClick}> <View className='toast-body-content'> {realImg ? ( <View className='toast-body-content__img'> <Image className='toast-body-content__img-item' src={realImg} mode='scaleToFill' /> </View> ) : null} {isRenderIcon && ( <View className='toast-body-content__icon'> <Text className={iconClass} /> </View> )} {text && ( <View className='toast-body-content__info'> <Text>{text}</Text> </View> )} </View> </View> </View> ) : null } } AtToast.defaultProps = { duration: 3000, isOpened: false } AtToast.propTypes = { text: PropTypes.string, icon: PropTypes.string, hasMask: PropTypes.bool, image: PropTypes.string, isOpened: PropTypes.bool, duration: PropTypes.number, status: PropTypes.oneOf(['', 'error', 'loading', 'success']), onClick: PropTypes.func, onClose: PropTypes.func }