reactjs / react-modal

Accessible modal dialog component for React
http://reactcommunity.org/react-modal
MIT License
7.35k stars 810 forks source link

shouldCloseOnOverlayClick not working #462

Open leaspark opened 7 years ago

leaspark commented 7 years ago

Summary:

The modal will not close when the overlay is clicked. Setting shouldCloseOnOverlayClick to either true or false does not change this behavior.

Expected behavior:

Modal closes when overlay is clicked.

Link to example of issue:

https://github.com/reactjs/react-modal/issues/149

diasbruno commented 7 years ago

@leaspark shouldCloseOnOverlayClick depends on onRequestClose because react-modal does not store the isOpen on its internal state. It's required so you can decide if the modal should be closed or display an alert to the user.

leonascimento commented 7 years ago

@leaspark, I have a simple suggestion for you. You can create a component, for example, SomeComponent with a simple state and a toggle function, SomeComponent must manage its state, and you can access this value on state displayModal and inject in isOpen property something like this <Modal isOpen={this.state.displayModal}.


class SomeComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { displayModal: false };
    this.toggleModal = this.toggleModal.bind(this);
  }

  toggleModal() {
    this.setState({ displayModal: !this.state.isOpen });
  }

  render() {
    <div>
     <button onClick={this.toggleModal} />
     <Modal 
       isOpen={this.state.displayModal}
       shouldCloseOnOverlayClick={true}
       onRequestClose={() => {
         this.setState({ displayModal: false });
       }} />
    </div>
  }
}
markalfred commented 7 years ago

Just a heads up in case it applies to anyone else, I ran into a similar issue because I had a setup like this:

<ReactModal onRequestClose={this.onClose}>
  <div className="modal-container">
    <div className="modal-contents">
      {this.props.children}
    </div>
  </div>
</ReactModal>
.modal-container {
  position: fixed;
  top: 0
  right: 0
  bottom: 0
  left: 0
}
.modal-content {
  min-height: 50%;
  min-width: 50%;
  background-color: white;
}

The library interpreted .modal-container as being a part of the modal's contents, so it registered a click on the container as a "do not close" event prior to firing the "close on overlay click" one.

The lib is correct in its interpretation here, so the fault is mine, but I could imagine others having a similar setup. 💁

diasbruno commented 7 years ago

Hi @leaspark, did you find a way to fix your issue?

ramusus commented 7 years ago

I'm also interested how to solve it.

fabiancook commented 6 years ago

Hi,

It appears that there is internal state on the component that prevents onRequestClose to be invoked.

As soon as any content is click on within the modal it prevents it.

If your content is full screen, then your modal would never close as it is being prevented on mouse down.

I have a feeling that it shouldn't be part of the react-modal component, and it should just have the onClick on the content to stop the propagation of the event to the overlay, or check what the event target was in, if the event target isn't the overlay then don't close the modal, if it is, request the close

Joel-Mercier commented 6 years ago

I feel like the default content styles kind of confuse you because they cover much of the screen and I adapted them to act as kind of an overlay and put the actual modal inside so the actual overlay never closed the modal. Not sure how to improve that because it's just a misunderstanding. Fixed it thanks to this thread though.

enapupe commented 6 years ago

Hey! I'm having a similar issue: I can close (dismiss) it by pressing [ESC] through onRequestClose function but not when clicking on the overlay..

└─ react-modal@3.2.1

enapupe commented 6 years ago

Never mind.. The implementation I was working on had an additional class via className prop and that class extended some div content to 100% top/right/bottom/left in a way it was impossible to click the outer div.

artshevtsov commented 1 year ago

ReactModal__Content should not overlap ReactModal__Overlay to make shouldCloseOnOverlayClick working.

Here is a working example with Tailwind classes applied:

import Modal from 'react-modal';
import { ReactNode } from "react";

interface MyModalProps {
    isModalOpen: boolean
    closeModal: () => void
    children: ReactNode
}
Modal.setAppElement('body');
const MyModal = (props: MyModalProps) => {
    return(
        <Modal
            className={'inline-flex'}
            overlayClassName={'fixed w-full h-screen top-0 left-0 z-[1000] backdrop-blur-sm flex justify-center items-center'}
            isOpen={props.isModalOpen}
            contentLabel="Example Modal"
            shouldCloseOnEsc={true}
            shouldCloseOnOverlayClick={true}
            onRequestClose={props.closeModal}
            preventScroll={true}
        >
            <div className={'w-[640px] h-[480px] bg-white p-10 rounded-lg'}>
                <button onClick={props.closeModal} className={'p-5 bg-dark text-white'}>Close</button>
                { props.children }
            </div>
        </Modal>
    )
}

export default MyModal;