expo-popcore-old/components/sker/img-tab/index.tsx

93 lines
2.1 KiB
TypeScript

import { useEffect, useRef } from 'react';
import { Dimensions, Pressable, ScrollView, StyleSheet, View } from 'react-native';
import VideoPlayer from '../video-player/video-player';
export type ImageItem = {
id: string;
uri: string;
};
export type ImgTabProps = {
images: ImageItem[];
activeId: string | null;
onActiveChange: (id: string) => void;
imageSize?: number;
gap?: number;
};
const SCREEN_WIDTH = Dimensions.get('window').width;
export function ImgTab({
images,
activeId,
onActiveChange,
imageSize = 44,
gap = 12
}: ImgTabProps) {
const scrollRef = useRef<ScrollView>(null);
const activeIndex = images.findIndex(img => img.id === activeId);
useEffect(() => {
if (activeIndex === -1 || !scrollRef.current) return;
const offset = activeIndex * (imageSize + gap);
scrollRef.current.scrollTo({ x: offset, animated: true });
}, [activeIndex, imageSize, gap]);
const paddingHorizontal = (SCREEN_WIDTH - imageSize) / 2;
return (
<ScrollView
ref={scrollRef}
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={[
styles.container,
{ gap, paddingHorizontal }
]}
style={styles.scroll}
>
{images.map(image => {
const isActive = image.id === activeId;
return (
<Pressable
key={image.id}
onPress={() => onActiveChange(image.id)}
>
<View style={[
styles.imageWrapper,
{ width: imageSize, height: imageSize },
isActive && styles.activeWrapper
]}>
<VideoPlayer source={{ uri: image.uri }} />
</View>
</Pressable>
);
})}
</ScrollView>
);
}
const styles = StyleSheet.create({
scroll: {
flexGrow: 0,
paddingTop: 4,
paddingBottom: 4
},
container: {
alignItems: 'center',
},
imageWrapper: {
borderRadius: 6,
overflow: 'hidden',
opacity: 0.5,
transform: [{ scale: 0.7 }],
},
activeWrapper: {
opacity: 1,
transform: [{ scale: 1.15 }],
borderWidth: 2,
borderColor: '#FFFFFF',
}
});