diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/App.native.tsx | 59 | ||||
-rw-r--r-- | src/App.web.tsx | 59 | ||||
-rw-r--r-- | src/routes/index.tsx | 72 | ||||
-rw-r--r-- | src/routes/types.ts | 24 | ||||
-rw-r--r-- | src/screens/Home.tsx | 17 | ||||
-rw-r--r-- | src/screens/Menu.tsx | 19 | ||||
-rw-r--r-- | src/screens/NotFound.tsx | 27 | ||||
-rw-r--r-- | src/screens/Notifications.tsx | 21 | ||||
-rw-r--r-- | src/screens/Profile.tsx | 7 | ||||
-rw-r--r-- | src/screens/Search.tsx | 19 |
10 files changed, 210 insertions, 114 deletions
diff --git a/src/App.native.tsx b/src/App.native.tsx index 40989caf0..2fadf993f 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -1,52 +1,6 @@ import React, {useState, useEffect} from 'react' -import { - SafeAreaView, - ScrollView, - StatusBar, - Text, - Button, - useColorScheme, - View, -} from 'react-native' -import {NavigationContainer} from '@react-navigation/native' -import { - createNativeStackNavigator, - NativeStackScreenProps, -} from '@react-navigation/native-stack' import {RootStore, setupState, RootStoreProvider} from './state' - -type RootStackParamList = { - Home: undefined - Profile: {name: string} -} -const Stack = createNativeStackNavigator() - -const HomeScreen = ({ - navigation, -}: NativeStackScreenProps<RootStackParamList, 'Home'>) => { - const isDarkMode = useColorScheme() === 'dark' - - return ( - <SafeAreaView> - <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> - <ScrollView contentInsetAdjustmentBehavior="automatic"> - <View> - <Text>Native</Text> - <Button - title="Go to Jane's profile" - onPress={() => navigation.navigate('Profile', {name: 'Jane'})} - /> - </View> - </ScrollView> - </SafeAreaView> - ) -} - -const ProfileScreen = ({ - route, -}: NativeStackScreenProps<RootStackParamList, 'Profile'>) => { - return <Text>This is {route.params.name}'s profile</Text> -} +import * as Routes from './routes' function App() { const [rootStore, setRootStore] = useState<RootStore | undefined>(undefined) @@ -63,16 +17,7 @@ function App() { return ( <RootStoreProvider value={rootStore}> - <NavigationContainer> - <Stack.Navigator> - <Stack.Screen - name="Home" - component={HomeScreen} - options={{title: 'Welcome'}} - /> - <Stack.Screen name="Profile" component={ProfileScreen} /> - </Stack.Navigator> - </NavigationContainer> + <Routes.Root /> </RootStoreProvider> ) } diff --git a/src/App.web.tsx b/src/App.web.tsx index 18b15821b..2fadf993f 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -1,52 +1,6 @@ import React, {useState, useEffect} from 'react' -import { - SafeAreaView, - ScrollView, - StatusBar, - Text, - Button, - useColorScheme, - View, -} from 'react-native' -import {NavigationContainer} from '@react-navigation/native' -import { - createNativeStackNavigator, - NativeStackScreenProps, -} from '@react-navigation/native-stack' import {RootStore, setupState, RootStoreProvider} from './state' - -type RootStackParamList = { - Home: undefined - Profile: {name: string} -} -const Stack = createNativeStackNavigator() - -const HomeScreen = ({ - navigation, -}: NativeStackScreenProps<RootStackParamList, 'Home'>) => { - const isDarkMode = useColorScheme() === 'dark' - - return ( - <SafeAreaView> - <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> - <ScrollView contentInsetAdjustmentBehavior="automatic"> - <View> - <Text>Web</Text> - <Button - title="Go to Jane's profile" - onPress={() => navigation.navigate('Profile', {name: 'Jane'})} - /> - </View> - </ScrollView> - </SafeAreaView> - ) -} - -const ProfileScreen = ({ - route, -}: NativeStackScreenProps<RootStackParamList, 'Profile'>) => { - return <Text>This is {route.params.name}'s profile</Text> -} +import * as Routes from './routes' function App() { const [rootStore, setRootStore] = useState<RootStore | undefined>(undefined) @@ -63,16 +17,7 @@ function App() { return ( <RootStoreProvider value={rootStore}> - <NavigationContainer> - <Stack.Navigator> - <Stack.Screen - name="Home" - component={HomeScreen} - options={{title: 'Welcome'}} - /> - <Stack.Screen name="Profile" component={ProfileScreen} /> - </Stack.Navigator> - </NavigationContainer> + <Routes.Root /> </RootStoreProvider> ) } diff --git a/src/routes/index.tsx b/src/routes/index.tsx new file mode 100644 index 000000000..9ea1766f5 --- /dev/null +++ b/src/routes/index.tsx @@ -0,0 +1,72 @@ +import React from 'react' +import {Text} from 'react-native' +import { + NavigationContainer, + LinkingOptions, + RouteProp, + ParamListBase, +} from '@react-navigation/native' +import {createNativeStackNavigator} from '@react-navigation/native-stack' +import {createBottomTabNavigator} from '@react-navigation/bottom-tabs' +import type {RootStackParamList} from './types' +import {Home} from '../screens/Home' +import {Search} from '../screens/Search' +import {Notifications} from '../screens/Notifications' +import {Menu} from '../screens/Menu' +import {Profile} from '../screens/Profile' +import {NotFound} from '../screens/NotFound' + +const linking: LinkingOptions<RootStackParamList> = { + prefixes: [ + 'http://localhost:3000', // local dev + ], + config: { + screens: { + Primary: { + screens: { + Home: '', + Search: 'search', + Notifications: 'notifications', + Menu: 'menu', + }, + }, + Profile: 'profile/:name', + NotFound: '*', + }, + }, +} + +export const RootStack = createNativeStackNavigator() +export const PrimaryTab = createBottomTabNavigator() + +const tabBarScreenOptions = ({ + route, +}: { + route: RouteProp<ParamListBase, string> +}) => ({ + tabBarIcon: (_state: {focused: boolean; color: string; size: number}) => { + // TODO: icons + return <Text>{route.name.at(0)}</Text> + }, +}) + +const Primary = () => ( + <PrimaryTab.Navigator + screenOptions={tabBarScreenOptions} + initialRouteName="Home"> + <PrimaryTab.Screen name="Home" component={Home} /> + <PrimaryTab.Screen name="Search" component={Search} /> + <PrimaryTab.Screen name="Notifications" component={Notifications} /> + <PrimaryTab.Screen name="Menu" component={Menu} /> + </PrimaryTab.Navigator> +) + +export const Root = () => ( + <NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}> + <RootStack.Navigator initialRouteName="Primary"> + <RootStack.Screen name="Primary" component={Primary} /> + <RootStack.Screen name="Profile" component={Profile} /> + <RootStack.Screen name="NotFound" component={NotFound} /> + </RootStack.Navigator> + </NavigationContainer> +) diff --git a/src/routes/types.ts b/src/routes/types.ts new file mode 100644 index 000000000..668dc2e2f --- /dev/null +++ b/src/routes/types.ts @@ -0,0 +1,24 @@ +import type {NavigatorScreenParams} from '@react-navigation/native' +import type {CompositeScreenProps} from '@react-navigation/native' +import type {StackScreenProps} from '@react-navigation/stack' +import type {BottomTabScreenProps} from '@react-navigation/bottom-tabs' + +export type RootStackParamList = { + Primary: undefined + Profile: {name: string} + NotFound: undefined +} +export type RootStackScreenProps<T extends keyof RootStackParamList> = + StackScreenProps<RootStackParamList, T> + +export type PrimaryTabParamList = { + Home: NavigatorScreenParams<RootStackParamList> + Search: undefined + Notifications: undefined + Menu: undefined +} +export type PrimaryTabScreenProps<T extends keyof PrimaryTabParamList> = + CompositeScreenProps< + BottomTabScreenProps<PrimaryTabParamList, T>, + RootStackScreenProps<keyof RootStackParamList> + > diff --git a/src/screens/Home.tsx b/src/screens/Home.tsx new file mode 100644 index 000000000..f4b8ffb63 --- /dev/null +++ b/src/screens/Home.tsx @@ -0,0 +1,17 @@ +import React from 'react' +import {Text, Button, View, SafeAreaView} from 'react-native' +import type {PrimaryTabScreenProps} from '../routes/types' + +export const Home = ({navigation}: PrimaryTabScreenProps<'Home'>) => { + return ( + <SafeAreaView style={{flex: 1}}> + <View style={{flex: 1}}> + <Text>Hello world</Text> + <Button + title="Go to Jane's profile" + onPress={() => navigation.navigate('Profile', {name: 'Jane'})} + /> + </View> + </SafeAreaView> + ) +} diff --git a/src/screens/Menu.tsx b/src/screens/Menu.tsx new file mode 100644 index 000000000..2e0376a49 --- /dev/null +++ b/src/screens/Menu.tsx @@ -0,0 +1,19 @@ +import React from 'react' +import {SafeAreaView, ScrollView, Text, Button, View} from 'react-native' +import type {PrimaryTabScreenProps} from '../routes/types' + +export const Menu = ({navigation}: PrimaryTabScreenProps<'Menu'>) => { + return ( + <SafeAreaView> + <ScrollView contentInsetAdjustmentBehavior="automatic"> + <View> + <Text>Hello world</Text> + <Button + title="Go to Jane's profile" + onPress={() => navigation.navigate('Profile', {name: 'Jane'})} + /> + </View> + </ScrollView> + </SafeAreaView> + ) +} diff --git a/src/screens/NotFound.tsx b/src/screens/NotFound.tsx new file mode 100644 index 000000000..afb91b402 --- /dev/null +++ b/src/screens/NotFound.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import { + SafeAreaView, + ScrollView, + StatusBar, + Text, + Button, + useColorScheme, + View, +} from 'react-native' +import type {RootStackScreenProps} from '../routes/types' + +export const NotFound = ({navigation}: RootStackScreenProps<'NotFound'>) => { + const isDarkMode = useColorScheme() === 'dark' + + return ( + <SafeAreaView> + <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> + <ScrollView contentInsetAdjustmentBehavior="automatic"> + <View> + <Text>Page not found</Text> + <Button title="Home" onPress={() => navigation.navigate('Primary')} /> + </View> + </ScrollView> + </SafeAreaView> + ) +} diff --git a/src/screens/Notifications.tsx b/src/screens/Notifications.tsx new file mode 100644 index 000000000..8ffb5bb87 --- /dev/null +++ b/src/screens/Notifications.tsx @@ -0,0 +1,21 @@ +import React from 'react' +import {SafeAreaView, ScrollView, Text, Button, View} from 'react-native' +import type {PrimaryTabScreenProps} from '../routes/types' + +export const Notifications = ({ + navigation, +}: PrimaryTabScreenProps<'Notifications'>) => { + return ( + <SafeAreaView> + <ScrollView contentInsetAdjustmentBehavior="automatic"> + <View> + <Text>Hello world</Text> + <Button + title="Go to Jane's profile" + onPress={() => navigation.navigate('Profile', {name: 'Jane'})} + /> + </View> + </ScrollView> + </SafeAreaView> + ) +} diff --git a/src/screens/Profile.tsx b/src/screens/Profile.tsx new file mode 100644 index 000000000..ffd30a499 --- /dev/null +++ b/src/screens/Profile.tsx @@ -0,0 +1,7 @@ +import React from 'react' +import {Text} from 'react-native' +import type {RootStackScreenProps} from '../routes/types' + +export const Profile = ({route}: RootStackScreenProps<'Profile'>) => { + return <Text>This is {route.params.name}'s profile</Text> +} diff --git a/src/screens/Search.tsx b/src/screens/Search.tsx new file mode 100644 index 000000000..85943190a --- /dev/null +++ b/src/screens/Search.tsx @@ -0,0 +1,19 @@ +import React from 'react' +import {SafeAreaView, ScrollView, Text, Button, View} from 'react-native' +import type {PrimaryTabScreenProps} from '../routes/types' + +export const Search = ({navigation}: PrimaryTabScreenProps<'Search'>) => { + return ( + <SafeAreaView> + <ScrollView contentInsetAdjustmentBehavior="automatic"> + <View> + <Text>Hello world</Text> + <Button + title="Go to Jane's profile" + onPress={() => navigation.navigate('Profile', {name: 'Jane'})} + /> + </View> + </ScrollView> + </SafeAreaView> + ) +} |