116 lines
3 KiB
TypeScript
116 lines
3 KiB
TypeScript
import {
|
|
Tabs,
|
|
TabList,
|
|
TabTrigger,
|
|
TabSlot,
|
|
TabTriggerSlotProps,
|
|
TabListProps,
|
|
} from 'expo-router/ui';
|
|
import { SymbolView } from 'expo-symbols';
|
|
import React from 'react';
|
|
import { Pressable, useColorScheme, View, StyleSheet } from 'react-native';
|
|
|
|
import { ExternalLink } from './external-link';
|
|
import { ThemedText } from './themed-text';
|
|
import { ThemedView } from './themed-view';
|
|
|
|
import { Colors, MaxContentWidth, Spacing } from '@/constants/theme';
|
|
|
|
export default function AppTabs() {
|
|
return (
|
|
<Tabs>
|
|
<TabSlot style={{ height: '100%' }} />
|
|
<TabList asChild>
|
|
<CustomTabList>
|
|
<TabTrigger name="home" href="/" asChild>
|
|
<TabButton>Home</TabButton>
|
|
</TabTrigger>
|
|
<TabTrigger name="explore" href="/explore" asChild>
|
|
<TabButton>Explore</TabButton>
|
|
</TabTrigger>
|
|
</CustomTabList>
|
|
</TabList>
|
|
</Tabs>
|
|
);
|
|
}
|
|
|
|
export function TabButton({ children, isFocused, ...props }: TabTriggerSlotProps) {
|
|
return (
|
|
<Pressable {...props} style={({ pressed }) => pressed && styles.pressed}>
|
|
<ThemedView
|
|
type={isFocused ? 'backgroundSelected' : 'backgroundElement'}
|
|
style={styles.tabButtonView}>
|
|
<ThemedText type="small" themeColor={isFocused ? 'text' : 'textSecondary'}>
|
|
{children}
|
|
</ThemedText>
|
|
</ThemedView>
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
export function CustomTabList(props: TabListProps) {
|
|
const scheme = useColorScheme();
|
|
const colors = Colors[scheme === 'unspecified' ? 'light' : scheme];
|
|
|
|
return (
|
|
<View {...props} style={styles.tabListContainer}>
|
|
<ThemedView type="backgroundElement" style={styles.innerContainer}>
|
|
<ThemedText type="smallBold" style={styles.brandText}>
|
|
Expo Starter
|
|
</ThemedText>
|
|
|
|
{props.children}
|
|
|
|
<ExternalLink href="https://docs.expo.dev" asChild>
|
|
<Pressable style={styles.externalPressable}>
|
|
<ThemedText type="link">Docs</ThemedText>
|
|
<SymbolView
|
|
tintColor={colors.text}
|
|
name={{ ios: 'arrow.up.right.square', web: 'link' }}
|
|
size={12}
|
|
/>
|
|
</Pressable>
|
|
</ExternalLink>
|
|
</ThemedView>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
tabListContainer: {
|
|
position: 'absolute',
|
|
width: '100%',
|
|
padding: Spacing.three,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
flexDirection: 'row',
|
|
},
|
|
innerContainer: {
|
|
paddingVertical: Spacing.two,
|
|
paddingHorizontal: Spacing.five,
|
|
borderRadius: Spacing.five,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
flexGrow: 1,
|
|
gap: Spacing.two,
|
|
maxWidth: MaxContentWidth,
|
|
},
|
|
brandText: {
|
|
marginRight: 'auto',
|
|
},
|
|
pressed: {
|
|
opacity: 0.7,
|
|
},
|
|
tabButtonView: {
|
|
paddingVertical: Spacing.one,
|
|
paddingHorizontal: Spacing.three,
|
|
borderRadius: Spacing.three,
|
|
},
|
|
externalPressable: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
gap: Spacing.one,
|
|
marginLeft: Spacing.three,
|
|
},
|
|
});
|