How to add animation to Modal (ReactJS)

I have the following Modal in ReactJS

const isClickInsideRectangle = (e: MouseEvent, element: HTMLElement) => {
    if (!element) return;
    const r = element.getBoundingClientRect();

    let isInside =
        e.clientX > r.left &&
        e.clientX < r.right &&
        e.clientY > r.top &&
        e.clientY < r.bottom;

    return isInside;
};

export const Modal = ({ isOpen, children, onOutsideClick }: Props) => {
    const ref = useRef<HTMLDialogElement>(null);

    useEffect(() => {
        if (isOpen) {
            ref.current?.close();
            ref.current?.showModal();
            document.body.classList.add("modal-open"); // prevent bg scroll
        } else {
            ref.current?.close();
            document.body.classList.remove("modal-open");
        }
    }, [isOpen]);

    const handleOutsideClick = (e: any) => {
        let isHidden = e.target.hidden;
        if (!isHidden && !isClickInsideRectangle(e, ref.current!)) {
            onOutsideClick && onOutsideClick();
        }
    };
    return (
        <div className="mw-modal" onClick={handleOutsideClick}>
            <dialog className="mw-modal--dialog" ref={ref}>
                {children}
            </dialog>
        </div>
    );
};

and I’m generating it by clicking button which sets isOpen to true. How can I animate it?

>Solution :

You can do some neat css animations. Here is something easy and not too complex:

Add these classes to your css file

.mw-modal--dialog {
  opacity: 0;
  transform: translateY(-10%);
  transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
}

.mw-modal--dialog.show {
  opacity: 1;
  transform: translateY(0);
}

Then you’ll need some JS to add and remove the css classes on trigger. Add this to your Modal component

export const Modal = ({ isOpen, children, onOutsideClick }: Props) => {
    const ref = useRef<HTMLDialogElement>(null);

    useEffect(() => {
        if (isOpen) {
            ref.current?.close();
            ref.current?.showModal();
            ref.current?.classList.add("show");     // Add show class
            document.body.classList.add("modal-open");
        } else {
            ref.current?.classList.remove("show");     // Remove show class
            ref.current?.close();
            document.body.classList.remove("modal-open");
        }
    }, [isOpen]);

    const handleOutsideClick = (e: any) => {
        let isHidden = e.target.hidden;
        if (!isHidden && !isClickInsideRectangle(e, ref.current!)) {
            onOutsideClick && onOutsideClick();
        }
    };
    return (
        <div className="mw-modal" onClick={handleOutsideClick}>
            <dialog className="mw-modal--dialog" ref={ref}>
                {children}
            </dialog>
        </div>
    );
};

Leave a Reply