From d813b8edc3baad2cdb2251a6fea2eee045364d57 Mon Sep 17 00:00:00 2001 From: Kyle Roach Date: Sat, 10 Aug 2019 00:22:04 +0000 Subject: [PATCH 1/2] fix: Bug where update to selectedIndex would not move indicator (#64) This is because the useEffect which calls selectTab did not have all the dependencies specified. RIP don't eslint-ignore react-hooks/exhaustive-deps Fixes #63 --- src/components/MaterialTabs.tsx | 107 ++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/src/components/MaterialTabs.tsx b/src/components/MaterialTabs.tsx index a8abd01..920a316 100644 --- a/src/components/MaterialTabs.tsx +++ b/src/components/MaterialTabs.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { Animated, ScrollView, @@ -57,63 +57,76 @@ const MaterialTabs: React.FC = ({ const scrollView = React.createRef(); const bar = React.createRef(); - useEffect(() => { - bar.current && - bar.current.measure((_, b, width) => { - getTabWidth(width); - }); + const getTabWidth = useCallback( + (width: number) => { + if (!scrollable) { + setTabWidth(width / items.length); + } - selectTab(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [items, barWidth]); + setBarWidth(width); + }, + [items.length, scrollable] + ); - const getAnimateValues = () => { - const scrollValue = !scrollable ? tabWidth : barWidth * 0.4; + useEffect(() => { + const getAnimateValues = () => { + const scrollValue = !scrollable ? tabWidth : barWidth * 0.4; - const indicator = I18nManager.isRTL - ? -selectedIndex * scrollValue - : selectedIndex * scrollValue; + const indicator = I18nManager.isRTL + ? -selectedIndex * scrollValue + : selectedIndex * scrollValue; + + // All props for fixed tabs are the same + if (!scrollable) { + return { + indicatorPosition: indicator, + scrollPosition: 0, + }; + } - // All props for fixed tabs are the same - if (!scrollable) { return { indicatorPosition: indicator, - scrollPosition: 0, + scrollPosition: I18nManager.isRTL + ? scrollValue * 0.25 + + scrollValue * (items.length - selectedIndex - 2) + : scrollValue * 0.25 + scrollValue * (selectedIndex - 1), }; - } - - return { - indicatorPosition: indicator, - scrollPosition: I18nManager.isRTL - ? scrollValue * 0.25 + scrollValue * (items.length - selectedIndex - 2) - : scrollValue * 0.25 + scrollValue * (selectedIndex - 1), }; - }; - const getTabWidth = (width: number) => { - if (!scrollable) { - setTabWidth(width / items.length); - } - - setBarWidth(width); - }; - - const selectTab = () => { - const values = getAnimateValues(); - - Animated.spring(indicatorPosition, { - toValue: values.indicatorPosition, - tension: 300, - friction: 20, - useNativeDriver: true, - }).start(); + const selectTab = () => { + const values = getAnimateValues(); + + Animated.spring(indicatorPosition, { + toValue: values.indicatorPosition, + tension: 300, + friction: 20, + useNativeDriver: true, + }).start(); + + if (scrollView.current) { + scrollView.current.scrollTo({ + x: values.scrollPosition, + }); + } + }; - if (scrollView.current) { - scrollView.current.scrollTo({ - x: values.scrollPosition, + bar.current && + bar.current.measure((_, b, width) => { + getTabWidth(width); }); - } - }; + + selectTab(); + }, [ + bar, + barWidth, + getTabWidth, + indicatorPosition, + items.length, + scrollView, + scrollable, + selectedIndex, + tabWidth, + ]); return ( items && ( From cfde9eb756f0ff9895fa225a1281a86f7baadd64 Mon Sep 17 00:00:00 2001 From: Kyle Roach Date: Fri, 9 Aug 2019 20:30:33 -0400 Subject: [PATCH 2/2] chore: Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 828ea99..508983c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-material-tabs", - "version": "4.1.0", + "version": "4.1.1", "description": "Material Design implementation of Tabs", "keywords": [ "react",