diff --git a/docs/README.md b/docs/README.md index 6a760a52..da9f7e50 100644 --- a/docs/README.md +++ b/docs/README.md @@ -52,6 +52,11 @@ import ReactModal from 'react-modal'; See the `Styles` section for more details. */ className="ReactModal__Content" + /* + String className to be applied to the document.body. + See the `Styles` section for more details. + */ + bodyOpenClassName="ReactModal__Body--open" /* Boolean indicating if the appElement should be hidden */ diff --git a/docs/styles/classes.md b/docs/styles/classes.md index 798a19ab..058a789a 100644 --- a/docs/styles/classes.md +++ b/docs/styles/classes.md @@ -1,5 +1,6 @@ ### CSS Classes Sometimes it may be preferable to use CSS classes rather than inline styles. You can use the `className` and `overlayClassName` props to specify a given CSS class for each of those. +You can override the default class that is added to `document.body` when the modal is open by defining a property `bodyOpenClassName`. Note: If you provide those props all default styles will not be applied, leaving all styles under control of the CSS class. The `portalClassName` can also be used however there are no styles by default applied diff --git a/lib/components/Modal.js b/lib/components/Modal.js index 03ea092b..34d23b1b 100644 --- a/lib/components/Modal.js +++ b/lib/components/Modal.js @@ -38,6 +38,7 @@ var Modal = createReactClass({ overlay: PropTypes.object }), portalClassName: PropTypes.string, + bodyOpenClassName: React.PropTypes.string, appElement: PropTypes.instanceOf(SafeHTMLElement), onAfterOpen: PropTypes.func, onRequestClose: PropTypes.func, @@ -53,6 +54,7 @@ var Modal = createReactClass({ return { isOpen: false, portalClassName: 'ReactModalPortal', + bodyOpenClassName: 'ReactModal__Body--open', ariaHideApp: true, closeTimeoutMS: 0, shouldCloseOnOverlayClick: true, @@ -114,16 +116,17 @@ var Modal = createReactClass({ ReactDOM.unmountComponentAtNode(this.node); var parent = getParentElement(this.props.parentSelector); parent.removeChild(this.node); + if (refCount.count() === 0) { - elementClass(document.body).remove('ReactModal__Body--open'); + elementClass(document.body).remove(this.props.bodyOpenClassName); } }, renderPortal: function(props) { if (props.isOpen || refCount.count() > 0) { - elementClass(document.body).add('ReactModal__Body--open'); + elementClass(document.body).add(this.props.bodyOpenClassName); } else { - elementClass(document.body).remove('ReactModal__Body--open'); + elementClass(document.body).remove(this.props.bodyOpenClassName); } if (props.ariaHideApp) { diff --git a/specs/Modal.spec.js b/specs/Modal.spec.js index 97d85494..4c2c210e 100644 --- a/specs/Modal.spec.js +++ b/specs/Modal.spec.js @@ -171,6 +171,11 @@ describe('State', () => { ).toBeTruthy(); }); + it('supports overriding react modal open class in document.body.', () => { + const modal = renderModal({ isOpen: true, bodyOpenClassName: 'custom-modal-open' }); + expect(document.body.className.indexOf('custom-modal-open') !== -1).toBeTruthy(); + }); + it('don\'t append class to document.body if modal is not open', () => { renderModal({ isOpen: false }); expect(!isBodyWithReactModalOpenClass()).toBeTruthy();