react-jam-ui
Version:
React JAM UI components
179 lines (151 loc) • 4.4 kB
JavaScript
import React from 'react'
import classNames from 'classnames'
import IconClose from '../Icons/feather/IconClose'
import '../Animate'
import './styles.styl'
const Store = () => {
const store = {
data: []
}
store.options = {
timeout: 3000,
close: false
}
store.create = function(toast) {
const id = `toast_${ Math.floor(Math.random() * 10000) }_${ new Date().getTime() }`;
toast.id = id;
toast.tm = setTimeout(() => {
store.data = store.data.filter(toast => toast.id !== id)
store.changed()
}, toast.timeout);
store.data.push(toast);
store.changed()
}
store.changed = function() {
if (store.cb) store.cb(store.data)
}
store.remove = e => {
const id = e.target.dataset.id
const toast = store.data.find(toast => toast.id == id)
clearTimeout(toast.tm)
store.data = store.data.filter(toast => toast.id !== id)
store.changed()
}
store.watch = function(fn) {
store.cb = fn;
}
store.setOptions = options => {
store.options = {
timeout: options.timeout || store.options.timeout,
close: options.close || store.options.close
}
}
store.success = function(message, options) {
const data = {
status: 'success',
message,
...store.options,
...options
};
store.create(data)
};
store.info = function(message, options) {
const data = {
status: 'info',
message,
...store.options,
...options
};
store.create(data)
};
store.warning = function(message, options) {
const data = {
status: 'warning',
message,
...store.options,
...options
};
store.create(data)
};
store.error = function(message, options) {
const data = {
status: 'error',
message,
...store.options,
...options
};
store.create(data)
};
return store;
};
export const Toast = Store();
export class ToastContainer extends React.Component {
constructor(props) {
super();
const styles = {};
switch (props.style) {
case 'top left':
styles.top = 10;
styles.left = 10;
break;
case 'top right':
styles.top = 10;
styles.right = 10;
break;
case 'bottom left':
styles.bottom = 10;
styles.left = 10;
break;
case 'bottom right':
styles.bottom = 10;
styles.right = 10;
break;
default:
styles.top = 10;
styles.right = 10;
break;
}
this.state = {
styles
}
props.store.setOptions({
timeout: props.timeout,
close: props.close
})
props.store.watch(data => {
setTimeout(() => this.forceUpdate(), 0)
})
}
render() {
const toasts = this.props.store.data;
return <div className='react-toasts-container' style={ this.state.styles } >
{
toasts.map(toast => <div key={`toast-${toast.id}`}>
<div className={`react-toasts ${toast.status} react-toasts-animation ${ toast.close ? 'react-toasts-close' : ''}`}>
{ toast.message }
{
toast.close &&
<IconClose onClick={ this.props.store.remove } data-id={ toast.id } />
}
</div>
</div>)
}
</div>
}
}
/*
<ToastContainer
store={ Toast }
timeout={ 10000 }
close={ true }
/>
Toast.success('Success', { timeout: 2000, close: false })
Toast.info('info', { timeout: 2000, close: false })
Toast.warning('warning', { timeout: 2000, close: false })
Toast.error('error', { timeout: 2000, close: false })
Toast.create({
status: 'any_other_type',
message: 'Any message',
timeout: 2000 (3000 default)
})
*/