Adding notifications in react context

This commit is contained in:
apanizo 2018-10-09 16:49:51 +02:00
parent 4cc92e5361
commit 2b45b24378
4 changed files with 131 additions and 11 deletions

View File

@ -0,0 +1,67 @@
// @flow
import * as React from 'react'
import SharedSnackBar from './index'
const SharedSnackbarContext = React.createContext({
openSnackbar: undefined,
closeSnackbar: undefined,
snackbarIsOpen: false,
message: '',
variant: 'info',
})
type Props = {
children: React$Node,
}
export type Variant = 'success' | 'error' | 'warning' | 'info'
type State = {
isOpen: boolean,
message: string,
variant: Variant,
}
export class SharedSnackbarProvider extends React.Component<Props, State> {
state = {
isOpen: false,
message: '',
variant: 'info',
}
openSnackbar = (message: string, variant: Variant) => {
this.setState({
message,
variant,
isOpen: true,
})
}
closeSnackbar = () => {
this.setState({
message: '',
isOpen: false,
})
}
render() {
const { children } = this.props
return (
<SharedSnackbarContext.Provider
value={{
openSnackbar: this.openSnackbar,
closeSnackbar: this.closeSnackbar,
snackbarIsOpen: this.state.isOpen,
message: this.state.message,
variant: this.state.variant,
}}
>
<SharedSnackBar />
{children}
</SharedSnackbarContext.Provider>
)
}
}
export const SharedSnackbarConsumer = SharedSnackbarContext.Consumer

View File

@ -0,0 +1,35 @@
// @flow
import * as React from 'react'
import { Snackbar } from '@material-ui/core'
import SnackbarContent from '~/components/SnackbarContent'
import { SharedSnackbarConsumer } from './Context'
const SharedSnackbar = () => (
<SharedSnackbarConsumer>
{(value) => {
const {
snackbarIsOpen, message, closeSnackbar, variant,
} = value
return (
<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
open={snackbarIsOpen}
autoHideDuration={4000}
onClose={closeSnackbar}
>
<SnackbarContent
onClose={closeSnackbar}
message={message}
variant={variant}
/>
</Snackbar>
)
}}
</SharedSnackbarConsumer>
)
export default SharedSnackbar

View File

@ -2,8 +2,6 @@
import SnackbarContent from '@material-ui/core/SnackbarContent' import SnackbarContent from '@material-ui/core/SnackbarContent'
import classNames from 'classnames/bind' import classNames from 'classnames/bind'
import * as React from 'react' import * as React from 'react'
import green from '@material-ui/core/colors/green'
import amber from '@material-ui/core/colors/amber'
import CloseIcon from '@material-ui/icons/Close' import CloseIcon from '@material-ui/icons/Close'
import CheckCircleIcon from '@material-ui/icons/CheckCircle' import CheckCircleIcon from '@material-ui/icons/CheckCircle'
import ErrorIcon from '@material-ui/icons/Error' import ErrorIcon from '@material-ui/icons/Error'
@ -12,6 +10,7 @@ import IconButton from '@material-ui/core/IconButton'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import WarningIcon from '@material-ui/icons/Warning' import WarningIcon from '@material-ui/icons/Warning'
import { type WithStyles } from '~/theme/mui' import { type WithStyles } from '~/theme/mui'
import { secondary } from '~/theme/variables'
type Variant = 'success' | 'error' | 'warning' | 'info' type Variant = 'success' | 'error' | 'warning' | 'info'
@ -37,16 +36,28 @@ const variantIcon = {
const styles = theme => ({ const styles = theme => ({
success: { success: {
backgroundColor: green[600], backgroundColor: '#ffffff',
}, },
error: { successIcon: {
backgroundColor: theme.palette.error.dark, color: '#00c4c4',
},
info: {
backgroundColor: theme.palette.primary.dark,
}, },
warning: { warning: {
backgroundColor: amber[700], backgroundColor: '#fff3e2',
},
warningIcon: {
color: '#ffc05f',
},
error: {
backgroundColor: '#ffe6ea',
},
errorIcon: {
color: '#fd7890',
},
info: {
backgroundColor: '#ffffff',
},
infoIcon: {
color: secondary,
}, },
icon: { icon: {
fontSize: 20, fontSize: 20,
@ -78,7 +89,7 @@ const Message = ({ classes, message, variant }: MessageProps) => {
return ( return (
<span id="client-snackbar" className={classes.message}> <span id="client-snackbar" className={classes.message}>
<Icon className={classNames(classes.icon, classes.iconVariant)} /> <Icon className={classNames(classes.icon, classes.iconVariant, classes[`${variant}Icon`])} />
{message} {message}
</span> </span>
) )
@ -87,7 +98,7 @@ const Message = ({ classes, message, variant }: MessageProps) => {
const GnoSnackbarContent = ({ const GnoSnackbarContent = ({
variant, classes, message, onClose, variant, classes, message, onClose,
}: Props) => { }: Props) => {
const action = onClose ? [<Close onClose={onClose} classes={classes} />] : undefined const action = onClose ? [<Close key="close" onClose={onClose} classes={classes} />] : undefined
const messageComponent = <Message classes={classes} message={message} variant={variant} /> const messageComponent = <Message classes={classes} message={message} variant={variant} />
return ( return (

View File

@ -118,6 +118,13 @@ export default createMuiTheme({
textAlign: 'left', textAlign: 'left',
}, },
}, },
MuiSnackbarContent: {
root: {
boxShadow: '0 0 10px 0 rgba(33, 48, 77, 0.1)',
borderRadius: '3px',
color: primary,
},
},
}, },
palette, palette,
}) })