Tab Indicator - borderRadius not working as expect
ricardolmsilva opened this issue · 3 comments
Current behavior
I was using version 2.16 in the previous version of my app and everything was working fine, but a problem appear when I updated it to the latest version 3.1.1. The problem is related to the borderRadius in the tabIndicator when the tab bar has width auto.
tabStyle={{
width: "auto",
height: "100%",
backgroundColor: "transparent",
}}
indicatorStyle={{
height: "100%",
backgroundColor: Colors.primary,
borderWidth: 0,
borderColor: "white",
borderRadius: 16,
}}
So yesterday I spend around two hours going deep and investigating the problem behind this and I found the problem. I fork this repo and to debug it easier I used the web version in the example "AutoWidthTabBarExample". Debugging it I discover that the problem was because was being used the property ScaleX to increase the width of the indicator instead use the prop width.
In resume, if we are using width auto in the tabBar, the value of the ScaleX will be equal to the supposed width of the tab and the width is always 1. That's why the borderRadius doesn't work.
transform: translateX(84px) scaleX(102) translateX(0.5px);
width: 1px;
I also found the code that is doing it. So the width is being interpolated and turning it into a ScaleX value.
transform.push(
{
scaleX:
routes.length > 1
? position.interpolate({
inputRange, // indexs of the tabs
outputRange, // widths of each tab
extrapolate: 'clamp',
})
: outputRange[0],
},
{ translateX: 0.5 }
);
}
Knowing it I was checking how was it being done in the version I was using before, and it was using width instead, that's why the borderRadius was working.
I started to work on an implementation, but then I notice that the Reanimated was removed, so it had to have small changes, anyway, and I did it.
private getWidth = (
position: Animated.AnimatedInterpolation,
routes: Route[],
getTabWidth: GetTabWidth
) => {
const inputRange = routes.map((_, i) => i);
const outputRange = inputRange.map(getTabWidth);
return position.interpolate({
inputRange,
outputRange,
extrapolate: 'clamp',
});
};
const indicatorWidth = width === 'auto' && routes.length > 1
? this.getWidth(position, routes, getTabWidth)
: getTabWidth(0);
All was working perfectly on the web... until ... I turned on the project in the IOS and this blew up.
Apparently, Animated API from React doesn't have support to width interpolations and that's why was used the ScaleX hack to make it work without the reanimated.
Expected behavior
So with the knowledge, I got during this investigation, the only way of solving this is to get back the reanimated inside this component and use it to interpolate the width as it was being used before.
I don't have a lot of knowledge about the project, so I would like to ask for someone closer if would have any problem of bringing reanimated back only in the tabIndicator and have this working 100%
I don't have experience with React classes and Reanimated 1 (the only one that works with React classes), but I can volunteer myself to help if there is no problem with bringing this back into the project.
Keep a great job,
Ricardo
Reproduction
https://github.com/satya164/react-native-tab-view/blob/v2.16.0/src/TabBarIndicator.tsx#L118
https://github.com/satya164/react-native-tab-view/blob/v3.1.1/src/TabBarIndicator.tsx#L103
Platform
- Android
- iOS
- Web
- Windows
- MacOS
Environment
package | version |
---|---|
react-native-tab-view | 3.1.1 |
react-native-pager-view | 5.4.9 |
react-native | 0.64.3 |
expo | 44.0.0 |
node | 16.13.1 |
npm or yarn | 1.22.17 |
Hey! Thanks for opening the issue. The issue doesn't seem to contain a link to a repro (a snack.expo.dev link or link to a GitHub repo under your username).
Can you provide a minimal repro which demonstrates the issue? A repro will help us debug the issue faster. Please try to keep the repro as small as possible and make sure that we can run it without additional setup.
The versions mentioned in the issue for the following packages differ from the latest versions on npm:
react-native-pager-view
(found:5.4.9
, latest:5.4.11
)react-native
(found:0.64.3
, latest:0.67.3
)expo
(found:44.0.0
, latest:44.0.6
)
Can you verify that the issue still exists after upgrading to the latest versions of these packages?
Hello 👋, this issue has been open for more than a month without a repro or any activity. If the issue is still present in the latest version, please provide a repro or leave a comment within 7 days to keep it open, otherwise it will be closed automatically. If you found a solution or workaround for the issue, please comment here for others to find. If this issue is critical for you, please consider sending a pull request to fix it.