expo-popcore-app/components/blocks/home/TabNavigation.tsx

128 lines
2.6 KiB
TypeScript

import React from 'react'
import {
View,
Text,
Pressable,
ScrollView,
StyleSheet,
ViewStyle,
} from 'react-native'
import { DownArrowIcon } from '@/components/icon'
interface TabNavigationProps {
tabs: string[]
activeIndex: number
onTabPress: (index: number) => void
showArrow?: boolean
onArrowPress?: () => void
isSticky?: boolean
wrapperStyle?: ViewStyle
onLayout?: (y: number, height: number) => void
}
export function TabNavigation({
tabs,
activeIndex,
onTabPress,
showArrow = false,
onArrowPress,
isSticky = false,
wrapperStyle,
onLayout,
}: TabNavigationProps): JSX.Element {
return (
<View
testID="tab-navigation"
style={[
styles.tabsWrapper,
isSticky && styles.stickyWrapper,
wrapperStyle,
]}
onLayout={(e) => {
const { y, height } = e.nativeEvent.layout
onLayout?.(y, height)
}}
>
<View style={styles.tabsContainer}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.tabsScrollContent}
>
{tabs.map((tab, index) => (
<Pressable
key={index}
testID={`tab-${index}`}
style={[styles.tab, activeIndex === index && styles.activeTab]}
onPress={() => onTabPress(index)}
>
<Text
style={[
styles.tabText,
activeIndex === index && styles.activeTabText,
]}
>
{tab}
</Text>
</Pressable>
))}
</ScrollView>
{showArrow && (
<Pressable
testID="tab-arrow"
style={styles.tabArrow}
onPress={onArrowPress}
>
<DownArrowIcon />
</Pressable>
)}
</View>
</View>
)
}
const styles = StyleSheet.create({
tabsWrapper: {
paddingHorizontal: 16,
paddingVertical: 8,
backgroundColor: '#090A0B',
},
stickyWrapper: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
zIndex: 100,
},
tabsContainer: {
flexDirection: 'row',
alignItems: 'center',
},
tabsScrollContent: {
gap: 8,
},
tab: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
backgroundColor: '#1C1E22',
},
activeTab: {
backgroundColor: '#F5F5F5',
},
tabText: {
color: '#F5F5F5',
fontSize: 14,
fontWeight: '500',
},
activeTabText: {
color: '#090A0B',
},
tabArrow: {
marginLeft: 8,
padding: 8,
backgroundColor: '#1C1E22',
borderRadius: 20,
},
})