TabBar
The TabBar provides primary navigation between main sections of the app. It uses a minimal design with gold accent indicators and haptic feedback.
Preview
Section titled “Preview”Anatomy
Section titled “Anatomy”| Element | Active | Inactive |
|---|---|---|
| Indicator | 4x4px gold dot | Hidden |
| Label | Gold, medium weight | Gray, regular weight |
| Touch | Full tab area responds | Full tab area responds |
Tab States
Section titled “Tab States”Inactive
Section titled “Inactive”BROWSE
Default state for unselected tabs.
Active
Section titled “Active”CAST
Currently selected tab with gold indicator and label.
Pressed
Section titled “Pressed”LEARN
Visual feedback during touch (70% opacity).
Behavior
Section titled “Behavior”Haptic Feedback
Section titled “Haptic Feedback”The TabBar triggers selection haptics on every tap:
const onPress = () => { haptics.selection(); // Light haptic feedback navigation.navigate(route.name);};Safe Area
Section titled “Safe Area”The TabBar automatically adjusts for device safe areas (notch, home indicator):
const bottomPadding = insets.bottom > 0 ? insets.bottom : theme.spacing.compact;| Device | Bottom Padding |
|---|---|
| iPhone with Face ID | ~34px |
| iPhone with Home Button | 12px (fallback) |
| Android | 12px (fallback) |
Specifications
Section titled “Specifications”| Property | Value |
|---|---|
| Base Height | 64px |
| Label Size | 11px |
| Letter Spacing | 0.5px (wide) |
| Indicator Size | 4x4px |
| Background | Surface @ 95% opacity |
| Border Top | 1px border color |
API Reference
Section titled “API Reference”The TabBar receives standard React Navigation bottom tab props:
| Prop | Type | Description |
|---|---|---|
state | TabNavigationState | Current navigation state |
descriptors | BottomTabDescriptorMap | Tab configuration |
navigation | NavigationProp | Navigation object |
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';import { CustomTabBar } from '@synchronicity/react-native';
const Tab = createBottomTabNavigator();
function Navigation() { return ( <Tab.Navigator tabBar={(props) => <CustomTabBar {...props} />} screenOptions={{ headerShown: false, }} > <Tab.Screen name="Cast" component={CastScreen} /> <Tab.Screen name="Browse" component={BrowseScreen} /> <Tab.Screen name="Learn" component={LearnScreen} /> <Tab.Screen name="History" component={HistoryScreen} /> </Tab.Navigator> );}Design Decisions
Section titled “Design Decisions”Text-Only Labels
Section titled “Text-Only Labels”We use text labels instead of icons for several reasons:
- Clarity: Words are unambiguous
- Accessibility: Better for screen readers
- Contemplative design: Less visual noise
- Brand: Unique, memorable navigation
Minimal Indicator
Section titled “Minimal Indicator”The small gold dot is chosen over:
- Underlines (too heavy)
- Background fills (too prominent)
- Icon changes (we don’t use icons)
The dot is subtle but clearly visible, drawing the eye without demanding it.
Uppercase Labels
Section titled “Uppercase Labels”Uppercase with wide letter spacing creates:
- Visual rhythm
- Clear separation from content
- Intentional, ceremonial feel
Accessibility
Section titled “Accessibility”- Role: Each tab is
accessibilityRole="button" - Label: Clear text description
- State:
accessibilityState={{ selected: isFocused }} - Hint: Navigate to the selected tab
- Touch target: Full tab width, 64px+ height
<TouchableOpacity accessibilityRole="button" accessibilityLabel="Cast" accessibilityState={{ selected: true }} accessibilityHint="Navigate to Cast tab"> ...</TouchableOpacity>Complete Example
Section titled “Complete Example”import { CustomTabBar } from '@synchronicity/react-native';import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
function AppNavigator() { return ( <Tab.Navigator tabBar={(props) => <CustomTabBar {...props} />} screenOptions={{ headerShown: false, tabBarHideOnKeyboard: true, }} > <Tab.Screen name="Cast" component={CastScreen} options={{ title: 'Cast' }} /> <Tab.Screen name="Browse" component={BrowseScreen} options={{ title: 'Browse' }} /> <Tab.Screen name="Learn" component={LearnScreen} options={{ title: 'Learn' }} /> <Tab.Screen name="History" component={HistoryScreen} options={{ title: 'History' }} /> </Tab.Navigator> );}