/
index.jsx
71 lines (61 loc) · 1.58 KB
/
index.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import React, { createContext, useState, useContext, useMemo } from 'react'
import Snackbar from '../../Snackbar'
import Alert from '../../Alert'
import AlertTitle from '../../AlertTitle'
/**
* @typedef {import('../../Alert').AlertProps & { message: string, title: string }} ShowAlertArgs
*/
/**
* @typedef {object} UseAlertReturn
* @property {(args: ShowAlertArgs) => void} showAlert
*/
export const AlertContext = createContext()
/**
* @returns {UseAlertReturn}
*/
export const useAlert = () => {
const context = useContext(AlertContext)
if (!context) {
throw new Error('useAlert must be used within a AlertProvider')
}
return context
}
const defaultState = {
title: '',
message: '',
open: false
}
const handleClose = (state, setState) => () => {
return setState({ ...state, open: false })
}
const AlertProvider = ({ children }) => {
const [state, setState] = useState(defaultState)
const { open, message, title, ...alertProps } = state
const value = useMemo(
() => ({
/**
* @param {ShowAlertArgs} args
*/
showAlert: args => {
setState({ open: true, ...args })
}
}),
[]
)
return (
<AlertContext.Provider value={value}>
{children}
<Snackbar open={open} onClose={handleClose(state, setState)}>
<Alert
elevation={6}
onClose={handleClose(state, setState)}
{...alertProps}
>
{title && <AlertTitle>{title}</AlertTitle>}
{message}
</Alert>
</Snackbar>
</AlertContext.Provider>
)
}
export default React.memo(AlertProvider)