diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/(tabs)/_layout.tsx | 45 | ||||
-rw-r--r-- | app/(tabs)/explore.tsx | 110 | ||||
-rw-r--r-- | app/(tabs)/index.tsx | 75 | ||||
-rw-r--r-- | app/+not-found.tsx | 32 | ||||
-rw-r--r-- | app/_layout.tsx | 29 |
5 files changed, 291 insertions, 0 deletions
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx new file mode 100644 index 0000000..cfbc1e2 --- /dev/null +++ b/app/(tabs)/_layout.tsx @@ -0,0 +1,45 @@ +import { Tabs } from 'expo-router'; +import React from 'react'; +import { Platform } from 'react-native'; + +import { HapticTab } from '@/components/HapticTab'; +import { IconSymbol } from '@/components/ui/IconSymbol'; +import TabBarBackground from '@/components/ui/TabBarBackground'; +import { Colors } from '@/constants/Colors'; +import { useColorScheme } from '@/hooks/useColorScheme'; + +export default function TabLayout() { + const colorScheme = useColorScheme(); + + return ( + <Tabs + screenOptions={{ + tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint, + headerShown: false, + tabBarButton: HapticTab, + tabBarBackground: TabBarBackground, + tabBarStyle: Platform.select({ + ios: { + // Use a transparent background on iOS to show the blur effect + position: 'absolute', + }, + default: {}, + }), + }}> + <Tabs.Screen + name="index" + options={{ + title: 'Home', + tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />, + }} + /> + <Tabs.Screen + name="explore" + options={{ + title: 'Explore', + tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />, + }} + /> + </Tabs> + ); +} diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx new file mode 100644 index 0000000..d4fbcaa --- /dev/null +++ b/app/(tabs)/explore.tsx @@ -0,0 +1,110 @@ +import { Image } from 'expo-image'; +import { Platform, StyleSheet } from 'react-native'; + +import { Collapsible } from '@/components/Collapsible'; +import { ExternalLink } from '@/components/ExternalLink'; +import ParallaxScrollView from '@/components/ParallaxScrollView'; +import { ThemedText } from '@/components/ThemedText'; +import { ThemedView } from '@/components/ThemedView'; +import { IconSymbol } from '@/components/ui/IconSymbol'; + +export default function TabTwoScreen() { + return ( + <ParallaxScrollView + headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }} + headerImage={ + <IconSymbol + size={310} + color="#808080" + name="chevron.left.forwardslash.chevron.right" + style={styles.headerImage} + /> + }> + <ThemedView style={styles.titleContainer}> + <ThemedText type="title">Explore</ThemedText> + </ThemedView> + <ThemedText>This app includes example code to help you get started.</ThemedText> + <Collapsible title="File-based routing"> + <ThemedText> + This app has two screens:{' '} + <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '} + <ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText> + </ThemedText> + <ThemedText> + The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '} + sets up the tab navigator. + </ThemedText> + <ExternalLink href="https://docs.expo.dev/router/introduction"> + <ThemedText type="link">Learn more</ThemedText> + </ExternalLink> + </Collapsible> + <Collapsible title="Android, iOS, and web support"> + <ThemedText> + You can open this project on Android, iOS, and the web. To open the web version, press{' '} + <ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project. + </ThemedText> + </Collapsible> + <Collapsible title="Images"> + <ThemedText> + For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '} + <ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for + different screen densities + </ThemedText> + <Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} /> + <ExternalLink href="https://reactnative.dev/docs/images"> + <ThemedText type="link">Learn more</ThemedText> + </ExternalLink> + </Collapsible> + <Collapsible title="Custom fonts"> + <ThemedText> + Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '} + <ThemedText style={{ fontFamily: 'SpaceMono' }}> + custom fonts such as this one. + </ThemedText> + </ThemedText> + <ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font"> + <ThemedText type="link">Learn more</ThemedText> + </ExternalLink> + </Collapsible> + <Collapsible title="Light and dark mode components"> + <ThemedText> + This template has light and dark mode support. The{' '} + <ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect + what the user's current color scheme is, and so you can adjust UI colors accordingly. + </ThemedText> + <ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/"> + <ThemedText type="link">Learn more</ThemedText> + </ExternalLink> + </Collapsible> + <Collapsible title="Animations"> + <ThemedText> + This template includes an example of an animated component. The{' '} + <ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses + the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '} + library to create a waving hand animation. + </ThemedText> + {Platform.select({ + ios: ( + <ThemedText> + The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '} + component provides a parallax effect for the header image. + </ThemedText> + ), + })} + </Collapsible> + </ParallaxScrollView> + ); +} + +const styles = StyleSheet.create({ + headerImage: { + color: '#808080', + bottom: -90, + left: -35, + position: 'absolute', + }, + titleContainer: { + flexDirection: 'row', + gap: 8, + }, +}); diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx new file mode 100644 index 0000000..462e8cd --- /dev/null +++ b/app/(tabs)/index.tsx @@ -0,0 +1,75 @@ +import { Image } from 'expo-image'; +import { Platform, StyleSheet } from 'react-native'; + +import { HelloWave } from '@/components/HelloWave'; +import ParallaxScrollView from '@/components/ParallaxScrollView'; +import { ThemedText } from '@/components/ThemedText'; +import { ThemedView } from '@/components/ThemedView'; + +export default function HomeScreen() { + return ( + <ParallaxScrollView + headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }} + headerImage={ + <Image + source={require('@/assets/images/partial-react-logo.png')} + style={styles.reactLogo} + /> + }> + <ThemedView style={styles.titleContainer}> + <ThemedText type="title">Welcome!</ThemedText> + <HelloWave /> + </ThemedView> + <ThemedView style={styles.stepContainer}> + <ThemedText type="subtitle">Step 1: Try it</ThemedText> + <ThemedText> + Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes. + Press{' '} + <ThemedText type="defaultSemiBold"> + {Platform.select({ + ios: 'cmd + d', + android: 'cmd + m', + web: 'F12', + })} + </ThemedText>{' '} + to open developer tools. + </ThemedText> + </ThemedView> + <ThemedView style={styles.stepContainer}> + <ThemedText type="subtitle">Step 2: Explore</ThemedText> + <ThemedText> + {`Tap the Explore tab to learn more about what's included in this starter app.`} + </ThemedText> + </ThemedView> + <ThemedView style={styles.stepContainer}> + <ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText> + <ThemedText> + {`When you're ready, run `} + <ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '} + <ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '} + <ThemedText type="defaultSemiBold">app</ThemedText> to{' '} + <ThemedText type="defaultSemiBold">app-example</ThemedText>. + </ThemedText> + </ThemedView> + </ParallaxScrollView> + ); +} + +const styles = StyleSheet.create({ + titleContainer: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + }, + stepContainer: { + gap: 8, + marginBottom: 8, + }, + reactLogo: { + height: 178, + width: 290, + bottom: 0, + left: 0, + position: 'absolute', + }, +}); diff --git a/app/+not-found.tsx b/app/+not-found.tsx new file mode 100644 index 0000000..215b0ed --- /dev/null +++ b/app/+not-found.tsx @@ -0,0 +1,32 @@ +import { Link, Stack } from 'expo-router'; +import { StyleSheet } from 'react-native'; + +import { ThemedText } from '@/components/ThemedText'; +import { ThemedView } from '@/components/ThemedView'; + +export default function NotFoundScreen() { + return ( + <> + <Stack.Screen options={{ title: 'Oops!' }} /> + <ThemedView style={styles.container}> + <ThemedText type="title">This screen does not exist.</ThemedText> + <Link href="/" style={styles.link}> + <ThemedText type="link">Go to home screen!</ThemedText> + </Link> + </ThemedView> + </> + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + padding: 20, + }, + link: { + marginTop: 15, + paddingVertical: 15, + }, +}); diff --git a/app/_layout.tsx b/app/_layout.tsx new file mode 100644 index 0000000..8d506f7 --- /dev/null +++ b/app/_layout.tsx @@ -0,0 +1,29 @@ +import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; +import { useFonts } from 'expo-font'; +import { Stack } from 'expo-router'; +import { StatusBar } from 'expo-status-bar'; +import 'react-native-reanimated'; + +import { useColorScheme } from '@/hooks/useColorScheme'; + +export default function RootLayout() { + const colorScheme = useColorScheme(); + const [loaded] = useFonts({ + SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), + }); + + if (!loaded) { + // Async font loading only occurs in development. + return null; + } + + return ( + <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> + <Stack> + <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> + <Stack.Screen name="+not-found" /> + </Stack> + <StatusBar style="auto" /> + </ThemeProvider> + ); +} |