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

94 lines
2.1 KiB
TypeScript

import React from 'react'
import { View, Text, Pressable, ScrollView, StyleSheet } from 'react-native'
import { Image } from 'expo-image'
export interface Activity {
id: string
title: string
titleEn?: string
desc: string
descEn?: string
coverUrl: string
link: string
}
interface HeroSliderProps {
activities: Activity[]
onActivityPress?: (link: string) => void
}
export function HeroSlider({
activities,
onActivityPress,
}: HeroSliderProps): React.ReactNode | null {
// 空数据时返回 null
if (!activities || activities.length === 0) {
return null
}
return (
<View testID="hero-slider" style={styles.heroSection}>
<ScrollView
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.heroSliderContent}
>
{activities.map((activity) => (
<Pressable
key={activity.id}
testID={`hero-slide-${activity.id}`}
style={styles.heroMainSlide}
onPress={() => onActivityPress?.(activity.link)}
>
<Image
source={{ uri: activity.coverUrl }}
style={styles.heroMainImage}
contentFit="cover"
/>
<View style={styles.heroTextContainer}>
<Text style={styles.heroText}>{activity.title}</Text>
<Text style={styles.heroSubtext}>{activity.desc}</Text>
</View>
</Pressable>
))}
</ScrollView>
</View>
)
}
const styles = StyleSheet.create({
heroSection: {
flexDirection: 'row',
paddingLeft: 12,
paddingTop: 12,
marginBottom: 40,
overflow: 'hidden',
},
heroSliderContent: {
gap: 12,
},
heroMainSlide: {
width: '100%',
},
heroMainImage: {
width: 265,
height: 150,
borderRadius: 12,
},
heroTextContainer: {
paddingTop: 12,
paddingHorizontal: 8,
},
heroText: {
color: '#ABABAB',
fontSize: 12,
marginBottom: 4,
},
heroSubtext: {
color: '#F5F5F5',
fontSize: 16,
fontWeight: '500',
},
})