fix custom tabs
deskripsi: - penambahan style untuk tabs
This commit is contained in:
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
@@ -86,7 +85,7 @@ const CustomTabNavigator = () => {
|
|||||||
activeIcon: "notifications",
|
activeIcon: "notifications",
|
||||||
label: "Forum",
|
label: "Forum",
|
||||||
component: NotificationScreen,
|
component: NotificationScreen,
|
||||||
path: "/(application)/(home-tabs)/forum",
|
path: "/forum",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "profile",
|
id: "profile",
|
||||||
@@ -94,7 +93,7 @@ const CustomTabNavigator = () => {
|
|||||||
activeIcon: "person",
|
activeIcon: "person",
|
||||||
label: "Katalog",
|
label: "Katalog",
|
||||||
component: ProfileScreen,
|
component: ProfileScreen,
|
||||||
path: "/(application)/(home-tabs)/katalog",
|
path: "/profile",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -102,7 +101,7 @@ const CustomTabNavigator = () => {
|
|||||||
// Function untuk handle tab press
|
// Function untuk handle tab press
|
||||||
const handleTabPress = (tabId: string) => {
|
const handleTabPress = (tabId: string) => {
|
||||||
setActiveTab(tabId);
|
setActiveTab(tabId);
|
||||||
// setShowHome(false); // Hide home when any tab is pressed
|
setShowHome(false); // Hide home when any tab is pressed
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine which component to show
|
// Determine which component to show
|
||||||
@@ -110,8 +109,9 @@ const CustomTabNavigator = () => {
|
|||||||
if (showHome || activeTab === "home") {
|
if (showHome || activeTab === "home") {
|
||||||
return HomeScreen;
|
return HomeScreen;
|
||||||
}
|
}
|
||||||
const selectedTab = tabs.find((tab) => tab.id === activeTab);
|
// const selectedTab = tabs.find((tab) => tab.id === activeTab);
|
||||||
return selectedTab ? selectedTab.component : HomeScreen;
|
// return selectedTab ? selectedTab.component : HomeScreen;
|
||||||
|
return HomeScreen
|
||||||
};
|
};
|
||||||
|
|
||||||
const ActiveComponent = getActiveComponent();
|
const ActiveComponent = getActiveComponent();
|
||||||
@@ -135,7 +135,7 @@ const CustomTabNavigator = () => {
|
|||||||
label={e.label}
|
label={e.label}
|
||||||
isActive={activeTab === e.id && !showHome}
|
isActive={activeTab === e.id && !showHome}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
// handleTabPress(e.id);
|
handleTabPress(e.id);
|
||||||
router.push(e.path as any);
|
router.push(e.path as any);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
13
components/_Interface/types.ts
Normal file
13
components/_Interface/types.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { Href } from "expo-router";
|
||||||
|
|
||||||
|
export { ITabs };
|
||||||
|
|
||||||
|
interface ITabs {
|
||||||
|
id: string;
|
||||||
|
icon: string;
|
||||||
|
activeIcon: string;
|
||||||
|
label: string;
|
||||||
|
path: Href;
|
||||||
|
isActive: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ import { MaterialCommunityIcons } from "@expo/vector-icons";
|
|||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
import { Text, View } from "react-native";
|
import { Text, View } from "react-native";
|
||||||
|
|
||||||
|
|
||||||
export default function RegisterView() {
|
export default function RegisterView() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -44,16 +43,16 @@ export default function RegisterView() {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<Spacing />
|
<Spacing />
|
||||||
{/* <ButtonCustom
|
<ButtonCustom
|
||||||
title="Home"
|
title="Coba"
|
||||||
backgroundColor={MainColor.yellow}
|
backgroundColor={MainColor.yellow}
|
||||||
textColor={MainColor.black}
|
textColor={MainColor.black}
|
||||||
radius={10}
|
radius={10}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
console.log("Home clicked");
|
console.log("Home clicked");
|
||||||
router.push("/(application)/home");
|
router.push("/(application)/coba");
|
||||||
}}
|
}}
|
||||||
/> */}
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</ViewWrapper>
|
</ViewWrapper>
|
||||||
|
|||||||
@@ -1,136 +1,26 @@
|
|||||||
/* eslint-disable no-unused-expressions */
|
// import { ITabs } from "@/components/_Interface/types";
|
||||||
import Spacing from "@/components/_ShareComponent/Spacing";
|
import Spacing from "@/components/_ShareComponent/Spacing";
|
||||||
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
import ViewWrapper from "@/components/_ShareComponent/ViewWrapper";
|
||||||
import { AccentColor, MainColor } from "@/constants/color-palet";
|
import { useNavigation } from "expo-router";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
|
||||||
import { Href, router, useNavigation } from "expo-router";
|
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import {
|
|
||||||
Dimensions,
|
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
TouchableOpacity,
|
|
||||||
View,
|
|
||||||
} from "react-native";
|
|
||||||
import Home_BottomFeatureSection from "./bottomFeatureSection";
|
import Home_BottomFeatureSection from "./bottomFeatureSection";
|
||||||
import Home_ImageSection from "./imageSection";
|
import Home_ImageSection from "./imageSection";
|
||||||
|
import TabSection from "./tabSection";
|
||||||
|
import { tabsHome } from "./tabsList";
|
||||||
import Home_FeatureSection from "./topFeatureSection";
|
import Home_FeatureSection from "./topFeatureSection";
|
||||||
|
|
||||||
interface Tabs {
|
|
||||||
id: string;
|
|
||||||
icon: string;
|
|
||||||
activeIcon: string;
|
|
||||||
label: string;
|
|
||||||
path: Href;
|
|
||||||
isActive: boolean;
|
|
||||||
disabled: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { width } = Dimensions.get("window");
|
|
||||||
|
|
||||||
export default function NewHomeView() {
|
export default function NewHomeView() {
|
||||||
const tabs: Tabs[] = [
|
|
||||||
{
|
|
||||||
id: "forum",
|
|
||||||
icon: "chatbubble-ellipses-outline",
|
|
||||||
activeIcon: "chatbubble-ellipses",
|
|
||||||
label: "Forum",
|
|
||||||
path: "/forum",
|
|
||||||
isActive: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "marketplace",
|
|
||||||
icon: "cart-outline",
|
|
||||||
activeIcon: "cart",
|
|
||||||
label: "Marketplace",
|
|
||||||
path: "/marketplace",
|
|
||||||
isActive: false,
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "maps",
|
|
||||||
icon: "map-outline",
|
|
||||||
activeIcon: "map",
|
|
||||||
label: "Maps",
|
|
||||||
path: "/maps",
|
|
||||||
isActive: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "profile",
|
|
||||||
icon: "person-outline",
|
|
||||||
activeIcon: "person",
|
|
||||||
label: "Profile",
|
|
||||||
path: "/profile",
|
|
||||||
isActive: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const CustomTab = ({ icon, label, isActive, onPress, disabled }: any) => (
|
|
||||||
<TouchableOpacity
|
|
||||||
style={[styles.tabItem, isActive && styles.activeTab]}
|
|
||||||
onPress={onPress}
|
|
||||||
activeOpacity={0.7}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={[styles.iconContainer, isActive && styles.activeIconContainer]}
|
|
||||||
>
|
|
||||||
<Ionicons name={icon} size={20} color={isActive ? "#fff" : "#666"} />
|
|
||||||
</View>
|
|
||||||
<Text style={[styles.tabLabel, isActive && styles.activeTabLabel]}>
|
|
||||||
{label}
|
|
||||||
</Text>
|
|
||||||
{isActive && <View style={styles.activeIndicator} />}
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
|
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({});
|
||||||
// headerTitle: "HIPMI",
|
|
||||||
// headerLeft: () => (
|
|
||||||
// <Ionicons
|
|
||||||
// name="search"
|
|
||||||
// size={18}
|
|
||||||
// color={MainColor.white}
|
|
||||||
// onPress={() => router.push("/(application)/user-search")}
|
|
||||||
// />
|
|
||||||
// ),
|
|
||||||
// headerRight: () => (
|
|
||||||
// <Ionicons
|
|
||||||
// name="notifications"
|
|
||||||
// size={18}
|
|
||||||
// color={MainColor.white}
|
|
||||||
// onPress={() => router.push("/(application)/notifications")}
|
|
||||||
// />
|
|
||||||
// ),
|
|
||||||
});
|
|
||||||
}, [navigation]);
|
}, [navigation]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewWrapper
|
<ViewWrapper tabBarComponent={<TabSection tabs={tabsHome} />}>
|
||||||
tabBarComponent={
|
{/* Content Image */}
|
||||||
<View style={styles.tabBar}>
|
|
||||||
<View style={styles.tabContainer}>
|
|
||||||
{tabs.map((e) => (
|
|
||||||
<CustomTab
|
|
||||||
key={e.id}
|
|
||||||
icon={e.icon}
|
|
||||||
label={e.label}
|
|
||||||
isActive={e.isActive}
|
|
||||||
onPress={() => {
|
|
||||||
e.disabled ? console.log("disabled") : router.push(e.path);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Home_ImageSection />
|
<Home_ImageSection />
|
||||||
<Spacing height={10} />
|
<Spacing height={10} />
|
||||||
|
|
||||||
@@ -145,74 +35,3 @@ export default function NewHomeView() {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
tabBar: {
|
|
||||||
backgroundColor: MainColor.darkblue,
|
|
||||||
borderTopColor: AccentColor.blue,
|
|
||||||
borderTopWidth: 1,
|
|
||||||
// borderTopEndRadius: 10,
|
|
||||||
// borderTopStartRadius: 10,
|
|
||||||
// tintColor: MainColor.yellow
|
|
||||||
// paddingBottom: 20,
|
|
||||||
// paddingTop: 10,
|
|
||||||
// shadowColor: AccentColor.blue,
|
|
||||||
// shadowOffset: {
|
|
||||||
// width: 0,
|
|
||||||
// height: -2,
|
|
||||||
// },
|
|
||||||
// shadowOpacity: 0.9,
|
|
||||||
// shadowRadius: 3,
|
|
||||||
// elevation: 5,
|
|
||||||
},
|
|
||||||
tabContainer: {
|
|
||||||
flexDirection: "row",
|
|
||||||
justifyContent: "space-around",
|
|
||||||
alignItems: "center",
|
|
||||||
paddingHorizontal: 0,
|
|
||||||
},
|
|
||||||
tabItem: {
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
paddingVertical: 8,
|
|
||||||
paddingHorizontal: 12,
|
|
||||||
minWidth: width / 5,
|
|
||||||
position: "relative",
|
|
||||||
},
|
|
||||||
activeTab: {
|
|
||||||
transform: [{ scale: 1.05 }],
|
|
||||||
},
|
|
||||||
iconContainer: {
|
|
||||||
padding: 8,
|
|
||||||
borderRadius: 20,
|
|
||||||
// marginBottom: 4,
|
|
||||||
},
|
|
||||||
activeIconContainer: {
|
|
||||||
// backgroundColor: "#007AFF",
|
|
||||||
// shadowColor: "#007AFF",
|
|
||||||
// shadowOffset: {
|
|
||||||
// width: 0,
|
|
||||||
// height: 2,
|
|
||||||
// },
|
|
||||||
// shadowOpacity: 0.3,
|
|
||||||
// shadowRadius: 4,
|
|
||||||
// elevation: 4,
|
|
||||||
},
|
|
||||||
tabLabel: {
|
|
||||||
fontSize: 10,
|
|
||||||
color: "#666",
|
|
||||||
fontWeight: "500",
|
|
||||||
},
|
|
||||||
activeTabLabel: {
|
|
||||||
color: MainColor.white,
|
|
||||||
fontWeight: "600",
|
|
||||||
},
|
|
||||||
activeIndicator: {
|
|
||||||
position: "absolute",
|
|
||||||
bottom: -2,
|
|
||||||
width: 4,
|
|
||||||
height: 4,
|
|
||||||
borderRadius: 2,
|
|
||||||
backgroundColor: "#007AFF",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
56
screens/Home/tabSection.tsx
Normal file
56
screens/Home/tabSection.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { ITabs } from "@/components/_Interface/types";
|
||||||
|
import { Styles } from "@/styles/global-styles";
|
||||||
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
|
import { router } from "expo-router";
|
||||||
|
import React from "react";
|
||||||
|
import { Text, TouchableOpacity, View } from "react-native";
|
||||||
|
|
||||||
|
interface ICustomTab {
|
||||||
|
icon: string;
|
||||||
|
label: string;
|
||||||
|
isActive: boolean;
|
||||||
|
onPress: () => void;
|
||||||
|
}
|
||||||
|
const CustomTab = ({ icon, label, isActive, onPress }: ICustomTab) => (
|
||||||
|
<TouchableOpacity
|
||||||
|
style={[Styles.tabItem, isActive && Styles.activeTab]}
|
||||||
|
onPress={onPress}
|
||||||
|
activeOpacity={0.7}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={[Styles.iconContainer, isActive && Styles.activeIconContainer]}
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={icon as any}
|
||||||
|
size={20}
|
||||||
|
color={isActive ? "#fff" : "#666"}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text style={[Styles.tabLabel, isActive && Styles.activeTabLabel]}>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default function TabSection({ tabs }: { tabs: ITabs[] }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View style={Styles.tabBar}>
|
||||||
|
<View style={Styles.tabContainer}>
|
||||||
|
{tabs.map((e) => (
|
||||||
|
<CustomTab
|
||||||
|
key={e.id}
|
||||||
|
icon={e.icon}
|
||||||
|
label={e.label}
|
||||||
|
isActive={e.isActive}
|
||||||
|
onPress={() => {
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
|
e.disabled ? console.log("disabled") : router.push(e.path);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
screens/Home/tabsList.ts
Normal file
40
screens/Home/tabsList.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { ITabs } from "@/components/_Interface/types";
|
||||||
|
|
||||||
|
export const tabsHome: ITabs[] = [
|
||||||
|
{
|
||||||
|
id: "forum",
|
||||||
|
icon: "chatbubble-ellipses-outline",
|
||||||
|
activeIcon: "chatbubble-ellipses",
|
||||||
|
label: "Forum",
|
||||||
|
path: "/forum",
|
||||||
|
isActive: true,
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "marketplace",
|
||||||
|
icon: "cart-outline",
|
||||||
|
activeIcon: "cart",
|
||||||
|
label: "Marketplace",
|
||||||
|
path: "/marketplace",
|
||||||
|
isActive: false,
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "maps",
|
||||||
|
icon: "map-outline",
|
||||||
|
activeIcon: "map",
|
||||||
|
label: "Maps",
|
||||||
|
path: "/maps",
|
||||||
|
isActive: true,
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "profile",
|
||||||
|
icon: "person-outline",
|
||||||
|
activeIcon: "person",
|
||||||
|
label: "Profile",
|
||||||
|
path: "/profile",
|
||||||
|
isActive: true,
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import { StyleSheet } from "react-native";
|
import { Dimensions, StyleSheet } from "react-native";
|
||||||
import { MainColor } from "../constants/color-palet";
|
import { AccentColor, MainColor } from "../constants/color-palet";
|
||||||
|
|
||||||
|
const { width } = Dimensions.get("window");
|
||||||
|
|
||||||
export const Styles = StyleSheet.create({
|
export const Styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
@@ -61,4 +63,75 @@ export const Styles = StyleSheet.create({
|
|||||||
paddingBlock: 10,
|
paddingBlock: 10,
|
||||||
backgroundColor: MainColor.darkblue,
|
backgroundColor: MainColor.darkblue,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// =============== TAB =============== //
|
||||||
|
tabBar: {
|
||||||
|
backgroundColor: MainColor.darkblue,
|
||||||
|
borderTopColor: AccentColor.blue,
|
||||||
|
borderTopWidth: 1,
|
||||||
|
// borderTopEndRadius: 10,
|
||||||
|
// borderTopStartRadius: 10,
|
||||||
|
// tintColor: MainColor.yellow
|
||||||
|
// paddingBottom: 20,
|
||||||
|
// paddingTop: 10,
|
||||||
|
// shadowColor: AccentColor.blue,
|
||||||
|
// shadowOffset: {
|
||||||
|
// width: 0,
|
||||||
|
// height: -2,
|
||||||
|
// },
|
||||||
|
// shadowOpacity: 0.9,
|
||||||
|
// shadowRadius: 3,
|
||||||
|
// elevation: 5,
|
||||||
|
},
|
||||||
|
tabContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
alignItems: "center",
|
||||||
|
paddingHorizontal: 0,
|
||||||
|
},
|
||||||
|
tabItem: {
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
paddingVertical: 8,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
minWidth: width / 5,
|
||||||
|
position: "relative",
|
||||||
|
},
|
||||||
|
activeTab: {
|
||||||
|
transform: [{ scale: 1.05 }],
|
||||||
|
},
|
||||||
|
iconContainer: {
|
||||||
|
padding: 8,
|
||||||
|
borderRadius: 20,
|
||||||
|
// marginBottom: 4,
|
||||||
|
},
|
||||||
|
activeIconContainer: {
|
||||||
|
// backgroundColor: "#007AFF",
|
||||||
|
// shadowColor: "#007AFF",
|
||||||
|
// shadowOffset: {
|
||||||
|
// width: 0,
|
||||||
|
// height: 2,
|
||||||
|
// },
|
||||||
|
// shadowOpacity: 0.3,
|
||||||
|
// shadowRadius: 4,
|
||||||
|
// elevation: 4,
|
||||||
|
},
|
||||||
|
tabLabel: {
|
||||||
|
fontSize: 10,
|
||||||
|
color: "#666",
|
||||||
|
fontWeight: "500",
|
||||||
|
},
|
||||||
|
activeTabLabel: {
|
||||||
|
color: MainColor.white,
|
||||||
|
fontWeight: "600",
|
||||||
|
},
|
||||||
|
activeIndicator: {
|
||||||
|
position: "absolute",
|
||||||
|
bottom: -2,
|
||||||
|
width: 4,
|
||||||
|
height: 4,
|
||||||
|
borderRadius: 2,
|
||||||
|
backgroundColor: "#007AFF",
|
||||||
|
},
|
||||||
|
// =============== TAB =============== //
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user