@codehogs/rn-country-phone-codes
v1.0.0
Published
React Native phone input with country picker and libphonenumber-js validation (iOS, Android, Web)
Downloads
101
Maintainers
Readme
@codehogs/rn-country-phone-codes
International phone number input for React Native: searchable country picker, per-country validation, and E.164 output using libphonenumber-js (same rules engine family as Google’s libphonenumber). Works on iOS, Android, and Web when using React Native for Web.
Why this library
- Accurate validation uses ISO 3166-1 alpha-2 (
iso2) and libphonenumber metadata, not dial-code-only regex (important for shared codes like+1). - Clear API: one main component, optional utilities, or headless modal + helpers.
- Flexible UI: style props and render props for custom design systems.
Requirements
| Dependency | Version |
|------------|---------|
| react | ≥ 17 |
| react-native | ≥ 0.71 |
libphonenumber-js is installed automatically as a dependency of this package (you do not need to add it separately).
Installation
npm install @codehogs/rn-country-phone-codesyarn add @codehogs/rn-country-phone-codespnpm add @codehogs/rn-country-phone-codesQuick start
import React, { useState } from 'react';
import { View } from 'react-native';
import { PhoneNumberInput } from '@codehogs/rn-country-phone-codes';
export default function SignUpPhone() {
const [phone, setPhone] = useState('');
const [valid, setValid] = useState(false);
return (
<View style={{ padding: 16 }}>
<PhoneNumberInput
defaultCountry="LK"
value={phone}
onChangeText={setPhone}
onValidChange={setValid}
onParsedChange={(result) => {
if (result?.e164Number) console.log('E.164:', result.e164Number);
}}
placeholder="Mobile number"
/>
</View>
);
}The user enters the national number (no +); the country is chosen with the flag/dial code control. Pasting a full international number starting with + is supported and will update the country when possible.
Exports
Components
| Export | Description |
|--------|-------------|
| PhoneNumberInput | Country selector + phone field + validation callbacks |
| CountryPickerModal | Searchable country list in a modal (use alone if you build your own field) |
| CountryListItem | Default row for the list |
Data
| Export | Description |
|--------|-------------|
| COUNTRIES / COUNTRY_LIST | All regions from libphonenumber (iso2, dialCode, country, flag) |
| getSortedCountries(preferredIso2?) | Same list sorted, optionally pinning one iso2 first |
Phone helpers
| Function | Description |
|----------|-------------|
| validatePhoneNumber({ country, phoneNumber }) | { isValid, e164Number, nationalNumber, countryIso2, dialCode, … } |
| parsePhoneNumber(country, phoneNumber) | Structured parse result; null if empty |
| formatPhoneNumber(country, phoneNumber, formatStyle?) | 'INTERNATIONAL' | 'E.164' | 'NATIONAL' |
| formatToE164(country, phoneNumber) | E.164 string or null |
| isValidPhoneNumberForCountry(country, phoneNumber) | boolean |
| formatNationalInput(iso2, digits, enabled?) | As-you-type national formatting |
| sanitizePhoneNumber / sanitizeForParse | Strip formatting for parsing |
Country helpers
| Function | Description |
|----------|-------------|
| getCountryByIso2(iso2) | CountryItem or undefined |
| getCountriesByDialCode(dialCode) | e.g. all +1 countries |
| getDialCodeForIso2(iso2) | e.g. "+94" |
CountryItem shape
Each country is:
{
iso2: 'US', // ISO 3166-1 alpha-2 — used for validation
dialCode: '+1',
country: 'United States',
flag: '🇺🇸',
}PhoneNumberInput props
Value / country
| Prop | Type | Description |
|------|------|-------------|
| value | string | Controlled national value |
| defaultValue | string | Uncontrolled initial value |
| defaultCountry | string | Default iso2 (e.g. "LK") |
| selectedCountry | CountryItem | Controlled selected country |
| countries | CountryItem[] | Override list (defaults to getSortedCountries(defaultCountry)) |
Callbacks
| Prop | Description |
|------|-------------|
| onChangeText(text) | National string (formatted if autoFormat) |
| onChangeFormattedText(e164) | Fires with E.164 when the number is valid |
| onChangeCountry(country) | Country changed (picker or international paste) |
| onValidChange(isValid) | Validation flag |
| onParsedChange(result \| null) | Full parse; null when empty |
Behavior
| Prop | Default | Description |
|------|---------|-------------|
| autoFormat | true | National formatting with AsYouType |
| enableSearch | true | Search in country modal |
| allowZeroAfterCountryCode | true | National leading zeros (e.g. some regions) |
| showFlag | true | Show flag on trigger |
| showDialCode | true | Show dial code on trigger |
| showCountryName | false | Show country name on trigger |
| disabled | false | Disable input |
| error | false | Error border |
| errorText | string | Message below field |
Styles & render props
| Style props | Render props |
|-------------|----------------|
| containerStyle, inputContainerStyle, countryButtonStyle, textInputStyle | renderCountryTrigger({ selectedCountry, openPicker }) |
| flagTextStyle, dialCodeTextStyle, countryTextStyle, errorTextStyle | renderInput({ value, onChangeText, ... }) |
| modalStyle, searchInputStyle, itemStyle, itemTextStyle | renderCountryItem({ item, onPress }) |
Also: placeholder, searchPlaceholder, modalTitle.
Custom trigger example
<PhoneNumberInput
defaultCountry="IN"
renderCountryTrigger={({ selectedCountry, openPicker }) => (
<TouchableOpacity onPress={openPicker}>
<Text>
{selectedCountry.flag} {selectedCountry.dialCode}
</Text>
</TouchableOpacity>
)}
/>Platform notes
- iOS / Android: Uses standard
Modal,TextInput,FlatList; touch targets and padding are tuned per platform (and web whenPlatform.OS === 'web'). - Web (React Native for Web): Same components; ensure your app includes
react-native-websetup. IfIntl.DisplayNamesis unavailable in your environment, country names fall back to theiso2code (rare on modern JS engines).
Validation accuracy
Validation is delegated to libphonenumber-js using the selected country’s iso2. That matches how real phone metadata is keyed (shared dial codes, variable length, etc.). This package does not maintain per-country regex by hand.
License
MIT
Maintainer
Published under the CodeHogs scope as @codehogs/rn-country-phone-codes.
