Modal window doesn't close smoothly

125 Views Asked by At

The modal window opens smoothly and there are no problems with this, but when closed, it closes instantly and no animation works. What needs to be fixed/added?

Modal component:

const ModalContent = ({ children, closeModal }) => {
  useEffect(() => {
    const listenerHandler = (e) => {
      if (e.key === 'Escape') {
        closeModal()
      }
    }
    document.addEventListener('keydown', listenerHandler)

    return () => {
      document.removeEventListener('keydown', listenerHandler)
    }
  }, [closeModal])

  return children
}

export function Modal({
  showModal, handleClose, children,
}) {
  useEffect(() => {
    showModal
      ? document.body.style.overflow = 'hidden'
      : document.body.style.overflow = 'unset'
  }, [showModal])

  if (!showModal) return null

  const classes = classNames({
    modal: true,
    hide: !showModal,
  })

  return createPortal(
    <div className={classes} onClick={handleClose}>
      <div className="modalContent" onClick={(e) => e.stopPropagation()}>

        <ModalContent closeModal={handleClose}>
          {children}
        </ModalContent>

      </div>
    </div>,

    document.getElementById('modal-root'),
  )
}

Css style:

.modal {
    width: 100vw;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 99;
    background-color: rgba(0, 0, 0, .9);
    display: flex;
    justify-content: center;
    align-items: center;

    animation-name: fade;
    animation-duration: .4s;
}

.modal.hide {
    animation-name: fade-out;
    animation-duration: .5s;
}

@keyframes fade {
     from {
         opacity: 0.7;
     }
     to {
         opacity: 1;
     }
 }

 @keyframes fade-out {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

The component where the modal window is used:

export function Project({
  projectName, projectDescription, projectLinkToGitHub, arrayOfUsedTools, orientation,
}) {
  const [currentImage, setCurrentImage] = useState(null)
  const [showModal, setShowModal] = useState(false)

  const imageClickHandler = (picture) => {
    setCurrentImage(picture)
    setShowModal(true)
  }

  const handleClose = () => setShowModal(false)

  return (
     ......
     <Swiper
        spaceBetween={30}
        centeredSlides
        autoplay={{
        delay: 2000,
        disableOnInteraction: false,}}
        pagination={{
        clickable: true,}}
        navigation
        modules={[Autoplay, Pagination, Navigation]}
        grabCursor
        loop
        slidesPerView={1}
        className={leftStyles.swiperContainer}
        >
         {dogFoodImages.map((picture, i) => (
            <SwiperSlide
              key={i}
              className={leftStyles.swiperSlide}
              onClick={() => imageClickHandler(picture)}
             >
               <img
                  src={picture}
                  alt={picture}
                  className={leftStyles.screens}
               />
             </SwiperSlide>
     ......
      <Modal showModal={showModal} handleClose={handleClose}>
        <img
          src={currentImage}
          alt=""
          className={rightStyles.screensForModal}
        />
      </Modal>

The bottom line is, there is a swiper with pictures, when you click on the picture, it is saved in a react state, and a modal window opens with this picture. When opening, the animation works, but when closing, nothing works, it closes instantly.

Tried to use modal window from react-overlay, CSSTransition (React Transition Group), but it didn't work out!

1

There are 1 best solutions below

0
Heliodor On

Try to make a state that corresponds to closing the window.

const [isClosing, setIsClosing] = useState(false);

And add this class to the modal window by condition

[cls.isClosing]: isClosing

.module.scss

 .isClosing {
    .content {
        transform: scale(0.2);
    }
}