diff --git a/.size-limit b/.size-limit index a5493389f46ed4..0ca5fdc6dd8c6b 100644 --- a/.size-limit +++ b/.size-limit @@ -9,7 +9,7 @@ "name": "The size of all the modules of material-ui.", "webpack": true, "path": "packages/material-ui/build/index.js", - "limit": "101.0 KB" + "limit": "101.1 KB" }, { "name": "The main bundle of the docs", diff --git a/docs/src/pages/guides/composition/composition.md b/docs/src/pages/guides/composition/composition.md index 751e428f63ea03..084116bf62ba24 100644 --- a/docs/src/pages/guides/composition/composition.md +++ b/docs/src/pages/guides/composition/composition.md @@ -89,6 +89,6 @@ class ListItemLink extends React.Component { } ``` -`renderLink` will now always reference the same component. Here is a demo: +`renderLink` will now always reference the same component. Here is a demo with react-router: {{"demo": "pages/guides/composition/ComponentProperty.js"}} diff --git a/docs/src/pages/utils/portal/portal.md b/docs/src/pages/utils/portal/portal.md index 61f442161c2042..0c371b357aa91d 100644 --- a/docs/src/pages/utils/portal/portal.md +++ b/docs/src/pages/utils/portal/portal.md @@ -15,3 +15,9 @@ You have to wait for the client side reconciliation to see the children. ## Simple Portal {{"demo": "pages/utils/portal/SimplePortal.js"}} + +## Portal & tests + +The portal behavior can be challenging for testing libraries, like [enzyme](https://github.com/airbnb/enzyme/issues/252), to handle. +We provide a global option to disable the behavior: `global.__MUI_PORTAL_DISABLE__`. +When set to `true`, the portal will behave as a pass-through component. diff --git a/packages/material-ui/src/Portal/Portal.js b/packages/material-ui/src/Portal/Portal.js index 0931b5b6ce9dec..e35e5438a9e1b7 100644 --- a/packages/material-ui/src/Portal/Portal.js +++ b/packages/material-ui/src/Portal/Portal.js @@ -1,3 +1,5 @@ +/* eslint-disable no-underscore-dangle */ + import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; @@ -44,13 +46,30 @@ class Portal extends React.Component { * @public */ getMountNode = () => { + if (this.disable) { + return ReactDOM.findDOMNode(this); + } + return this.mountNode; }; + // Hack waiting for https://github.com/airbnb/enzyme/issues/252 to be solved. + // When `global.__MUI_PORTAL_DISABLE__` is set to `true`, + // the portal will behave as a pass-through component. + disable = typeof global !== 'undefined' && global.__MUI_PORTAL_DISABLE__; + render() { const { children } = this.props; - return this.mountNode ? ReactDOM.createPortal(children, this.mountNode) : null; + if (this.mountNode) { + if (this.disable) { + return children; + } + + return ReactDOM.createPortal(children, this.mountNode); + } + + return null; } } diff --git a/packages/material-ui/src/Portal/Portal.test.js b/packages/material-ui/src/Portal/Portal.test.js index c9aac3e6a2c3c5..06cdb967d10c59 100644 --- a/packages/material-ui/src/Portal/Portal.test.js +++ b/packages/material-ui/src/Portal/Portal.test.js @@ -1,3 +1,4 @@ +/* eslint-disable no-underscore-dangle */ /* eslint-disable react/no-multi-comp */ import React from 'react'; @@ -24,6 +25,29 @@ describe('', () => { mount.cleanUp(); }); + describe('disable portal for tests', () => { + const Portal = NewPortal; + + before(() => { + global.__MUI_PORTAL_DISABLE__ = true; + }); + + after(() => { + global.__MUI_PORTAL_DISABLE__ = false; + }); + + it('should disable the portal feature', () => { + const wrapper = mount( + +

Foo

+
, + ); + assert.strictEqual(wrapper.children().length, 1, 'should have one children'); + const instance = wrapper.instance(); + assert.strictEqual(instance.getMountNode().nodeName.toLowerCase(), 'h1'); + }); + }); + versions.map(verion => { describe(verion, () => { let Portal;