From 97ef41537fef7dc0b6a35921279e0124c6f40152 Mon Sep 17 00:00:00 2001 From: jquense Date: Sun, 28 Jun 2015 23:12:54 -0400 Subject: [PATCH] [fixed] Modal won't steal focus from children fixes #903 --- src/Modal.js | 25 ++++++++++++++++++++++--- test/ModalSpec.js | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/Modal.js b/src/Modal.js index 41b0d51b6e..55e2eb3113 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -101,6 +101,7 @@ const Modal = React.createClass({ animation: React.PropTypes.bool, onRequestHide: React.PropTypes.func.isRequired, dialogClassName: React.PropTypes.string, + autoFocus: React.PropTypes.bool, enforceFocus: React.PropTypes.bool }, @@ -111,6 +112,8 @@ const Modal = React.createClass({ keyboard: true, animation: true, closeButton: true, + + autoFocus: true, enforceFocus: true }; }, @@ -205,6 +208,10 @@ const Modal = React.createClass({ React.findDOMNode(this.refs.backdrop).onclick = function () {}; }, + componentWillMount(){ + this.checkForFocus(); + }, + componentDidMount() { const doc = domUtils.ownerDocument(this); const win = domUtils.ownerWindow(this); @@ -286,11 +293,23 @@ const Modal = React.createClass({ this.setState(this._getStyles()); }, + checkForFocus(){ + if ( domUtils.canUseDom ) { + try { + this.lastFocus = document.activeElement; + } + catch (e) {} + } + }, + focusModalContent () { - if (this.props.enforceFocus) { - this.lastFocus = domUtils.activeElement(this); + let modalContent = React.findDOMNode(this.refs.modal); + let current = domUtils.activeElement(this); + let focusInModal = current && domUtils.contains(modalContent, current); + + if (this.props.autoFocus && !focusInModal) { + this.lastFocus = current; - let modalContent = React.findDOMNode(this.refs.modal); modalContent.focus(); } }, diff --git a/test/ModalSpec.js b/test/ModalSpec.js index 0e516d52dc..c1480d87dc 100644 --- a/test/ModalSpec.js +++ b/test/ModalSpec.js @@ -156,7 +156,7 @@ describe('Modal', function () { }, 0); }); - it('Should not focus on the Modal when enforceFocus is false', function (done) { + it('Should not focus on the Modal when autoFocus is false', function (done) { document.activeElement.should.equal(focusableContainer); @@ -167,7 +167,7 @@ describe('Modal', function () { render() { if (this.state.modalOpen) { return ( - {}} container={this}> + {}} container={this}> Message ); @@ -185,6 +185,38 @@ describe('Modal', function () { done(); }, 0); }); + + it('Should not focus Modal when child has focus', function (done) { + + document.activeElement.should.equal(focusableContainer); + + let Container = React.createClass({ + getInitialState() { + return {modalOpen: true}; + }, + render() { + if (this.state.modalOpen) { + return ( + {}} container={this}> + + + ); + } else { + return ; + } + } + }); + + var instance = React.render(, focusableContainer); + + setTimeout(function () { + let input = React.findDOMNode( + ReactTestUtils.findRenderedDOMComponentWithTag(instance, 'input')) + + document.activeElement.should.equal(input); + done(); + }, 0); + }); });