Skip to main content

Full-screen modal

To add a new plant we'll use a full screen modal that renders over the rest of the app content. And we'll create a header button to that allows the user to navigate to it.

New modal

Create a new screen called new.tsx for the "Add a plant" modal.

New file: app/new.tsx
import { View, Text, StyleSheet } from "react-native";
import { theme } from "@/theme";

export default function NewScreen() {
return (
<View style={styles.container}>
<Text>New plant</Text>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: theme.colorWhite,
justifyContent: "center",
alignItems: "center",
},
});

Add the screen to the main root layout:

Update app/_layout.tsx
@@ -15,6 +15,13 @@ export default function RootLayout() {
animation: "fade",
}}
/>
+ <Stack.Screen
+ name="new"
+ options={{
+ presentation: "modal",
+ title: "New plant",
+ }}
+ />
</Stack>
);
}

Icon button

And add an icon button to the header of the home screen using a vector icon and have it open the /new modal:

Update app/(tabs)/_layout.tsx
@@ -1,8 +1,10 @@
-import { Redirect, Tabs } from "expo-router";
+import { Redirect, Tabs, Link } from "expo-router";
import Entypo from "@expo/vector-icons/Entypo";
import Feather from "@expo/vector-icons/Feather";
import { theme } from "@/theme";
import { useUserStore } from "@/store/userStore";
+import AntDesign from "@expo/vector-icons/AntDesign";
+import { Pressable } from "react-native";

export default function Layout() {
const hasFinishedOnboarding = useUserStore(
@@ -23,6 +25,17 @@ export default function Layout() {
tabBarIcon: ({ size, color }) => (
<Entypo name="leaf" size={size} color={color} />
),
+ headerRight: () => (
+ <Link href="/new" asChild>
+ <Pressable hitSlop={20} style={{ marginRight: 18 }}>
+ <AntDesign
+ name="pluscircleo"
+ size={24}
+ color={theme.colorGreen}
+ />
+ </Pressable>
+ </Link>
+ ),
}}
/>
<Tabs.Screen

Checkpoint

AndroidiOS
Checkpoint