react-modal
react-modal copied to clipboard
shouldCloseOnOverlayClick not working
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
@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.
@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>
}
}
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. 💁
Hi @leaspark, did you find a way to fix your issue?
I'm also interested how to solve it.
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
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.
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..
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.
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;