import PropTypes from "prop-types";
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
useState,
} from "react";
const DEFAULT_AUTO_HIDE_MS = 5000;
const MessageContext = createContext({
isVisible: false,
message: null,
icon: null,
showMessage: () => {},
hideMessage: () => {},
});
export const MessageProvider = ({
children,
defaultAutoHideDelay = DEFAULT_AUTO_HIDE_MS,
}) => {
const [state, setState] = useState({
message: null,
icon: null,
isVisible: false,
});
const hideTimeoutRef = useRef(null);
const clearHideTimeout = useCallback(() => {
if (hideTimeoutRef.current) {
window.clearTimeout(hideTimeoutRef.current);
hideTimeoutRef.current = null;
}
}, []);
const hideMessage = useCallback(() => {
clearHideTimeout();
setState((prev) => ({
...prev,
isVisible: false,
}));
}, [clearHideTimeout]);
const showMessage = useCallback(
(messageText, icon = null, autoHide = true) => {
if (!messageText) {
console.warn("showMessage called without message text");
return;
}
clearHideTimeout();
setState({
message: messageText,
icon,
isVisible: true,
});
const resolvedDelay =
typeof autoHide === "number" && autoHide > 0
? autoHide
: defaultAutoHideDelay;
if (autoHide && typeof window !== "undefined") {
hideTimeoutRef.current = window.setTimeout(() => {
setState((prev) => ({
...prev,
isVisible: false,
}));
hideTimeoutRef.current = null;
}, resolvedDelay);
}
},
[clearHideTimeout, defaultAutoHideDelay]
);
useEffect(() => {
return () => {
clearHideTimeout();
};
}, [clearHideTimeout]);
const contextValue = useMemo(
() => ({
isVisible: state.isVisible,
message: state.message,
icon: state.icon,
showMessage,
hideMessage,
}),
[state.isVisible, state.message, state.icon, showMessage, hideMessage]
);
return (