Skip to content

Commit ff09b49

Browse files
d-mon-claydiffrient
authored andcommitted
[fixed] Close modal when mouseDown and MouseUp happen only on the overlay (#217)
1 parent 6550b87 commit ff09b49

File tree

2 files changed

+65
-12
lines changed

2 files changed

+65
-12
lines changed

Diff for: lib/components/ModalPortal.js

+21-9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var CLASS_NAMES = {
2121
var ModalPortal = module.exports = React.createClass({
2222

2323
displayName: 'ModalPortal',
24+
shouldClose: null,
2425

2526
getDefaultProps: function() {
2627
return {
@@ -128,20 +129,28 @@ var ModalPortal = module.exports = React.createClass({
128129
}
129130
},
130131

131-
handleOverlayClick: function(event) {
132-
var node = event.target
133-
134-
while (node) {
135-
if (node === this.refs.content) return
136-
node = node.parentNode
132+
handleOverlayMouseDown: function(event) {
133+
if (this.shouldClose === null) {
134+
this.shouldClose = true;
137135
}
136+
},
138137

139-
if (this.props.shouldCloseOnOverlayClick) {
138+
handleOverlayMouseUp: function(event) {
139+
if (this.shouldClose && this.props.shouldCloseOnOverlayClick) {
140140
if (this.ownerHandlesClose())
141141
this.requestClose(event);
142142
else
143143
this.focusContent();
144144
}
145+
this.shouldClose = null;
146+
},
147+
148+
handleContentMouseDown: function(event) {
149+
this.shouldClose = false;
150+
},
151+
152+
handleContentMouseUp: function(event) {
153+
this.shouldClose = false;
145154
},
146155

147156
requestClose: function(event) {
@@ -175,14 +184,17 @@ var ModalPortal = module.exports = React.createClass({
175184
ref: "overlay",
176185
className: this.buildClassName('overlay', this.props.overlayClassName),
177186
style: Assign({}, overlayStyles, this.props.style.overlay || {}),
178-
onClick: this.handleOverlayClick
187+
onMouseDown: this.handleOverlayMouseDown,
188+
onMouseUp: this.handleOverlayMouseUp
179189
},
180190
div({
181191
ref: "content",
182192
style: Assign({}, contentStyles, this.props.style.content || {}),
183193
className: this.buildClassName('content', this.props.className),
184194
tabIndex: "-1",
185-
onKeyDown: this.handleKeyDown
195+
onKeyDown: this.handleKeyDown,
196+
onMouseDown: this.handleContentMouseDown,
197+
onMouseUp: this.handleContentMouseUp
186198
},
187199
this.props.children
188200
)

Diff for: specs/Modal.spec.js

+44-3
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ describe('Modal', function () {
247247
equal(modal.props.isOpen, true);
248248
var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
249249
equal(overlay.length, 1);
250-
Simulate.click(overlay[0]); // click the overlay
250+
Simulate.mouseDown(overlay[0]); // click the overlay
251+
Simulate.mouseUp(overlay[0]);
251252
ok(!requestCloseCallback.called)
252253
});
253254

@@ -263,10 +264,49 @@ describe('Modal', function () {
263264
equal(modal.props.isOpen, true);
264265
var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
265266
equal(overlay.length, 1);
266-
Simulate.click(overlay[0]); // click the overlay
267+
Simulate.mouseDown(overlay[0]); // click the overlay
268+
Simulate.mouseUp(overlay[0]);
267269
ok(requestCloseCallback.called)
268270
});
269271

272+
it('verify overlay mouse down and content mouse up when shouldCloseOnOverlayClick sets to true', function() {
273+
var requestCloseCallback = sinon.spy();
274+
var modal = renderModal({
275+
isOpen: true,
276+
shouldCloseOnOverlayClick: true,
277+
onRequestClose: function() {
278+
requestCloseCallback();
279+
}
280+
});
281+
equal(modal.props.isOpen, true);
282+
var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
283+
var content = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Content');
284+
equal(overlay.length, 1);
285+
equal(content.length, 1);
286+
Simulate.mouseDown(overlay[0]); // click the overlay
287+
Simulate.mouseUp(content[0]);
288+
ok(!requestCloseCallback.called)
289+
});
290+
291+
it('verify content mouse down and overlay mouse up when shouldCloseOnOverlayClick sets to true', function() {
292+
var requestCloseCallback = sinon.spy();
293+
var modal = renderModal({
294+
isOpen: true,
295+
shouldCloseOnOverlayClick: true,
296+
onRequestClose: function() {
297+
requestCloseCallback();
298+
}
299+
});
300+
equal(modal.props.isOpen, true);
301+
var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
302+
var content = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Content');
303+
equal(content.length, 1);
304+
equal(overlay.length, 1);
305+
Simulate.mouseDown(content[0]); // click the overlay
306+
Simulate.mouseUp(overlay[0]);
307+
ok(!requestCloseCallback.called)
308+
});
309+
270310
it('should not stop event propagation', function() {
271311
var hasPropagated = false
272312
var modal = renderModal({
@@ -290,7 +330,8 @@ describe('Modal', function () {
290330
equal(modal.props.isOpen, true);
291331
var overlay = TestUtils.scryRenderedDOMComponentsWithClass(modal.portal, 'ReactModal__Overlay');
292332
equal(overlay.length, 1);
293-
Simulate.click(overlay[0]); // click the overlay
333+
Simulate.mouseDown(overlay[0]); // click the overlay
334+
Simulate.mouseUp(overlay[0]);
294335
ok(requestCloseCallback.called)
295336
// Check if event is passed to onRequestClose callback.
296337
var event = requestCloseCallback.getCall(0).args[0];

0 commit comments

Comments
 (0)