11

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.

darKnight
  • 5,651
  • 13
  • 47
  • 87

1 Answers1

35

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

Peter Ambruzs
  • 7,763
  • 3
  • 30
  • 36
  • 1
    That's some progress, but the fade effect does not work when closing the modal. Can we achieve that somehow? I managed to achieve the 'slide-in` effect. Code link : https://codesandbox.io/s/csstransition-component-11mew – darKnight Oct 12 '19 at 16:19
  • I am using `CSSTransition` in a box inside the modal to animate its opacity. The box is a direct child of the `Modal`. But it's not working. Can you figure out the reason? https://codesandbox.io/s/csstransition-component-z1y2r . Thanks – darKnight Oct 12 '19 at 17:42
  • I'm not familiar with CSSTransition but I would check its classNames property is it really has to be 'modal'? – Peter Ambruzs Oct 12 '19 at 17:49
  • I think the syntax is correct. Check this http://reactcommunity.org/react-transition-group/css-transition – darKnight Oct 12 '19 at 17:50