import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import Component from '../utils/Component'
import classnames from 'classnames'
import Logger from '../utils/logger'
import Icon from '../icon'
import '../style'
import 'phoenix-styles/less/modules/toast.less'
/**
* 飘字组件<br/>
* - 由于飘字的使用范围可预估, 为方便使用在原组件的基础上更进一步改为函数式的使用方式。
* - 普通信息: `Toast.info(message, duration, callback)`
* - 成功信息: `Toast.success(message, duration, callback)`
* - 失败信息: `Toast.fail(message, duration, callback)`
* - 加载中: `Toast.loading(message, duration, callback)`
* - 移除: `Toast.remove()`
* - 如果不根据设置的时间移除飘字,`duration`设置为false,`Toast.remove()`移除飘字。
*
* 示例: <br/>
* - 显示普通飘字, 如:<br/>
* `Toast.info('只显示信息的toast!', 1000, ()=>{console.log('飘字消失时执行的回调函数');})`
* - 显示成功信息, 如:<br/>
* `Toast.success('操作成功', 1000, ()=>{console.log('飘字消失时执行的回调函数');})`
* - 显示失败信息, 如:<br/>
* `Toast.fail('操作失败', 1000, ()=>{console.log('飘字消失时执行的回调函数');})`
* - 显示加载中, 如:<br/>
* `Toast.loading('加载中...', 1000, ()=>{console.log('飘字消失时执行的回调函数');})`
* - 移除飘字, 如:<br/>
* `Toast.remove()`
*
* @class Toast
* @module 操作类组件
* @extends Component
* @constructor
* @since 0.3.0
* @demo toast|toast.js
* @show true
* */
class Toast extends Component{
static propTypes = {};
static defaultProps = {
classPrefix:'toast',
componentTag:'div',
classMapping : {}
};
constructor(props, context) {
super(props, context)
new Logger('Toast')
}
renderChildren(){
let {phIcon,children} = this.props
if(phIcon){
let loading = phIcon.indexOf('loading')!=-1
return (
<div className={classnames(
this.setPhPrefix('body'),
loading? this.setPhPrefix('loading'):'',
children? '':this.setPhPrefix('only-icon')
)}>
{phIcon? <Icon phIcon={phIcon} phSize={loading?'lg':'xlg'} /> :null}
{children? <p>{children}</p>:null}
</div>
)
}else{
return children;
}
}
renderToast(){
let {componentTag:Component, className, phIcon} = this.props;
return (
<Component {...this.otherProps} className={classnames(
this.getProperty(true),
className
)}>
<div className={this.setPhPrefix('shadow')}></div>
<div className={this.setPhPrefix('main')}>
<div className={classnames(this.setPhPrefix('content'), phIcon? this.setPhPrefix('rect'):'')}>
{this.renderChildren(className)}
</div>
</div>
</Component>
);
}
render(){
return this.renderToast()
}
}
let _layer = document.createElement('div'),
timer = null,
visible = false;
function renderLayer(content,phIcon){
return <Toast phIcon={phIcon}>{content}</Toast>;
}
function _renderLayer(layerElement, duration, callback){
visible = true;
ReactDOM.render(layerElement, _layer);
document.body.appendChild(_layer);
window.addEventListener('hashchange', _unrenderLayer, false);
if(duration){
timer = setTimeout(function(){
visible = false;
_unrenderLayer();
if(callback) callback();
}, duration);
}
}
function _unrenderLayer(){
ReactDOM.unmountComponentAtNode(_layer);
if(visible) document.body.removeChild(_layer);
window.removeEventListener('hashchange', _unrenderLayer, false);
clearTimeout(timer);
}
export default {
info(content, duration, callback){
let layerElement = renderLayer(content);
_renderLayer(layerElement, duration, callback);
},
success(content, duration, callback){
let layerElement = renderLayer(content, 'success-circle');
_renderLayer(layerElement, duration, callback);
},
fail(content, duration, callback){
let layerElement = renderLayer(content, 'fail-circle');
_renderLayer(layerElement, duration, callback);
},
tip(content, duration, callback){
let layerElement = renderLayer(content, 'warning-circle');
_renderLayer(layerElement, duration, callback);
},
loading(content, duration, callback){
let layerElement = renderLayer(content, 'loading-white');
_renderLayer(layerElement, duration, callback);
},
remove(){
_unrenderLayer();
clearTimeout(timer);
}
}