Skip to content

Commit 52b8415

Browse files
authored
feat: add expo example (#148)
* feat: add expo example * build: expo on the CI * Update package.json
1 parent a175601 commit 52b8415

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+6195
-1982
lines changed

.eslintrc.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module.exports = {
2+
root: true,
3+
extends: ['@react-native', 'prettier'],
4+
plugins: ['prettier'],
5+
rules: {
6+
'react/react-in-jsx-scope': 'off',
7+
'prettier/prettier': [
8+
'error',
9+
{
10+
quoteProps: 'consistent',
11+
singleQuote: true,
12+
tabWidth: 2,
13+
trailingComma: 'es5',
14+
useTabs: false,
15+
},
16+
],
17+
},
18+
ignorePatterns: ['**/lib/**', '**/dist/**', '**/node_modules/**'],
19+
};

.github/workflows/ci.yml

+12
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ jobs:
5050
- name: Setup
5151
uses: ./.github/actions/setup
5252

53+
- name: Build package
54+
run: yarn prepare
55+
5356
- name: Cache turborepo for Android
5457
uses: actions/cache@v3
5558
with:
@@ -106,6 +109,9 @@ jobs:
106109
- name: Setup
107110
uses: ./.github/actions/setup
108111

112+
- name: Build package
113+
run: yarn prepare
114+
109115
- name: Cache turborepo for Android new arch
110116
uses: actions/cache@v3
111117
with:
@@ -162,6 +168,9 @@ jobs:
162168
- name: Setup
163169
uses: ./.github/actions/setup
164170

171+
- name: Build package
172+
run: yarn prepare
173+
165174
- name: Cache turborepo for iOS
166175
uses: actions/cache@v3
167176
with:
@@ -202,6 +211,9 @@ jobs:
202211
- name: Setup
203212
uses: ./.github/actions/setup
204213

214+
- name: Build package
215+
run: yarn prepare
216+
205217
- name: Cache turborepo for iOS
206218
uses: actions/cache@v3
207219
with:

.yarnrc.yml

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
nodeLinker: node-modules
2-
nmHoistingLimits: workspaces
32

43
plugins:
54
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs

apps/example-expo/.gitignore

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2+
3+
# dependencies
4+
node_modules/
5+
6+
# Expo
7+
.expo/
8+
dist/
9+
web-build/
10+
expo-env.d.ts
11+
android
12+
ios
13+
14+
# Native
15+
*.orig.*
16+
*.jks
17+
*.p8
18+
*.p12
19+
*.key
20+
*.mobileprovision
21+
22+
# Metro
23+
.metro-health-check*
24+
25+
# debug
26+
npm-debug.*
27+
yarn-debug.*
28+
yarn-error.*
29+
30+
# macOS
31+
.DS_Store
32+
*.pem
33+
34+
# local env files
35+
.env*.local
36+
37+
# typescript
38+
*.tsbuildinfo
39+
40+
app-example

apps/example-expo/app.json

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"expo": {
3+
"name": "bottom-tabs",
4+
"slug": "bottom-tabs",
5+
"version": "1.0.0",
6+
"orientation": "portrait",
7+
"icon": "./assets/images/icon.png",
8+
"scheme": "myapp",
9+
"userInterfaceStyle": "automatic",
10+
"ios": {
11+
"supportsTablet": true,
12+
"bundleIdentifier": "com.anonymous.bottomtabs"
13+
},
14+
"android": {
15+
"adaptiveIcon": {
16+
"foregroundImage": "./assets/images/adaptive-icon.png",
17+
"backgroundColor": "#ffffff"
18+
},
19+
"package": "com.anonymous.bottomtabs"
20+
},
21+
"web": {
22+
"bundler": "metro",
23+
"output": "static",
24+
"favicon": "./assets/images/favicon.png"
25+
},
26+
"plugins": [
27+
"expo-router",
28+
"react-native-bottom-tabs",
29+
[
30+
"expo-splash-screen",
31+
{
32+
"image": "./assets/images/splash-icon.png",
33+
"imageWidth": 200,
34+
"resizeMode": "contain",
35+
"backgroundColor": "#ffffff"
36+
}
37+
],
38+
[
39+
"expo-build-properties",
40+
{
41+
"ios": {
42+
"deploymentTarget": "14.0",
43+
"useFrameworks": "static"
44+
}
45+
}
46+
],
47+
"expo-font"
48+
],
49+
"experiments": {
50+
"typedRoutes": true
51+
}
52+
}
53+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
3+
import { withLayoutContext } from 'expo-router';
4+
import createNativeBottomTabNavigator from '../../../../packages/react-native-bottom-tabs/src/react-navigation/navigators/createNativeBottomTabNavigator';
5+
6+
const Tabs = withLayoutContext(createNativeBottomTabNavigator().Navigator);
7+
8+
function TabLayout() {
9+
return (
10+
<Tabs>
11+
<Tabs.Screen
12+
name="index"
13+
options={{
14+
title: 'Home',
15+
tabBarIcon: () => ({ sfSymbol: 'house.fill' }),
16+
}}
17+
/>
18+
<Tabs.Screen
19+
name="explore"
20+
options={{
21+
title: 'Explore',
22+
tabBarIcon: () => ({ sfSymbol: 'house.fill' }),
23+
}}
24+
/>
25+
</Tabs>
26+
);
27+
}
28+
29+
export default TabLayout;
+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { StyleSheet, Image } from 'react-native';
2+
3+
import { Collapsible } from '@/components/Collapsible';
4+
import { ExternalLink } from '@/components/ExternalLink';
5+
import { ThemedText } from '@/components/ThemedText';
6+
import { ThemedView } from '@/components/ThemedView';
7+
import { ScrollView } from 'react-native-gesture-handler';
8+
9+
function TabTwoScreen() {
10+
return (
11+
<ScrollView>
12+
<ThemedView style={styles.titleContainer}>
13+
<ThemedText type="title">Explore</ThemedText>
14+
</ThemedView>
15+
<ThemedText>
16+
This app includes example code to help you get started.
17+
</ThemedText>
18+
<Collapsible title="File-based routing">
19+
<ThemedText>
20+
This app has two screens:{' '}
21+
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText>{' '}
22+
and{' '}
23+
<ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
24+
</ThemedText>
25+
<ThemedText>
26+
The layout file in{' '}
27+
<ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
28+
sets up the tab navigator.
29+
</ThemedText>
30+
<ExternalLink href="https://docs.expo.dev/router/introduction">
31+
<ThemedText type="link">Learn more</ThemedText>
32+
</ExternalLink>
33+
</Collapsible>
34+
<Collapsible title="Android, iOS, and web support">
35+
<ThemedText>
36+
You can open this project on Android, iOS, and the web. To open the
37+
web version, press <ThemedText type="defaultSemiBold">w</ThemedText>{' '}
38+
in the terminal running this project.
39+
</ThemedText>
40+
</Collapsible>
41+
<Collapsible title="Images">
42+
<ThemedText>
43+
For static images, you can use the{' '}
44+
<ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
45+
<ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to
46+
provide files for different screen densities
47+
</ThemedText>
48+
<Image
49+
source={require('@/assets/images/react-logo.png')}
50+
style={{ alignSelf: 'center' }}
51+
/>
52+
<ExternalLink href="https://reactnative.dev/docs/images">
53+
<ThemedText type="link">Learn more</ThemedText>
54+
</ExternalLink>
55+
</Collapsible>
56+
<Collapsible title="Custom fonts">
57+
<ThemedText>
58+
Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText>{' '}
59+
to see how to load{' '}
60+
<ThemedText style={{ fontFamily: 'SpaceMono' }}>
61+
custom fonts such as this one.
62+
</ThemedText>
63+
</ThemedText>
64+
<ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font">
65+
<ThemedText type="link">Learn more</ThemedText>
66+
</ExternalLink>
67+
</Collapsible>
68+
<Collapsible title="Light and dark mode components">
69+
<ThemedText>
70+
This template has light and dark mode support. The{' '}
71+
<ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook
72+
lets you inspect what the user's current color scheme is, and so you
73+
can adjust UI colors accordingly.
74+
</ThemedText>
75+
<ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
76+
<ThemedText type="link">Learn more</ThemedText>
77+
</ExternalLink>
78+
</Collapsible>
79+
</ScrollView>
80+
);
81+
}
82+
83+
const styles = StyleSheet.create({
84+
headerImage: {
85+
color: '#808080',
86+
bottom: -90,
87+
left: -35,
88+
position: 'absolute',
89+
},
90+
titleContainer: {
91+
flexDirection: 'row',
92+
gap: 8,
93+
},
94+
});
95+
96+
export default TabTwoScreen;
+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { ScrollView, StyleSheet, Platform } from 'react-native';
2+
3+
import { ThemedText } from '@/components/ThemedText';
4+
import { ThemedView } from '@/components/ThemedView';
5+
6+
function HomeScreen() {
7+
return (
8+
<ScrollView>
9+
<ThemedView style={styles.titleContainer}>
10+
<ThemedText type="title">Welcome!</ThemedText>
11+
</ThemedView>
12+
<ThemedView style={styles.stepContainer}>
13+
<ThemedText type="subtitle">Step 1: Try it</ThemedText>
14+
<ThemedText>
15+
Edit{' '}
16+
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText>{' '}
17+
to see changes. Press{' '}
18+
<ThemedText type="defaultSemiBold">
19+
{Platform.select({
20+
ios: 'cmd + d',
21+
android: 'cmd + m',
22+
web: 'F12',
23+
})}
24+
</ThemedText>{' '}
25+
to open developer tools.
26+
</ThemedText>
27+
</ThemedView>
28+
<ThemedView style={styles.stepContainer}>
29+
<ThemedText type="subtitle">Step 2: Explore</ThemedText>
30+
<ThemedText>
31+
Tap the Explore tab to learn more about what's included in this
32+
starter app.
33+
</ThemedText>
34+
</ThemedView>
35+
<ThemedView style={styles.stepContainer}>
36+
<ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
37+
<ThemedText>
38+
When you're ready, run{' '}
39+
<ThemedText type="defaultSemiBold">npm run reset-project</ThemedText>{' '}
40+
to get a fresh <ThemedText type="defaultSemiBold">app</ThemedText>{' '}
41+
directory. This will move the current{' '}
42+
<ThemedText type="defaultSemiBold">app</ThemedText> to{' '}
43+
<ThemedText type="defaultSemiBold">app-example</ThemedText>.
44+
</ThemedText>
45+
</ThemedView>
46+
</ScrollView>
47+
);
48+
}
49+
50+
const styles = StyleSheet.create({
51+
titleContainer: {
52+
flexDirection: 'row',
53+
alignItems: 'center',
54+
gap: 8,
55+
},
56+
stepContainer: {
57+
gap: 8,
58+
marginBottom: 8,
59+
},
60+
reactLogo: {
61+
height: 178,
62+
width: 290,
63+
bottom: 0,
64+
left: 0,
65+
position: 'absolute',
66+
},
67+
});
68+
69+
export default HomeScreen;

apps/example-expo/app/+not-found.tsx

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Link, Stack } from 'expo-router';
2+
import { StyleSheet } from 'react-native';
3+
4+
import { ThemedText } from '@/components/ThemedText';
5+
import { ThemedView } from '@/components/ThemedView';
6+
7+
export default function NotFoundScreen() {
8+
return (
9+
<>
10+
<Stack.Screen options={{ title: 'Oops!' }} />
11+
<ThemedView style={styles.container}>
12+
<ThemedText type="title">This screen doesn't exist.</ThemedText>
13+
<Link href="/" style={styles.link}>
14+
<ThemedText type="link">Go to home screen!</ThemedText>
15+
</Link>
16+
</ThemedView>
17+
</>
18+
);
19+
}
20+
21+
const styles = StyleSheet.create({
22+
container: {
23+
flex: 1,
24+
alignItems: 'center',
25+
justifyContent: 'center',
26+
padding: 20,
27+
},
28+
link: {
29+
marginTop: 15,
30+
paddingVertical: 15,
31+
},
32+
});

0 commit comments

Comments
 (0)