diff --git a/docs/examples/ModalStatic.js b/docs/examples/ModalStatic.js
index 545efbee73..f01a4d058e 100644
--- a/docs/examples/ModalStatic.js
+++ b/docs/examples/ModalStatic.js
@@ -1,6 +1,7 @@
const modalInstance = (
document.detachEvent('onfocusin', handler);
+ } else {
+ document.addEventListener('focus', handler, true);
+ remove = () => document.removeEventListener('focus', handler, true);
+ }
+ return { remove };
+}
+
+let scrollbarSize;
if ( domUtils.canUseDom) {
let scrollDiv = document.createElement('div');
@@ -60,7 +82,8 @@ const Modal = React.createClass({
closeButton: React.PropTypes.bool,
animation: React.PropTypes.bool,
onRequestHide: React.PropTypes.func.isRequired,
- dialogClassName: React.PropTypes.string
+ dialogClassName: React.PropTypes.string,
+ enforceFocus: React.PropTypes.bool
},
getDefaultProps() {
@@ -69,10 +92,15 @@ const Modal = React.createClass({
backdrop: true,
keyboard: true,
animation: true,
- closeButton: true
+ closeButton: true,
+ enforceFocus: true
};
},
+ getInitialState(){
+ return { };
+ },
+
render() {
let state = this.state;
let modalStyle = { ...state.dialogStyles, display: 'block'};
@@ -107,7 +135,7 @@ const Modal = React.createClass({
);
return this.props.backdrop ?
- this.renderBackdrop(modal) : modal;
+ this.renderBackdrop(modal, state.backdropStyles) : modal;
},
renderBackdrop(modal) {
@@ -132,8 +160,8 @@ const Modal = React.createClass({
let closeButton;
if (this.props.closeButton) {
closeButton = (
-
- );
+
+ );
}
return (
@@ -169,6 +197,10 @@ const Modal = React.createClass({
this._onWindowResizeListener =
EventListener.listen(win, 'resize', this.handleWindowResize);
+ if (this.props.enforceFocus) {
+ this._onFocusinListener = onFocus(this, this.enforceFocus);
+ }
+
let container = getContainer(this);
container.className += container.className.length ? ' modal-open' : 'modal-open';
@@ -199,6 +231,10 @@ const Modal = React.createClass({
this._onDocumentKeyupListener.remove();
this._onWindowResizeListener.remove();
+ if (this._onFocusinListener) {
+ this._onFocusinListener.remove();
+ }
+
let container = getContainer(this);
container.className = container.className.replace(/ ?modal-open/, '');
@@ -237,6 +273,19 @@ const Modal = React.createClass({
}
},
+ enforceFocus() {
+ if ( !this.isMounted() ) {
+ return;
+ }
+
+ let active = domUtils.activeElement(this)
+ , modal = React.findDOMNode(this.refs.modal);
+
+ if (modal !== active && !domUtils.contains(modal, active)){
+ modal.focus();
+ }
+ },
+
_getStyles() {
if ( !domUtils.canUseDom ) { return {}; }
diff --git a/src/utils/domUtils.js b/src/utils/domUtils.js
index ae56eb210d..31fa7c0340 100644
--- a/src/utils/domUtils.js
+++ b/src/utils/domUtils.js
@@ -26,6 +26,20 @@ function ownerWindow(componentOrElement) {
: doc.parentWindow;
}
+/**
+ * get the active element, safe in IE
+ * @return {HTMLElement}
+ */
+function getActiveElement(componentOrElement){
+ let doc = ownerDocument(componentOrElement);
+
+ try {
+ return doc.activeElement || doc.body;
+ } catch (e) {
+ return doc.body;
+ }
+}
+
/**
* Shortcut to compute element style
*
@@ -160,5 +174,6 @@ export default {
getComputedStyles,
getOffset,
getPosition,
+ activeElement: getActiveElement,
offsetParent: offsetParentFunc
};