@uiw/react-native
Version:
UIW for React Native
83 lines • 2.56 kB
JavaScript
import React from 'react';
import { TouchableOpacity, Text } from 'react-native';
import Animated, { Extrapolate, interpolate, interpolateColor, useAnimatedStyle } from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useTheme } from '@shopify/restyle';
import Box from '../Typography/Box';
import Flex from '../Flex';
import helpers from './helpers';
import Icon from '../Icon';
const {
px,
ONE_PIXEL,
deviceWidth
} = helpers;
const HEADER_HEIGHT = px(44);
const AnimateHeader = props => {
const theme = useTheme();
const insets = useSafeAreaInsets();
const {
scrollY,
headerTitle,
headerTitleStyle,
scrollHeight = 300,
onPress,
showLeft = true,
headerRight,
headerLeftColor = theme.colors.gray500,
headerLeft,
headerBackgroundColor = theme.colors.background
} = props;
const inputRange = [0, scrollHeight];
const style = useAnimatedStyle(() => {
const opacity = interpolate(scrollY.value, inputRange, [0, 1], Extrapolate.CLAMP);
const borderBottomWidth = interpolate(scrollY.value, inputRange, [0, ONE_PIXEL], Extrapolate.CLAMP);
const backgroundColor = interpolateColor(scrollY.value, inputRange, ['transparent', headerBackgroundColor]);
return {
borderBottomWidth,
backgroundColor,
opacity
};
});
return <Animated.View style={[{
width: deviceWidth,
position: 'absolute',
top: 0,
zIndex: 99,
justifyContent: 'center',
alignItems: 'center',
borderBottomColor: theme.colors.border,
paddingTop: insets.top,
height: HEADER_HEIGHT + insets.top
}, style]}>
<Flex style={{
flex: 1
}}>
{showLeft ? <TouchableOpacity activeOpacity={0.5} onPress={onPress} style={{
flex: 1
}}>
<Flex>
<Icon name="left" size={px(24)} color={headerLeftColor} />
{typeof headerLeft === 'string' ? <Text style={{
color: headerLeftColor
}}>{headerLeft}</Text> : headerLeft}
</Flex>
</TouchableOpacity> : <Box flex={1} />}
<Animated.View style={{
flex: 5,
alignItems: 'center'
}}>
<Text numberOfLines={1} style={[{
color: '#333333'
}, headerTitleStyle]}>
{headerTitle}
</Text>
</Animated.View>
<Box flex={1} alignItems="flex-end">
{headerRight}
</Box>
</Flex>
</Animated.View>;
};
AnimateHeader.displayName = 'AnimateHeader';
export default AnimateHeader;