Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {
root: true,
extends: ['@react-native', 'prettier'],
plugins: ['prettier'],
rules: {
'react/react-in-jsx-scope': 'off',
'prettier/prettier': [
'error',
{
quoteProps: 'consistent',
singleQuote: true,
tabWidth: 2,
trailingComma: 'es5',
useTabs: false,
},
],
},
ignorePatterns: ['**/lib/**', '**/dist/**', '**/node_modules/**'],
};
106 changes: 106 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ jobs:
- name: Setup
uses: ./.github/actions/setup

- name: Build package
run: yarn prepare

- name: Cache turborepo for Android
uses: actions/cache@v3
with:
Expand Down Expand Up @@ -106,6 +109,9 @@ jobs:
- name: Setup
uses: ./.github/actions/setup

- name: Build package
run: yarn prepare

- name: Cache turborepo for Android new arch
uses: actions/cache@v3
with:
Expand Down Expand Up @@ -162,6 +168,9 @@ jobs:
- name: Setup
uses: ./.github/actions/setup

- name: Build package
run: yarn prepare

- name: Cache turborepo for iOS
uses: actions/cache@v3
with:
Expand Down Expand Up @@ -202,6 +211,9 @@ jobs:
- name: Setup
uses: ./.github/actions/setup

- name: Build package
run: yarn prepare

- name: Cache turborepo for iOS
uses: actions/cache@v3
with:
Expand Down Expand Up @@ -230,3 +242,97 @@ jobs:
- name: Build example for iOS
run: |
yarn turbo run build:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}"

build-ios-expo:
runs-on: macos-15
env:
TURBO_CACHE_DIR: .turbo/expo-ios
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup

- name: Build package
run: yarn prepare

- name: Cache turborepo for iOS
uses: actions/cache@v3
with:
path: ${{ env.TURBO_CACHE_DIR }}
key: ${{ runner.os }}-turborepo-expo-ios-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-turborepo-expo-ios-

- name: Check turborepo cache for iOS
run: |
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run build:ios-expo --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'build:ios-expo').cache.status")

if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then
echo "turbo_cache_hit=1" >> $GITHUB_ENV
fi

- name: Build example for iOS
run: |
yarn turbo run build:ios-expo --cache-dir="${{ env.TURBO_CACHE_DIR }}"


build-android-expo:
runs-on: ubuntu-latest
env:
TURBO_CACHE_DIR: .turbo/android
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup
uses: ./.github/actions/setup

- name: Build package
run: yarn prepare

- name: Cache turborepo for Android
uses: actions/cache@v3
with:
path: ${{ env.TURBO_CACHE_DIR }}
key: ${{ runner.os }}-turborepo-expo-android-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-turborepo-expo-android-

- name: Check turborepo cache for Android
run: |
TURBO_CACHE_STATUS=$(node -p "($(yarn turbo run build:android-expo --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'build:android-expo').cache.status")

if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then
echo "turbo_cache_hit=1" >> $GITHUB_ENV
fi

- name: Install JDK
if: env.turbo_cache_hit != 1
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'

- name: Finalize Android SDK
if: env.turbo_cache_hit != 1
run: |
/bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null"

- name: Cache Gradle
if: env.turbo_cache_hit != 1
uses: actions/cache@v3
with:
path: |
~/.gradle/wrapper
~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('apps/example/android/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Build example for Android
env:
JAVA_OPTS: "-XX:MaxHeapSize=6g"
run: |
yarn turbo run build:android-expo --cache-dir="${{ env.TURBO_CACHE_DIR }}"
1 change: 0 additions & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
nodeLinker: node-modules
nmHoistingLimits: workspaces

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
Expand Down
40 changes: 40 additions & 0 deletions apps/example-expo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts
android
ios

# Native
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

app-example
53 changes: 53 additions & 0 deletions apps/example-expo/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"expo": {
"name": "bottom-tabs",
"slug": "bottom-tabs",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "myapp",
"userInterfaceStyle": "automatic",
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.anonymous.bottomtabs"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.anonymous.bottomtabs"
},
"web": {
"bundler": "metro",
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"plugins": [
"expo-router",
"react-native-bottom-tabs",
[
"expo-splash-screen",
{
"image": "./assets/images/splash-icon.png",
"imageWidth": 200,
"resizeMode": "contain",
"backgroundColor": "#ffffff"
}
],
[
"expo-build-properties",
{
"ios": {
"deploymentTarget": "14.0",
"useFrameworks": "static"
}
}
],
"expo-font"
],
"experiments": {
"typedRoutes": true
}
}
}
29 changes: 29 additions & 0 deletions apps/example-expo/app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

import { withLayoutContext } from 'expo-router';
import createNativeBottomTabNavigator from '../../../../packages/react-native-bottom-tabs/src/react-navigation/navigators/createNativeBottomTabNavigator';

const Tabs = withLayoutContext(createNativeBottomTabNavigator().Navigator);

function TabLayout() {
return (
<Tabs>
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarIcon: () => ({ sfSymbol: 'house.fill' }),
}}
/>
<Tabs.Screen
name="explore"
options={{
title: 'Explore',
tabBarIcon: () => ({ sfSymbol: 'house.fill' }),
}}
/>
</Tabs>
);
}

export default TabLayout;
96 changes: 96 additions & 0 deletions apps/example-expo/app/(tabs)/explore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { StyleSheet, Image } from 'react-native';

import { Collapsible } from '@/components/Collapsible';
import { ExternalLink } from '@/components/ExternalLink';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
import { ScrollView } from 'react-native-gesture-handler';

function TabTwoScreen() {
return (
<ScrollView>
<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>
</ScrollView>
);
}

const styles = StyleSheet.create({
headerImage: {
color: '#808080',
bottom: -90,
left: -35,
position: 'absolute',
},
titleContainer: {
flexDirection: 'row',
gap: 8,
},
});

export default TabTwoScreen;
Loading