import React, { useState, useEffect, useRef } from "react"; import ReactDOM from "react-dom"; import clsx from "clsx"; import type { BackdropProps } from "./types"; import backdropTheme from "./backdropTheme"; const BackdropComponent: React.FC = ({ className, appendToBody = false, show, animate = true, theme: customTheme, ...props }) => { const theme = { ...backdropTheme, ...customTheme }; const [displayBackdrop, setDisplayBackdrop] = useState(show); const [showBackdrop, setShowBackdrop] = useState(false); const backdropTransitionTimeRef = useRef(0); const backdropRef = useRef(null); const interval = useRef | null>(null); const backdropClasses = clsx( theme.wrapper, displayBackdrop ? "block" : "hidden", showBackdrop ? "opacity-50" : "opacity-0" ); useEffect(() => { if (backdropRef.current) { const { transitionDuration } = window.getComputedStyle( backdropRef.current ); const time = Number(transitionDuration.replace("s", "")) * 1000; backdropTransitionTimeRef.current = time; } }, []); useEffect(() => { if (show) { setDisplayBackdrop(show); interval.current = setTimeout( () => { setShowBackdrop(show); }, animate ? 50 : 0 ); } else { setShowBackdrop(show); interval.current = setTimeout( () => { setDisplayBackdrop(show); }, animate ? backdropTransitionTimeRef.current : 0 ); } return () => { if (interval.current) { clearInterval(interval.current); } }; }, [show]); const backdropTemplate = (
); const appendToBodyTemplate = ( <>{ReactDOM.createPortal(backdropTemplate, document.body)} ); return <>{appendToBody ? appendToBodyTemplate : backdropTemplate}; }; export default BackdropComponent;