Steps to Enable Bottom Tab Bar in All Pages
1. Choose Home Page Navigation Type as "Tab Home"
To begin, navigate to the Shopify Extension settings in the Appmaker dashboard and select Tab Home as the navigation type for the home page.
2. Enable Bottom Bar Handler in “App Settings” Extension
Next, ensure that the "Bottom Bar Handler" is enabled. You can find this option in the App Settings section of the Appmaker dashboard.
3. Implement Bottom Tab Bar Code in Theme
Once the bottom bar handler is enabled, you need to modify the code to integrate the bottom tab bar. This is done by using filters provided by the @appmaker-xyz/core
package.
Here’s an example of how to import and apply the bottom tab bar component:
import { add filter } from "@appmaker-xyz/core";
import CustomBottomBar from "./path-to-component";
export function activate(params) {
// Adds a custom bottom tab bar to the home page
addFilter("custom-bottom-block", "theme-id", () => {
return CustomBottomBar;
});
// Sets the default visibility of the bottom tab bar to false
addFilter("default-bottom-tab-visibility", "theme-id", () => false);
}
4. Hide Bottom Tab Bar on Specific Pages
To hide the bottom tab bar on certain pages, you can add the following block to the page configuration. This block will control the visibility of the bottom tab bar on a per-page basis:
{
"name": "appmaker/bottom-tabs-handler",
"attributes": {
"isVisible": false
}
}
This block should be added to the specific page's configuration in the JSON format to hide the bottom tab bar for that page.
Sample code for Custom BottomTabBar component that can be displayed across all pages
import React, { useState, useCallback } from "react";
import { ThemeText, Layout } from "@appmaker-xyz/ui";
import { handleAction, useTabBlocks } from "@appmaker-xyz/react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useAppStorage } from "@appmaker-xyz/core";
import { FlatList, Pressable, StyleSheet } from "react-native";
import { useNavigation, useFocusEffect } from "@react-navigation/native";
import Icon from "react-native-vector-icons/Feather";
function CartCount({ countStyle, countTextStyle = {}, wishlistCount = false }) {
const count = useAppStorage((state) => {
let totalQuantity = 0;
if (state.checkout?.lineItems?.edges?.length > 0) {
state.checkout?.lineItems?.edges?.forEach((item) => {
totalQuantity += item?.node?.quantity;
});
}
if (wishlistCount) {
totalQuantity = state?.saved_items_count;
}
return totalQuantity || 0;
});
return (
<Layout style={[styles.count, countStyle]}>
<ThemeText size="10" color="#fff" style={countTextStyle}>
{count}
</ThemeText>
</Layout>
);
}
function BottomBarIcon({
iconName,
individualIconSize,
activeColor,
defaultColor,
count,
label,
isActive,
}) {
const color = isActive ? activeColor : defaultColor;
return (
<Layout style={{ alignItems: "center" }}>
<Icon name={iconName} size={individualIconSize || 18} color={color} />
{count && <CartCount />}
<ThemeText size="10" color={color}>
{label}
</ThemeText>
</Layout>
);
}
const isHomeScreen = (state) => {
return (
state?.routes?.length === 1 && state?.routes[0]?.state?.type === "drawer"
);
};
const getLastOpenedPage = (navState) => {
const stateAction =
navState?.routes?.[navState?.routes?.length - 1]?.params?.action;
return stateAction?.pageId;
};
const BottomBarItem = ({ tab, index }) => {
const {
enableIndividualIconSize,
label,
pageId,
iconName,
activeColor,
defaultColor,
count,
individualIconSize,
appmakerAction,
} = tab?.attributes || {};
const navigation = useNavigation();
const [isActive, setIsActive] = useState(false);
useFocusEffect(
useCallback(() => {
const updateActiveState = () => {
const currentNavState = navigation.getState();
const lastOpenedPage = getLastOpenedPage(currentNavState);
let newIsActive = false;
if (pageId === "home" && isHomeScreen(currentNavState)) {
newIsActive = true;
} else if (
appmakerAction?.action === "OPEN_DRAWER" &&
lastOpenedPage === "DrawerMenu"
) {
newIsActive = true;
} else {
newIsActive = lastOpenedPage === pageId;
}
setIsActive(newIsActive);
};
updateActiveState();
// Set up a listener for navigation state changes
const unsubscribe = navigation.addListener("state", updateActiveState);
// Clean up the listener when the component unmounts
return unsubscribe;
}, [navigation, pageId, appmakerAction])
);
const onPress = () => {
const currentNavState = navigation.getState();
if (appmakerAction) {
if (appmakerAction.action === "OPEN_DRAWER") {
if (isHomeScreen(currentNavState)) {
handleAction({
action: "TOGGLE_DRAWER",
});
} else if (getLastOpenedPage(currentNavState) !== "DrawerMenu") {
const action = {
action: "OPEN_INAPP_PAGE",
pageId: "DrawerMenu",
};
handleAction(action);
}
} else {
handleAction(appmakerAction);
}
} else if (pageId) {
if (pageId === "home") {
!isHomeScreen(currentNavState) &&
handleAction({
action: "RESET",
});
} else {
const stateAction =
currentNavState?.routes?.[currentNavState?.routes?.length - 1]?.params
?.action;
if (!stateAction?.pageId || stateAction?.pageId !== pageId) {
handleAction({
action: "OPEN_INAPP_PAGE",
pageId: pageId,
});
}
}
}
};
return (
<Layout>
<Pressable style={styles.tab} onPress={onPress}>
<BottomBarIcon
iconName={iconName}
individualIconSize={individualIconSize}
enableIndividualIconSize={enableIndividualIconSize}
activeColor={activeColor}
defaultColor={defaultColor}
count={count}
label={label}
isActive={isActive}
/>
</Pressable>
</Layout>
);
};
const CustomBottomBar = (props) => {
const { tabBlocks } = useTabBlocks();
const insets = useSafeAreaInsets();
return (
<Layout>
<FlatList
data={tabBlocks}
contentContainerStyle={[
styles.tabContainer,
{ paddingBottom: insets.bottom },
]}
renderItem={({ item, index }) => (
<BottomBarItem tab={item} index={index} />
)}
/>
</Layout>
);
};
const styles = StyleSheet.create({
tabContainer: {
flexDirection: "row",
justifyContent: "space-around",
backgroundColor: "#f1f1f1",
},
tab: {
flex: 1,
position: "relative",
justifyContent: "center",
paddingVertical: 12,
},
count: {
borderRadius: 10,
paddingHorizontal: 4,
position: "absolute",
right: -4,
zIndex: 10,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#212121",
height: 14,
minWidth: 14,
},
});
export default CustomBottomBar;
By following these steps and using the code samples, you will be able to enable and customize a bottom tab bar for your Appmaker app, and control its visibility across different pages.