or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# React Native Modal

1

2

React Native Modal is an enhanced, animated, and highly customizable modal component for React Native applications. It extends the original React Native Modal component by adding smooth enter/exit animations, customizable backdrop appearance, swipe-to-dismiss functionality, and comprehensive event handling with device rotation support and keyboard avoidance.

3

4

## Package Information

5

6

- **Package Name**: react-native-modal

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install react-native-modal` or `yarn add react-native-modal`

10

11

## Core Imports

12

13

```typescript

14

import Modal from "react-native-modal";

15

```

16

17

For named imports:

18

19

```typescript

20

import {

21

ReactNativeModal,

22

ModalProps,

23

OnSwipeCompleteParams,

24

AnimationEvent,

25

Animations,

26

SupportedAnimation,

27

Orientation,

28

Direction,

29

PresentationStyle,

30

OnOrientationChange,

31

GestureResponderEvent

32

} from "react-native-modal";

33

```

34

35

CommonJS:

36

37

```javascript

38

const Modal = require("react-native-modal");

39

```

40

41

For TypeScript usage with React Native types:

42

43

```typescript

44

import { StyleProp, ViewStyle, NativeSyntheticEvent, NativeTouchEvent } from "react-native";

45

import { PanResponderGestureState } from "react-native";

46

```

47

48

## Basic Usage

49

50

```typescript

51

import React, { useState } from "react";

52

import { Button, Text, View } from "react-native";

53

import Modal from "react-native-modal";

54

55

function ModalExample() {

56

const [isModalVisible, setModalVisible] = useState(false);

57

58

const toggleModal = () => {

59

setModalVisible(!isModalVisible);

60

};

61

62

return (

63

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

64

<Button title="Show modal" onPress={toggleModal} />

65

66

<Modal isVisible={isModalVisible}>

67

<View style={{ flex: 1, backgroundColor: "white" }}>

68

<Text>Hello! I am a modal.</Text>

69

<Button title="Hide modal" onPress={toggleModal} />

70

</View>

71

</Modal>

72

</View>

73

);

74

}

75

```

76

77

## Architecture

78

79

React Native Modal is built around several key components:

80

81

- **ReactNativeModal Component**: Main modal class extending React.Component with enhanced functionality

82

- **Animation System**: Built on react-native-animatable with custom slide animations and timing controls

83

- **Gesture Handling**: PanResponder-based swipe detection with configurable directions and thresholds

84

- **Backdrop Management**: Customizable backdrop with opacity transitions and custom backdrop support

85

- **State Management**: Internal state tracking for visibility, dimensions, and animation states

86

- **Event System**: Comprehensive lifecycle callbacks for show/hide/swipe events

87

88

## Capabilities

89

90

### Modal Component

91

92

The main modal component providing enhanced functionality over React Native's built-in Modal.

93

94

```typescript { .api }

95

/**

96

* Enhanced React Native modal component with animations and gesture support

97

*/

98

class ReactNativeModal extends React.Component<ModalProps, State> {

99

static defaultProps: typeof defaultProps;

100

}

101

102

/**

103

* Default export - same as ReactNativeModal class

104

*/

105

export default ReactNativeModal;

106

```

107

108

### Modal Props Interface

109

110

Complete props interface for configuring modal behavior and appearance.

111

112

```typescript { .api }

113

type ModalProps = ViewProps & {

114

children: React.ReactNode;

115

116

// Swipe Gesture Props

117

onSwipeStart?: (gestureState: PanResponderGestureState) => void;

118

onSwipeMove?: (percentageShown: number, gestureState: PanResponderGestureState) => void;

119

onSwipeComplete?: (params: OnSwipeCompleteParams, gestureState: PanResponderGestureState) => void;

120

onSwipeCancel?: (gestureState: PanResponderGestureState) => void;

121

style?: StyleProp<ViewStyle>;

122

swipeDirection?: Direction | Array<Direction>;

123

124

// Inherited React Native Modal Props

125

onDismiss?: () => void;

126

onShow?: () => void;

127

hardwareAccelerated?: boolean;

128

onOrientationChange?: OnOrientationChange;

129

presentationStyle?: PresentationStyle;

130

131

// Additional Modal Props (defaults provided by defaultProps)

132

useNativeDriverForBackdrop?: boolean;

133

} & typeof defaultProps;

134

135

// All properties from defaultProps are automatically available as optional props:

136

// animationIn, animationInTiming, animationOut, animationOutTiming, avoidKeyboard,

137

// coverScreen, hasBackdrop, backdropColor, backdropOpacity, backdropTransitionInTiming,

138

// backdropTransitionOutTiming, customBackdrop, useNativeDriver, deviceHeight, deviceWidth,

139

// hideModalContentWhileAnimating, propagateSwipe, isVisible, panResponderThreshold,

140

// swipeThreshold, onModalShow, onModalWillShow, onModalHide, onModalWillHide,

141

// onBackdropPress, onBackButtonPress, scrollTo, scrollOffset, scrollOffsetMax,

142

// scrollHorizontal, statusBarTranslucent, supportedOrientations

143

```

144

145

### Swipe Complete Parameters

146

147

Parameters passed to the onSwipeComplete callback when a swipe gesture completes.

148

149

```typescript { .api }

150

interface OnSwipeCompleteParams {

151

swipingDirection: Direction;

152

}

153

```

154

155

### Animation System

156

157

```typescript { .api }

158

/**

159

* Initializes custom slide animations, overriding react-native-animatable defaults

160

*/

161

function initializeAnimations(): void;

162

163

/**

164

* Builds animation configuration objects, handling custom animation definitions

165

*/

166

function buildAnimations(options: {

167

animationIn: Animation | CustomAnimation;

168

animationOut: Animation | CustomAnimation;

169

}): Animations;

170

171

/**

172

* Utility function for animation calculations: returns -(x - 1)

173

*/

174

function reversePercentage(x: number): number;

175

176

/**

177

* Creates slide translation animation objects for react-native-animatable

178

*/

179

function makeSlideTranslation(

180

translationType: string,

181

fromValue: number,

182

toValue: number

183

): CustomAnimation;

184

```

185

186

## Types

187

188

### Core Types

189

190

```typescript { .api }

191

type SupportedAnimation = Animation | CustomAnimation;

192

193

interface Animations {

194

animationIn: string;

195

animationOut: string;

196

}

197

198

type Orientation =

199

| "portrait"

200

| "portrait-upside-down"

201

| "landscape"

202

| "landscape-left"

203

| "landscape-right";

204

205

type Direction = "up" | "down" | "left" | "right";

206

207

type PresentationStyle =

208

| "fullScreen"

209

| "pageSheet"

210

| "formSheet"

211

| "overFullScreen";

212

213

type AnimationEvent = (...args: any[]) => void;

214

215

type OnOrientationChange = (orientation: NativeSyntheticEvent<any>) => void;

216

217

type OrNull<T> = null | T;

218

219

interface GestureResponderEvent extends NativeSyntheticEvent<NativeTouchEvent> {}

220

221

interface PanResponderGestureState {

222

stateID: number;

223

moveX: number;

224

moveY: number;

225

x0: number;

226

y0: number;

227

dx: number;

228

dy: number;

229

vx: number;

230

vy: number;

231

numberActiveTouches: number;

232

}

233

234

// React Native types used in the API

235

type StyleProp<T> = T | T[] | null | undefined;

236

type ViewStyle = Record<string, any>;

237

interface ViewProps {

238

style?: StyleProp<ViewStyle>;

239

testID?: string;

240

accessible?: boolean;

241

accessibilityLabel?: string;

242

accessibilityHint?: string;

243

accessibilityRole?: string;

244

accessibilityState?: Record<string, any>;

245

accessibilityValue?: Record<string, any>;

246

onLayout?: (event: any) => void;

247

pointerEvents?: 'none' | 'box-none' | 'box-only' | 'auto';

248

removeClippedSubviews?: boolean;

249

renderToHardwareTextureAndroid?: boolean;

250

shouldRasterizeIOS?: boolean;

251

collapsable?: boolean;

252

needsOffscreenAlphaCompositing?: boolean;

253

onStartShouldSetResponder?: (event: any) => boolean;

254

onMoveShouldSetResponder?: (event: any) => boolean;

255

onResponderGrant?: (event: any) => void;

256

onResponderMove?: (event: any) => void;

257

onResponderRelease?: (event: any) => void;

258

onResponderTerminate?: (event: any) => void;

259

onResponderTerminationRequest?: (event: any) => boolean;

260

onStartShouldSetResponderCapture?: (event: any) => boolean;

261

onMoveShouldSetResponderCapture?: (event: any) => boolean;

262

}

263

interface NativeSyntheticEvent<T> {

264

nativeEvent: T;

265

currentTarget: number;

266

target: number;

267

bubbles?: boolean;

268

cancelable?: boolean;

269

defaultPrevented?: boolean;

270

eventPhase?: number;

271

isTrusted?: boolean;

272

preventDefault(): void;

273

stopPropagation(): void;

274

persist(): void;

275

timeStamp: number;

276

type: string;

277

}

278

interface NativeTouchEvent {

279

changedTouches: Array<NativeTouchEvent>;

280

identifier: string;

281

locationX: number;

282

locationY: number;

283

pageX: number;

284

pageY: number;

285

target: string;

286

timestamp: number;

287

touches: Array<NativeTouchEvent>;

288

}

289

```

290

291

### Default Props Values

292

293

```typescript { .api }

294

const defaultProps = {

295

animationIn: "slideInUp" as Animation | CustomAnimation,

296

animationInTiming: 300,

297

animationOut: "slideOutDown" as Animation | CustomAnimation,

298

animationOutTiming: 300,

299

avoidKeyboard: false,

300

coverScreen: true,

301

hasBackdrop: true,

302

backdropColor: "black",

303

backdropOpacity: 0.7,

304

backdropTransitionInTiming: 300,

305

backdropTransitionOutTiming: 300,

306

customBackdrop: null,

307

useNativeDriver: false,

308

deviceHeight: null,

309

deviceWidth: null,

310

hideModalContentWhileAnimating: false,

311

propagateSwipe: false,

312

isVisible: false,

313

panResponderThreshold: 4,

314

swipeThreshold: 100,

315

onModalShow: () => null,

316

onModalWillShow: () => null,

317

onModalHide: () => null,

318

onModalWillHide: () => null,

319

onBackdropPress: () => null,

320

onBackButtonPress: () => null,

321

scrollTo: null,

322

scrollOffset: 0,

323

scrollOffsetMax: 0,

324

scrollHorizontal: false,

325

statusBarTranslucent: false,

326

supportedOrientations: ["portrait", "landscape"] as Orientation[]

327

};

328

```

329

330

## Usage Examples

331

332

### Basic Modal with Animation

333

334

```typescript

335

import React, { useState } from "react";

336

import { Button, Text, View } from "react-native";

337

import Modal from "react-native-modal";

338

339

function AnimatedModal() {

340

const [isVisible, setVisible] = useState(false);

341

342

return (

343

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

344

<Button title="Show Modal" onPress={() => setVisible(true)} />

345

346

<Modal

347

isVisible={isVisible}

348

animationIn="slideInUp"

349

animationOut="slideOutDown"

350

animationInTiming={600}

351

animationOutTiming={600}

352

onBackdropPress={() => setVisible(false)}>

353

<View style={{ backgroundColor: "white", padding: 20 }}>

354

<Text>This is a modal with custom animations!</Text>

355

<Button title="Close" onPress={() => setVisible(false)} />

356

</View>

357

</Modal>

358

</View>

359

);

360

}

361

```

362

363

### Swipeable Modal

364

365

```typescript

366

import React, { useState } from "react";

367

import { Text, View } from "react-native";

368

import Modal from "react-native-modal";

369

370

function SwipeableModal() {

371

const [isVisible, setVisible] = useState(true);

372

373

return (

374

<Modal

375

isVisible={isVisible}

376

swipeDirection={["up", "down"]}

377

swipeThreshold={100}

378

onSwipeComplete={() => setVisible(false)}

379

onSwipeStart={(gestureState) => console.log("Swipe started")}

380

onSwipeMove={(percentageShown) => console.log("Swipe progress:", percentageShown)}>

381

<View style={{ backgroundColor: "white", padding: 20 }}>

382

<Text>Swipe up or down to dismiss this modal</Text>

383

</View>

384

</Modal>

385

);

386

}

387

```

388

389

### Custom Backdrop Modal

390

391

```typescript

392

import React, { useState } from "react";

393

import { Text, View, ImageBackground } from "react-native";

394

import Modal from "react-native-modal";

395

396

function CustomBackdropModal() {

397

const [isVisible, setVisible] = useState(true);

398

399

const CustomBackdrop = () => (

400

<ImageBackground

401

source={{ uri: "https://example.com/background.jpg" }}

402

style={{ flex: 1 }}

403

blurRadius={5}

404

/>

405

);

406

407

return (

408

<Modal

409

isVisible={isVisible}

410

customBackdrop={<CustomBackdrop />}

411

onBackdropPress={() => setVisible(false)}>

412

<View style={{ backgroundColor: "white", padding: 20 }}>

413

<Text>Modal with custom backdrop</Text>

414

</View>

415

</Modal>

416

);

417

}

418

```

419

420

### Modal with Keyboard Avoidance

421

422

```typescript

423

import React, { useState } from "react";

424

import { TextInput, Button, View } from "react-native";

425

import Modal from "react-native-modal";

426

427

function KeyboardModal() {

428

const [isVisible, setVisible] = useState(true);

429

const [text, setText] = useState("");

430

431

return (

432

<Modal

433

isVisible={isVisible}

434

avoidKeyboard={true}

435

onBackdropPress={() => setVisible(false)}>

436

<View style={{ backgroundColor: "white", padding: 20 }}>

437

<TextInput

438

value={text}

439

onChangeText={setText}

440

placeholder="Type something..."

441

style={{ borderWidth: 1, padding: 10, marginBottom: 10 }}

442

/>

443

<Button title="Close" onPress={() => setVisible(false)} />

444

</View>

445

</Modal>

446

);

447

}

448

```

449

450

### Full Screen Modal

451

452

```typescript

453

import React, { useState } from "react";

454

import { Text, Button, View } from "react-native";

455

import Modal from "react-native-modal";

456

457

function FullScreenModal() {

458

const [isVisible, setVisible] = useState(true);

459

460

return (

461

<Modal

462

isVisible={isVisible}

463

style={{ margin: 0 }} // Remove default margin for full screen

464

animationIn="slideInRight"

465

animationOut="slideOutRight">

466

<View style={{ flex: 1, backgroundColor: "white", padding: 20 }}>

467

<Text>Full screen modal</Text>

468

<Button title="Close" onPress={() => setVisible(false)} />

469

</View>

470

</Modal>

471

);

472

}

473

```