Repository: mui/material-ui (TypeScript)
Date: 2018-06-17 21:16:00+00:00
Task type: Bug Fix

Issue:
Animate Tab and selection box problem
## Expected Behavior
I am using the tab with "react-swipeable-views" animation like the example https://material-ui.com/demos/tabs/#fixed-tabs. And I use the selection box like the example https://material-ui.com/demos/selects/#simple-select under the tab content.

I expect the switching animation can be shown as the tabs example.

## Current Behavior
The current behavior is there is no animation for the first switching action. But after the first switching, everything is work as expected including the animation.

If I change the simple selection box to native selection box, the animation also works well.

So, the problem occurs if I use the tabs with "react-swipeable-views" and the simple selection box together.

## Steps to Reproduce (for bugs)

Demo: https://codesandbox.io/s/zwm62j8j1x

- Switching tabs (Only the first switch is no animation)
- Refresh page to reproduce the problem

##  Environment
<!--- Include as many relevant details about the environment with which you experienced the bug. -->

| Tech         | Version |
|--------------|---------|
| Material-UI  |    1.0.0-beta.37     |
| React        |   16.2.0  |
| react-swipeable-views      |    0.12.12     |



Issue discussion:
Related to https://github.com/oliviertassinari/react-swipeable-views/issues/417
Problem solved by downgrading the react-swipeable-views version to 0.12.4
with 0.12.4 problem gone
The root of the issue is in this line. 
https://github.com/mui-org/material-ui/blob/e199c9fb70622b8a2b4bf42ff6af22029ada2ea6/src/Select/SelectInput.js#L266
We are asking the browser to perform layout computation during the animation with `displayNode.clientWidth`. It's consistently behaving on the latest version of Firefox, Chrome and Safari. I'm preparing a fix. It's simple.
I believe this is a problem still/again. Here's a demo with material-ui 1.1.0 and react-swipeable-views 0.12.13:

https://codesandbox.io/s/p95332j6z7
I have the same symptoms with the following versions:
```
"@material-ui/core": "^1.2.0",
"@material-ui/icons": "^1.1.0",
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-router-dom": "^4.2.2",
"react-swipeable-views": "^0.12.13"
```
I can confirm this. Downgrading does not help.
I can confirm too.
The behavior was fixed in #10706 but broken in #10956.
This comment might explain the source of the issue: https://github.com/reactjs/react-transition-group/issues/10#issuecomment-287463848.

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,62 @@ Material-UI strictly follows [Semantic Versioning 2.0.0](http://semver.org/).
 - Weekly release: patch or minor version at the end of every week for routine bugfix or new features (anytime for urgent bugfix).
 - Major version release is not included in this schedule for breaking change and new features.
 
+## 1.2.2
+###### *Jun 18, 2018*
+
+Big thanks to the 16 contributors who made this release possible.
+
+### Breaking change
+
+N/A
+
+#### Component Fixes / Enhancements
+
+- [ClickAwayListener] Add a demo (#11801) @oliviertassinari
+- [Grid] Add support a auto value (#11804) @oliviertassinari
+- [StepButton] Fix IE 11 flexbox (#11814) @paulnta
+- [styles] Re-add default parameter of string for WithStyles (#11808) @pelotom
+- [SwipeableDrawer] Allow custom style (#11805) @Johann-S
+- [ButtonBase] Corrected the type definitions for the TouchRipple classes (#11818) @C-Rodg
+- [RootRef] Updated main index.js to include RootRef export (#11817) @C-Rodg
+- [typography] Add a `allVariants` key in the theme (#11802) @oliviertassinari
+- [ButtonBase] Add a disableTouchRipple property (#11820) @oliviertassinari
+- [Tabs] Fix calculating tab indicator position (#11825) @ljani
+- [Tabs] Fix IE11 support (#11832) @oliviertassinari
+- [withWidth] Reading initialWidth from the theme (#11831) @kleyson
+- [Tabs] Add support for a `component` property (#11844) @C-Rodg
+- [ListItemText] Detect and avoid re-wrapping Typography (#11849) @jedwards1211
+- [ListItemText] Add primaryTypographyProps and secondaryTypographyProps (#11858) @jedwards1211
+- [Tooltip] Update react-popper (#11862) @oliviertassinari
+- [TableCell] Fix property name (#11870) @marutanm
+- [Modal] Fix removeEventListener (#11875) @DominikSerafin
+- [CircularProgress] Fix wobble (#11886) @oliviertassinari
+- [CircularProgress] End of line shape: use butt (#11888) @Modestas
+
+#### Docs
+
+- [docs] Add structured data (#11798) @oliviertassinari
+- [docs] Add a link to a CSS-in-JS egghead.io course (98168a2c749d8da2376d6a997145e3622df71bff) @kof
+- [Table] Derive sorted rows from state at render time in demo (#11828) @charlax
+- [docs] Document the dynamic override alternatives (#11782) @adeelibr
+- [docs] Add a Select required example (#11838) @oliviertassinari
+- [docs] Better class names conflict FAQ (#11846) @oliviertassinari
+- [docs] Add a link toward dx-react-chart-material-ui (#11859) @Krijovnick
+- [docs] Fix the Gatsby example (d7fe8c79dc097105fd1c6035b76a4d30666e9080) @oliviertassinari
+- [docs] Update npm downloads badge to point to @material-ui/core (#11590) @davidcalhoun
+- [examples] Add Server Rendering implementation (#11880) @oliviertassinari
+- [docs] Update react-swipeable-views to fix a warning (#11890) @oliviertassinari
+
+#### Core
+
+- [core] Misc (#11797) @oliviertassinari
+- [core] Better `component` prop types (#11863) @jedwards1211
+- [core] Remove some unneeded code (#11873) @oliviertassinari
+- [core] Fix the UMD release (#11878) @oliviertassinari
+- [core] Document the non supported children properties (#11879) @oliviertassinari
+
+#### Labs
+
 ## 1.2.1
 ###### *Jun 10, 2018*
 
diff --git a/packages/material-ui/src/Select/SelectInput.js b/packages/material-ui/src/Select/SelectInput.js
--- a/packages/material-ui/src/Select/SelectInput.js
+++ b/packages/material-ui/src/Select/SelectInput.js
@@ -10,6 +10,7 @@ import { isFilled } from '../Input/Input';
  */
 class SelectInput extends React.Component {
   state = {
+    menuMinWidth: null,
     open: false,
   };
 
@@ -27,24 +28,10 @@ class SelectInput extends React.Component {
     }
   }
 
-  shouldComponentUpdate() {
-    this.updateDisplayWidth();
-
-    return true;
-  }
-
   ignoreNextBlur = false;
   displayNode = null;
-  displayWidth = null;
   isOpenControlled = this.props.open !== undefined;
 
-  updateDisplayWidth = () => {
-    // Perfom the layout computation outside of the render method.
-    if (this.displayNode) {
-      this.displayWidth = this.displayNode.clientWidth;
-    }
-  };
-
   update = this.isOpenControlled
     ? ({ event, open }) => {
         if (open) {
@@ -53,7 +40,13 @@ class SelectInput extends React.Component {
           this.props.onClose(event);
         }
       }
-    : ({ open }) => this.setState({ open });
+    : ({ open }) => {
+        this.setState({
+          // Perfom the layout computation outside of the render method.
+          menuMinWidth: this.props.autoWidth ? null : this.displayNode.clientWidth,
+          open,
+        });
+      };
 
   handleClick = event => {
     // Opening the menu is going to blur the. It will be focused back when closed.
@@ -139,7 +132,6 @@ class SelectInput extends React.Component {
 
   handleDisplayRef = node => {
     this.displayNode = node;
-    this.updateDisplayWidth();
   };
 
   handleInputRef = node => {
@@ -243,7 +235,12 @@ class SelectInput extends React.Component {
       display = multiple ? displayMultiple.join(', ') : displaySingle;
     }
 
-    const MenuMinWidth = this.displayNode && !autoWidth ? this.displayWidth : undefined;
+    // Avoid performing a layout computation in the render method.
+    let menuMinWidth = this.state.menuMinWidth;
+
+    if (!autoWidth && this.isOpenControlled && this.displayNode) {
+      menuMinWidth = this.displayNode.clientWidth;
+    }
 
     let tabIndex;
     if (typeof tabIndexProp !== 'undefined') {
@@ -302,7 +299,7 @@ class SelectInput extends React.Component {
           PaperProps={{
             ...MenuProps.PaperProps,
             style: {
-              minWidth: MenuMinWidth,
+              minWidth: menuMinWidth,
               ...(MenuProps.PaperProps != null ? MenuProps.PaperProps.style : null),
             },
           }}


Test patch:
diff --git a/packages/material-ui/src/Select/SelectInput.test.js b/packages/material-ui/src/Select/SelectInput.test.js
--- a/packages/material-ui/src/Select/SelectInput.test.js
+++ b/packages/material-ui/src/Select/SelectInput.test.js
@@ -243,16 +243,20 @@ describe('<SelectInput />', () => {
   describe('prop: autoWidth', () => {
     it('should take the anchor width into account', () => {
       const wrapper = shallow(<SelectInput {...defaultProps} />);
-      wrapper.instance().displayNode = { clientWidth: 14 };
-      wrapper.setProps({});
+      const instance = wrapper.instance();
+      instance.displayNode = { clientWidth: 14 };
+      instance.update({ open: true });
+      wrapper.update();
       assert.strictEqual(wrapper.find(Menu).props().PaperProps.style.minWidth, 14);
     });
 
     it('should not take the anchor width into account', () => {
       const wrapper = shallow(<SelectInput {...defaultProps} autoWidth />);
-      wrapper.instance().displayNode = { clientWidth: 14 };
-      wrapper.setProps({});
-      assert.strictEqual(wrapper.find(Menu).props().PaperProps.style.minWidth, undefined);
+      const instance = wrapper.instance();
+      instance.displayNode = { clientWidth: 14 };
+      instance.update({ open: true });
+      wrapper.update();
+      assert.strictEqual(wrapper.find(Menu).props().PaperProps.style.minWidth, null);
     });
   });