Skip to content

Commit

Permalink
prevent modal from closing when modal is partial target of click
Browse files Browse the repository at this point in the history
  • Loading branch information
1000hz committed Aug 21, 2019
1 parent 0bee6ec commit 54ae531
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 15 deletions.
11 changes: 8 additions & 3 deletions src/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export default class ReactModal2 extends React.Component {
closeOnBackdropClick: true
};

preventModalClose = false

componentDidMount() {
if (ExecutionEnvironment.canUseDOM) {
setFocusOn(ReactModal2.getApplicationElement(), this.modal);
Expand All @@ -60,13 +62,15 @@ export default class ReactModal2 extends React.Component {
}

handleBackdropClick = () => {
if (this.props.closeOnBackdropClick) {
if (this.props.closeOnBackdropClick && !this.preventModalClose) {
this.props.onClose();
}

this.preventModalClose = false
}

handleModalClick = event => {
event.stopPropagation();
this.preventModalClose = true
}

render() {
Expand All @@ -78,7 +82,8 @@ export default class ReactModal2 extends React.Component {
<div ref={i => this.modal = i}
className={this.props.modalClassName}
style={this.props.modalStyles}
onClick={this.handleModalClick}
onMouseDown={this.handleModalClick}
onMouseUp={this.handleModalClick}
tabIndex="-1">
{this.props.children}
</div>
Expand Down
58 changes: 46 additions & 12 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {expect} from 'chai';
import { expect } from 'chai';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
Expand All @@ -21,29 +21,39 @@ describe('ReactModal2', function() {

it('should call `onClose` when the `esc` key is pressed', function() {
var called = false;
var onClose = function() { called = true; };
var onClose = function() {
called = true;
};

var dom = <ReactModal2 onClose={onClose}/>;
var instance = ReactDOM.render(dom, this.root);

instance.handleDocumentKeydown({ keyCode: 27 });
instance.handleDocumentKeydown({
keyCode: 27
});
expect(called).to.be.true;
});

it('should not call `onClose` when the `esc` key is pressed but `closeOnEsc` is `false`', function() {
var called = false;
var onClose = function() { called = true; };
var onClose = function() {
called = true;
};

var dom = <ReactModal2 onClose={onClose} closeOnEsc={false}/>;
var instance = ReactDOM.render(dom, this.root);

instance.handleDocumentKeydown({ keyCode: 27 });
instance.handleDocumentKeydown({
keyCode: 27
});
expect(called).to.be.false;
});

it('should call `onClose` when the backdrop is clicked', function() {
var called = false;
var onClose = function() { called = true; };
var onClose = function() {
called = true;
};

var dom = <ReactModal2 onClose={onClose}/>;
var instance = ReactDOM.render(dom, this.root);
Expand All @@ -55,7 +65,9 @@ describe('ReactModal2', function() {

it('should not call `onClose` when the backdrop is clicked but `closeOnBackdropClick` is `false`', function() {
var called = false;
var onClose = function() { called = true; };
var onClose = function() {
called = true;
};

var dom = <ReactModal2 onClose={onClose} closeOnBackdropClick={false}/>;
var instance = ReactDOM.render(dom, this.root);
Expand All @@ -65,14 +77,34 @@ describe('ReactModal2', function() {
expect(called).to.be.false;
});

it('should not call `onClose` when the modal is clicked', function() {
it('should not call `onClose` when the modal is the start target of a click', function() {
var called = false;
var onClose = function() { called = true; };
var onClose = function() {
called = true;
};

var dom = <ReactModal2 onClose={onClose}/>;
var instance = ReactDOM.render(dom, this.root);

TestUtils.Simulate.click(instance.modal);
TestUtils.Simulate.mouseDown(instance.modal);
TestUtils.Simulate.mouseUp(instance.backdrop);
TestUtils.Simulate.click(instance.backdrop);

expect(called).to.be.false;
});

it('should not call `onClose` when the modal is the end target of a click', function() {
var called = false;
var onClose = function() {
called = true;
};

var dom = <ReactModal2 onClose={onClose}/>;
var instance = ReactDOM.render(dom, this.root);

TestUtils.Simulate.mouseDown(instance.backdrop);
TestUtils.Simulate.mouseUp(instance.modal);
TestUtils.Simulate.click(instance.backdrop);

expect(called).to.be.false;
});
Expand Down Expand Up @@ -115,7 +147,8 @@ describe('ReactModal2', function() {
expect(applicationElement.getAttribute('aria-hidden')).to.equal('true');

document.body.removeChild(applicationElement);
ReactModal2.getApplicationElement = () => {};
ReactModal2.getApplicationElement = () => {
};
});

it('should "unhide" the applicationElement when mounted', function() {
Expand All @@ -130,6 +163,7 @@ describe('ReactModal2', function() {
expect(applicationElement.getAttribute('aria-hidden')).to.equal(null);

document.body.removeChild(applicationElement);
ReactModal2.getApplicationElement = () => {};
ReactModal2.getApplicationElement = () => {
};
});
});

0 comments on commit 54ae531

Please sign in to comment.