Skip to content

Instantly share code, notes, and snippets.

@manakuro
Created June 29, 2022 07:18
Show Gist options
  • Save manakuro/b5a30295d42abb88cc9d79430a777aec to your computer and use it in GitHub Desktop.
Save manakuro/b5a30295d42abb88cc9d79430a777aec to your computer and use it in GitHub Desktop.
import React, {useEffect} from 'react';
import {Animated, StyleSheet} from 'react-native';
import ReAnimated, {
interpolate,
useAnimatedStyle,
useSharedValue,
} from 'react-native-reanimated';
import {NavigationState, Route} from 'react-native-tab-view';
import {Measure} from './types';
type Props<T extends Route> = {
measures: Measure[];
position: Animated.AnimatedInterpolation;
navigationState: NavigationState<T>;
};
export const TabBarIndicator = <T extends Route>(props: Props<T>) => {
const inputRange = props.navigationState.routes.map((_, i) => i);
const animation = useSharedValue(0);
useEffect(() => {
// Assign the position value to the shared value.
const id = props.position.addListener((value: {value: number}) => {
animation.value = value.value;
});
return () => props.position.removeListener(id);
}, [animation, props.position]);
const animatedStyle = useAnimatedStyle(() => {
const width = interpolate(
animation.value,
inputRange,
props.measures.map(m => m.width),
);
const translateX = interpolate(
animation.value,
inputRange,
props.measures.map(m => m.x),
);
return {
width,
transform: [{translateX}],
};
}, []);
return <ReAnimated.View style={[styles.container, animatedStyle]} />;
};
const styles = StyleSheet.create({
container: {
position: 'absolute',
height: 1,
backgroundColor: 'white',
bottom: 0,
left: 0,
},
});
TabBarIndicator.displayName = 'TabBarIndicator';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment