From bbe3265f63bba7ffbe1a9af0ef41598750bb074a Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Tue, 24 Oct 2017 22:17:42 +0200 Subject: [PATCH] [Tabs] Fix consecutive updates (#8831) --- package.json | 2 +- pages/api/tabs.md | 2 +- src/Tabs/Tabs.js | 16 +++++++++------- src/Tabs/Tabs.spec.js | 31 ++++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index e56c149884e50a..50595d0ea8713c 100644 --- a/package.json +++ b/package.json @@ -183,7 +183,7 @@ "size-limit": [ { "path": "build/index.js", - "limit": "93 KB" + "limit": "94 KB" } ], "nyc": { diff --git a/pages/api/tabs.md b/pages/api/tabs.md index a705374013b55e..87a283242f5947 100644 --- a/pages/api/tabs.md +++ b/pages/api/tabs.md @@ -6,7 +6,7 @@ filename: /src/Tabs/Tabs.js # Tabs -Notice that this Component is incompatible with server side rendering. + ## Props diff --git a/src/Tabs/Tabs.js b/src/Tabs/Tabs.js index 008aa9c9e47fd7..62eb2ab5fca61d 100644 --- a/src/Tabs/Tabs.js +++ b/src/Tabs/Tabs.js @@ -144,9 +144,6 @@ export type TabsMeta = { right: number, }; -/** - * Notice that this Component is incompatible with server side rendering. - */ class Tabs extends React.Component { static defaultProps = { centered: false, @@ -180,10 +177,13 @@ class Tabs extends React.Component { componentDidUpdate(prevProps, prevState) { this.updateScrollButtonState(); + + // The index might have changed at the same time. + // We need to check again the right indicator position. + this.updateIndicatorState(this.props); + if (this.state.indicatorStyle !== prevState.indicatorStyle) { this.scrollSelectedIntoView(); - } else { - this.updateIndicatorState(this.props); } } @@ -335,8 +335,10 @@ class Tabs extends React.Component { }; if ( - indicatorStyle.left !== this.state.indicatorStyle.left || - indicatorStyle.width !== this.state.indicatorStyle.width + (indicatorStyle.left !== this.state.indicatorStyle.left || + indicatorStyle.width !== this.state.indicatorStyle.width) && + !Number.isNaN(indicatorStyle.left) && + !Number.isNaN(indicatorStyle.width) ) { this.setState({ indicatorStyle }); } diff --git a/src/Tabs/Tabs.spec.js b/src/Tabs/Tabs.spec.js index 43b4ae62ab2412..b49c8f6c794081 100644 --- a/src/Tabs/Tabs.spec.js +++ b/src/Tabs/Tabs.spec.js @@ -4,13 +4,15 @@ import React from 'react'; import { assert } from 'chai'; import { spy, stub, useFakeTimers } from 'sinon'; import scroll from 'scroll'; -import { createShallow, createMount, getClasses } from '../test-utils'; +import { createShallow, createMount, getClasses, unwrap } from '../test-utils'; import consoleErrorMock from '../../test/utils/consoleErrorMock'; import Tabs from './Tabs'; import TabScrollButton from './TabScrollButton'; import TabIndicator from './TabIndicator'; import Tab from './Tab'; +const TabsNaked = unwrap(Tabs); + const noop = () => {}; const fakeTabs = { getBoundingClientRect: () => ({}), @@ -207,6 +209,33 @@ describe('', () => { ); assert.strictEqual(wrapper2.find(TabIndicator).length, 1); }); + + it('should update the indicator state no matter what', () => { + const wrapper2 = mount( + + + + , + ); + const instance = wrapper2.instance(); + stub(instance, 'scrollSelectedIntoView'); + + wrapper2.setState({ + indicatorStyle: { + left: 10, + width: 40, + }, + }); + wrapper2.setProps({ + value: 0, + }); + + assert.strictEqual( + instance.scrollSelectedIntoView.callCount >= 2, + true, + 'should have called scrollSelectedIntoView', + ); + }); }); it('should warn when the value is invalid', () => {