mui-alert-provider
Version:
Make your alerts float! A lightweight provider for Material UI’s Alert that fits seamlessly into any web UI.
80 lines (79 loc) • 3.54 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useCallback, useMemo, useState } from "react";
import AlertComponent from "./Alert";
import { Box, useMediaQuery } from "@mui/material";
const AlertContext = React.createContext(undefined);
const AlertProvider = ({ children, limit = 4, mobileLimit = 1, position = "top-right", width = "20%", minWidth = "280px", containerSx = {}, duration = 300, mobileBreakpoint = "600px", muiAlertProps = {}, muiStackProps = {}, }) => {
const [alerts, setAlerts] = useState([]);
const isMobile = useMediaQuery(`(max-width:${mobileBreakpoint})`);
const limitToApply = useMemo(() => {
return isMobile ? mobileLimit : limit;
}, [isMobile, limit, mobileLimit]);
const addAlert = useCallback(({ message, severity }) => {
const newAlert = { message, severity, isNewAlert: true };
setAlerts(prevAlerts => {
if (prevAlerts.length >= limitToApply) {
// Remove the oldest alert if the max number is reached.
return [...prevAlerts.slice(1), newAlert];
}
return [...prevAlerts, newAlert];
});
// Remove the isNewAlert property after the duration.
setTimeout(() => {
setAlerts(prevAlerts => {
return prevAlerts.map(alert => {
return Object.assign(Object.assign({}, alert), { isNewAlert: false });
});
});
}, duration);
}, [limitToApply, duration]);
const removeAlert = useCallback((index) => {
setAlerts(prevAlerts => {
// Reduce prevAlerts to exclude prevAlerts[index].
// Also remove the isNewAlert property from the alert.
return prevAlerts.reduce((acc, alert, i) => {
if (i !== index) {
acc.push(Object.assign(Object.assign({}, alert), { isNewAlert: false }));
}
return acc;
}, []);
});
}, []);
const getSxPosition = useCallback(() => {
if (position === "top-right") {
return {
top: 0,
right: 0,
};
}
else if (position === "top-left") {
return {
top: 0,
left: 0,
};
}
else if (position === "bottom-right") {
return {
bottom: 0,
right: 0,
};
}
else if (position === "bottom-left") {
return {
bottom: 0,
left: 0,
};
}
else {
// Default to top-right if the position is not recognized.
console.warn(`Unrecognized position "${position}". Defaulting to "top-right".`);
return {
top: 0,
right: 0,
};
}
}, [position]);
return (_jsx(AlertContext.Provider, { value: { addAlert }, children: _jsxs(Box, { children: [_jsx(Box, { id: "mui-alerts-provider-container", sx: Object.assign(Object.assign({ boxSizing: "border-box", width: !isMobile ? width : "100%", minWidth: !isMobile ? minWidth : "100%", position: "absolute", zIndex: 9999, p: 1 }, getSxPosition()), containerSx), children: _jsx(AlertComponent, { alerts: alerts, removeAlert: removeAlert, duration: duration, muiAlertProps: muiAlertProps, muiStackProps: muiStackProps }) }), _jsx(Box, { children: children })] }) }));
};
export { AlertContext };
export default AlertProvider;