or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

header-components.mdhooks-contexts.mdindex.mdinteractive-components.mdlayout-components.mdutility-components.mdutility-functions.md

interactive-components.mddocs/

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

```