diff --git a/lib/components/Modal.js b/lib/components/Modal.js index 07b5dac8..2b80d7cc 100644 --- a/lib/components/Modal.js +++ b/lib/components/Modal.js @@ -7,12 +7,15 @@ var elementClass = require('element-class'); var renderSubtreeIntoContainer = require("react-dom").unstable_renderSubtreeIntoContainer; var SafeHTMLElement = ExecutionEnvironment.canUseDOM ? window.HTMLElement : {}; +var AppElement = ExecutionEnvironment.canUseDOM ? document.body : {appendChild: function() {}}; var Modal = module.exports = React.createClass({ displayName: 'Modal', statics: { - setAppElement: ariaAppHider.setElement, + setAppElement: function(element) { + AppElement = ariaAppHider.setElement(element); + }, injectCSS: function() { "production" !== process.env.NODE_ENV && console.warn('React-Modal: injectCSS has been deprecated ' + @@ -45,7 +48,7 @@ var Modal = module.exports = React.createClass({ componentDidMount: function() { this.node = document.createElement('div'); this.node.className = 'ReactModalPortal'; - document.body.appendChild(this.node); + AppElement.appendChild(this.node); this.renderPortal(this.props); }, @@ -55,7 +58,7 @@ var Modal = module.exports = React.createClass({ componentWillUnmount: function() { ReactDOM.unmountComponentAtNode(this.node); - document.body.removeChild(this.node); + AppElement.removeChild(this.node); }, renderPortal: function(props) { diff --git a/lib/helpers/ariaAppHider.js b/lib/helpers/ariaAppHider.js index 5c17894b..05b4c128 100644 --- a/lib/helpers/ariaAppHider.js +++ b/lib/helpers/ariaAppHider.js @@ -6,6 +6,7 @@ function setElement(element) { element = 'length' in el ? el[0] : el; } _element = element || _element; + return _element; } function hide(appElement) { diff --git a/specs/Modal.spec.js b/specs/Modal.spec.js index 1076cbba..4162bfd4 100644 --- a/specs/Modal.spec.js +++ b/specs/Modal.spec.js @@ -31,6 +31,9 @@ describe('Modal', function () { var node = document.createElement('div'); Modal.setAppElement(app); ReactDOM.render(React.createElement(Modal, {isOpen: true}), node); + var modalParent = app.querySelector('.ReactModalPortal').parentNode; + assert.notEqual(modalParent, document.body); + assert.equal(modalParent, app); equal(app.getAttribute('aria-hidden'), 'true'); ariaAppHider.resetForTesting(); ReactDOM.unmountComponentAtNode(node); @@ -54,6 +57,7 @@ describe('Modal', function () { return React.DOM.div({}, React.createElement(Modal, {isOpen: true, ariaHideApp: false}, 'hello')); } }); + Modal.setAppElement(document.body); ReactDOM.render(React.createElement(App), node); var modalParent = document.body.querySelector('.ReactModalPortal').parentNode; equal(modalParent, document.body); @@ -78,6 +82,7 @@ describe('Modal', function () { equal(props.shouldCloseOnOverlayClick, true); ReactDOM.unmountComponentAtNode(node); ariaAppHider.resetForTesting(); + Modal.setAppElement(document.body); // restore default }); it('removes the portal node', function() {