or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

customization.mdframework-integrations.mdindex.mdinput-components.mdinternationalization.mdphone-input-components.mdutility-functions.md

framework-integrations.mddocs/

0

# Framework Integrations

1

2

Specialized React Phone Number Input components designed for seamless integration with popular React frameworks and form libraries. These components maintain the same core functionality while providing framework-specific APIs and behaviors.

3

4

## Capabilities

5

6

### React Hook Form Integration

7

8

Components specifically designed for React Hook Form integration with built-in field registration and validation support.

9

10

```typescript { .api }

11

/**

12

* React Hook Form compatible phone input with country selection

13

* Integrates directly with useForm() hook and Controller component

14

*/

15

interface ReactHookFormProps<FormValues extends FieldValues> {

16

/** Field name for form registration (required) */

17

name: string;

18

/** Default phone number value in E.164 format */

19

defaultValue?: string;

20

/** React Hook Form control object from useForm() */

21

control?: Control<FormValues>;

22

/** Validation rules object */

23

rules?: {

24

required?: boolean | string;

25

validate?: (value: string) => boolean | string;

26

pattern?: RegExp;

27

minLength?: number;

28

maxLength?: number;

29

[key: string]: any;

30

};

31

/** Unregister field when component unmounts */

32

shouldUnregister?: boolean;

33

/** All standard phone input props */

34

defaultCountry?: Country;

35

placeholder?: string;

36

disabled?: boolean;

37

countries?: Country[];

38

labels?: Labels;

39

className?: string;

40

style?: object;

41

onCountryChange?(country?: Country): void;

42

// ... all other PhoneInput props supported

43

}

44

45

declare const PhoneInputWithCountrySelect: <FormValues extends FieldValues = FieldValues>(

46

props: ReactHookFormProps<FormValues>

47

) => JSX.Element;

48

```

49

50

**Usage Examples:**

51

52

```typescript

53

import React from "react";

54

import { useForm, Controller } from "react-hook-form";

55

import PhoneInput from "react-phone-number-input/react-hook-form";

56

import "react-phone-number-input/style.css";

57

58

interface FormData {

59

phoneNumber: string;

60

name: string;

61

}

62

63

// Basic React Hook Form integration

64

function ReactHookFormExample() {

65

const { control, handleSubmit, formState: { errors } } = useForm<FormData>();

66

67

const onSubmit = (data: FormData) => {

68

console.log('Form data:', data);

69

console.log('Phone number:', data.phoneNumber); // E.164 format

70

};

71

72

return (

73

<form onSubmit={handleSubmit(onSubmit)}>

74

<PhoneInput

75

name="phoneNumber"

76

control={control}

77

defaultCountry="US"

78

placeholder="Enter phone number"

79

rules={{

80

required: "Phone number is required",

81

validate: (value) =>

82

value && value.length > 5 || "Please enter a valid phone number"

83

}}

84

/>

85

{errors.phoneNumber && (

86

<span className="error">{errors.phoneNumber.message}</span>

87

)}

88

<button type="submit">Submit</button>

89

</form>

90

);

91

}

92

93

// With FormProvider (no control prop needed)

94

function FormProviderExample() {

95

const methods = useForm<FormData>();

96

97

return (

98

<FormProvider {...methods}>

99

<form onSubmit={methods.handleSubmit(console.log)}>

100

<PhoneInput

101

name="phoneNumber"

102

defaultCountry="US"

103

rules={{ required: true }}

104

/>

105

</form>

106

</FormProvider>

107

);

108

}

109

110

// Custom validation

111

function CustomValidationExample() {

112

const { control, handleSubmit } = useForm<FormData>();

113

114

const validatePhoneNumber = (value: string) => {

115

if (!value) return "Phone number is required";

116

if (!value.startsWith("+1")) return "Please enter a US phone number";

117

if (value.length < 12) return "Phone number appears incomplete";

118

return true;

119

};

120

121

return (

122

<form onSubmit={handleSubmit(console.log)}>

123

<PhoneInput

124

name="phoneNumber"

125

control={control}

126

defaultCountry="US"

127

countries={["US", "CA"]}

128

rules={{ validate: validatePhoneNumber }}

129

/>

130

</form>

131

);

132

}

133

```

134

135

### React Hook Form Input-Only Integration

136

137

Input-only version for React Hook Form without country selection.

138

139

```typescript { .api }

140

/**

141

* React Hook Form compatible input-only phone component

142

* Provides the same React Hook Form integration without country dropdown

143

*/

144

interface ReactHookFormInputProps<FormValues extends FieldValues>

145

extends ReactHookFormProps<FormValues> {

146

/** Specific country for national formatting */

147

country?: Country;

148

/** Force international format */

149

international?: boolean;

150

/** Include country calling code when international=true */

151

withCountryCallingCode?: boolean;

152

/** Default country for ambiguous numbers */

153

defaultCountry?: Country;

154

/** Custom input component */

155

inputComponent?: React.ElementType;

156

/** Enable smart caret positioning */

157

smartCaret?: boolean;

158

}

159

160

declare const PhoneInput: <FormValues extends FieldValues = FieldValues>(

161

props: ReactHookFormInputProps<FormValues>

162

) => JSX.Element;

163

```

164

165

**Usage Example:**

166

167

```typescript

168

import PhoneInput from "react-phone-number-input/react-hook-form-input";

169

170

function ReactHookFormInputExample() {

171

const { control, handleSubmit } = useForm();

172

173

return (

174

<form onSubmit={handleSubmit(console.log)}>

175

<PhoneInput

176

name="phoneNumber"

177

control={control}

178

country="US"

179

placeholder="(555) 123-4567"

180

rules={{ required: "Phone number is required" }}

181

/>

182

</form>

183

);

184

}

185

```

186

187

### React Hook Form Core Variants

188

189

Core versions requiring manual metadata for smaller bundle sizes.

190

191

```typescript { .api }

192

// React Hook Form with country select (core)

193

import PhoneInput from "react-phone-number-input/react-hook-form-core";

194

195

// React Hook Form input-only (core)

196

import PhoneInput from "react-phone-number-input/react-hook-form-input-core";

197

198

interface ReactHookFormCoreProps<FormValues>

199

extends ReactHookFormProps<FormValues> {

200

/** libphonenumber-js metadata object (required) */

201

metadata: Metadata;

202

/** Localization labels (required) */

203

labels: Labels;

204

}

205

```

206

207

### React Native Integration

208

209

Specialized component for React Native applications.

210

211

```typescript { .api }

212

/**

213

* React Native compatible phone input component

214

* Optimized for mobile interfaces and React Native TextInput

215

*/

216

interface ReactNativeInputProps {

217

/** Phone number value in E.164 format */

218

value?: string;

219

/** Called when phone number changes */

220

onChange(value?: string): void;

221

/** Specific country for national formatting */

222

country?: Country;

223

/** Force international format */

224

international?: boolean;

225

/** Include country calling code */

226

withCountryCallingCode?: boolean;

227

/** Default country for ambiguous numbers */

228

defaultCountry?: Country;

229

/** Custom TextInput component */

230

inputComponent?: React.ElementType;

231

/** React Native TextInput props */

232

placeholder?: string;

233

editable?: boolean;

234

autoFocus?: boolean;

235

keyboardType?: 'phone-pad' | 'number-pad' | 'default';

236

returnKeyType?: string;

237

onFocus?(event: any): void;

238

onBlur?(event: any): void;

239

style?: any;

240

// ... other React Native TextInput props

241

}

242

243

declare const PhoneInput: React.ForwardRefExoticComponent<ReactNativeInputProps>;

244

```

245

246

**Usage Example:**

247

248

```typescript

249

import React, { useState } from "react";

250

import { View } from "react-native";

251

import PhoneInput from "react-phone-number-input/react-native-input";

252

253

function ReactNativeExample() {

254

const [phoneNumber, setPhoneNumber] = useState();

255

256

return (

257

<View>

258

<PhoneInput

259

value={phoneNumber}

260

onChange={setPhoneNumber}

261

defaultCountry="US"

262

placeholder="Enter phone number"

263

keyboardType="phone-pad"

264

style={{

265

height: 40,

266

borderColor: 'gray',

267

borderWidth: 1,

268

paddingHorizontal: 10

269

}}

270

/>

271

</View>

272

);

273

}

274

```

275

276

### Field Values Type System

277

278

Framework integrations provide proper TypeScript support for form values.

279

280

```typescript { .api }

281

// React Hook Form field values constraint

282

interface FieldValues {

283

[key: string]: any;

284

}

285

286

// Default form values type

287

type DefaultFormValues = FieldValues;

288

289

// Control type from React Hook Form

290

interface Control<FormValues extends FieldValues> {

291

register: (name: keyof FormValues, options?: any) => any;

292

unregister: (name: keyof FormValues) => void;

293

formState: FormState<FormValues>;

294

watch: (name?: keyof FormValues) => any;

295

// ... other Control methods

296

}

297

```

298

299

### Error Handling and Validation

300

301

Framework integrations handle validation and error states consistently.

302

303

```typescript { .api }

304

// Validation rules interface

305

interface ValidationRules {

306

required?: boolean | string;

307

min?: number | { value: number; message: string };

308

max?: number | { value: number; message: string };

309

minLength?: number | { value: number; message: string };

310

maxLength?: number | { value: number; message: string };

311

pattern?: RegExp | { value: RegExp; message: string };

312

validate?:

313

| ((value: any) => boolean | string)

314

| Record<string, (value: any) => boolean | string>;

315

}

316

317

// Form state for error handling

318

interface FormState<FormValues> {

319

errors: Record<keyof FormValues, { message?: string; type?: string }>;

320

isDirty: boolean;

321

isValid: boolean;

322

isSubmitting: boolean;

323

// ... other form state properties

324

}

325

```

326

327

**Validation Examples:**

328

329

```typescript

330

// Phone number specific validation

331

const phoneValidationRules = {

332

required: "Phone number is required",

333

validate: {

334

validFormat: (value: string) =>

335

!value || value.startsWith('+') || "Phone number must be in international format",

336

usNumber: (value: string) =>

337

!value || value.startsWith('+1') || "Please enter a US phone number",

338

minLength: (value: string) =>

339

!value || value.length >= 12 || "Phone number appears to be too short"

340

}

341

};

342

343

function ValidationExample() {

344

const { control, formState: { errors } } = useForm();

345

346

return (

347

<>

348

<PhoneInput

349

name="phoneNumber"

350

control={control}

351

rules={phoneValidationRules}

352

defaultCountry="US"

353

/>

354

{errors.phoneNumber && (

355

<span className="error">

356

{errors.phoneNumber.message}

357

</span>

358

)}

359

</>

360

);

361

}

362

```

363

364

### shouldUnregister Behavior

365

366

Framework integrations support the shouldUnregister option for proper form cleanup.

367

368

```typescript { .api }

369

interface UnregisterBehavior {

370

/**

371

* Controls whether field value is retained when component unmounts

372

* true: field is unregistered and value is removed (recommended)

373

* false: field value is retained even after unmount

374

*/

375

shouldUnregister?: boolean;

376

}

377

```

378

379

This affects form behavior when phone input components are conditionally rendered or removed from the DOM.