fix: bug
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { memo } from 'react';
|
||||
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import { memo, useCallback, useEffect, useRef } from 'react';
|
||||
import { Pressable, ScrollView, StyleSheet, Text, View, useWindowDimensions } from 'react-native';
|
||||
|
||||
type Category = {
|
||||
id: string;
|
||||
@@ -13,18 +13,77 @@ type CategoryTabsProps = {
|
||||
};
|
||||
|
||||
export function CategoryTabs({ categories, activeId, onChange }: CategoryTabsProps) {
|
||||
const scrollViewRef = useRef<ScrollView>(null);
|
||||
const tabPositionsRef = useRef<Map<string, { x: number; width: number }>>(new Map());
|
||||
const containerWidthRef = useRef<number>(0);
|
||||
const { width: screenWidth } = useWindowDimensions();
|
||||
|
||||
const scrollToActiveTab = useCallback(() => {
|
||||
if (!activeId) {
|
||||
console.log('[CategoryTabs] No activeId');
|
||||
return;
|
||||
}
|
||||
|
||||
const position = tabPositionsRef.current.get(activeId);
|
||||
if (!position || !scrollViewRef.current) {
|
||||
console.log('[CategoryTabs] Missing position or ref:', { position, hasRef: !!scrollViewRef.current });
|
||||
return;
|
||||
}
|
||||
|
||||
const centerOffset = screenWidth / 2;
|
||||
const tabCenter = position.x + position.width / 2;
|
||||
const scrollX = tabCenter - centerOffset;
|
||||
|
||||
const maxScrollX = Math.max(0, containerWidthRef.current - screenWidth);
|
||||
const targetX = Math.max(0, Math.min(scrollX, maxScrollX));
|
||||
|
||||
console.log('[CategoryTabs] Scrolling to:', {
|
||||
activeId,
|
||||
position,
|
||||
screenWidth,
|
||||
tabCenter,
|
||||
targetX,
|
||||
containerWidth: containerWidthRef.current,
|
||||
});
|
||||
|
||||
scrollViewRef.current.scrollTo({
|
||||
x: targetX,
|
||||
animated: true,
|
||||
});
|
||||
}, [activeId, screenWidth]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(scrollToActiveTab, 150);
|
||||
return () => clearTimeout(timer);
|
||||
}, [scrollToActiveTab]);
|
||||
|
||||
const handleContentSizeChange = useCallback((width: number) => {
|
||||
containerWidthRef.current = width;
|
||||
console.log('[CategoryTabs] Content size:', width);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
ref={scrollViewRef}
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
contentContainerStyle={styles.container}
|
||||
style={styles.scrollView}
|
||||
onContentSizeChange={handleContentSizeChange}
|
||||
>
|
||||
{categories.map(category => (
|
||||
{categories.map((category, index) => (
|
||||
<CategoryTabItem
|
||||
key={category.id}
|
||||
category={category}
|
||||
isActive={category.id === activeId}
|
||||
onPress={onChange}
|
||||
onLayout={(layout) => {
|
||||
tabPositionsRef.current.set(category.id, {
|
||||
x: layout.x,
|
||||
width: layout.width,
|
||||
});
|
||||
console.log(`[CategoryTabs] Tab layout [${category.label}]:`, layout);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</ScrollView>
|
||||
@@ -35,11 +94,19 @@ type CategoryTabItemProps = {
|
||||
category: Category;
|
||||
isActive: boolean;
|
||||
onPress: (id: string) => void;
|
||||
onLayout: (layout: { x: number; width: number }) => void;
|
||||
};
|
||||
|
||||
const CategoryTabItem = memo(({ category, isActive, onPress }: CategoryTabItemProps) => {
|
||||
const CategoryTabItem = memo(({ category, isActive, onPress, onLayout }: CategoryTabItemProps) => {
|
||||
return (
|
||||
<Pressable onPress={() => onPress(category.id)} style={styles.tabButton}>
|
||||
<Pressable
|
||||
onPress={() => onPress(category.id)}
|
||||
style={styles.tabButton}
|
||||
onLayout={(event) => {
|
||||
const { x, width } = event.nativeEvent.layout;
|
||||
onLayout({ x, width });
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.label, isActive && styles.labelActive]}>{category.label}</Text>
|
||||
<View style={[styles.indicator, isActive && styles.indicatorActive]} />
|
||||
</Pressable>
|
||||
@@ -48,6 +115,10 @@ const CategoryTabItem = memo(({ category, isActive, onPress }: CategoryTabItemPr
|
||||
CategoryTabItem.displayName = 'CategoryTabItem';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
scrollView: {
|
||||
flexGrow: 0,
|
||||
flexShrink: 0,
|
||||
},
|
||||
container: {
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 6,
|
||||
|
||||
Reference in New Issue
Block a user