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

hooks-contexts.mddocs/

0

# Hooks and Contexts

1

2

React hooks and context providers for accessing navigation state, dimensions, header information, and frame size tracking.

3

4

## Capabilities

5

6

### useHeaderHeight Hook

7

8

Hook to access the current header height from the HeaderHeightContext, useful for positioning content relative to the header.

9

10

```typescript { .api }

11

/**

12

* Hook to access current header height from context

13

* @returns Current header height in pixels

14

* @throws Error if used outside HeaderHeightContext provider

15

*/

16

function useHeaderHeight(): number;

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import { useHeaderHeight } from "@react-navigation/elements";

23

24

// Basic usage

25

function ContentWithHeaderOffset() {

26

const headerHeight = useHeaderHeight();

27

28

return (

29

<ScrollView

30

style={{ flex: 1 }}

31

contentInset={{ top: headerHeight }}

32

>

33

<Text>Content offset by header height</Text>

34

</ScrollView>

35

);

36

}

37

38

// Positioning floating elements

39

function FloatingActionButton() {

40

const headerHeight = useHeaderHeight();

41

42

return (

43

<View

44

style={{

45

position: 'absolute',

46

top: headerHeight + 20,

47

right: 20,

48

width: 56,

49

height: 56,

50

borderRadius: 28,

51

backgroundColor: '#007AFF'

52

}}

53

>

54

<Icon name="plus" color="white" />

55

</View>

56

);

57

}

58

59

// Conditional layout based on header height

60

function AdaptiveLayout() {

61

const headerHeight = useHeaderHeight();

62

const isCompactHeader = headerHeight < 100;

63

64

return (

65

<View style={{ flex: 1, paddingTop: headerHeight }}>

66

{isCompactHeader ? (

67

<CompactLayout />

68

) : (

69

<ExpandedLayout />

70

)}

71

</View>

72

);

73

}

74

```

75

76

### useFrameSize Hook

77

78

Hook for tracking frame size changes with optional throttling, providing current dimensions and selector-based updates.

79

80

```typescript { .api }

81

/**

82

* Hook for tracking frame size with optional throttling

83

* @param selector - Function to select specific values from frame

84

* @param throttle - Whether to throttle frame updates (default: false)

85

* @returns Selected value from current frame dimensions

86

*/

87

function useFrameSize<T>(

88

selector: (frame: Frame) => T,

89

throttle?: boolean

90

): T;

91

92

interface Frame {

93

width: number;

94

height: number;

95

}

96

```

97

98

**Usage Examples:**

99

100

```typescript

101

import { useFrameSize } from "@react-navigation/elements";

102

103

// Get current frame width

104

function ResponsiveComponent() {

105

const width = useFrameSize(frame => frame.width);

106

107

return (

108

<View style={{

109

flexDirection: width > 768 ? 'row' : 'column'

110

}}>

111

<Text>Responsive layout based on width: {width}px</Text>

112

</View>

113

);

114

}

115

116

// Get both width and height

117

function FullFrameInfo() {

118

const dimensions = useFrameSize(frame => ({

119

width: frame.width,

120

height: frame.height,

121

aspectRatio: frame.width / frame.height

122

}));

123

124

return (

125

<View>

126

<Text>Width: {dimensions.width}px</Text>

127

<Text>Height: {dimensions.height}px</Text>

128

<Text>Aspect Ratio: {dimensions.aspectRatio.toFixed(2)}</Text>

129

</View>

130

);

131

}

132

133

// Throttled updates for performance

134

function ThrottledFrameSize() {

135

const width = useFrameSize(

136

frame => frame.width,

137

true // Throttle updates

138

);

139

140

return (

141

<Text>

142

Throttled width updates: {width}px

143

</Text>

144

);

145

}

146

147

// Conditional rendering based on frame size

148

function AdaptiveContent() {

149

const isLandscape = useFrameSize(

150

frame => frame.width > frame.height

151

);

152

153

return (

154

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

155

{isLandscape ? (

156

<LandscapeLayout />

157

) : (

158

<PortraitLayout />

159

)}

160

</View>

161

);

162

}

163

```

164

165

## Context Components

166

167

### FrameSizeProvider

168

169

Provider component that enables frame size tracking for `useFrameSize` hook by monitoring and providing device dimensions.

170

171

```typescript { .api }

172

/**

173

* Provider for frame size tracking context

174

* @param initialFrame - Initial frame dimensions

175

* @param children - Child components that will have access to frame size

176

* @param style - Optional style for the provider container

177

*/

178

function FrameSizeProvider(props: {

179

initialFrame: Frame;

180

children: React.ReactNode;

181

style?: StyleProp<ViewStyle>;

182

}): React.ReactElement;

183

184

interface Frame {

185

width: number;

186

height: number;

187

}

188

```

189

190

**Usage Examples:**

191

192

```typescript

193

import { FrameSizeProvider, useFrameSize } from "@react-navigation/elements";

194

195

// Basic provider setup

196

function App() {

197

const initialFrame = { width: 375, height: 812 }; // iPhone dimensions

198

199

return (

200

<FrameSizeProvider initialFrame={initialFrame}>

201

<ResponsiveApp />

202

</FrameSizeProvider>

203

);

204

}

205

206

// Nested providers automatically avoid double-wrapping

207

function NestedProviders({ children }) {

208

const frame1 = { width: 768, height: 1024 };

209

const frame2 = { width: 1024, height: 768 };

210

211

return (

212

<FrameSizeProvider initialFrame={frame1}>

213

<FrameSizeProvider initialFrame={frame2}>

214

{children} {/* Only one provider is active */}

215

</FrameSizeProvider>

216

</FrameSizeProvider>

217

);

218

}

219

220

// Using with safe area frame

221

import { useSafeAreaFrame } from 'react-native-safe-area-context';

222

223

function SafeAreaFrameProvider({ children }) {

224

const safeAreaFrame = useSafeAreaFrame();

225

226

return (

227

<FrameSizeProvider initialFrame={safeAreaFrame}>

228

{children}

229

</FrameSizeProvider>

230

);

231

}

232

```

233

234

### HeaderBackContext

235

236

Context providing back button state and navigation information for header components.

237

238

```typescript { .api }

239

/**

240

* Context for back button state and navigation info

241

* @type React context providing back button configuration or undefined

242

*/

243

const HeaderBackContext: React.Context<{

244

/** Back button title (usually previous screen title) */

245

title: string | undefined;

246

/** Back button href for web navigation */

247

href: string | undefined;

248

} | undefined>;

249

```

250

251

**Usage Examples:**

252

253

```typescript

254

import { HeaderBackContext } from "@react-navigation/elements";

255

import { useContext } from "react";

256

257

// Accessing back context

258

function CustomHeaderComponent() {

259

const backContext = useContext(HeaderBackContext);

260

261

return (

262

<View>

263

{backContext && (

264

<Text>Back to: {backContext.title || 'Previous Screen'}</Text>

265

)}

266

</View>

267

);

268

}

269

270

// Providing back context

271

<HeaderBackContext.Provider value={{ title: "Settings", href: undefined }}>

272

<HeaderContent />

273

</HeaderBackContext.Provider>

274

```

275

276

### HeaderHeightContext

277

278

Context providing the current header height for layout calculations and positioning.

279

280

```typescript { .api }

281

/**

282

* Context for current header height

283

* @type React context providing header height in pixels or undefined

284

*/

285

const HeaderHeightContext: React.Context<number | undefined>;

286

```

287

288

**Usage Examples:**

289

290

```typescript

291

import { HeaderHeightContext } from "@react-navigation/elements";

292

import { useContext } from "react";

293

294

// Manual context access (prefer useHeaderHeight hook)

295

function ManualHeaderHeight() {

296

const headerHeight = useContext(HeaderHeightContext);

297

298

return (

299

<View style={{ paddingTop: headerHeight || 0 }}>

300

<Text>Content with header padding</Text>

301

</View>

302

);

303

}

304

305

// Providing header height context

306

<HeaderHeightContext.Provider value={88}>

307

<ScreenContent />

308

</HeaderHeightContext.Provider>

309

```

310

311

### HeaderShownContext

312

313

Context indicating whether the header is currently shown, useful for layout adjustments.

314

315

```typescript { .api }

316

/**

317

* Context for header visibility state

318

* @type React context providing boolean indicating if header is shown

319

*/

320

const HeaderShownContext: React.Context<boolean>;

321

```

322

323

**Usage Examples:**

324

325

```typescript

326

import { HeaderShownContext } from "@react-navigation/elements";

327

import { useContext } from "react";

328

329

// Accessing header shown state

330

function ConditionalContent() {

331

const isHeaderShown = useContext(HeaderShownContext);

332

333

return (

334

<View style={{

335

paddingTop: isHeaderShown ? 0 : 20

336

}}>

337

<Text>

338

Header is {isHeaderShown ? 'shown' : 'hidden'}

339

</Text>

340

</View>

341

);

342

}

343

344

// Providing header shown context

345

<HeaderShownContext.Provider value={true}>

346

<ScreenWithHeader />

347

</HeaderShownContext.Provider>

348

349

// Combined with other contexts

350

function FullHeaderContext({ children, headerHeight, isShown, backInfo }) {

351

return (

352

<HeaderHeightContext.Provider value={headerHeight}>

353

<HeaderShownContext.Provider value={isShown}>

354

<HeaderBackContext.Provider value={backInfo}>

355

{children}

356

</HeaderBackContext.Provider>

357

</HeaderShownContext.Provider>

358

</HeaderHeightContext.Provider>

359

);

360

}

361

```

362

363

## Advanced Usage Patterns

364

365

### Responsive Layout Hook

366

367

Combine useFrameSize with breakpoints for responsive design:

368

369

```typescript

370

function useResponsiveLayout() {

371

return useFrameSize(frame => {

372

const { width } = frame;

373

374

if (width < 480) return 'mobile';

375

if (width < 768) return 'tablet';

376

if (width < 1024) return 'desktop';

377

return 'large';

378

});

379

}

380

381

function ResponsiveComponent() {

382

const layout = useResponsiveLayout();

383

384

const styles = {

385

mobile: { padding: 16, fontSize: 14 },

386

tablet: { padding: 24, fontSize: 16 },

387

desktop: { padding: 32, fontSize: 18 },

388

large: { padding: 40, fontSize: 20 }

389

};

390

391

return (

392

<View style={styles[layout]}>

393

<Text>Layout: {layout}</Text>

394

</View>

395

);

396

}

397

```

398

399

### Header-Aware Scrolling

400

401

Combine header height with scroll views for proper content positioning:

402

403

```typescript

404

function HeaderAwareScrollView({ children }) {

405

const headerHeight = useHeaderHeight();

406

const isHeaderShown = useContext(HeaderShownContext);

407

408

return (

409

<ScrollView

410

style={{ flex: 1 }}

411

contentContainerStyle={{

412

paddingTop: isHeaderShown ? headerHeight : 0

413

}}

414

scrollIndicatorInsets={{

415

top: isHeaderShown ? headerHeight : 0

416

}}

417

>

418

{children}

419

</ScrollView>

420

);

421

}

422

```

423

424

### Performance Monitoring

425

426

Use frame size changes to monitor performance:

427

428

```typescript

429

function PerformanceMonitor() {

430

const frameChanges = useRef(0);

431

432

useFrameSize(frame => {

433

frameChanges.current += 1;

434

console.log(`Frame changed ${frameChanges.current} times:`, frame);

435

return frame;

436

});

437

438

return null; // This is just for monitoring

439

}

440

```

441

442

## Context Error Handling

443

444

The hooks include proper error handling when used outside their providers:

445

446

```typescript

447

// useHeaderHeight will throw if used outside HeaderHeightContext

448

function ComponentWithErrorHandling() {

449

try {

450

const headerHeight = useHeaderHeight();

451

return <Text>Header height: {headerHeight}</Text>;

452

} catch (error) {

453

return <Text>No header context available</Text>;

454

}

455

}

456

```

457

458

## Platform Considerations

459

460

### Web

461

- **ResizeObserver**: Uses ResizeObserver API for efficient frame size tracking

462

- **CSS Layout**: Frame size updates coordinate with CSS layout changes

463

- **Performance**: Throttled updates prevent excessive re-renders during window resize

464

465

### Mobile (iOS/Android)

466

- **Orientation Changes**: Automatically handles device orientation changes

467

- **Safe Area**: Frame size accounts for safe area insets

468

- **Keyboard**: Frame updates when software keyboard appears/disappears