Repository: mui/material-ui (TypeScript)
Date: 2018-07-20 21:58:57+00:00
Task type: Bug Fix

Issue:
[Popper] Weird Behavior While Hiding it.
<!--- Provide a general summary of the issue in the Title above -->
I'm using the new Popper component that released in 1.4.0. While closing the menu there's some weird behavior happening and I believe that is happening because of the transition from position absolute and static.

## Expected Behavior
 While closing it I expect smooth behavior with the transition effect.

## Current Behavior
What actually happening is weird. It transforms from position absolute to static that make it push the button itself.

## Steps to Reproduce
Just open the Popper then close it by clicking anywhere outside.
[![Edit create-react-app](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/jpwrk616w)

## Environment

| Tech         | Version |
|--------------|---------|
| Material-UI  |1.4|
| React |1.6|



Issue discussion:
Please provide a full reproduction test case. This would help a lot 👷 .
A live example would be perfect. [This **codesandbox.io** template](https://codesandbox.io/s/github/callemall/material-ui/tree/master/examples/create-react-app) _may_ be a good starting point. Thank you!

Solution patch:
diff --git a/docs/src/pages/utils/popper/PositionedPopper.js b/docs/src/pages/utils/popper/PositionedPopper.js
--- a/docs/src/pages/utils/popper/PositionedPopper.js
+++ b/docs/src/pages/utils/popper/PositionedPopper.js
@@ -28,7 +28,7 @@ class PositionedPopper extends React.Component {
     const { currentTarget } = event;
     this.setState(state => ({
       anchorEl: currentTarget,
-      open: !state.placement === placement || !state.open,
+      open: state.placement !== placement || !state.open,
       placement,
     }));
   };
diff --git a/packages/material-ui/src/Popper/Popper.js b/packages/material-ui/src/Popper/Popper.js
--- a/packages/material-ui/src/Popper/Popper.js
+++ b/packages/material-ui/src/Popper/Popper.js
@@ -43,20 +43,21 @@ class Popper extends React.Component {
   }
 
   componentDidUpdate(prevProps) {
-    if (prevProps.open && !this.props.open && !this.props.transition) {
+    if (prevProps.open !== this.props.open && !this.props.open && !this.props.transition) {
       // Otherwise handleExited will call this.
       this.handleClose();
     }
 
     // Let's update the popper position.
     if (
+      prevProps.open !== this.props.open ||
       prevProps.anchorEl !== this.props.anchorEl ||
       prevProps.popperOptions !== this.props.popperOptions ||
       prevProps.modifiers !== this.props.modifiers ||
       prevProps.disablePortal !== this.props.disablePortal ||
       prevProps.placement !== this.props.placement
     ) {
-      this.handleRendered();
+      this.handleOpen();
     }
   }
 
@@ -81,7 +82,7 @@ class Popper extends React.Component {
     return null;
   }
 
-  handleRendered = () => {
+  handleOpen = () => {
     const {
       anchorEl,
       modifiers,
@@ -93,15 +94,15 @@ class Popper extends React.Component {
     } = this.props;
     const popperNode = ReactDOM.findDOMNode(this);
 
+    if (!popperNode || !anchorEl || !open) {
+      return;
+    }
+
     if (this.popper) {
       this.popper.destroy();
       this.popper = null;
     }
 
-    if (!popperNode || !anchorEl || !open) {
-      return;
-    }
-
     this.popper = new PopperJS(getAnchorEl(anchorEl), popperNode, {
       placement: flipPlacement(theme, placement),
       ...popperOptions,
@@ -178,7 +179,7 @@ class Popper extends React.Component {
     }
 
     return (
-      <Portal onRendered={this.handleRendered} disablePortal={disablePortal} container={container}>
+      <Portal onRendered={this.handleOpen} disablePortal={disablePortal} container={container}>
         <div
           role="tooltip"
           style={{


Test patch:
diff --git a/packages/material-ui/src/Popper/Popper.test.js b/packages/material-ui/src/Popper/Popper.test.js
--- a/packages/material-ui/src/Popper/Popper.test.js
+++ b/packages/material-ui/src/Popper/Popper.test.js
@@ -106,6 +106,22 @@ describe('<Popper />', () => {
       wrapper.setProps({ open: false });
       assert.strictEqual(wrapper.find('span').length, 0);
     });
+
+    it('should position the popper when opening', () => {
+      const wrapper = mount(<PopperNaked {...defaultProps} open={false} anchorEl={anchorEl} />);
+      const instance = wrapper.instance();
+      assert.strictEqual(instance.popper, null);
+      wrapper.setProps({ open: true });
+      assert.strictEqual(instance.popper !== null, true);
+    });
+
+    it('should not position the popper when closing', () => {
+      const wrapper = mount(<PopperNaked {...defaultProps} open anchorEl={anchorEl} />);
+      const instance = wrapper.instance();
+      assert.strictEqual(instance.popper !== null, true);
+      wrapper.setProps({ open: false });
+      assert.strictEqual(instance.popper, null);
+    });
   });
 
   describe('prop: transition', () => {
@@ -124,6 +140,12 @@ describe('<Popper />', () => {
       assert.strictEqual(wrapper.find('span').text(), 'Hello World');
       assert.strictEqual(instance.popper !== null, true);
       wrapper.setProps({ anchorEl: null });
+      assert.strictEqual(instance.popper !== null, true);
+      wrapper.setProps({ open: false });
+      wrapper
+        .find(Grow)
+        .props()
+        .onExited();
       assert.strictEqual(instance.popper, null);
     });
   });