import {useTheme} from '../../theme/ThemeProvider';
import {memo, useCallback, useEffect, useState} from 'react';
import {Pressable, StyleSheet, Text, View} from 'react-native';
import type {TabControlProps} from '../../types';
type TabProps = {
index: number;
isFirst: boolean;
isLast: boolean;
label: string;
selected: boolean;
backgroundColor: string;
tintColor: string;
textColor: string;
selectedTextColor: string;
testID?: string;
onPress: (index: number) => void;
};
const Tab = memo(
({
index,
isFirst,
isLast,
label,
selected,
backgroundColor,
tintColor,
textColor,
selectedTextColor,
testID,
onPress,
}: TabProps) => (
onPress(index)}
style={[
styles.tab,
{backgroundColor: selected ? tintColor : backgroundColor},
isFirst && styles.first,
isLast && styles.last,
]}>
{label}
),
);
export const TabControl = (props: TabControlProps) => {
const {colors} = useTheme();
const {
accessibilityLabel,
values,
selectedIndex = 0,
label,
labelStyle,
backgroundTabColor = colors.surface,
tabTintColor = colors.background,
textColor = colors.text,
selectedTextColor = colors.text,
containerStyle,
style,
testID,
} = props;
const [selected, setSelected] = useState(selectedIndex);
// Keep in sync when `selectedIndex` changes after mount.
useEffect(() => {
setSelected(selectedIndex);
}, [selectedIndex]);
const handlePress = useCallback((idx: number) => {
setSelected(idx);
}, []);
// Fall back to the first tab when the index is out of range.
const current = values[selected] ?? values[0];
const Component = current?.renderItem;
return (
{!!label && {label}}
{values.map((value, index) => (
))}
{!!Component && }
);
};
const styles = StyleSheet.create({
tabs: {
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 2,
paddingLeft: 1,
paddingRight: 1,
borderTopLeftRadius: 5,
borderTopRightRadius: 5,
marginTop: 5,
},
tab: {
flex: 1,
paddingVertical: 5,
},
first: {
borderTopLeftRadius: 5,
},
last: {
borderTopRightRadius: 5,
},
text: {
textAlign: 'center',
fontWeight: '700',
fontSize: 16,
},
content: {
paddingBottom: 5,
},
});