native bottom tab

This commit is contained in:
EthanShoeDev
2025-09-15 00:42:49 -04:00
parent 2078b022ea
commit 89cb6c4b6b
5 changed files with 50 additions and 11 deletions

View File

@@ -1,11 +1,24 @@
import { QueryClientProvider } from '@tanstack/react-query';
import { Stack } from 'expo-router';
import { NativeTabs, Icon, Label } from 'expo-router/unstable-native-tabs';
import { queryClient } from '../lib/utils';
export default function RootLayout() {
return (
<QueryClientProvider client={queryClient}>
<Stack screenOptions={{ headerShown: false }} />
<NativeTabs>
<NativeTabs.Trigger name="index">
<Label>Host</Label>
<Icon sf="house.fill" drawable="custom_android_drawable" />
</NativeTabs.Trigger>
<NativeTabs.Trigger name="shell">
<Icon sf="gear" drawable="custom_settings_drawable" />
<Label>Shell</Label>
</NativeTabs.Trigger>
<NativeTabs.Trigger name="settings">
<Icon sf="gear" drawable="custom_settings_drawable" />
<Label>Settings</Label>
</NativeTabs.Trigger>
</NativeTabs>
</QueryClientProvider>
);
}

View File

@@ -5,6 +5,7 @@ import { useMutation, useQuery } from '@tanstack/react-query';
import { useRouter } from 'expo-router';
import React from 'react';
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { AbortSignalTimeout } from '@/lib/utils';
import { useAppForm, useFieldContext } from '../components/form-components';
import { KeyManagerModal } from '../components/key-manager-modal';
@@ -104,7 +105,7 @@ export default function Index() {
);
return (
<View style={styles.container}>
<SafeAreaView style={styles.container}>
<ScrollView
contentContainerStyle={styles.scrollContent}
keyboardShouldPersistTaps="handled"
@@ -218,7 +219,7 @@ export default function Index() {
}}
/>
</ScrollView>
</View>
</SafeAreaView>
);
}

View File

@@ -0,0 +1,17 @@
import { View, Text, StyleSheet } from 'react-native';
export default function Tab() {
return (
<View style={styles.container}>
<Text>Tab [Home|Settings]</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});

View File

@@ -5,9 +5,9 @@ export const queryClient = new QueryClient();
export type StrictOmit<T, K extends keyof T> = Omit<T, K>;
export const AbortSignalTimeout = (timeout: number) => {
// AbortSignal.timeout is not available as of expo 54
// TypeError: AbortSignal.timeout is not a function (it is undefined)
const controller = new AbortController();
setTimeout(() => controller.abort(), timeout);
return controller.signal;
}
// AbortSignal.timeout is not available as of expo 54
// TypeError: AbortSignal.timeout is not a function (it is undefined)
const controller = new AbortController();
setTimeout(() => controller.abort(), timeout);
return controller.signal;
};

View File

@@ -8,6 +8,14 @@
### Future reading
#### Misc
https://www.youtube.com/watch?v=iYh-7WfJTR0 - Expo 54 highlights
#### App icon generator
https://github.com/betomoedano/snapai
#### AI Libraries
- https://github.com/software-mansion/react-native-executorch
@@ -36,7 +44,7 @@
- https://code.visualstudio.com/docs/terminal/shell-integration
- https://github.com/termux/termux-app/wiki/Termux-Libraries/bd010af15b8434ba136c32fa70a50c504ea04363
Uniffi is broken on RN 0.80
#### Uniffi is broken on RN 0.80
- https://github.com/jhugman/uniffi-bindgen-react-native/issues/295
- https://github.com/realm/realm-js/issues/7011#issuecomment-3149613234