Skip to content

Commit e8749dd

Browse files
committedMar 26, 2016
Merge pull request #128 from dorsha/master
[added] The ability to decide whether the modal should be closed when clicking the overlay area
2 parents 93c73f3 + 6282c3e commit e8749dd

File tree

6 files changed

+81
-8
lines changed

6 files changed

+81
-8
lines changed
 

Diff for: ‎README.md

+16
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,22 @@ var App = React.createClass({
124124
ReactDOM.render(<App/>, appElement);
125125
```
126126

127+
By default the modal is closed when clicking outside of it (the overlay area). If you want to prevent this behavior you can
128+
pass the 'shouldCloseOnOverlayClick' prop with 'false' value.
129+
```xml
130+
<Modal
131+
isOpen={bool}
132+
onRequestClose={fn}
133+
closeTimeoutMS={n}
134+
shouldCloseOnOverlayClick={false}
135+
style={customStyle}>
136+
137+
<h1>Force Modal</h1>
138+
<p>Modal cannot be closed when clickig the overlay area</p>
139+
<button onClick={handleCloseFunc}>Close Modal...</button>
140+
</Modal>
141+
```
142+
127143
# Demos
128144
* http://reactjs.github.io/react-modal/
129145
* http://reactjs.github.io/react-modal/bootstrap

Diff for: ‎lib/components/Modal.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,16 @@ var Modal = module.exports = React.createClass({
2929
appElement: React.PropTypes.instanceOf(SafeHTMLElement),
3030
onRequestClose: React.PropTypes.func,
3131
closeTimeoutMS: React.PropTypes.number,
32-
ariaHideApp: React.PropTypes.bool
32+
ariaHideApp: React.PropTypes.bool,
33+
shouldCloseOnOverlayClick: React.PropTypes.bool
3334
},
3435

3536
getDefaultProps: function () {
3637
return {
3738
isOpen: false,
3839
ariaHideApp: true,
39-
closeTimeoutMS: 0
40+
closeTimeoutMS: 0,
41+
shouldCloseOnOverlayClick: true
4042
};
4143
},
4244

Diff for: ‎lib/components/ModalPortal.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,12 @@ var ModalPortal = module.exports = React.createClass({
149149
},
150150

151151
handleOverlayClick: function() {
152-
if (this.ownerHandlesClose())
153-
this.requestClose();
154-
else
155-
this.focusContent();
152+
if (this.props.shouldCloseOnOverlayClick) {
153+
if (this.ownerHandlesClose())
154+
this.requestClose();
155+
else
156+
this.focusContent();
157+
}
156158
},
157159

158160
requestClose: function() {

Diff for: ‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"react-dom": "^0.14.0",
4040
"reactify": "^1.1.1",
4141
"rf-release": "0.4.0",
42+
"sinon": "^1.17.3",
4243
"uglify-js": "2.4.24",
4344
"webpack": "^1.12.14",
4445
"webpack-dev-server": "1.11.0"

Diff for: ‎specs/Modal.spec.js

+53-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var Modal = require('../lib/components/Modal');
66
var Simulate = TestUtils.Simulate;
77
var ariaAppHider = require('../lib/helpers/ariaAppHider');
88
var button = ReactDOM.button;
9+
var sinon = require('sinon');
910

1011
describe('Modal', function () {
1112

@@ -74,6 +75,7 @@ describe('Modal', function () {
7475
equal(props.isOpen, false);
7576
equal(props.ariaHideApp, true);
7677
equal(props.closeTimeoutMS, 0);
78+
equal(props.shouldCloseOnOverlayClick, true);
7779
ReactDOM.unmountComponentAtNode(node);
7880
ariaAppHider.resetForTesting();
7981
});
@@ -102,13 +104,13 @@ describe('Modal', function () {
102104

103105
it('supports custom className', function() {
104106
var modal = renderModal({isOpen: true, className: 'myClass'});
105-
equal(modal.portal.refs.content.className.contains('myClass'), true);
107+
notEqual(modal.portal.refs.content.className.indexOf('myClass'), -1);
106108
unmountModal();
107109
});
108110

109111
it('supports overlayClassName', function () {
110112
var modal = renderModal({isOpen: true, overlayClassName: 'myOverlayClass'});
111-
equal(modal.portal.refs.overlay.className.contains('myOverlayClass'), true);
113+
notEqual(modal.portal.refs.overlay.className.indexOf('myOverlayClass'), -1);
112114
unmountModal();
113115
});
114116

@@ -164,6 +166,55 @@ describe('Modal', function () {
164166
unmountModal();
165167
});
166168

169+
describe('should close on overlay click', function() {
170+
afterEach('Unmount modal', function() {
171+
unmountModal();
172+
});
173+
174+
describe('verify props', function() {
175+
it('verify default prop of shouldCloseOnOverlayClick', function () {
176+
var modal = renderModal({isOpen: true});
177+
equal(modal.props.shouldCloseOnOverlayClick, true);
178+
});
179+
180+
it('verify prop of shouldCloseOnOverlayClick', function () {
181+
var modal = renderModal({isOpen: true, shouldCloseOnOverlayClick: false});
182+
equal(modal.props.shouldCloseOnOverlayClick, false);
183+
});
184+
});
185+
186+
describe('verify clicks', function() {
187+
it('verify overlay click when shouldCloseOnOverlayClick sets to false', function () {
188+
var requestCloseCallback = sinon.spy();
189+
var modal = renderModal({
190+
isOpen: true,
191+
shouldCloseOnOverlayClick: false
192+
});
193+
equal(modal.props.isOpen, true);
194+
var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
195+
equal(overlay.length, 1);
196+
Simulate.click(overlay[0]); // click the overlay
197+
ok(!requestCloseCallback.called)
198+
});
199+
200+
it('verify overlay click when shouldCloseOnOverlayClick sets to true', function() {
201+
var requestCloseCallback = sinon.spy();
202+
var modal = renderModal({
203+
isOpen: true,
204+
shouldCloseOnOverlayClick: true,
205+
onRequestClose: function() {
206+
requestCloseCallback();
207+
}
208+
});
209+
equal(modal.props.isOpen, true);
210+
var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
211+
equal(overlay.length, 1);
212+
Simulate.click(overlay[0]); // click the overlay
213+
ok(requestCloseCallback.called)
214+
});
215+
});
216+
});
217+
167218
//it('adds --before-close for animations', function() {
168219
//var node = document.createElement('div');
169220

Diff for: ‎specs/helper.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var Modal = React.createFactory(require('../lib/components/Modal'));
55

66
ok = assert.ok;
77
equal = assert.equal;
8+
notEqual = assert.notEqual;
89
strictEqual = assert.strictEqual;
910
throws = assert.throws;
1011

0 commit comments

Comments
 (0)
Please sign in to comment.