feat: add TemplateGrid and TitleBar components with tests
- Implemented TemplateGrid component for displaying templates in a grid layout. - Added calculateCardWidth helper function for dynamic card sizing. - Created TitleBar component for displaying the title and points with interaction. - Added unit tests for TemplateGrid and TitleBar components to ensure proper functionality. - Introduced useStickyTabs and useTabNavigation hooks with tests for managing sticky tab behavior and navigation logic. - Implemented useTemplateFilter hook for filtering templates based on video content. - Added comprehensive tests for all new hooks and components to validate behavior and edge cases.
This commit is contained in:
87
components/blocks/home/TitleBar.tsx
Normal file
87
components/blocks/home/TitleBar.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import React from 'react'
|
||||
import { View, Text, Pressable, StyleSheet } from 'react-native'
|
||||
import { PointsIcon, SearchIcon } from '@/components/icon'
|
||||
|
||||
interface TitleBarProps {
|
||||
points?: number
|
||||
onPointsPress?: () => void
|
||||
onSearchPress?: () => void
|
||||
onLayout?: (height: number) => void
|
||||
}
|
||||
|
||||
export function TitleBar({
|
||||
points = 60,
|
||||
onPointsPress,
|
||||
onSearchPress,
|
||||
onLayout,
|
||||
}: TitleBarProps): JSX.Element {
|
||||
return (
|
||||
<View
|
||||
testID="title-bar"
|
||||
style={styles.titleBar}
|
||||
onLayout={(event) => {
|
||||
const { height } = event.nativeEvent.layout
|
||||
onLayout?.(height)
|
||||
}}
|
||||
>
|
||||
<Text style={styles.title}>Popcore</Text>
|
||||
<View style={styles.titleBarRight}>
|
||||
<Pressable
|
||||
testID="points-container"
|
||||
style={styles.pointsContainer}
|
||||
onPress={onPointsPress}
|
||||
>
|
||||
<PointsIcon />
|
||||
<Text style={styles.pointsText}>{points}</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
testID="search-button"
|
||||
style={styles.searchButton}
|
||||
onPress={onSearchPress}
|
||||
>
|
||||
<SearchIcon />
|
||||
</Pressable>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
titleBar: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
backgroundColor: '#090A0B',
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: 'bold',
|
||||
color: '#F5F5F5',
|
||||
},
|
||||
titleBarRight: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 12,
|
||||
},
|
||||
pointsContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#1C1E22',
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 6,
|
||||
borderRadius: 16,
|
||||
gap: 4,
|
||||
},
|
||||
pointsText: {
|
||||
color: '#F5F5F5',
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
},
|
||||
searchButton: {
|
||||
padding: 8,
|
||||
backgroundColor: '#1C1E22',
|
||||
borderRadius: 20,
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user