-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: add useToast hook for toast notifications (#3593)
- Loading branch information
Showing
16 changed files
with
243 additions
and
248 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import Alert from "@mui/material/Alert"; | ||
import Snackbar from "@mui/material/Snackbar"; | ||
import { useToast } from "hooks/useToast"; | ||
import React from "react"; | ||
|
||
import { Toast as ToastProps } from "./types"; | ||
|
||
const Toast = ({ message, type = "success", id }: ToastProps) => { | ||
const toast = useToast(); | ||
|
||
const handleCloseToast = () => { | ||
if (toast) { | ||
toast.remove(id); | ||
} else { | ||
console.warn("ToastContext is not provided."); | ||
} | ||
}; | ||
|
||
return ( | ||
<Snackbar onClose={handleCloseToast} autoHideDuration={6000} open={true}> | ||
<Alert onClose={handleCloseToast} severity={type} sx={{ width: "100%" }}> | ||
{message} | ||
</Alert> | ||
</Snackbar> | ||
); | ||
}; | ||
|
||
export default Toast; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from "react"; | ||
|
||
import Toast from "./Toast"; | ||
import { Toast as ToastComponent } from "./types"; | ||
|
||
const ToastContainer = ({ toasts }: { toasts: ToastComponent[] }) => { | ||
return ( | ||
<div className="toasts-container"> | ||
{toasts.map((toast) => ( | ||
<Toast key={toast.id} {...toast} /> | ||
))} | ||
</div> | ||
); | ||
}; | ||
|
||
export default ToastContainer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
export interface Toast { | ||
message: string; | ||
type: ToastType; | ||
id: number; | ||
} | ||
export type ToastType = "success" | "warning" | "info" | "error"; | ||
|
||
export type ToastState = { | ||
toasts: Toast[]; | ||
}; | ||
|
||
export type ToastAction = AddToast | DeleteToast; | ||
|
||
type AddToast = { | ||
type: "ADD_TOAST"; | ||
payload: Toast; | ||
}; | ||
|
||
type DeleteToast = { | ||
type: "DELETE_TOAST"; | ||
payload: { id: number }; | ||
}; | ||
|
||
export type ToastContextType = { | ||
addToast: (type: ToastType, message: string) => void; | ||
remove: (id: number) => void; | ||
success: (message: string) => void; | ||
warning: (message: string) => void; | ||
info: (message: string) => void; | ||
error: (message: string) => void; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* eslint-disable @typescript-eslint/no-empty-function */ | ||
import ToastContainer from "components/Toast/ToastContainer"; | ||
import { | ||
ToastContextType, | ||
ToastState, | ||
ToastType, | ||
} from "components/Toast/types"; | ||
import React, { createContext, ReactNode, useReducer } from "react"; | ||
import { toastReducer } from "reducers/toastReducer"; | ||
|
||
const defaultCreateContextValue = { | ||
remove: (_id: number) => {}, | ||
addToast: (_type: ToastType, _message: string) => {}, | ||
success: (_message: string) => {}, | ||
warning: (_message: string) => {}, | ||
info: (_message: string) => {}, | ||
error: (_message: string) => {}, | ||
}; | ||
|
||
export const ToastContext = createContext<ToastContextType>( | ||
defaultCreateContextValue, | ||
); | ||
|
||
const initialState: ToastState = { | ||
toasts: [], | ||
}; | ||
|
||
export const ToastContextProvider = ({ | ||
children, | ||
}: Readonly<{ children: ReactNode }>) => { | ||
const [state, dispatch] = useReducer(toastReducer, initialState); | ||
const addToast = (type: ToastType, message: string) => { | ||
const id = Math.floor(Math.random() * 10_000_000); | ||
dispatch({ type: "ADD_TOAST", payload: { id, message, type } }); | ||
}; | ||
const remove = (id: number) => { | ||
dispatch({ type: "DELETE_TOAST", payload: { id } }); | ||
}; | ||
const success = (message: string) => { | ||
addToast("success", message); | ||
}; | ||
|
||
const warning = (message: string) => { | ||
addToast("warning", message); | ||
}; | ||
|
||
const info = (message: string) => { | ||
addToast("info", message); | ||
}; | ||
|
||
const error = (message: string) => { | ||
addToast("error", message); | ||
}; | ||
|
||
const value: ToastContextType = { | ||
success, | ||
warning, | ||
info, | ||
error, | ||
remove, | ||
addToast, | ||
}; | ||
|
||
return ( | ||
<ToastContext.Provider value={value}> | ||
<ToastContainer toasts={state.toasts} /> | ||
{children} | ||
</ToastContext.Provider> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { useContext } from "react"; | ||
|
||
import { ToastContext } from "../contexts/ToastContext"; | ||
|
||
export const useToast = () => useContext(ToastContext); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.