Skip to content

Instantly share code, notes, and snippets.

@Karthik-B-06
Created June 6, 2021 13:10
Show Gist options
  • Save Karthik-B-06/0c67c447550cc4f65ac0fabe5704e2f4 to your computer and use it in GitHub Desktop.
Save Karthik-B-06/0c67c447550cc4f65ac0fabe5704e2f4 to your computer and use it in GitHub Desktop.
import React from 'react';
import {
GestureResponderEvent,
InteractionManager,
Pressable,
StyleSheet,
Text,
View,
ViewProps,
} from 'react-native';
import Animated, { Extrapolate, interpolateNode, spring, useValue } from 'react-native-reanimated';
import { headingTextStyle } from 'src/styles/textStyles';
import { tailwind } from 'tailwind';
type PageHeaderProps = {
leftNode?: JSX.Element;
rightNode?: JSX.Element;
headerText?: string;
handleOnPressLeftNode?: (event: GestureResponderEvent) => void;
handleOnPressRightNode?: (event: GestureResponderEvent) => void;
rightContainerStyle?: ViewProps['style'] | null;
leftContainerStyle?: ViewProps['style'] | null;
animatingWidthValues?: number[];
};
const PageHeader: React.FC<PageHeaderProps> = ({
leftNode = null,
rightNode = null,
headerText = '',
handleOnPressLeftNode = null,
handleOnPressRightNode = null,
rightContainerStyle = null,
leftContainerStyle = null,
animatingWidthValues = [0, 0],
}) => {
const animatingValue = useValue(0);
React.useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
InteractionManager.runAfterInteractions(() => {
spring(animatingValue, {
toValue: 1,
mass: 1,
damping: 15,
stiffness: 120,
overshootClamping: 0.001,
restDisplacementThreshold: 0.001,
restSpeedThreshold: 0.001,
}).start();
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<View>
<View style={styles.pageHeaderContainer}>
<Pressable onPress={handleOnPressLeftNode} style={leftContainerStyle || styles.leftItem}>
{leftNode}
</Pressable>
<View style={styles.headerItem}>
<Text style={[headingTextStyle.FS17_SEMIBOLD, tailwind('text-center')]}>
{headerText}
</Text>
</View>
<Pressable onPress={handleOnPressRightNode} style={rightContainerStyle || styles.rightItem}>
{rightNode}
</Pressable>
</View>
<View style={tailwind('border-b w-full border-gray-200')}>
<Animated.View
style={[
tailwind('absolute border-b-2 border-blue-600'),
{
width: interpolateNode(animatingValue, {
inputRange: [0, 1],
outputRange: [animatingWidthValues[0], animatingWidthValues[1]],
extrapolate: Extrapolate.CLAMP,
}),
},
styles.animatingBorder,
]}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
pageHeaderContainer: tailwind('flex flex-row items-center justify-between '),
leftItem: tailwind('flex-1 pl-4 py-4'),
rightItem: tailwind('flex-1 pr-4 items-end py-4'),
headerItem: tailwind('flex-1 py-4'),
animatingBorder: { top: -1 },
});
export default PageHeader;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment