Replace drawer menu page and menu items with custom components
Description
This document provides instructions on how to substitute the default drawer menu page and menu items with custom components. This is particularly valuable when you want to incorporate personalized elements into the dra`wer menu, such as a custom header, footer, or custom menu items.
Example
Steps
Create a page file named
DrawerMenu.js
in thesrc/pages
folder.Add the following code to the
DrawerMenu.js
file.
const DrawerMenu = {
parentID: "mainmenu",
id: "mainmenu",
blocks: [
// add your custom blocks here if any
{
name: "appmaker/core-menu",
clientId: "drawer-menu",
// Note: core-menu block will provide the menu items added in the appmaker dashboard
},
],
stickyFooter: [
// add your custom blocks here if any
],
attributes: {},
};
export default DrawerMenu;
- import the
DrawerMenu
page in thesrc/pages/index.js
file.
import DrawerMenu from "./DrawerMenu";
const pages = {
DrawerMenu,
};
export { pages };
Ensure that you include the pages
module within the registerTheme
function located in the src/index.js
file.
- Create a component in
src/components
folder to represent the core menu items added in the appmaker dashboard.
Core menu (Sample Component)
import React, { useState } from "react";
import {
FlatList,
Image,
Pressable,
StyleSheet,
Text,
View,
} from "react-native";
import Icon from "react-native-vector-icons/SimpleLineIcons";
const MenuItem = ({ item, onAction }) => {
const {
icon,
title,
action,
nodes = [],
fontColor,
badge,
badgeColor,
badgeText,
badgeTextColor,
dotIndicator,
dotIndicatorColor,
dotSize,
} = item;
const innerBlocks = nodes;
const [expandState, setExpandState] = useState(false);
return (
<View>
<Pressable
style={styles.pressableView}
onPress={() => {
if (innerBlocks.length > 0) {
setExpandState(!expandState);
} else {
onAction(action);
}
}}
>
<View style={styles.viewRow}>
{icon ? <Image source={{ uri: icon }} style={styles.image} /> : null}
<Text
numberOfLines={1}
style={[styles.textRow, { color: fontColor || "#5C5C5C" }]}
>
{title}
</Text>
{badge ? (
<View
style={[
styles.badgeTextContainer,
{
backgroundColor: badgeColor,
},
]}
>
<Text
style={[
styles.badgeText,
{
color: badgeTextColor,
},
]}
>
{badgeText}
</Text>
</View>
) : null}
{dotIndicator ? (
<View
style={[
styles.dotIndicator,
{
width: dotSize,
height: dotSize,
backgroundColor: dotIndicatorColor,
},
]}
/>
) : null}
</View>
{innerBlocks.length > 0 ? (
<Icon name={expandState ? "arrow-down" : "arrow-right"} size={12} />
) : null}
</Pressable>
{innerBlocks.length > 0 && expandState === true ? (
<FlatList
data={innerBlocks}
renderItem={({ item }) => (
<MenuItem item={item} onAction={onAction} />
)}
keyExtractor={(item) => item.id}
style={styles.innerContainer}
/>
) : null}
</View>
);
};
const CoreMenu = ({ attributes, onAction }) => {
const menuItems = attributes?.menuItems?.blocks;
return (
<FlatList
data={menuItems}
renderItem={({ item }) => <MenuItem item={item} onAction={onAction} />}
keyExtractor={(item) => item.id}
contentContainerStyle={styles.container}
/>
);
};
const styles = StyleSheet.create({
container: {
paddingHorizontal: 10,
},
pressableView: {
paddingVertical: 10,
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
flex: 1,
},
viewRow: {
flexDirection: "row",
alignItems: "center",
flexShrink: 1,
},
image: {
width: 22,
height: 22,
marginRight: 10,
},
textRow: {
fontSize: 14,
marginRight: 5,
color: "#5C5C5C",
flexShrink: 1,
},
innerContainer: {
paddingLeft: 10,
},
badgeText: {
fontSize: 12,
},
badgeTextContainer: {
paddingHorizontal: 5,
paddingVertical: 2,
borderRadius: 5,
marginLeft: 5,
},
dotIndicator: {
borderRadius: 50,
marginLeft: 6,
},
});
export default CoreMenu;
- In the
src/blocks/index.js
file, please make sure to register the Menu component under the nameappmaker/core-drawer-menu
.
import CoreMenu from "../components/CoreMenu";
const blocks = [
{
name: "appmaker/core-drawer-menu",
View: CoreMenu,
},
];
export { blocks };
- The menu items you've added in the appmaker dashboard will be displayed within the drawer menu. Feel free to modify the
CoreMenu
component to tailor the menu items according to your specific needs.
Please refrain from substituting the appmaker/core-menu
block, as it is essential for displaying menu items in the appmaker dashboard. If you replace the appmaker/core-menu
block, the menu items in the appmaker dashboard will no longer appear. Instead, consider replacing it with the appmaker/core-drawer-menu
block if you wish to customize the menu items.
Customizing the drawer menu header
- Create a component in
src/components
folder to represent the drawer menu header.
Drawer menu header (Sample Component)
import React from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";
import Icon from "react-native-vector-icons/FontAwesome";
import { useUser } from "@appmaker-xyz/shopify";
const DrawerMenuHeader = (props) => {
const { isLoggedin, user } = useUser(props);
const firstName = user?.firstName;
const lastName = user?.lastName;
return (
<Pressable
onPress={() =>
isLoggedin
? props.onAction({ action: "OPEN_MY_ACCOUNT" })
: props.onAction({ action: "OPEN_LOGIN_PAGE" })
}
style={styles.container}
>
<Icon name="user-circle" size={24} color="#000000" style={styles.icon} />
{isLoggedin ? (
firstName || lastName ? (
<Text>
{firstName} {lastName}
</Text>
) : (
<Text>Welcome</Text>
)
) : (
<Text>Login</Text>
)}
</Pressable>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: "center",
padding: 10,
backgroundColor: "#f1f2f5",
},
icon: {
marginRight: 10,
},
});
export default DrawerMenuHeader;
The DrawerMenuHeader
component uses the useUser
hook to determine whether the user is logged in or not. If the user is logged in, the component will display the user's first name and last name. If the user is not logged in, the component will display the text "Login". Refer to the useUser hook documentation for more information.
- In the
src/blocks/index.js
file, please make sure to register the DrawerMenuHeader component under the nameappmaker/drawer-menu-header
.
import DrawerMenuHeader from "../components/DrawerMenuHeader";
const blocks = [
// other blocks
{
name: "appmaker/drawer-menu-header",
View: DrawerMenuHeader,
},
];
export { blocks };
- In the
src/pages/DrawerMenu.js
file, please make sure to add theappmaker/drawer-menu-header
block toblocks
array.
const DrawerMenu = {
parentID: "mainmenu",
id: "mainmenu",
blocks: [
// other blocks
{
name: "appmaker/drawer-menu-header",
clientId: "drawer-menu-header",
},
],
stickyFooter: [
// other blocks
],
attributes: {},
};
export default DrawerMenu;
- The drawer menu header will be displayed within the drawer menu. Feel free to modify the
DrawerMenuHeader
component to tailor the menu items according to your specific needs.