Repository: mui/material-ui (TypeScript)
Date: 2018-12-07 23:36:34+00:00
Task type: Bug Fix

Issue:
tabs scrollable bugs
tabs scrollable bugs after open or close devtools
![1](https://user-images.githubusercontent.com/23016311/49506305-71010b00-f886-11e8-9b69-f1f1bfd2764e.PNG)
![2](https://user-images.githubusercontent.com/23016311/49506426-ba515a80-f886-11e8-9293-f1f86b249b94.PNG)





Issue discussion:
@maystrenkoYurii do you have a minimal reproducible example? 

Why? These bugs are also on your site, on the example tabs page. Open your site, go to tab tabs, open and close the developer panel and watch the bugs.
https://material-ui.com/demos/tabs/
@maystrenkoYurii I don't see the issues you described. Pleas fill out the issue template. Otherwise it's very hard to help you.
Not funny.... Appears after the opening and closing devtools
![3](https://user-images.githubusercontent.com/23016311/49583344-8480a480-f960-11e8-828e-0d28ca28f0e4.PNG)
![4](https://user-images.githubusercontent.com/23016311/49583345-8480a480-f960-11e8-8b38-c8fa0bcf92dc.PNG)

 panel
What version of chrome are you using? 
Latest version Google Crome
![5](https://user-images.githubusercontent.com/23016311/49647052-dfca9980-fa29-11e8-9b00-cd54c90201f3.PNG)
![6](https://user-images.githubusercontent.com/23016311/49647053-e0633000-fa29-11e8-8024-af33721b26a3.PNG)

I can't reproduce it:

![capture d ecran 2018-12-07 a 21 57 04](https://user-images.githubusercontent.com/3165635/49672364-1ecd0f00-fa6b-11e8-8d24-a9e75b907e7c.png)

![capture d ecran 2018-12-07 a 21 57 15](https://user-images.githubusercontent.com/3165635/49672393-31dfdf00-fa6b-11e8-8460-e5845906018c.png)

![image](https://user-images.githubusercontent.com/12938082/49672820-42d92200-fa64-11e8-9ecb-71bb04c911c4.png)

 This happens when I follow these steps:
1. Open dev tools
2. Set size to 627 and 472
3. Press F12
@joshwooding We add some style to hide the scroll bar 🤔. Any idea what's wrong? I still can't manage to reproduce.

![capture d ecran 2018-12-07 a 22 23 44](https://user-images.githubusercontent.com/3165635/49673438-c6980c00-fa6e-11e8-9fdc-e7d82f573874.png)

@oliviertassinari I'll have a look, I can't reproduce the scrollbar issue though, It also does depend on the screen with CSS issues so that might be why I can't produce it with my lower res screen
![tabs](https://user-images.githubusercontent.com/12938082/49675181-7c159000-fa6c-11e8-8933-17457200f071.gif)


Solution patch:
diff --git a/.size-limit.js b/.size-limit.js
--- a/.size-limit.js
+++ b/.size-limit.js
@@ -22,7 +22,7 @@ module.exports = [
     name: 'The size of the @material-ui/core modules',
     webpack: true,
     path: 'packages/material-ui/build/index.js',
-    limit: '95 KB',
+    limit: '94.9 KB',
   },
   {
     name: 'The size of the @material-ui/styles modules',
@@ -35,7 +35,7 @@ module.exports = [
     name: 'The size of the @material-ui/core/Popper component',
     webpack: true,
     path: 'packages/material-ui/build/Popper/index.js',
-    limit: '10.0 KB',
+    limit: '9.9 KB',
   },
   {
     name: 'The main docs bundle',
diff --git a/packages/material-ui/src/Tabs/ScrollbarSize.js b/packages/material-ui/src/Tabs/ScrollbarSize.js
--- a/packages/material-ui/src/Tabs/ScrollbarSize.js
+++ b/packages/material-ui/src/Tabs/ScrollbarSize.js
@@ -4,11 +4,12 @@ import EventListener from 'react-event-listener';
 import debounce from 'debounce'; // < 1kb payload overhead when lodash/debounce is > 3kb.
 
 const styles = {
-  width: 100,
-  height: 100,
+  width: 90,
+  height: 90,
   position: 'absolute',
-  top: -10000,
+  top: -9000,
   overflow: 'scroll',
+  // Support IE 11
   msOverflowStyle: 'scrollbar',
 };
 
@@ -23,13 +24,11 @@ class ScrollbarSize extends React.Component {
 
     if (typeof window !== 'undefined') {
       this.handleResize = debounce(() => {
-        const { onChange } = this.props;
-
         const prevHeight = this.scrollbarHeight;
-        const prevWidth = this.scrollbarWidth;
         this.setMeasurements();
-        if (prevHeight !== this.scrollbarHeight || prevWidth !== this.scrollbarWidth) {
-          onChange({ scrollbarHeight: this.scrollbarHeight, scrollbarWidth: this.scrollbarWidth });
+
+        if (prevHeight !== this.scrollbarHeight) {
+          this.props.onChange(this.scrollbarHeight);
         }
       }, 166); // Corresponds to 10 frames at 60 Hz.
     }
@@ -37,16 +36,17 @@ class ScrollbarSize extends React.Component {
 
   componentDidMount() {
     this.setMeasurements();
-    this.props.onLoad({
-      scrollbarHeight: this.scrollbarHeight,
-      scrollbarWidth: this.scrollbarWidth,
-    });
+    this.props.onChange(this.scrollbarHeight);
   }
 
   componentWillUnmount() {
     this.handleResize.clear();
   }
 
+  handleRef = ref => {
+    this.nodeRef = ref;
+  };
+
   setMeasurements = () => {
     const nodeRef = this.nodeRef;
 
@@ -55,29 +55,20 @@ class ScrollbarSize extends React.Component {
     }
 
     this.scrollbarHeight = nodeRef.offsetHeight - nodeRef.clientHeight;
-    this.scrollbarWidth = nodeRef.offsetWidth - nodeRef.clientWidth;
   };
 
   render() {
-    const { onChange } = this.props;
-
     return (
-      <div>
-        {onChange ? <EventListener target="window" onResize={this.handleResize} /> : null}
-        <div
-          style={styles}
-          ref={ref => {
-            this.nodeRef = ref;
-          }}
-        />
-      </div>
+      <React.Fragment>
+        <EventListener target="window" onResize={this.handleResize} />
+        <div style={styles} ref={this.handleRef} />
+      </React.Fragment>
     );
   }
 }
 
 ScrollbarSize.propTypes = {
   onChange: PropTypes.func.isRequired,
-  onLoad: PropTypes.func.isRequired,
 };
 
 export default ScrollbarSize;
diff --git a/packages/material-ui/src/Tabs/Tabs.js b/packages/material-ui/src/Tabs/Tabs.js
--- a/packages/material-ui/src/Tabs/Tabs.js
+++ b/packages/material-ui/src/Tabs/Tabs.js
@@ -114,10 +114,7 @@ class Tabs extends React.Component {
     const { classes, scrollable, ScrollButtonComponent, scrollButtons, theme } = this.props;
     const conditionalElements = {};
     conditionalElements.scrollbarSizeListener = scrollable ? (
-      <ScrollbarSize
-        onLoad={this.handleScrollbarSizeChange}
-        onChange={this.handleScrollbarSizeChange}
-      />
+      <ScrollbarSize onChange={this.handleScrollbarSizeChange} />
     ) : null;
 
     const showScrollButtons = scrollable && (scrollButtons === 'auto' || scrollButtons === 'on');
@@ -194,7 +191,7 @@ class Tabs extends React.Component {
     this.moveTabsScroll(this.tabsRef.clientWidth);
   };
 
-  handleScrollbarSizeChange = ({ scrollbarHeight }) => {
+  handleScrollbarSizeChange = scrollbarHeight => {
     this.setState({
       scrollerStyle: {
         marginBottom: -scrollbarHeight,


Test patch:
diff --git a/packages/material-ui/src/Tabs/ScrollbarSize.test.js b/packages/material-ui/src/Tabs/ScrollbarSize.test.js
--- a/packages/material-ui/src/Tabs/ScrollbarSize.test.js
+++ b/packages/material-ui/src/Tabs/ScrollbarSize.test.js
@@ -7,7 +7,6 @@ import ScrollbarSize from './ScrollbarSize';
 
 describe('<ScrollbarSize />', () => {
   const defaultProps = {
-    onLoad: () => {},
     onChange: () => {},
   };
   let clock;
@@ -20,7 +19,7 @@ describe('<ScrollbarSize />', () => {
     clock.restore();
   });
 
-  describe('prop: onLoad', () => {
+  describe('mount', () => {
     let wrapper;
 
     afterEach(() => {
@@ -28,20 +27,16 @@ describe('<ScrollbarSize />', () => {
     });
 
     it('should not call on initial load', () => {
-      const onLoad = spy();
+      const onChange = spy();
       wrapper = mount(<ScrollbarSize {...defaultProps} />);
-      assert.strictEqual(onLoad.callCount, 0, 'should not have been called');
+      assert.strictEqual(onChange.callCount, 0);
     });
 
     it('should call on initial load', () => {
-      const onLoad = spy();
-      wrapper = mount(<ScrollbarSize {...defaultProps} onLoad={onLoad} />);
-      assert.strictEqual(onLoad.callCount, 1, 'should have been called once');
-      assert.strictEqual(
-        onLoad.calledWith({ scrollbarHeight: 0, scrollbarWidth: 0 }),
-        true,
-        'should have been called with expected sizes',
-      );
+      const onChange = spy();
+      wrapper = mount(<ScrollbarSize {...defaultProps} onChange={onChange} />);
+      assert.strictEqual(onChange.callCount, 1);
+      assert.strictEqual(onChange.calledWith(0), true);
     });
   });
 
@@ -56,26 +51,22 @@ describe('<ScrollbarSize />', () => {
       instance.nodeRef = {
         offsetHeight: 17,
         clientHeight: 0,
-        offsetWidth: 17,
-        clientWidth: 0,
       };
     });
 
     it('should call on first resize event', () => {
+      assert.strictEqual(onChange.callCount, 1);
       wrapper.find(EventListener).simulate('resize');
       clock.tick(166);
-      assert.strictEqual(onChange.callCount, 1, 'should have been called once');
-      assert.strictEqual(
-        onChange.calledWith({ scrollbarHeight: 17, scrollbarWidth: 17 }),
-        true,
-        'should have been called with expected sizes',
-      );
+      assert.strictEqual(onChange.callCount, 2);
+      assert.strictEqual(onChange.calledWith(17), true);
     });
 
     it('should not call on second resize event', () => {
+      assert.strictEqual(onChange.callCount, 1);
       wrapper.find(EventListener).simulate('resize');
       clock.tick(166);
-      assert.strictEqual(onChange.callCount, 1, 'should only have been called once');
+      assert.strictEqual(onChange.callCount, 2);
     });
   });
 });