0
# Interactive Components
1
2
Button and pressable components with navigation integration, platform-specific press effects, theme support, and accessibility features.
3
4
## Capabilities
5
6
### Button
7
8
Themed button component with navigation integration, multiple visual variants, and automatic color calculation.
9
10
```typescript { .api }
11
/**
12
* Themed button component with navigation integration
13
* @param props - Button configuration, content, and navigation options
14
* @returns React element representing a styled button
15
*/
16
// Basic button with onPress handler
17
function Button(props: ButtonBaseProps): React.ReactElement;
18
19
// Navigation button with screen/action routing
20
function Button<ParamList extends ReactNavigation.RootParamList>(
21
props: ButtonLinkProps<ParamList>
22
): React.ReactElement;
23
24
interface ButtonBaseProps {
25
/** Visual style variant */
26
variant?: 'plain' | 'tinted' | 'filled';
27
/** Custom button color (defaults to theme primary) */
28
color?: string;
29
/** Button text content (required) */
30
children: string | string[];
31
/** Callback when button is pressed */
32
onPress?: () => void;
33
/** Whether button is disabled */
34
disabled?: boolean;
35
/** Screen reader accessibility label */
36
accessibilityLabel?: string;
37
/** Test identifier for automated testing */
38
testID?: string;
39
/** Web anchor href for link behavior */
40
href?: string;
41
/** Custom button styling */
42
style?: StyleProp<ViewStyle>;
43
/** Android material ripple color */
44
pressColor?: string;
45
/** Press opacity when ripple not supported */
46
pressOpacity?: number;
47
}
48
49
interface ButtonLinkProps<ParamList extends ReactNavigation.RootParamList> {
50
/** Visual style variant */
51
variant?: 'plain' | 'tinted' | 'filled';
52
/** Custom button color (defaults to theme primary) */
53
color?: string;
54
/** Button text content (required) */
55
children: string | string[];
56
/** Target screen name for navigation */
57
screen: keyof ParamList;
58
/** Parameters to pass to target screen */
59
params?: ParamList[keyof ParamList];
60
/** Navigation action to dispatch */
61
action?: NavigationAction;
62
/** Web anchor href for link behavior */
63
href?: string;
64
/** Whether button is disabled */
65
disabled?: boolean;
66
/** Screen reader accessibility label */
67
accessibilityLabel?: string;
68
/** Test identifier for automated testing */
69
testID?: string;
70
/** Custom button styling */
71
style?: StyleProp<ViewStyle>;
72
/** Android material ripple color */
73
pressColor?: string;
74
/** Press opacity when ripple not supported */
75
pressOpacity?: number;
76
}
77
```
78
79
**Usage Examples:**
80
81
```typescript
82
import { Button } from "@react-navigation/elements";
83
84
// Basic button
85
<Button onPress={() => console.log('Pressed')}>
86
Press me
87
</Button>
88
89
// Styled button variants
90
<Button variant="filled" color="#007AFF">
91
Filled Button
92
</Button>
93
94
<Button variant="tinted" color="#34C759">
95
Tinted Button
96
</Button>
97
98
<Button variant="plain">
99
Plain Button
100
</Button>
101
102
// Navigation button
103
<Button
104
screen="Profile"
105
params={{ userId: 123 }}
106
variant="filled"
107
>
108
Go to Profile
109
</Button>
110
111
// Disabled button
112
<Button
113
onPress={handleSubmit}
114
disabled={!isFormValid}
115
variant="filled"
116
>
117
Submit Form
118
</Button>
119
120
// Custom styled button
121
<Button
122
onPress={handleAction}
123
variant="tinted"
124
style={{ marginTop: 20, paddingHorizontal: 30 }}
125
accessibilityLabel="Perform important action"
126
>
127
Custom Action
128
</Button>
129
```
130
131
### PlatformPressable
132
133
Cross-platform pressable component with platform-specific press effects, hover support for web, and ref forwarding.
134
135
```typescript { .api }
136
/**
137
* Cross-platform pressable component with platform-specific optimizations
138
* @param props - Pressable configuration and content
139
* @returns React element representing a platform-optimized pressable area
140
*/
141
const PlatformPressable: React.ForwardRefExoticComponent<{
142
/** Web anchor href for link behavior */
143
href?: string;
144
/** Android material ripple color (Android >= 5.0) */
145
pressColor?: string;
146
/** Press opacity fallback when ripple not supported */
147
pressOpacity?: number;
148
/** Web hover effect configuration */
149
hoverEffect?: HoverEffectProps;
150
/** Custom pressable styling */
151
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
152
/** Press event callback */
153
onPress?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | GestureResponderEvent) => void;
154
/** Pressable content (required) */
155
children: React.ReactNode;
156
} & Omit<PressableProps, 'style' | 'onPress'>>;
157
158
interface HoverEffectProps {
159
/** Hover background color */
160
color?: string;
161
/** Opacity on hover */
162
hoverOpacity?: number;
163
/** Opacity when active/pressed */
164
activeOpacity?: number;
165
}
166
```
167
168
**Usage Examples:**
169
170
```typescript
171
import { PlatformPressable } from "@react-navigation/elements";
172
173
// Basic pressable
174
<PlatformPressable onPress={() => console.log('Pressed')}>
175
<View style={{ padding: 16 }}>
176
<Text>Tap me</Text>
177
</View>
178
</PlatformPressable>
179
180
// With custom press effects
181
<PlatformPressable
182
onPress={handlePress}
183
pressColor="#e3f2fd"
184
pressOpacity={0.7}
185
>
186
<View style={styles.pressableContent}>
187
<Icon name="star" />
188
<Text>Star this item</Text>
189
</View>
190
</PlatformPressable>
191
192
// Web hover effects
193
<PlatformPressable
194
onPress={handlePress}
195
hoverEffect={{
196
color: '#f0f0f0',
197
hoverOpacity: 0.8,
198
activeOpacity: 0.6
199
}}
200
>
201
<View style={styles.hoverableItem}>
202
<Text>Hover over me (web only)</Text>
203
</View>
204
</PlatformPressable>
205
206
// Link behavior
207
<PlatformPressable
208
href="https://reactnavigation.org"
209
style={styles.linkButton}
210
>
211
<Text style={styles.linkText}>Visit React Navigation</Text>
212
</PlatformPressable>
213
214
// With ref forwarding
215
function MyComponent() {
216
const pressableRef = useRef(null);
217
218
return (
219
<PlatformPressable
220
ref={pressableRef}
221
onPress={() => {
222
// Access pressable methods if needed
223
console.log('Pressed:', pressableRef.current);
224
}}
225
>
226
<Text>Pressable with ref</Text>
227
</PlatformPressable>
228
);
229
}
230
231
// Complex interactive element
232
<PlatformPressable
233
onPress={() => setExpanded(!expanded)}
234
accessibilityRole="button"
235
accessibilityState={{ expanded }}
236
style={[
237
styles.expandableItem,
238
expanded && styles.expandedItem
239
]}
240
>
241
<View style={styles.itemHeader}>
242
<Text style={styles.itemTitle}>Expandable Item</Text>
243
<Icon name={expanded ? "chevron-up" : "chevron-down"} />
244
</View>
245
{expanded && (
246
<View style={styles.itemContent}>
247
<Text>Additional content when expanded</Text>
248
</View>
249
)}
250
</PlatformPressable>
251
```
252
253
## Button Variants
254
255
### Plain Variant
256
- Minimal styling with no background
257
- Uses theme text color
258
- No border or elevation
259
- Best for secondary actions
260
261
### Tinted Variant (Default)
262
- Subtle background color with transparency
263
- Uses theme primary color with opacity
264
- Rounded corners (40px border radius)
265
- Good for primary actions in most contexts
266
267
### Filled Variant
268
- Solid background color
269
- High contrast with white text on colored background
270
- Most prominent visual treatment
271
- Best for primary call-to-action buttons
272
273
## Platform-Specific Behavior
274
275
### iOS
276
- **Haptic Feedback**: Subtle haptic feedback on button press
277
- **Animation**: Smooth scale and opacity transitions
278
- **Typography**: Uses iOS system font weights
279
- **Accessibility**: VoiceOver support with proper button roles
280
281
### Android
282
- **Material Ripple**: Native material ripple effects on press
283
- **Elevation**: Subtle elevation changes on filled buttons
284
- **Typography**: Uses Roboto font family
285
- **Accessibility**: TalkBack support with proper semantics
286
287
### Web
288
- **Hover States**: CSS hover effects for better desktop experience
289
- **Focus Management**: Keyboard focus indicators
290
- **Cursor**: Proper cursor changes (pointer for buttons, text for links)
291
- **Accessibility**: ARIA labels and semantic HTML elements
292
293
## Navigation Integration
294
295
The Button component integrates seamlessly with React Navigation:
296
297
```typescript
298
// Navigate to screen
299
<Button screen="Details" params={{ id: 123 }}>
300
View Details
301
</Button>
302
303
// Navigate with custom action
304
<Button
305
action={NavigationActions.reset({
306
index: 0,
307
routes: [{ name: 'Home' }]
308
})}
309
>
310
Reset to Home
311
</Button>
312
313
// External link
314
<Button href="https://example.com">
315
Open External Link
316
</Button>
317
```
318
319
## Accessibility Features
320
321
Both Button and PlatformPressable include comprehensive accessibility support:
322
323
- **Screen Reader Support**: Proper accessibility labels and roles
324
- **Keyboard Navigation**: Full keyboard interaction support
325
- **Focus Management**: Visible focus indicators
326
- **State Announcements**: Disabled and pressed states announced
327
- **Hit Targets**: Minimum 44px touch targets on mobile
328
- **High Contrast**: Proper color contrast ratios
329
330
```typescript
331
// Accessibility best practices
332
<Button
333
onPress={handleSubmit}
334
disabled={!isValid}
335
accessibilityLabel="Submit registration form"
336
accessibilityHint="Double tap to submit your registration"
337
>
338
Submit
339
</Button>
340
341
<PlatformPressable
342
onPress={toggleFavorite}
343
accessibilityRole="button"
344
accessibilityState={{ selected: isFavorite }}
345
accessibilityLabel={isFavorite ? "Remove from favorites" : "Add to favorites"}
346
>
347
<Icon name={isFavorite ? "heart-filled" : "heart-outline"} />
348
</PlatformPressable>
349
```