Ru

Animated modal in React using – onAnimationEnd

12.08.2023

animated modal in react

In this component, when creating an animation, onAnimationEnd is applied, as in this case. onAnimationEnd is the handler for the animationEnd event, which is called when the element’s CSS animation ends. This component does not use third party libraries for animation and when the modal window is closed, it is not in the DOM.

 

App.jsx

import { useState } from "react";
import Modal from "./components/modal";

function App() {
  const [showModal, setShowModal] = useState(false);
   return (
    <div className="App">
      <button
        onClick={() => {
          setShowModal(true);
        }}
        className={"button"}
      >
        Open modal
      </button>  
      <Modal buttonShowModal={showModal} setButtonShowModal={setShowModal} />
    </div>
  );   
}

export default App;
 

index.jsx (modal)

import styles from "./modal.module.css";
import { useState, useEffect, useRef } from "react";
import Close from "../svg/Icon/Close";
import Horse from "../svg/Drawing/Horse";

export default function Modal({ buttonShowModal, setButtonShowModal }) {
  const [showModal, setShowModal] = useState(false);
  useEffect(() => {
    if (buttonShowModal) {
      setShowModal(true);
    }
  }, [buttonShowModal]);
  const [fadeOut, setFadeOut] = useState(false);

  // Click tracking outside the modal
  const modalRef = useRef();
  useEffect(() => {
    if (modalRef.current) {
      const handler = (e) => {
        if (!modalRef.current.contains(e.target)) {
          setFadeOut(true);
        }
      };
      document.addEventListener("mousedown", handler);
      return () => {
        document.removeEventListener("mousedown", handler);
      };
    }
  });

  return (
    <>
      {showModal && (
        <div
          className={
            fadeOut
              ? `${styles.modal_wrap} ${styles.modal_wrap__fade_out}`
              : `${styles.modal_wrap}`
          }
          onAnimationEnd={(e) => {
            if (e.animationName === styles.fadeOut) {
              setFadeOut(false);
            }
          }}
        >
          <div
            ref={modalRef}
            className={
              fadeOut
                ? `${styles.modal} ${styles.modal__fade_out}`
                : `${styles.modal}`
            }
            onAnimationEnd={(e) => {
              if (e.animationName === styles.fadeOut) {
                setShowModal(false);
                setFadeOut(false);
                setButtonShowModal(false);
              }
            }}
          >
            <Horse />
            <div
              onClick={() => {
                setFadeOut(true);
                setButtonShowModal(false);
              }}
              className={styles.close_button}
            >
              <Close />
            </div>
          </div>
        </div>
      )}
    </>
  );
}
 

modal.module.css

.modal_wrap {
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.069);
  position: fixed;
  width: 100%;
  height: 100%;
  animation: fadeInModalWrap 0.5s forwards;
  opacity: 0;
  left: 0;
  top: 0;
}

.modal_wrap__fade_out {
  animation: fadeOut 0.5s forwards;
  opacity: 1;
}

@keyframes fadeInModalWrap {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.modal {
  width: 100%;
  max-width: 260px;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 250px;
  border-radius: 5px;
  position: relative;
  animation: fadeInModal 0.8s forwards;
  background-color: rgb(255, 255, 255);
  margin-right: 15px;
  margin-left: 15px;
}

.modal__fade_out {
  animation: fadeOut 0.5s forwards;
}

@keyframes fadeInModal {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.close_button {
  position: absolute;
  right: 5px;
  top: 5px;
  border: 2px solid rgb(90, 90, 90);
  cursor: pointer;
  border-radius: 3px;
}

Look at GitHub, Live

Share

Copy

BTC (Network BTC) - 1C2EWWeEXVhg93hJA9KovpkSd3Rn3BkcYm

Ethereum (Network ERC20) - 0x05037ecbd8bcd15631d780c95c3799861182e6b8

This website uses cookies. By clicking the 'Accept' button or continuing to use the website, you agree to the use of cookies.