import React , { useRef } from 'react' ; import { Animated , Easing , Platform , TouchableOpacity , View , } from 'react-native' ; import { Text } from '../core-ui' ; import { makeStyles , useTheme } from '../theme' ; type Props < T > = { values : Array < T > ; selectedIndex : number ; width : number ; labelExtractor : ( item : T ) => string ; onItemPress : ( item : T , index : number ) => void ; } ; const ios = Platform . OS === 'ios' ; export function SegmentedControl < T > ( props ) { const styles = useStyles ( ) ; const { spacing } = useTheme ( ) ; const { values , selectedIndex , width , labelExtractor , onItemPress } = props ; const positionValue = useRef ( new Animated . Value ( 0 ) ) . current ; const onSegmentSelected = ( value , index ) => { onItemPress ( value , index ) ; Animated . timing ( positionValue , { toValue : index , duration : 100 , easing : Easing . ease , useNativeDriver : false , } ) . start ( ( ) => { } ) ; } ; const IOS_SEGMENT_HEIGHT = 20 + spacing . s * 2 ; const IOS_SEGMENT_WIDTH = ( width - ( spacing . xxl * 2 + spacing . s ) ) / values . length ; return ( < View style = { styles . container } > { ios && ( < Animated . View style = { [ { transform : [ { translateX : positionValue . interpolate ( { inputRange : [ 0 , values . length - 1 ] , outputRange : [ 4 , ( values . length - 1 ) * IOS_SEGMENT_WIDTH ] , } ) , } , ] , } , styles . animatedSegment , { height : IOS_SEGMENT_HEIGHT , width : IOS_SEGMENT_WIDTH , } , ] } />)} { values . map ( ( value , index ) => ( < TouchableOpacity key = { index } style = { [ styles . item , selectedIndex === index && styles . itemChosen ] } onPress = { ( ) => onSegmentSelected ( value , index ) } disabled = { selectedIndex === index } > < Text style = { [ styles . text , selectedIndex === index && styles . textChosen ] } > { labelExtractor ( value ) } < /Text> < /TouchableOpacity>))} < /View>); } const useStyles = makeStyles ( ( { colors , fontVariants , shadow , spacing } ) => ios ? { container : { backgroundColor : colors . backgroundDarker , borderRadius : 4 , padding : spacing . s , flexDirection : 'row' , justifyContent : 'space-between' , alignItems : 'center' , marginVertical : spacing . m , } , item : { flex : 1 , padding : spacing . s , textAlign : 'center' , } , animatedSegment : { borderRadius : 4 , backgroundColor : colors . background , position : 'absolute' , ... shadow , } , text : { textAlign : 'center' , color : colors . textLight , } , textChosen : { color : colors . textNormal , } , } : { container : { flexDirection : 'row' , justifyContent : 'space-between' , } , item : { flex : 1 , padding : spacing . xl , textAlign : 'center' , } , itemChosen : { borderBottomColor : colors . primary , borderBottomWidth : 2 , } , text : { textAlign : 'center' , color : colors . textLight , } , textChosen : { color : colors . textNormal , ... fontVariants . semiBold , } , } ) ;