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>
);
};