muinotify
Version:
muinotify has an imperative API that makes it easy to display snackbars, without having to handle their open/close state. It also enables you to stack them on top of one another (although this is discouraged by the Material Design guidelines).
79 lines (66 loc) • 1.85 kB
JavaScript
import React from "react";
import { useRef, useState, useEffect, useCallback, memo } from "react";
import Alert from "@mui/material/Alert";
function useIsMounted() {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
}, []);
return useCallback(() => isMounted.current, []);
}
const NotifyItem = (props) => {
const { message, options = {}, id, isEntered, notifyItemProps } = props;
const {
defaultSeverity,
TransitionComponent,
TransitionProps,
AlertProps,
generalTimeOut,
remove,
customAlert,
} = notifyItemProps;
const { timeOut = generalTimeOut, isPersist } = options;
const [open, setOpen] = useState(true);
const isMounted = useIsMounted();
let timer = useRef(null);
// after an amount of time we remove the notif from the view
useEffect(() => {
clearTimeout(timer.current);
timer.current = setTimeout(() => {
if (isMounted && !isPersist) setOpen(false);
}, timeOut);
return () => clearTimeout(timer.current);
}, [timeOut, isPersist, isMounted]);
useEffect(() => {
if (!isEntered) setOpen(false);
}, [isEntered, id]);
const handleExited = () => {
if (!open && remove) remove(id);
};
return (
<TransitionComponent
in={open}
mountOnEnter
unmountOnExit
onExited={handleExited}
{...TransitionProps}
// addEndListener={handleListener(target, event)}
>
{customAlert ? (
<div className="Custom-Alert">{customAlert(props)}</div>
) : (
<Alert
id={id}
severity={(options && options.variant) || defaultSeverity}
{...AlertProps}
>
{message}
</Alert>
)}
</TransitionComponent>
);
};
export default memo(NotifyItem);