UNPKG

react-native-segmented-control-2

Version:

🚀 React Native Segmented Control, Pure Javascript for iOS and Android

56 lines • 2.64 kB
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