react-native-segmented-control-2
Version:
🚀 React Native Segmented Control, Pure Javascript for iOS and Android
56 lines • 2.64 kB
JavaScript
import React, { useCallback, useEffect, useState } from "react";
import { View, Text, Animated, TouchableOpacity, I18nManager, } from "react-native";
import styles from "./SegmentedControl.style";
const SegmentedControl = ({ style, tabs, onChange, value, tabStyle, textStyle, selectedTabStyle, initialIndex = 0, gap = 2, activeTextColor = "#000", activeTabColor = "#fff", }) => {
const [slideAnimation, _] = useState(new Animated.Value(0));
const [localCurrentIndex, setCurrentIndex] = useState(initialIndex);
const [tabLayouts, setTabLayouts] = useState({});
const currentIndex = value ?? localCurrentIndex;
const handleTabPress = useCallback((index) => {
setCurrentIndex(index);
onChange && onChange(index);
}, [onChange]);
useEffect(() => {
Animated.spring(slideAnimation, {
toValue: (I18nManager.isRTL ? -1 : 1) * (tabLayouts[currentIndex]?.x || 0),
stiffness: 180,
damping: 25,
mass: 1,
useNativeDriver: true,
}).start();
}, [currentIndex, slideAnimation, tabLayouts]);
const onLayoutTab = useCallback((index, { nativeEvent }) => {
setTabLayouts((prev) => ({ ...prev, [index]: nativeEvent.layout }));
}, []);
const tabSpecificStyle = useCallback((tabIndex) => {
if (typeof tabStyle === "function") {
return tabStyle(tabIndex);
}
return tabStyle;
}, [tabStyle]);
const renderSelectedTab = useCallback(() => (<Animated.View style={[
styles.activeTab(tabLayouts[currentIndex]?.width || 0, gap, activeTabColor, slideAnimation),
selectedTabStyle,
]}/>), [activeTabColor, gap, selectedTabStyle, slideAnimation, tabLayouts]);
const renderTab = (tab, index) => {
const isActiveTab = currentIndex === index;
const isTabText = typeof tab === "string";
return (<TouchableOpacity key={index} activeOpacity={0.5} style={[styles.tab, tabSpecificStyle(index)]} onPress={() => handleTabPress(index)} onLayout={(e) => onLayoutTab(index, e)}>
{!isTabText ? (tab) : (<Text numberOfLines={1} style={[
styles.textStyle,
textStyle,
isActiveTab && { color: activeTextColor },
]}>
{tab}
</Text>)}
</TouchableOpacity>);
};
return (<View style={[styles.container, style]}>
{renderSelectedTab()}
<View style={[styles.tabsContainer, { marginHorizontal: gap }]}>
{tabs.map((tab, index) => renderTab(tab, index))}
</View>
</View>);
};
export default SegmentedControl;
//# sourceMappingURL=SegmentedControl.js.map