Skip to content

Commit 2ac5290

Browse files
committed
Better solution for applying focus
1 parent c04e083 commit 2ac5290

File tree

3 files changed

+27
-20
lines changed

3 files changed

+27
-20
lines changed

lib/components/ModalPortal.js

+20-12
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,33 @@ var ModalPortal = module.exports = React.createClass({
3333
},
3434

3535
componentDidMount: function() {
36+
// Focus needs to be set when mounting and already open
37+
if (this.props.isOpen) {
38+
this.setFocusAfterRender(true);
39+
}
3640
this.handleProps(this.props);
37-
this.maybeFocus();
3841
},
3942

4043
componentWillReceiveProps: function(newProps) {
44+
// Focus only needs to be set once when the modal is being opened
45+
if (!this.props.isOpen && newProps.isOpen) {
46+
this.setFocusAfterRender(true);
47+
}
48+
4149
this.handleProps(newProps);
4250
},
4351

52+
componentDidUpdate: function () {
53+
if (this.focusAfterRender) {
54+
this.focusContent();
55+
this.setFocusAfterRender(false);
56+
}
57+
},
58+
59+
setFocusAfterRender: function (focus) {
60+
this.focusAfterRender = focus;
61+
},
62+
4463
handleProps: function(props) {
4564
if (props.isOpen === true)
4665
this.open();
@@ -65,17 +84,6 @@ var ModalPortal = module.exports = React.createClass({
6584
this.closeWithoutTimeout();
6685
},
6786

68-
componentDidUpdate: function() {
69-
this.maybeFocus();
70-
},
71-
72-
maybeFocus: function() {
73-
if (this.props.isOpen &&
74-
!this.refs.content.getDOMNode().contains(document.activeElement)) {
75-
this.focusContent();
76-
}
77-
},
78-
7987
focusContent: function() {
8088
this.refs.content.getDOMNode().focus();
8189
},

specs/Modal.spec.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,10 @@ describe('Modal', function () {
9292
});
9393

9494
it('focuses the modal content', function() {
95-
var modal = renderModal({isOpen: true});
96-
strictEqual(document.activeElement, modal.portal.refs.content.getDOMNode());
97-
unmountModal();
95+
renderModal({isOpen: true}, null, function () {
96+
strictEqual(document.activeElement, this.portal.refs.content.getDOMNode());
97+
unmountModal();
98+
});
9899
});
99100

100101
it('adds --after-open for animations', function() {
@@ -129,4 +130,3 @@ describe('Modal', function () {
129130
//unmountModal();
130131
//});
131132
});
132-

specs/helper.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,15 @@ throws = assert.throws;
1010

1111
var _currentDiv = null;
1212

13-
renderModal = function(def) {
14-
def.ariaHideApp = false;
13+
renderModal = function(props, children, callback) {
14+
props.ariaHideApp = false;
1515
_currentDiv = document.createElement('div');
1616
document.body.appendChild(_currentDiv);
17-
return React.renderComponent(Modal.apply(Modal, arguments), _currentDiv);
17+
return React.renderComponent(Modal(props, children), _currentDiv, callback);
1818
};
1919

2020
unmountModal = function() {
2121
React.unmountComponentAtNode(_currentDiv);
2222
document.body.removeChild(_currentDiv);
2323
_currentDiv = null;
2424
};
25-

0 commit comments

Comments
 (0)