cssreactjsreact-modal

Animate React Modal


I have a Modal in my web app which I want to slide in when the user clicks "open" button. I am using react-transition-group to achieve this. But I am unable to get the animation working. Not sure what's wrong here?

import React from 'react';
import ReactDOM from 'react-dom';
import { CSSTransition } from 'react-transition-group';
import Modal from 'react-modal';

import './styles.css';

class Example extends React.Component {
  state = {
    isOpen: false,
  };

  toggleModal = () => {
    this.setState(prevState => ({
      isOpen: !prevState.isOpen,
    }));
  };
  render() {
    const modalStyles = {
      overlay: {
        backgroundColor: '#ffffff',
      },
    };
    return (
      <div>
        <button onClick={this.toggleModal}>
          Open Modal
        </button>
        <CSSTransition
          in={this.state.isOpen}
          timeout={300}
          classNames="dialog"
        >
          <Modal
            isOpen={this.state.isOpen}
            style={modalStyles}
          >
            <button onClick={this.toggleModal}>
              Close Modal
            </button>
            <div>Hello World</div>
          </Modal>
        </CSSTransition>
      </div>
    );
  }
}

CSS File:

.dialog-enter {
  left: -100%;
  transition: left 300ms linear;
}
.dialog-enter-active {
  left: 0;
}
.dialog-exit {
  left: 0;
  transition: left 300ms linear;
}
.dialog-exit-active {
  left: -100%;
}

Here is the working code.


Solution

  • The problem here is that react-modal uses a react-portal as its mounting point. So it is not rendered as the children of the CSSTransition component. So you could not use the CSSTransition with it.

    You can use some custom css to create transition effects. It is in the react-modal documentation.

    So if you add this to your css. There will be transition.

    .ReactModal__Overlay {
      opacity: 0;
      transform: translateX(-100px);
      transition: all 500ms ease-in-out;
    }
    
    .ReactModal__Overlay--after-open {
      opacity: 1;
      transform: translateX(0px);
    }
    
    .ReactModal__Overlay--before-close {
      opacity: 0;
      transform: translateX(-100px);
    }
    

    And we have to add the closeTimeoutMS prop to the modal in order the closing animation to work.

          <Modal
            closeTimeoutMS={500}
            isOpen={this.state.isOpen}
            style={modalStyles}
          >
    

    https://codesandbox.io/s/csstransition-component-forked-7jiwn