0
# Tab Bar Component
1
2
The TabBar component is the default tab bar implementation that provides scrollable tabs with an animated indicator. It handles tab press events, supports customization of colors and styling, and provides accessibility features.
3
4
## Capabilities
5
6
### TabBar Component
7
8
Default tab bar component with scrollable tabs, animated indicator, and comprehensive customization options.
9
10
```typescript { .api }
11
/**
12
* Default TabBar component for rendering tab navigation
13
* @param props - TabBar configuration and styling options
14
* @returns JSX element containing the tab bar interface
15
*/
16
function TabBar<T extends Route>(props: Props<T>): JSX.Element;
17
18
interface Props<T extends Route> extends SceneRendererProps {
19
/** Required navigation state */
20
navigationState: NavigationState<T>;
21
/** Enable horizontal scrolling when tabs exceed container width */
22
scrollEnabled?: boolean;
23
/** Enable bouncing effect on scroll (iOS) */
24
bounces?: boolean;
25
/** Active tab text color */
26
activeColor?: string;
27
/** Inactive tab text color */
28
inactiveColor?: string;
29
/** Tab press ripple color (Android) */
30
pressColor?: string;
31
/** Tab press opacity effect */
32
pressOpacity?: number;
33
/** Per-route tab configuration options */
34
options?: Record<string, TabDescriptor<T>>;
35
/** Custom indicator renderer */
36
renderIndicator?: (props: IndicatorProps<T>) => React.ReactNode;
37
/** Custom tab item renderer */
38
renderTabBarItem?: (props: TabBarItemProps<T> & { key: string }) => React.ReactElement;
39
/** Tab press event handler */
40
onTabPress?: (scene: Scene<T> & Event) => void;
41
/** Tab long press event handler */
42
onTabLongPress?: (scene: Scene<T>) => void;
43
/** Individual tab styling */
44
tabStyle?: StyleProp<ViewStyle>;
45
/** Indicator styling */
46
indicatorStyle?: StyleProp<ViewStyle>;
47
/** Indicator container styling */
48
indicatorContainerStyle?: StyleProp<ViewStyle>;
49
/** Content container styling */
50
contentContainerStyle?: StyleProp<ViewStyle>;
51
/** Tab bar container styling */
52
style?: StyleProp<ViewStyle>;
53
/** Text direction - 'ltr' or 'rtl' */
54
direction?: LocaleDirection;
55
/** Space between tabs in pixels */
56
gap?: number;
57
/** Test identifier */
58
testID?: string;
59
/** Android ripple configuration */
60
android_ripple?: PressableAndroidRippleConfig;
61
}
62
```
63
64
**Usage Examples:**
65
66
```typescript
67
import React, { useState } from 'react';
68
import { TabView, TabBar, NavigationState, Route } from 'react-native-tab-view';
69
70
// Basic custom TabBar
71
const BasicTabBarExample = () => {
72
const [index, setIndex] = useState(0);
73
const [routes] = useState([
74
{ key: 'home', title: 'Home' },
75
{ key: 'profile', title: 'Profile' },
76
]);
77
78
const renderTabBar = (props) => (
79
<TabBar
80
{...props}
81
activeColor="#ffffff"
82
inactiveColor="#cccccc"
83
style={{ backgroundColor: '#2196f3' }}
84
indicatorStyle={{ backgroundColor: '#ffeb3b' }}
85
/>
86
);
87
88
return (
89
<TabView
90
navigationState={{ index, routes }}
91
renderScene={renderScene}
92
renderTabBar={renderTabBar}
93
onIndexChange={setIndex}
94
/>
95
);
96
};
97
98
// Advanced TabBar with custom styling and events
99
const AdvancedTabBarExample = () => {
100
const [index, setIndex] = useState(0);
101
const [routes] = useState([
102
{ key: 'feed', title: 'Feed' },
103
{ key: 'search', title: 'Search' },
104
{ key: 'notifications', title: 'Notifications' },
105
{ key: 'profile', title: 'Profile' },
106
]);
107
108
const handleTabPress = (scene) => {
109
console.log('Tab pressed:', scene.route.key);
110
// Can prevent default navigation by calling scene.preventDefault()
111
};
112
113
const renderTabBar = (props) => (
114
<TabBar
115
{...props}
116
scrollEnabled
117
activeColor="#1976d2"
118
inactiveColor="#757575"
119
pressColor="#e3f2fd"
120
pressOpacity={0.8}
121
onTabPress={handleTabPress}
122
gap={16}
123
style={{
124
backgroundColor: '#ffffff',
125
elevation: 4,
126
shadowOpacity: 0.1,
127
}}
128
tabStyle={{
129
minWidth: 120,
130
}}
131
indicatorStyle={{
132
backgroundColor: '#2196f3',
133
height: 3,
134
}}
135
contentContainerStyle={{
136
paddingHorizontal: 16,
137
}}
138
/>
139
);
140
141
return (
142
<TabView
143
navigationState={{ index, routes }}
144
renderScene={renderScene}
145
renderTabBar={renderTabBar}
146
onIndexChange={setIndex}
147
/>
148
);
149
};
150
```
151
152
### Tab Bar Indicator
153
154
The TabBar includes an animated indicator that shows the active tab position.
155
156
```typescript { .api }
157
/**
158
* Props for the TabBarIndicator component
159
*/
160
interface IndicatorProps<T extends Route> extends SceneRendererProps {
161
/** Navigation state */
162
navigationState: NavigationState<T>;
163
/** Indicator width configuration */
164
width: 'auto' | `${number}%` | number;
165
/** Function to get tab width by index */
166
getTabWidth: (index: number) => number;
167
/** Text direction */
168
direction: LocaleDirection;
169
/** Indicator styling */
170
style?: StyleProp<ViewStyle>;
171
/** Space between tabs */
172
gap?: number;
173
/** Child components */
174
children?: React.ReactNode;
175
}
176
```
177
178
### Tab Bar Items
179
180
Individual tab rendering with support for labels, icons, and badges.
181
182
```typescript { .api }
183
/**
184
* Props for individual TabBarItem components
185
*/
186
interface TabBarItemProps<T extends Route> extends TabDescriptor<T> {
187
/** Animated position value */
188
position: Animated.AnimatedInterpolation<number>;
189
/** Route object */
190
route: T;
191
/** Navigation state */
192
navigationState: NavigationState<T>;
193
/** Active tab color */
194
activeColor?: string;
195
/** Inactive tab color */
196
inactiveColor?: string;
197
/** Press ripple color */
198
pressColor?: string;
199
/** Press opacity effect */
200
pressOpacity?: number;
201
/** Layout event handler */
202
onLayout?: (event: LayoutChangeEvent) => void;
203
/** Press event handler */
204
onPress: () => void;
205
/** Long press event handler */
206
onLongPress: () => void;
207
/** Default tab width */
208
defaultTabWidth?: number;
209
/** Tab styling */
210
style: StyleProp<ViewStyle>;
211
/** Android ripple configuration */
212
android_ripple?: PressableAndroidRippleConfig;
213
}
214
```
215
216
### Customization Options
217
218
TabBar supports extensive customization through styling and render functions.
219
220
```typescript { .api }
221
/**
222
* TabDescriptor interface for tab configuration
223
*/
224
interface TabDescriptor<T extends Route> {
225
/** Override accessibility label */
226
accessibilityLabel?: string;
227
/** Override accessibility enabled flag */
228
accessible?: boolean;
229
/** Test identifier */
230
testID?: string;
231
/** Override tab label text */
232
labelText?: string;
233
/** Allow font scaling */
234
labelAllowFontScaling?: boolean;
235
/** Web navigation href */
236
href?: string;
237
/** Custom label renderer */
238
label?: (props: {
239
route: T;
240
labelText?: string;
241
focused: boolean;
242
color: string;
243
allowFontScaling?: boolean;
244
style?: StyleProp<TextStyle>;
245
}) => React.ReactNode;
246
/** Label text styling */
247
labelStyle?: StyleProp<TextStyle>;
248
/** Custom icon renderer */
249
icon?: (props: {
250
route: T;
251
focused: boolean;
252
color: string;
253
size: number;
254
}) => React.ReactNode;
255
/** Custom badge renderer */
256
badge?: (props: { route: T }) => React.ReactElement;
257
/** Scene container styling */
258
sceneStyle?: StyleProp<ViewStyle>;
259
}
260
```
261
262
**Custom Rendering Examples:**
263
264
```typescript
265
// Custom tab with icon and badge
266
const renderTabBar = (props) => (
267
<TabBar
268
{...props}
269
renderTabBarItem={({ route, ...itemProps }) => (
270
<TabBarItem
271
{...itemProps}
272
route={route}
273
icon={({ focused, color }) => (
274
<Icon
275
name={getIconName(route.key)}
276
color={color}
277
size={24}
278
/>
279
)}
280
badge={({ route }) =>
281
getBadgeCount(route.key) > 0 ? (
282
<Badge count={getBadgeCount(route.key)} />
283
) : null
284
}
285
/>
286
)}
287
/>
288
);
289
290
// Custom indicator
291
const renderTabBar = (props) => (
292
<TabBar
293
{...props}
294
renderIndicator={(indicatorProps) => (
295
<TabBarIndicator
296
{...indicatorProps}
297
style={{ backgroundColor: 'red', height: 4 }}
298
/>
299
)}
300
/>
301
);
302
```
303
304
### Event Handling
305
306
Handle tab interactions with custom logic and event prevention.
307
308
```typescript { .api }
309
/**
310
* Event object for tab press interactions
311
*/
312
interface Event {
313
/** Whether default navigation has been prevented */
314
defaultPrevented: boolean;
315
/** Function to prevent default navigation */
316
preventDefault(): void;
317
}
318
319
/**
320
* Scene context for event handlers
321
*/
322
interface Scene<T extends Route> {
323
/** The route being interacted with */
324
route: T;
325
}
326
```
327
328
**Event Handling Examples:**
329
330
```typescript
331
const handleTabPress = (scene: Scene<Route> & Event) => {
332
// Custom logic before navigation
333
if (scene.route.key === 'protected' && !isAuthenticated) {
334
scene.preventDefault();
335
showLoginModal();
336
return;
337
}
338
339
// Allow default navigation
340
console.log('Navigating to:', scene.route.key);
341
};
342
343
const renderTabBar = (props) => (
344
<TabBar
345
{...props}
346
onTabPress={handleTabPress}
347
onTabLongPress={(scene) => {
348
showTabContextMenu(scene.route);
349
}}
350
/>
351
);
352
```
353
354
### Accessibility
355
356
TabBar provides comprehensive accessibility support.
357
358
```typescript { .api }
359
/**
360
* Accessibility configuration through TabDescriptor
361
*/
362
interface AccessibilityProps {
363
/** Whether the tab is accessible */
364
accessible?: boolean;
365
/** Accessibility label for screen readers */
366
accessibilityLabel?: string;
367
/** Test identifier for automated testing */
368
testID?: string;
369
/** Allow font scaling for better accessibility */
370
labelAllowFontScaling?: boolean;
371
}
372
```
373
374
### Styling and Layout
375
376
Control TabBar appearance through comprehensive styling options.
377
378
```typescript { .api }
379
/**
380
* Layout and styling interfaces
381
*/
382
interface StyleProps {
383
/** Main tab bar container style */
384
style?: StyleProp<ViewStyle>;
385
/** Individual tab styling */
386
tabStyle?: StyleProp<ViewStyle>;
387
/** Content container styling */
388
contentContainerStyle?: StyleProp<ViewStyle>;
389
/** Indicator styling */
390
indicatorStyle?: StyleProp<ViewStyle>;
391
/** Indicator container styling */
392
indicatorContainerStyle?: StyleProp<ViewStyle>;
393
}
394
395
/**
396
* Android-specific ripple configuration
397
*/
398
interface PressableAndroidRippleConfig {
399
/** Ripple color */
400
color?: string;
401
/** Whether ripple extends beyond bounds */
402
borderless?: boolean;
403
/** Ripple radius */
404
radius?: number;
405
}
406
```