UNPKG

react-redux-toastr

Version:

react-redux-toastr is a React toastr message implemented with Redux

164 lines (148 loc) 4.38 kB
import React from 'react'; import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import cn from 'classnames'; import ToastrBox from './ToastrBox'; import ToastrConfirm from './ToastrConfirm'; import * as actions from './actions'; import {EE} from './toastrEmitter'; import {updateConfig} from './utils'; import {TRANSITIONS} from './constants'; export class ReduxToastr extends React.Component { static displayName = 'ReduxToastr'; static propTypes = { toastr: PropTypes.object, position: PropTypes.string, newestOnTop: PropTypes.bool, timeOut: PropTypes.number, confirmOptions: PropTypes.object, progressBar: PropTypes.bool, transitionIn: PropTypes.oneOf(TRANSITIONS.in), transitionOut: PropTypes.oneOf(TRANSITIONS.out), preventDuplicates: PropTypes.bool, closeOnToastrClick: PropTypes.bool }; static defaultProps = { position: 'top-right', newestOnTop: true, timeOut: 5000, progressBar: false, transitionIn: TRANSITIONS.in[0], transitionOut: TRANSITIONS.out[0], preventDuplicates: false, closeOnToastrClick: false, getState: (state) => state.toastr, confirmOptions: { okText: 'ok', cancelText: 'cancel' } }; toastrFired = {}; toastrPositions = [ 'top-left', 'top-right', 'top-center', 'bottom-left', 'bottom-right', 'bottom-center' ]; constructor(props) { super(props); updateConfig(props); } componentDidMount() { const {add, showConfirm, clean, removeByType, remove} = this.props; EE.on('toastr/confirm', showConfirm); EE.on('add/toastr', add); EE.on('clean/toastr', clean); EE.on('removeByType/toastr', removeByType); EE.on('remove/toastr', remove); } componentWillUnmount() { EE.removeListener('toastr/confirm'); EE.removeListener('add/toastr'); EE.removeListener('clean/toastr'); EE.removeListener('removeByType/toastr'); EE.removeListener('remove/toastr'); this.toastrFired = {}; } _addToMemory(id) { this.toastrFired[id] = true; } _renderToastrForPosition(position) { const {toastrs} = this.props.toastr; if (toastrs) { return toastrs .filter(item => item.position === position) .map(item => { const mergedItem = { ...item, options: { progressBar: this.props.progressBar, transitionIn: this.props.transitionIn, transitionOut: this.props.transitionOut, closeOnToastrClick: this.props.closeOnToastrClick, ...item.options } }; return ( <div key={item.id}> <ToastrBox inMemory={this.toastrFired} addToMemory={() => this._addToMemory(item.id)} item={mergedItem} {...this.props} /> {item.options && item.options.attention && <div onClick={() => { if (typeof item.options.onAttentionClick === 'function') { item.options.onAttentionClick(item.id); } else { this.props.remove(item.id); } }} className="toastr-attention"/> } </div> ); }); } } _renderToastrs() { const {toastr} = this.props; const width = toastr.toastrs && toastr.toastrs[0] && toastr.toastrs[0].options && toastr.toastrs[0].options.width; const style = width ? {width: width} : {}; return ( <div> {this.toastrPositions.map(position => { return ( <div key={position} className={position} style={style}> {this._renderToastrForPosition(position)} </div> ); })} </div> ); } render() { const {className, toastr} = this.props; return ( <div className={cn('redux-toastr', className)} aria-live="assertive"> {toastr.confirm && <ToastrConfirm confirm={toastr.confirm} {...this.props} /> } {this._renderToastrs()} </div> ); } } export default connect( (state, ownProps) => ({ toastr: ownProps.getState ? ownProps.getState(state) : state.toastr, }), actions )(ReduxToastr);