or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-functions.mdexperimental-features.mdheader-components.mdindex.mdnavigation-utilities.mdscreen-components.mdtypes-interfaces.md

navigation-utilities.mddocs/

0

# Navigation Utilities

1

2

Utility functions, hooks, and configuration objects that provide additional navigation behavior and integration capabilities. These utilities enhance the core screen functionality with platform-specific features and performance optimizations.

3

4

## Core Imports

5

6

```typescript

7

import {

8

executeNativeBackPress,

9

isSearchBarAvailableForCurrentPlatform,

10

useTransitionProgress,

11

ScreenContext,

12

compatibilityFlags,

13

featureFlags

14

} from "react-native-screens";

15

```

16

17

## Capabilities

18

19

### Native Back Press

20

21

Executes the native back press behavior on Android, which typically exits the application or navigates to the previous activity.

22

23

```typescript { .api }

24

/**

25

* Executes native back press behavior, exits the app on Android

26

* @returns Always returns true to indicate the event was handled

27

*/

28

function executeNativeBackPress(): boolean;

29

```

30

31

**Usage Example:**

32

33

```typescript

34

import { executeNativeBackPress } from "react-native-screens";

35

import { BackHandler, Platform } from "react-native";

36

37

// Custom back handler that can exit the app

38

function handleBackPress() {

39

// Perform custom logic

40

if (canExit) {

41

if (Platform.OS === 'android') {

42

return executeNativeBackPress();

43

}

44

}

45

return false; // Let default behavior handle it

46

}

47

48

// Register back handler

49

BackHandler.addEventListener('hardwareBackPress', handleBackPress);

50

```

51

52

**Platform Behavior:**

53

- **Android**: Exits the application or navigates to previous activity

54

- **iOS**: No effect (iOS doesn't have a hardware back button)

55

- **Return Value**: Always returns `true` to indicate the event was handled

56

57

### Search Bar Availability

58

59

Boolean constant indicating whether the SearchBar component is available on the current platform.

60

61

```typescript { .api }

62

/**

63

* Boolean indicating if SearchBar is available on the current platform

64

*/

65

const isSearchBarAvailableForCurrentPlatform: boolean;

66

```

67

68

**Usage Example:**

69

70

```typescript

71

import {

72

isSearchBarAvailableForCurrentPlatform,

73

SearchBar

74

} from "react-native-screens";

75

76

function ConditionalSearchScreen() {

77

return (

78

<View>

79

{isSearchBarAvailableForCurrentPlatform ? (

80

<SearchBar placeholder="Search..." />

81

) : (

82

<TextInput placeholder="Search..." />

83

)}

84

</View>

85

);

86

}

87

```

88

89

**Platform Support:**

90

- **iOS**: `true` - Native UISearchController integration

91

- **Android**: `true` - Material Design search view

92

- **Web/Other platforms**: `false` - Use fallback components

93

94

### Transition Progress Hook

95

96

Hook that provides transition progress information for native stack screens. Allows for custom animations and UI updates based on screen transition state.

97

98

```typescript { .api }

99

/**

100

* Hook that provides transition progress information for native stack screens

101

* @returns Transition progress context value with animation data

102

* @throws Error if used outside a native stack screen

103

*/

104

function useTransitionProgress(): TransitionProgressContext;

105

106

interface TransitionProgressContext {

107

/** Current transition progress (0-1) */

108

progress: Animated.Value;

109

110

/** Whether the screen is being closed (0 or 1) */

111

closing: Animated.Value;

112

113

/** Whether navigation is going forward (0 or 1) */

114

goingForward: Animated.Value;

115

}

116

```

117

118

**Usage Example:**

119

120

```typescript

121

import React from 'react';

122

import { useTransitionProgress } from "react-native-screens";

123

import { Animated } from 'react-native';

124

125

function AnimatedScreen() {

126

const { progress, closing, goingForward } = useTransitionProgress();

127

128

const scale = progress.interpolate({

129

inputRange: [0, 1],

130

outputRange: [0.8, 1],

131

});

132

133

const opacity = progress.interpolate({

134

inputRange: [0, 1],

135

outputRange: [0, 1],

136

});

137

138

return (

139

<Animated.View style={[

140

{ flex: 1 },

141

{

142

transform: [{ scale }],

143

opacity,

144

}

145

]}>

146

{/* Screen content */}

147

</Animated.View>

148

);

149

}

150

```

151

152

**Advanced Usage:**

153

154

```typescript

155

import React from 'react';

156

import { useTransitionProgress } from "react-native-screens";

157

import { Animated, View } from 'react-native';

158

159

function ComplexTransitionScreen() {

160

const { progress, closing, goingForward } = useTransitionProgress();

161

162

// Different animations for push vs pop

163

const headerTranslateY = Animated.multiply(

164

goingForward,

165

progress.interpolate({

166

inputRange: [0, 1],

167

outputRange: [-50, 0],

168

})

169

);

170

171

const contentOpacity = progress.interpolate({

172

inputRange: [0, 1],

173

outputRange: [0, 1],

174

});

175

176

return (

177

<View style={{ flex: 1 }}>

178

<Animated.View style={[

179

{ height: 60, backgroundColor: '#007AFF' },

180

{ transform: [{ translateY: headerTranslateY }] }

181

]} />

182

<Animated.View style={[

183

{ flex: 1 },

184

{ opacity: contentOpacity }

185

]}>

186

{/* Screen content */}

187

</Animated.View>

188

</View>

189

);

190

}

191

```

192

193

### Screen Context

194

195

React context that allows swapping the Screen component implementation. This is primarily used for enhanced integrations like Reanimated support.

196

197

```typescript { .api }

198

/**

199

* React context for swapping Screen component implementation

200

*/

201

const ScreenContext: React.Context<React.ComponentType<ScreenProps>>;

202

```

203

204

**Usage Example:**

205

206

```typescript

207

import React from 'react';

208

import { ScreenContext, InnerScreen } from "react-native-screens";

209

import { CustomReanimatedScreen } from './CustomReanimatedScreen';

210

211

// Provider that allows using enhanced screen implementation

212

function EnhancedScreenProvider({ children, useReanimatedScreen = false }) {

213

const ScreenImplementation = useReanimatedScreen ? CustomReanimatedScreen : InnerScreen;

214

215

return (

216

<ScreenContext.Provider value={ScreenImplementation}>

217

{children}

218

</ScreenContext.Provider>

219

);

220

}

221

222

// Consumer that uses the context

223

function ScreenConsumer(props) {

224

const ScreenWrapper = React.useContext(ScreenContext) || InnerScreen;

225

226

return <ScreenWrapper {...props} />;

227

}

228

```

229

230

**Note:** This context is primarily used internally and for advanced integrations. Most applications should use the standard `Screen` component directly.

231

232

### Compatibility Flags

233

234

Configuration object that exposes compatibility information for downstream navigation libraries to detect feature availability and maintain backward compatibility.

235

236

```typescript { .api }

237

/**

238

* Exposes compatibility information for downstream navigation libraries

239

*/

240

const compatibilityFlags: CompatibilityFlags;

241

242

interface CompatibilityFlags {

243

/** Indicates new back title implementation (v3.21+) */

244

isNewBackTitleImplementation: boolean;

245

246

/** Indicates new header implementation (v4.0+) */

247

usesHeaderFlexboxImplementation: boolean;

248

}

249

```

250

251

**Usage Example:**

252

253

```typescript

254

import { compatibilityFlags } from "react-native-screens";

255

256

// Library code that needs to handle different versions

257

function configureHeaderLayout() {

258

if (compatibilityFlags.usesHeaderFlexboxImplementation) {

259

// Use new flexbox-based header layout

260

return { flex: 1, justifyContent: 'center' };

261

} else {

262

// Use legacy header layout

263

return { position: 'absolute', top: 0, left: 0, right: 0 };

264

}

265

}

266

267

function configureBackButton() {

268

if (compatibilityFlags.isNewBackTitleImplementation) {

269

// Use new back title system

270

return { backTitle: 'Back', backTitleVisible: true };

271

} else {

272

// Use legacy back button handling

273

return { backButtonTitle: 'Back' };

274

}

275

}

276

```

277

278

### Feature Flags

279

280

Configuration object for controlling experimental and stable features globally across the application.

281

282

```typescript { .api }

283

/**

284

* Configurable global behavior flags

285

*/

286

const featureFlags: FeatureFlags;

287

288

interface FeatureFlags {

289

/** Experimental feature flags */

290

experiment: {

291

/** Experimental bottom tabs control */

292

controlledBottomTabs: boolean;

293

};

294

295

/** Stable configuration flags (currently empty) */

296

stable: {};

297

}

298

```

299

300

**Usage Example:**

301

302

```typescript

303

import { featureFlags } from "react-native-screens";

304

305

// Enable experimental bottom tabs

306

featureFlags.experiment.controlledBottomTabs = true;

307

308

// Check if experimental features are enabled

309

function useExperimentalBottomTabs() {

310

return featureFlags.experiment.controlledBottomTabs;

311

}

312

313

function ConditionalBottomTabs() {

314

if (useExperimentalBottomTabs()) {

315

return <ExperimentalBottomTabs />;

316

}

317

318

return <StandardBottomTabs />;

319

}

320

```

321

322

## Integration Patterns

323

324

### React Navigation Integration

325

326

```typescript

327

import { useTransitionProgress } from "react-native-screens";

328

import { useRoute, useNavigation } from "@react-navigation/native";

329

330

function ReactNavigationIntegration() {

331

const route = useRoute();

332

const navigation = useNavigation();

333

334

// Use transition progress for custom animations

335

const { progress } = useTransitionProgress();

336

337

// Combine with React Navigation hooks

338

const isScreenFocused = navigation.isFocused();

339

340

return (

341

<View>

342

<Text>Route: {route.name}</Text>

343

<Text>Focused: {isScreenFocused ? 'Yes' : 'No'}</Text>

344

</View>

345

);

346

}

347

```

348

349

### Custom Navigation System

350

351

```typescript

352

import {

353

executeNativeBackPress,

354

useTransitionProgress,

355

ScreenContext

356

} from "react-native-screens";

357

358

function CustomNavigationSystem({ children }) {

359

const handleBackPress = useCallback(() => {

360

// Custom back handling logic

361

if (canGoBack) {

362

goBack();

363

return true;

364

}

365

366

// Exit app on Android

367

return executeNativeBackPress();

368

}, [canGoBack, goBack]);

369

370

return (

371

<ScreenContext.Provider value={{ isActive: true, screenId: 'custom' }}>

372

{children}

373

</ScreenContext.Provider>

374

);

375

}

376

```

377

378

### Performance Monitoring

379

380

```typescript

381

import { useTransitionProgress } from "react-native-screens";

382

383

function PerformanceMonitor() {

384

const { progress } = useTransitionProgress();

385

386

useEffect(() => {

387

const listener = progress.addListener(({ value }) => {

388

// Monitor transition performance

389

console.log('Transition progress:', value);

390

391

if (value === 1) {

392

console.log('Transition completed');

393

// Log performance metrics

394

}

395

});

396

397

return () => progress.removeListener(listener);

398

}, [progress]);

399

400

return null;

401

}

402

```

403

404

## Platform-Specific Utilities

405

406

### Android Back Button Handling

407

408

```typescript

409

import { executeNativeBackPress } from "react-native-screens";

410

import { BackHandler, Platform } from "react-native";

411

412

function setupAndroidBackHandler() {

413

if (Platform.OS !== 'android') return;

414

415

const handleBackPress = () => {

416

// Custom logic before exiting

417

if (shouldExit()) {

418

executeNativeBackPress();

419

return true;

420

}

421

return false;

422

};

423

424

BackHandler.addEventListener('hardwareBackPress', handleBackPress);

425

426

return () => {

427

BackHandler.removeEventListener('hardwareBackPress', handleBackPress);

428

};

429

}

430

```

431

432

### iOS Search Integration

433

434

```typescript

435

import {

436

isSearchBarAvailableForCurrentPlatform,

437

SearchBar

438

} from "react-native-screens";

439

440

function iOSSearchIntegration() {

441

if (!isSearchBarAvailableForCurrentPlatform) {

442

return null;

443

}

444

445

return (

446

<SearchBar

447

placeholder="Search..."

448

placement="stacked"

449

hideWhenScrolling={true}

450

/>

451

);

452

}

453

```

454

455

## Error Handling

456

457

### Context Validation

458

459

```typescript

460

import { ScreenContext } from "react-native-screens";

461

462

function useScreenContext() {

463

const context = useContext(ScreenContext);

464

465

if (!context) {

466

throw new Error(

467

'useScreenContext must be used within a Screen component'

468

);

469

}

470

471

return context;

472

}

473

```

474

475

### Hook Safety

476

477

```typescript

478

import { useTransitionProgress } from "react-native-screens";

479

480

function SafeTransitionHook() {

481

try {

482

const progress = useTransitionProgress();

483

return progress;

484

} catch (error) {

485

console.warn('useTransitionProgress called outside native stack screen');

486

return null;

487

}

488

}

489

```