import { createContext, useContext, useState, useEffect, isValidElement, Children, } from '@wordpress/element'; type ModalContextType = { closeModal: () => void; openModal: () => void; }; const ModalContext = createContext(null); export const useModalContext = () => { const context = useContext(ModalContext); if (!context) { throw new Error('useModalContext must be used within a ModalProvider'); } return context; }; import { Modal as WordpressModal } from '@wordpress/components'; import classNames from 'classnames'; type ModalProps = { children: React.ReactElement | React.ReactElement[]; defaultOpen: boolean; onOpenChange: (checked: boolean) => void; }; const Modal: React.FC = ({ children, defaultOpen, onOpenChange, }) => { const [isOpen, setOpen] = useState(false); // Sync `isOpen` with `defaultOpen` when `defaultOpen` changes useEffect(() => { setOpen(defaultOpen); }, [defaultOpen]); const openModal = () => setOpen(true); const closeModal = () => setOpen(false); useEffect(() => { onOpenChange(isOpen); }, [isOpen, onOpenChange]); return ( {/* Render MOdalTrigger */} {Children.map(children, (child) => { return isValidElement(child) && child.type === ModalTrigger ? child : null; })} {isOpen && (
{/* Render ModalHeader */} {Children.map(children, (child) => { return isValidElement(child) && child.type === ModalHeader ? child : null; })} {/* Render ModalContent */} {Children.map(children, (child) => { return isValidElement(child) && child.type === ModalContent ? child : null; })} {/* Render ModalFooter */} {Children.map(children, (child) => { return isValidElement(child) && child.type === ModalFooter ? child : null; })}
)}
); }; // Header component for modal const ModalHeader: React.FC<{ children: React.ReactNode; className?: string; }> = ({ children, className = '', ...props }) => (
{children}
); // Footer component for modal const ModalFooter: React.FC<{ children: React.ReactNode; className?: string; }> = ({ children, className = '', ...props }) => (
{children}
); // Title component for modal const ModalTitle: React.FC<{ children: React.ReactNode; className?: string; }> = ({ children, className = '', ...props }) => (
{children}
); // Description component for modal const ModalContent: React.FC<{ children: React.ReactNode; className?: string; }> = ({ children, className = '', ...props }) => (
{children}
); const ModalClose: React.FC<{ children: React.ReactNode; }> = ({ children }) => { const { closeModal } = useModalContext(); return (
{children}
); }; const ModalTrigger: React.FC<{ children: React.ReactNode; }> = ({ children }) => { const { openModal } = useModalContext(); return (
{children}
); }; export { Modal, ModalHeader, ModalFooter, ModalTitle, ModalContent, ModalClose, ModalTrigger, };