diff --git a/src/components/TabSelector/TabSelector.js b/src/components/TabSelector/TabSelector.js index 4efa033c60d0..3483ec10f804 100644 --- a/src/components/TabSelector/TabSelector.js +++ b/src/components/TabSelector/TabSelector.js @@ -1,5 +1,5 @@ import {View} from 'react-native'; -import React from 'react'; +import React, {useMemo, useState} from 'react'; import PropTypes from 'prop-types'; import _ from 'underscore'; import * as Expensicons from '../Icon/Expensicons'; @@ -53,7 +53,7 @@ const getIconAndTitle = (route, translate) => { } }; -const getOpacity = (position, routesLength, tabIndex, active) => { +const getOpacity = (position, routesLength, tabIndex, active, affectedTabs) => { const activeValue = active ? 1 : 0; const inactiveValue = active ? 0 : 1; @@ -62,19 +62,19 @@ const getOpacity = (position, routesLength, tabIndex, active) => { return position.interpolate({ inputRange, - outputRange: _.map(inputRange, (i) => (i === tabIndex ? activeValue : inactiveValue)), + outputRange: _.map(inputRange, (i) => (affectedTabs.includes(tabIndex) && i === tabIndex ? activeValue : inactiveValue)), }); } return activeValue; }; -const getBackgroundColor = (position, routesLength, tabIndex) => { +const getBackgroundColor = (position, routesLength, tabIndex, affectedTabs) => { if (routesLength > 1) { const inputRange = Array.from({length: routesLength}, (v, i) => i); return position.interpolate({ inputRange, - outputRange: _.map(inputRange, (i) => (i === tabIndex ? themeColors.border : themeColors.appBG)), + outputRange: _.map(inputRange, (i) => (affectedTabs.includes(tabIndex) && i === tabIndex ? themeColors.border : themeColors.appBG)), }); } return themeColors.border; @@ -82,12 +82,23 @@ const getBackgroundColor = (position, routesLength, tabIndex) => { function TabSelector({state, navigation, onTabPress, position}) { const {translate} = useLocalize(); + + const defaultAffectedAnimatedTabs = useMemo(() => Array.from({length: state.routes.length}, (v, i) => i), [state.routes.length]); + const [affectedAnimatedTabs, setAffectedAnimatedTabs] = useState(defaultAffectedAnimatedTabs); + + React.useEffect(() => { + // It is required to wait transition end to reset affectedAnimatedTabs because tabs style is still animating during transition. + setTimeout(() => { + setAffectedAnimatedTabs(defaultAffectedAnimatedTabs); + }, CONST.ANIMATED_TRANSITION); + }, [defaultAffectedAnimatedTabs, state.index]); + return ( {_.map(state.routes, (route, index) => { - const activeOpacity = getOpacity(position, state.routes.length, index, true); - const inactiveOpacity = getOpacity(position, state.routes.length, index, false); - const backgroundColor = getBackgroundColor(position, state.routes.length, index); + const activeOpacity = getOpacity(position, state.routes.length, index, true, affectedAnimatedTabs); + const inactiveOpacity = getOpacity(position, state.routes.length, index, false, affectedAnimatedTabs); + const backgroundColor = getBackgroundColor(position, state.routes.length, index, affectedAnimatedTabs); const isFocused = index === state.index; const {icon, title} = getIconAndTitle(route.name, translate); @@ -96,6 +107,8 @@ function TabSelector({state, navigation, onTabPress, position}) { return; } + setAffectedAnimatedTabs([state.index, index]); + const event = navigation.emit({ type: 'tabPress', target: route.key,