expo-popcore-app/components/skeleton/UploadReferenceImageDrawerS...

160 lines
4.9 KiB
TypeScript

import { View, StyleSheet, FlatList, Dimensions } from 'react-native'
import { Skeleton } from './skeleton'
const { width: screenWidth } = Dimensions.get('window')
const GAP = 2
const NUM_COLUMNS = 3
const ITEM_WIDTH = (screenWidth - GAP * 2) / NUM_COLUMNS
export function UploadReferenceImageDrawerSkeleton() {
return (
<View style={styles.container}>
{/* 顶部标题栏骨架 */}
<View style={styles.header}>
<View style={styles.headerTitles}>
<Skeleton width={160} height={18} borderRadius={4} />
<Skeleton width={140} height={16} borderRadius={4} style={styles.headerSubtitle} />
</View>
<Skeleton width={24} height={24} borderRadius={12} />
</View>
{/* 标签切换骨架 */}
<View style={styles.tabContainer}>
<View style={styles.tab}>
<View style={styles.tabIconContainer}>
<Skeleton width={27} height={27} borderRadius={6} />
</View>
<Skeleton width={60} height={14} borderRadius={4} />
</View>
<View style={styles.tab}>
<View style={styles.tabIconContainer}>
<Skeleton width={26} height={26} borderRadius={6} />
</View>
<Skeleton width={80} height={14} borderRadius={4} />
</View>
</View>
{/* 筛选区域骨架 */}
<View style={styles.filterContainer}>
<View style={styles.categoryButton}>
<Skeleton width={120} height={18} borderRadius={4} />
<Skeleton width={16} height={16} borderRadius={8} />
</View>
<View style={styles.filterButtons}>
<View style={styles.filterButton}>
<Skeleton width={36} height={16} borderRadius={8} />
</View>
<View style={styles.filterButton}>
<Skeleton width={36} height={16} borderRadius={8} />
</View>
</View>
</View>
{/* 图片网格骨架 */}
<FlatList
data={Array.from({ length: 30 }, (_, i) => i)}
keyExtractor={(item) => item.toString()}
numColumns={NUM_COLUMNS}
renderItem={({ index }) => {
const isLastInRow = (index + 1) % NUM_COLUMNS === 0
const isLastRow = index >= Math.floor(30 / NUM_COLUMNS) * NUM_COLUMNS
return (
<View
style={[
styles.imageItem,
{
width: ITEM_WIDTH,
marginRight: isLastInRow ? 0 : GAP,
marginBottom: isLastRow ? 0 : GAP,
},
]}
>
<Skeleton width="100%" height="100%" borderRadius={0} />
</View>
)
}}
showsVerticalScrollIndicator={false}
/>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#16181B',
paddingTop: 24,
},
header: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingBottom: 20,
},
headerTitles: {
gap: 4,
},
headerSubtitle: {
marginTop: 2,
},
tabContainer: {
flexDirection: 'row',
paddingHorizontal: 16,
gap: 8,
marginBottom: 24,
},
tab: {
flex: 1,
height: 52,
backgroundColor: '#272A30',
borderRadius: 12,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: 4,
},
tabIconContainer: {
width: 28,
height: 28,
alignItems: 'center',
justifyContent: 'center',
},
filterContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 16,
marginBottom: 9,
},
categoryButton: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
filterButtons: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#1C1E22',
borderRadius: 100,
height: 32,
padding: 3,
},
filterButton: {
paddingHorizontal: 12,
paddingVertical: 4,
minWidth: 48,
alignItems: 'center',
justifyContent: 'center',
},
imageItem: {
aspectRatio: 1 / 1.3,
overflow: 'hidden',
backgroundColor: '#262A31',
},
})