diff --git a/src/Modal.js b/src/Modal.js index 6536487..ae74e58 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -39,6 +39,8 @@ export default class ReactModal2 extends React.Component { closeOnBackdropClick: true }; + preventModalClose = false + componentDidMount() { if (ExecutionEnvironment.canUseDOM) { setFocusOn(ReactModal2.getApplicationElement(), this.modal); @@ -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() { @@ -78,7 +82,8 @@ export default class ReactModal2 extends React.Component {
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}
diff --git a/test/index.js b/test/index.js index e995f41..59f052b 100644 --- a/test/index.js +++ b/test/index.js @@ -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'; @@ -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 = ; 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 = ; 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 = ; var instance = ReactDOM.render(dom, this.root); @@ -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 = ; var instance = ReactDOM.render(dom, this.root); @@ -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 = ; 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 = ; + 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; }); @@ -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() { @@ -130,6 +163,7 @@ describe('ReactModal2', function() { expect(applicationElement.getAttribute('aria-hidden')).to.equal(null); document.body.removeChild(applicationElement); - ReactModal2.getApplicationElement = () => {}; + ReactModal2.getApplicationElement = () => { + }; }); });