Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animated example breaks with multiple dialogs #12

Open
aij opened this issue Mar 30, 2016 · 3 comments
Open

Animated example breaks with multiple dialogs #12

aij opened this issue Mar 30, 2016 · 3 comments

Comments

@aij
Copy link

aij commented Mar 30, 2016

When rendering multiple modal dialogs based on the example in https://github.com/cloudflare/react-modal2/blob/master/example/animated/script.js only one of them will ever work, as only a single component can be rendered into a given GatewayDest. This applies even if one one modal is ever opened at a time, so long as there is more than one instance of the app-specific Modal class.

As a workaround I'm using CSSTransitionGroup as the tagName for GatewayDest so that the transition group is always rendered, which works as long as at most one modal is rendered into it at any given time.

Here's the code I'm using

const Modal = propTypes({
  onBackgroundClick: PropTypes.func,
  show: PropTypes.bool.isRequired,
  children: PropTypes.node,
  className: PropTypes.string
})(defaultProps({
  onBackgroundClick: event => void 0
})(props => {
  const { show, children, className, onBackgroundClick } = props;
  return show ? <Gateway into='modal'>
    <ReactModal
      onClose={onBackgroundClick}
      modalClassName={classNames('reveal-modal', className)}
      backdropClassName='reveal-modal-bg'
    >
      { children }
    </ReactModal>
  </Gateway> : <div/>;
}));

export class ModalWrapper extends Component {

  static init() {
    ReactModal.getApplicationElement = () => document.getElementById('app-content');
  }

  render() {
    return <GatewayProvider>
      <application>
        <div id="app-content">
          {this.props.children}
        </div>
        <GatewayDest
          name="modal"
          className="modal-container"
          tagName={TransitionGroup}
          transitionName='modal'
          transitionEnterTimeout={300}
          transitionLeaveTimeout={300}
        />
      </application>
    </GatewayProvider>;
  }
}

Note that the above produces a bogus prop type warning in development mode because the tagName proptype is set as string even though any value suitable for React.createElement is accepted.

@jamesplease
Copy link

I'm not using react-modal2 (building a similar-ish thing), but I'm trying to solve this same problem. Any luck, @aij ?

One solution that worked for my Alerts system involved only having a single Alert instance for the entire app. I built it this way because new alerts are not necessarily immediately displayed: they're queued until the old one disappears or is dismissed. This is more complex than just rendering Alerts wherever, and it has some drawbacks, like only serializable data can be passed to the Alert. I don't really want to do the same system for modals just for the benefit of being able to animate them, but it is an option that's out there.

@thejameskyle, did you ever need to support animations for things rendered in gateways?

@aij
Copy link
Author

aij commented Jun 24, 2016

@jmeas We ended up passing the current modal (if any) through redux, and then conditionally rendering it inside a ReactCSSTransitionGroup. (Always rendering the ReactCSSTransitionGroup though.)

We're still only ever rendering one modal at a time, though it shouldn't be too hard to pass an array of modals through redux and render the topmost one, removing it when it is closed.

@jamesplease
Copy link

Ah okay, cool. Thanks for the update! I've been thinking of doing that, but I'm going to hold off and try to think up other alternatives, so that I can more easily pass in functions and non-serializable things into my modals (I'm making an effort to keep my store always serializable).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants