frontend first version
This commit is contained in:
198
src/navigation/TabNavigator.tsx
Normal file
198
src/navigation/TabNavigator.tsx
Normal file
@@ -0,0 +1,198 @@
|
||||
import React from 'react';
|
||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||
import { View, Text, StyleSheet } from 'react-native';
|
||||
import { Feather, MaterialCommunityIcons, FontAwesome5 } from '@expo/vector-icons';
|
||||
import { colors, borderRadius, typography } from '../theme/colors';
|
||||
|
||||
// Screens
|
||||
import FlowScreen from '../screens/FlowScreen';
|
||||
import VaultScreen from '../screens/VaultScreen';
|
||||
import SentinelScreen from '../screens/SentinelScreen';
|
||||
import HeritageScreen from '../screens/HeritageScreen';
|
||||
import MeScreen from '../screens/MeScreen';
|
||||
|
||||
const Tab = createBottomTabNavigator();
|
||||
|
||||
// Custom Tab Bar Button with icon on top and label below
|
||||
const TabBarItem = ({
|
||||
name,
|
||||
label,
|
||||
focused,
|
||||
color,
|
||||
isDark = false
|
||||
}: {
|
||||
name: string;
|
||||
label: string;
|
||||
focused: boolean;
|
||||
color: string;
|
||||
isDark?: boolean;
|
||||
}) => {
|
||||
const iconSize = 22;
|
||||
|
||||
const renderIcon = () => {
|
||||
switch (name) {
|
||||
case 'Flow':
|
||||
return <FontAwesome5 name="scroll" size={iconSize - 2} color={color} />;
|
||||
case 'Vault':
|
||||
return <MaterialCommunityIcons name="treasure-chest" size={iconSize} color={color} />;
|
||||
case 'Sentinel':
|
||||
return <FontAwesome5 name="anchor" size={iconSize - 2} color={color} />;
|
||||
case 'Heritage':
|
||||
return <MaterialCommunityIcons name="compass-outline" size={iconSize} color={color} />;
|
||||
case 'Me':
|
||||
return <MaterialCommunityIcons name="ship-wheel" size={iconSize} color={color} />;
|
||||
default:
|
||||
return <Feather name="circle" size={iconSize} color={color} />;
|
||||
}
|
||||
};
|
||||
|
||||
const bgColor = focused
|
||||
? (isDark ? 'rgba(184, 224, 229, 0.12)' : colors.nautical.lightMint)
|
||||
: 'transparent';
|
||||
|
||||
return (
|
||||
<View style={[styles.tabItem, { backgroundColor: bgColor }]}>
|
||||
<View style={styles.iconWrapper}>
|
||||
{renderIcon()}
|
||||
</View>
|
||||
<Text style={[
|
||||
styles.tabLabel,
|
||||
{ color },
|
||||
focused && styles.tabLabelActive
|
||||
]}>
|
||||
{label}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default function TabNavigator() {
|
||||
return (
|
||||
<Tab.Navigator
|
||||
screenOptions={{
|
||||
headerShown: false,
|
||||
tabBarShowLabel: false,
|
||||
tabBarStyle: styles.tabBar,
|
||||
}}
|
||||
>
|
||||
<Tab.Screen
|
||||
name="Flow"
|
||||
component={FlowScreen}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => (
|
||||
<TabBarItem
|
||||
name="Flow"
|
||||
label="Flow"
|
||||
focused={focused}
|
||||
color={focused ? colors.flow.primary : colors.nautical.sage}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Vault"
|
||||
component={VaultScreen}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => (
|
||||
<TabBarItem
|
||||
name="Vault"
|
||||
label="Vault"
|
||||
focused={focused}
|
||||
color={focused ? colors.vault.primary : colors.vault.textSecondary}
|
||||
isDark
|
||||
/>
|
||||
),
|
||||
tabBarStyle: styles.tabBarDark,
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Sentinel"
|
||||
component={SentinelScreen}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => (
|
||||
<TabBarItem
|
||||
name="Sentinel"
|
||||
label="Sentinel"
|
||||
focused={focused}
|
||||
color={focused ? colors.sentinel.primary : colors.sentinel.textSecondary}
|
||||
isDark
|
||||
/>
|
||||
),
|
||||
tabBarStyle: styles.tabBarDark,
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Heritage"
|
||||
component={HeritageScreen}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => (
|
||||
<TabBarItem
|
||||
name="Heritage"
|
||||
label="Heritage"
|
||||
focused={focused}
|
||||
color={focused ? colors.heritage.primary : colors.nautical.sage}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name="Me"
|
||||
component={MeScreen}
|
||||
options={{
|
||||
tabBarIcon: ({ focused }) => (
|
||||
<TabBarItem
|
||||
name="Me"
|
||||
label="Me"
|
||||
focused={focused}
|
||||
color={focused ? colors.me.primary : colors.nautical.sage}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
tabBar: {
|
||||
backgroundColor: colors.nautical.cream,
|
||||
borderTopWidth: 0,
|
||||
height: 80,
|
||||
paddingHorizontal: 4,
|
||||
shadowColor: colors.nautical.navy,
|
||||
shadowOffset: { width: 0, height: -6 },
|
||||
shadowOpacity: 0.06,
|
||||
shadowRadius: 16,
|
||||
elevation: 12,
|
||||
},
|
||||
tabBarDark: {
|
||||
backgroundColor: colors.nautical.navy,
|
||||
borderTopWidth: 0,
|
||||
height: 80,
|
||||
paddingHorizontal: 4,
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: -4 },
|
||||
shadowOpacity: 0.15,
|
||||
shadowRadius: 12,
|
||||
elevation: 12,
|
||||
},
|
||||
tabItem: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
borderRadius: borderRadius.lg,
|
||||
minWidth: 64,
|
||||
},
|
||||
iconWrapper: {
|
||||
marginBottom: 4,
|
||||
},
|
||||
tabLabel: {
|
||||
fontSize: 10,
|
||||
fontWeight: '500',
|
||||
letterSpacing: 0.3,
|
||||
},
|
||||
tabLabelActive: {
|
||||
fontWeight: '700',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user