gnar-edge
Version:
A sharp set of utilities: base64, drain, handleChange, jwt, notifications
130 lines (118 loc) • 3.45 kB
JSX
import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles';
import CheckCircleIcon from '@material-ui/icons/CheckCircle';
import CloseIcon from '@material-ui/icons/Close';
import ErrorIcon from '@material-ui/icons/Error';
import IconButton from '@material-ui/core/IconButton';
import InfoIcon from '@material-ui/icons/Info';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import SnackbarContent from '@material-ui/core/SnackbarContent';
import WarningIcon from '@material-ui/icons/Warning';
import amber from '@material-ui/core/colors/amber';
import classNames from 'classnames';
import green from '@material-ui/core/colors/green';
import notificationActions from '../redux/actions';
import 'animate.css/source/zooming_exits/zoomOutUp.css';
const variantIcon = {
success: CheckCircleIcon,
warning: WarningIcon,
error: ErrorIcon,
info: InfoIcon
};
const styles = theme => {
const margin = theme.spacing.unit;
return {
success: {
backgroundColor: green[600],
margin
},
error: {
backgroundColor: theme.palette.error.dark,
margin
},
info: {
backgroundColor: theme.palette.primary.dark,
margin
},
warning: {
backgroundColor: amber[700],
margin
},
icon: {
fontSize: 25
},
iconVariant: {
opacity: 0.9,
marginRight: theme.spacing.unit
},
closeIcon: {
fontSize: 20
},
message: {
alignItems: 'center',
display: 'flex',
fontSize: 16
}
};
};
const mapDispatchToProps = notificationActions;
(styles)
(() => ({}), mapDispatchToProps)
export default class Notification extends Component {
static propTypes = {
$key: PropTypes.string.isRequired,
autoDismissMillis: PropTypes.number,
classes: PropTypes.shape({}).isRequired,
dismissNotification: PropTypes.func.isRequired,
message: PropTypes.node.isRequired,
onDismiss: PropTypes.func,
variant: PropTypes.oneOf([ 'success', 'warning', 'error', 'info' ]).isRequired
};
static defaultProps = {
autoDismissMillis: 5000,
onDismiss: () => {}
}
state = {
discard: false
}
componentDidMount() {
if (this.props.autoDismissMillis > 0) {
setTimeout(this.close, this.props.autoDismissMillis);
}
}
close = userDismissed => {
if (!this.state.discard) {
this.setState({ discard: true });
setTimeout(() => { this.props.dismissNotification(this.props.$key); }, 1000);
this.props.onDismiss(!!userDismissed);
}
}
render() {
const { classes, message, variant } = this.props;
const { discard } = this.state;
const Icon = variantIcon[variant];
return (
<SnackbarContent
action={(
<IconButton
aria-label='Close'
className={classes.close}
color='inherit'
onClick={() => { this.close(true); }}
>
<CloseIcon className={classNames(classes.closeIcon, classes.iconVariant)} />
</IconButton>
)}
aria-describedby='user-snackbar'
className={classNames(classes[variant], { 'animated zoomOutUp': discard }, 'notification')}
message={(
<span className={classes.message}>
<Icon className={classNames(classes.icon, classes.iconVariant)} />
{message}
</span>
)}
/>
);
}
}