Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit b241577

Browse files
committed
feat: implement custom BottomTabBar and TabBarButton components with updated styles
1 parent 54c385c commit b241577

File tree

3 files changed

+145
-2
lines changed

3 files changed

+145
-2
lines changed

src/app/_layout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const RootLayout = () => {
1414
screenOptions={{
1515
// headerShown: false,
1616
// tabBarStyle: { display: 'none' },
17-
tabBarActiveTintColor: '#e91e63',
17+
tabBarActiveTintColor: '#4B6BFB',
18+
tabBarInactiveTintColor: '#666666',
1819
}}
1920
>
2021
<Tabs.Screen
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { BottomTabBarProps } from '@react-navigation/bottom-tabs';
2+
import { StyleSheet, View } from 'react-native';
3+
4+
import TabBarButton from '@/components/tabbar/TabBarButton';
5+
6+
const BottomTabBar = ({
7+
state,
8+
descriptors,
9+
navigation,
10+
}: BottomTabBarProps) => {
11+
return (
12+
<View style={styles.container}>
13+
{state.routes.map((route, index) => {
14+
const { options } = descriptors[route.key];
15+
const label = options.title || route.name;
16+
const tabBarIcon = options.tabBarIcon;
17+
18+
if (['_sitemap', '+not-found'].includes(route.name)) return null;
19+
20+
const isFocused = state.index === index;
21+
22+
const onPress = () => {
23+
const event = navigation.emit({
24+
type: 'tabPress',
25+
target: route.key,
26+
canPreventDefault: true,
27+
});
28+
29+
if (!isFocused && !event.defaultPrevented) {
30+
navigation.navigate(route.name, route.params);
31+
}
32+
};
33+
34+
const onLongPress = () => {
35+
navigation.emit({
36+
type: 'tabLongPress',
37+
target: route.key,
38+
});
39+
};
40+
41+
return (
42+
<TabBarButton
43+
label={label}
44+
isFocused={isFocused}
45+
onPress={onPress}
46+
onLongPress={onLongPress}
47+
tabBarIcon={tabBarIcon}
48+
tabBarActiveTintColor={options.tabBarActiveTintColor!}
49+
tabBarInactiveTintColor={options.tabBarInactiveTintColor!}
50+
/>
51+
);
52+
})}
53+
</View>
54+
);
55+
};
56+
57+
const styles = StyleSheet.create({
58+
container: {
59+
flexDirection: 'row',
60+
justifyContent: 'space-around',
61+
backgroundColor: 'white',
62+
paddingVertical: 14,
63+
borderTopWidth: 2,
64+
borderTopColor: '#EEEEEE',
65+
},
66+
});
67+
68+
export default BottomTabBar;
Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,77 @@
1-
const TabBarButton = () => {};
1+
import { Pressable, StyleSheet, Text } from 'react-native';
2+
3+
export interface TabBarButtonProps {
4+
label: string;
5+
isFocused: boolean;
6+
onPress: () => void;
7+
onLongPress: () => void;
8+
tabBarIcon?: (props: {
9+
focused: boolean;
10+
color: string;
11+
size: number;
12+
}) => React.ReactNode;
13+
tabBarActiveTintColor: string;
14+
tabBarInactiveTintColor: string;
15+
}
16+
17+
const TabBarButton = ({
18+
label,
19+
isFocused,
20+
onPress,
21+
onLongPress,
22+
tabBarIcon,
23+
tabBarActiveTintColor,
24+
tabBarInactiveTintColor,
25+
}: TabBarButtonProps) => {
26+
return (
27+
<Pressable
28+
onPress={onPress}
29+
onLongPress={onLongPress}
30+
android_ripple={null}
31+
style={[styles.tab, isFocused && styles.activeTab]}
32+
>
33+
{tabBarIcon &&
34+
tabBarIcon({
35+
color: isFocused ? tabBarActiveTintColor : tabBarInactiveTintColor,
36+
size: 24,
37+
focused: isFocused,
38+
})}
39+
40+
<Text
41+
style={[
42+
{
43+
color: isFocused ? tabBarActiveTintColor : tabBarInactiveTintColor,
44+
},
45+
styles.tabText,
46+
isFocused && styles.activeTabText,
47+
]}
48+
>
49+
{label}
50+
</Text>
51+
</Pressable>
52+
);
53+
};
54+
55+
const styles = StyleSheet.create({
56+
tab: {
57+
flex: 1,
58+
alignItems: 'center',
59+
justifyContent: 'center',
60+
paddingTop: 6,
61+
paddingBottom: 6,
62+
borderRadius: 16,
63+
},
64+
tabText: {
65+
fontSize: 12,
66+
marginTop: 4,
67+
},
68+
activeTab: {
69+
backgroundColor: '#e6f0ff',
70+
},
71+
activeTabText: {
72+
color: '#4B6BFB',
73+
fontWeight: 'bold',
74+
},
75+
});
276

377
export default TabBarButton;

0 commit comments

Comments
 (0)