0
# Tab Bar Item
1
2
The TabBarItem component represents an individual tab in the tab bar. It handles rendering of labels, icons, badges, and provides touch interaction capabilities with accessibility support. Each tab item automatically adapts its appearance based on the active/inactive state.
3
4
## Capabilities
5
6
### TabBarItem Component
7
8
Individual tab item component with support for labels, icons, badges, and custom rendering.
9
10
```typescript { .api }
11
/**
12
* Individual tab item component for rendering single tabs
13
* @param props - TabBarItem configuration and interaction handlers
14
* @returns JSX element containing the tab item interface
15
*/
16
function TabBarItem<T extends Route>(props: Props<T>): JSX.Element;
17
18
interface Props<T extends Route> extends TabDescriptor<T> {
19
/** Animated position value for state transitions */
20
position: Animated.AnimatedInterpolation<number>;
21
/** Route object associated with this tab */
22
route: T;
23
/** Complete navigation state */
24
navigationState: NavigationState<T>;
25
/** Active tab color override */
26
activeColor?: string;
27
/** Inactive tab color override */
28
inactiveColor?: string;
29
/** Press ripple color (Android) */
30
pressColor?: string;
31
/** Press opacity effect value */
32
pressOpacity?: number;
33
/** Layout measurement event handler */
34
onLayout?: (event: LayoutChangeEvent) => void;
35
/** Required press event handler */
36
onPress: () => void;
37
/** Required long press event handler */
38
onLongPress: () => void;
39
/** Default tab width for layout calculations */
40
defaultTabWidth?: number;
41
/** Tab container styling */
42
style: StyleProp<ViewStyle>;
43
/** Android ripple effect configuration */
44
android_ripple?: PressableAndroidRippleConfig;
45
}
46
```
47
48
**Usage Examples:**
49
50
```typescript
51
import React from 'react';
52
import { TabBar, TabBarItem } from 'react-native-tab-view';
53
import Icon from 'react-native-vector-icons/MaterialIcons';
54
55
// Custom tab item with icon
56
const renderTabBar = (props) => (
57
<TabBar
58
{...props}
59
renderTabBarItem={({ route, ...itemProps }) => (
60
<TabBarItem
61
{...itemProps}
62
route={route}
63
icon={({ focused, color }) => (
64
<Icon
65
name={getIconName(route.key)}
66
size={24}
67
color={color}
68
/>
69
)}
70
activeColor="#1976d2"
71
inactiveColor="#757575"
72
/>
73
)}
74
/>
75
);
76
77
// Tab item with badge
78
const renderTabBarWithBadges = (props) => (
79
<TabBar
80
{...props}
81
renderTabBarItem={({ route, ...itemProps }) => (
82
<TabBarItem
83
{...itemProps}
84
route={route}
85
badge={({ route }) => {
86
const count = getBadgeCount(route.key);
87
return count > 0 ? (
88
<View style={styles.badge}>
89
<Text style={styles.badgeText}>{count}</Text>
90
</View>
91
) : null;
92
}}
93
/>
94
)}
95
/>
96
);
97
98
// Custom label rendering
99
const renderTabBarWithCustomLabels = (props) => (
100
<TabBar
101
{...props}
102
renderTabBarItem={({ route, ...itemProps }) => (
103
<TabBarItem
104
{...itemProps}
105
route={route}
106
label={({ focused, color, labelText }) => (
107
<Text
108
style={[
109
{ color, fontSize: 12 },
110
focused && { fontWeight: 'bold', fontSize: 14 }
111
]}
112
>
113
{labelText?.toUpperCase()}
114
</Text>
115
)}
116
/>
117
)}
118
/>
119
);
120
```
121
122
### Tab Item Configuration
123
124
Configure tab appearance and behavior through TabDescriptor interface.
125
126
```typescript { .api }
127
/**
128
* Configuration interface for tab appearance and behavior
129
*/
130
interface TabDescriptor<T extends Route> {
131
/** Override accessibility label */
132
accessibilityLabel?: string;
133
/** Override accessibility enabled flag */
134
accessible?: boolean;
135
/** Test identifier for automation */
136
testID?: string;
137
/** Override tab label text */
138
labelText?: string;
139
/** Allow font scaling for accessibility */
140
labelAllowFontScaling?: boolean;
141
/** Web navigation href */
142
href?: string;
143
/** Custom label renderer function */
144
label?: (props: LabelProps<T>) => React.ReactNode;
145
/** Label text styling */
146
labelStyle?: StyleProp<TextStyle>;
147
/** Custom icon renderer function */
148
icon?: (props: IconProps<T>) => React.ReactNode;
149
/** Custom badge renderer function */
150
badge?: (props: BadgeProps<T>) => React.ReactElement;
151
/** Scene container styling */
152
sceneStyle?: StyleProp<ViewStyle>;
153
}
154
155
/**
156
* Props for custom label renderers
157
*/
158
interface LabelProps<T extends Route> {
159
route: T;
160
labelText?: string;
161
focused: boolean;
162
color: string;
163
allowFontScaling?: boolean;
164
style?: StyleProp<TextStyle>;
165
}
166
167
/**
168
* Props for custom icon renderers
169
*/
170
interface IconProps<T extends Route> {
171
route: T;
172
focused: boolean;
173
color: string;
174
size: number;
175
}
176
177
/**
178
* Props for custom badge renderers
179
*/
180
interface BadgeProps<T extends Route> {
181
route: T;
182
}
183
```
184
185
### Animation and State Management
186
187
Tab items automatically animate between active and inactive states.
188
189
```typescript { .api }
190
/**
191
* Animation configuration for tab state transitions
192
*/
193
interface TabAnimationConfig {
194
/** Default active color */
195
DEFAULT_ACTIVE_COLOR: 'rgba(255, 255, 255, 1)';
196
/** Default inactive color */
197
DEFAULT_INACTIVE_COLOR: 'rgba(255, 255, 255, 0.7)';
198
/** Default icon size */
199
ICON_SIZE: 24;
200
}
201
202
/**
203
* Opacity calculation functions for smooth transitions
204
*/
205
interface OpacityCalculations {
206
/** Calculate active state opacity */
207
getActiveOpacity: (
208
position: Animated.AnimatedInterpolation<number>,
209
routesLength: number,
210
tabIndex: number
211
) => Animated.AnimatedInterpolation<number> | number;
212
/** Calculate inactive state opacity */
213
getInactiveOpacity: (
214
position: Animated.AnimatedInterpolation<number>,
215
routesLength: number,
216
tabIndex: number
217
) => Animated.AnimatedInterpolation<number> | number;
218
}
219
```
220
221
**Animation Examples:**
222
223
```typescript
224
// Custom animated tab item
225
const AnimatedTabItem = ({ route, focused, position, ...props }) => {
226
const scale = position.interpolate({
227
inputRange: [route.index - 1, route.index, route.index + 1],
228
outputRange: [0.9, 1.1, 0.9],
229
extrapolate: 'clamp',
230
});
231
232
return (
233
<Animated.View style={{ transform: [{ scale }] }}>
234
<TabBarItem {...props} route={route} />
235
</Animated.View>
236
);
237
};
238
```
239
240
### Platform-Specific Features
241
242
TabBarItem handles platform differences automatically.
243
244
```typescript { .api }
245
/**
246
* Android-specific ripple configuration
247
*/
248
interface PressableAndroidRippleConfig {
249
/** Ripple effect color */
250
color?: string;
251
/** Whether ripple extends beyond component bounds */
252
borderless?: boolean;
253
/** Ripple radius */
254
radius?: number;
255
}
256
257
/**
258
* Default Android ripple configuration
259
*/
260
const ANDROID_RIPPLE_DEFAULT: PressableAndroidRippleConfig = {
261
borderless: true
262
};
263
```
264
265
**Platform Examples:**
266
267
```typescript
268
// Platform-specific styling
269
const renderPlatformTabBar = (props) => (
270
<TabBar
271
{...props}
272
renderTabBarItem={({ route, ...itemProps }) => (
273
<TabBarItem
274
{...itemProps}
275
route={route}
276
android_ripple={{
277
color: '#e3f2fd',
278
borderless: true,
279
radius: 32,
280
}}
281
style={Platform.select({
282
ios: { borderRadius: 10 }, // iPad hover effect
283
android: { backgroundColor: 'transparent' },
284
default: { backgroundColor: 'transparent' },
285
})}
286
/>
287
)}
288
/>
289
);
290
```
291
292
### Accessibility Support
293
294
TabBarItem provides comprehensive accessibility features.
295
296
```typescript { .api }
297
/**
298
* Accessibility configuration
299
*/
300
interface AccessibilityConfig {
301
/** ARIA role for web accessibility */
302
role: 'tab';
303
/** ARIA label attribute */
304
'aria-label': string;
305
/** ARIA selected state */
306
'aria-selected': boolean;
307
/** React Native accessibility properties */
308
accessible: boolean;
309
accessibilityLabel: string;
310
}
311
```
312
313
**Accessibility Examples:**
314
315
```typescript
316
// Enhanced accessibility
317
const renderAccessibleTabBar = (props) => (
318
<TabBar
319
{...props}
320
renderTabBarItem={({ route, ...itemProps }) => (
321
<TabBarItem
322
{...itemProps}
323
route={route}
324
accessible={true}
325
accessibilityLabel={`${route.title} tab`}
326
accessibilityHint={`Navigate to ${route.title} screen`}
327
testID={`tab-${route.key}`}
328
/>
329
)}
330
/>
331
);
332
```
333
334
### Styling and Layout
335
336
Complete control over tab item appearance and layout.
337
338
```typescript { .api }
339
/**
340
* Default tab item styles
341
*/
342
interface DefaultTabStyles {
343
/** Icon container styling */
344
icon: {
345
margin: 2;
346
};
347
/** Main item container */
348
item: {
349
flex: 1;
350
alignItems: 'center';
351
justifyContent: 'center';
352
padding: 10;
353
minHeight: 48;
354
};
355
/** Badge positioning */
356
badge: {
357
position: 'absolute';
358
top: 0;
359
end: 0;
360
};
361
/** Pressable container */
362
pressable: {
363
backgroundColor: 'transparent';
364
};
365
}
366
```
367
368
**Advanced Styling Examples:**
369
370
```typescript
371
// Custom tab item styling
372
const renderStyledTabBar = (props) => (
373
<TabBar
374
{...props}
375
renderTabBarItem={({ route, focused, ...itemProps }) => (
376
<TabBarItem
377
{...itemProps}
378
route={route}
379
style={[
380
styles.tabItem,
381
focused && styles.tabItemFocused,
382
{ minWidth: 100 }
383
]}
384
labelStyle={[
385
styles.tabLabel,
386
focused && styles.tabLabelFocused,
387
]}
388
pressOpacity={0.7}
389
/>
390
)}
391
/>
392
);
393
394
const styles = StyleSheet.create({
395
tabItem: {
396
borderRadius: 8,
397
marginHorizontal: 4,
398
paddingVertical: 8,
399
},
400
tabItemFocused: {
401
backgroundColor: 'rgba(33, 150, 243, 0.1)',
402
},
403
tabLabel: {
404
fontSize: 12,
405
fontWeight: '500',
406
},
407
tabLabelFocused: {
408
fontSize: 14,
409
fontWeight: '700',
410
},
411
});
412
```
413
414
### Event Handling
415
416
Handle user interactions with custom logic.
417
418
```typescript { .api }
419
/**
420
* Event handler types
421
*/
422
interface EventHandlers {
423
/** Press event handler */
424
onPress: () => void;
425
/** Long press event handler */
426
onLongPress: () => void;
427
/** Layout measurement handler */
428
onLayout?: (event: LayoutChangeEvent) => void;
429
}
430
431
/**
432
* Layout change event structure
433
*/
434
interface LayoutChangeEvent {
435
nativeEvent: {
436
layout: {
437
x: number;
438
y: number;
439
width: number;
440
height: number;
441
};
442
};
443
}
444
```
445
446
**Event Handling Examples:**
447
448
```typescript
449
// Custom event handling
450
const renderInteractiveTabBar = (props) => (
451
<TabBar
452
{...props}
453
renderTabBarItem={({ route, onPress, onLongPress, ...itemProps }) => (
454
<TabBarItem
455
{...itemProps}
456
route={route}
457
onPress={() => {
458
console.log('Tab pressed:', route.key);
459
onPress();
460
}}
461
onLongPress={() => {
462
console.log('Tab long pressed:', route.key);
463
showTabContextMenu(route);
464
onLongPress();
465
}}
466
onLayout={(event) => {
467
const { width, height } = event.nativeEvent.layout;
468
console.log(`Tab ${route.key} size:`, { width, height });
469
}}
470
/>
471
)}
472
/>
473
);
474
```