diff --git a/lib/components/Modal.js b/lib/components/Modal.js index 49f0a86c..1d9ef54f 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 ' + @@ -43,7 +46,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); }, @@ -53,7 +56,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 e0052815..94ff48cc 100644 --- a/specs/Modal.spec.js +++ b/specs/Modal.spec.js @@ -30,6 +30,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); @@ -53,6 +56,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); @@ -76,6 +80,7 @@ describe('Modal', function () { equal(props.closeTimeoutMS, 0); ReactDOM.unmountComponentAtNode(node); ariaAppHider.resetForTesting(); + Modal.setAppElement(document.body); // restore default }); it('removes the portal node', function() {