diff options
author | Santo Cariotti <santo@dcariotti.me> | 2024-08-28 15:53:21 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2024-08-28 15:53:21 +0200 |
commit | 83643a78b73dee5610be6ad9837fb72e9b944cb7 (patch) | |
tree | 1eca6bad452656f78879c829181362f3b586d697 /app |
Initial commit
Generated by create-expo-app 3.0.0.
Diffstat (limited to 'app')
-rw-r--r-- | app/(tabs)/_layout.tsx | 37 | ||||
-rw-r--r-- | app/(tabs)/explore.tsx | 102 | ||||
-rw-r--r-- | app/(tabs)/index.tsx | 70 | ||||
-rw-r--r-- | app/+html.tsx | 39 | ||||
-rw-r--r-- | app/+not-found.tsx | 32 | ||||
-rw-r--r-- | app/_layout.tsx | 37 |
6 files changed, 317 insertions, 0 deletions
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx new file mode 100644 index 0000000..22a49b6 --- /dev/null +++ b/app/(tabs)/_layout.tsx @@ -0,0 +1,37 @@ +import { Tabs } from 'expo-router'; +import React from 'react'; + +import { TabBarIcon } from '@/components/navigation/TabBarIcon'; +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, + }}> + <Tabs.Screen + name="index" + options={{ + title: 'Home', + tabBarIcon: ({ color, focused }) => ( + <TabBarIcon name={focused ? 'home' : 'home-outline'} color={color} /> + ), + }} + /> + <Tabs.Screen + name="explore" + options={{ + title: 'Explore', + tabBarIcon: ({ color, focused }) => ( + <TabBarIcon name={focused ? 'code-slash' : 'code-slash-outline'} color={color} /> + ), + }} + /> + </Tabs> + ); +} diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx new file mode 100644 index 0000000..e480218 --- /dev/null +++ b/app/(tabs)/explore.tsx @@ -0,0 +1,102 @@ +import Ionicons from '@expo/vector-icons/Ionicons'; +import { StyleSheet, Image, Platform } 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'; + +export default function TabTwoScreen() { + return ( + <ParallaxScrollView + headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }} + headerImage={<Ionicons size={310} name="code-slash" 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..324aeb7 --- /dev/null +++ b/app/(tabs)/index.tsx @@ -0,0 +1,70 @@ +import { Image, StyleSheet, Platform } 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' })} + </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/+html.tsx b/app/+html.tsx new file mode 100644 index 0000000..8b92456 --- /dev/null +++ b/app/+html.tsx @@ -0,0 +1,39 @@ +import { ScrollViewStyleReset } from 'expo-router/html'; +import { type PropsWithChildren } from 'react'; + +/** + * This file is web-only and used to configure the root HTML for every web page during static rendering. + * The contents of this function only run in Node.js environments and do not have access to the DOM or browser APIs. + */ +export default function Root({ children }: PropsWithChildren) { + return ( + <html lang="en"> + <head> + <meta charSet="utf-8" /> + <meta httpEquiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> + + {/* + Disable body scrolling on web. This makes ScrollView components work closer to how they do on native. + However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line. + */} + <ScrollViewStyleReset /> + + {/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */} + <style dangerouslySetInnerHTML={{ __html: responsiveBackground }} /> + {/* Add any additional <head> elements that you want globally available on web... */} + </head> + <body>{children}</body> + </html> + ); +} + +const responsiveBackground = ` +body { + background-color: #fff; +} +@media (prefers-color-scheme: dark) { + body { + background-color: #000; + } +}`; diff --git a/app/+not-found.tsx b/app/+not-found.tsx new file mode 100644 index 0000000..963b04f --- /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 doesn't 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..2e37cdd --- /dev/null +++ b/app/_layout.tsx @@ -0,0 +1,37 @@ +import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; +import { useFonts } from 'expo-font'; +import { Stack } from 'expo-router'; +import * as SplashScreen from 'expo-splash-screen'; +import { useEffect } from 'react'; +import 'react-native-reanimated'; + +import { useColorScheme } from '@/hooks/useColorScheme'; + +// Prevent the splash screen from auto-hiding before asset loading is complete. +SplashScreen.preventAutoHideAsync(); + +export default function RootLayout() { + const colorScheme = useColorScheme(); + const [loaded] = useFonts({ + SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), + }); + + useEffect(() => { + if (loaded) { + SplashScreen.hideAsync(); + } + }, [loaded]); + + if (!loaded) { + return null; + } + + return ( + <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> + <Stack> + <Stack.Screen name="(tabs)" options={{ headerShown: false }} /> + <Stack.Screen name="+not-found" /> + </Stack> + </ThemeProvider> + ); +} |