82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
import React, { createContext, useContext, useState, useEffect, useRef } from "react";
|
|
|
|
const ModalContext = createContext();
|
|
|
|
export const useModal = () => useContext(ModalContext);
|
|
|
|
// ModalProvider to manage modal state and expose functionality to the rest of the app
|
|
export const ModalProvider = ({ children }) => {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [modalContent, setModalContent] = useState(null);
|
|
const [onSubmit, setOnSubmit] = useState(null);
|
|
const [modalSize, setModalSize] = useState('lg');
|
|
|
|
// Ref to track the modal content element
|
|
const modalRef = useRef(null);
|
|
|
|
const openModal = (content, onSubmitCallback, size = 'lg') => {
|
|
setModalContent(content); // Set modal content dynamically
|
|
setOnSubmit(() => onSubmitCallback); // Set the submit handler dynamically
|
|
setIsOpen(true); // Open the modal
|
|
setModalSize(size); // Set the modal size
|
|
};
|
|
|
|
// Function to close the modal
|
|
const closeModal = () => {
|
|
setIsOpen(false); // Close the modal
|
|
setModalContent(null); // Clear modal content
|
|
setOnSubmit(null); // Clear the submit callback
|
|
setModalSize('lg'); // Reset modal size
|
|
};
|
|
|
|
|
|
useEffect(() => {
|
|
const handleClickOutside = (event) => {
|
|
if (modalRef.current && !modalRef.current.contains(event.target)) {
|
|
closeModal();
|
|
}
|
|
};
|
|
document.addEventListener("mousedown", handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<ModalContext.Provider value={{ isOpen, openModal, closeModal, modalContent, modalSize, onSubmit }}>
|
|
{children}
|
|
|
|
{isOpen && (
|
|
<div style={overlayStyles}>
|
|
<div ref={modalRef} style={{ ...modalStyles, maxWidth: modalSize === 'sm' ? '400px' : '800px' }}>
|
|
<div>{modalContent}</div>
|
|
|
|
</div>
|
|
</div>
|
|
)}
|
|
</ModalContext.Provider>
|
|
);
|
|
};
|
|
|
|
const overlayStyles = {
|
|
position: "fixed",
|
|
top: 0,
|
|
left: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
display: "flex",
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
zIndex: 1050,
|
|
};
|
|
|
|
const modalStyles = {
|
|
backgroundColor: "white",
|
|
padding: "20px",
|
|
borderRadius: "5px",
|
|
boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
|
|
width: "90%",
|
|
maxWidth: "800px",
|
|
};
|