Socket
Book a DemoInstallSign in
Socket

react-native-international-phone-number

Package Overview
Dependencies
Maintainers
1
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-native-international-phone-number

International mobile phone input component with mask for React Native

0.10.4
Source
npmnpm
Version published
Maintainers
1
Created
Source

React Native International Phone Number Input Lib preview

React Native International Phone Number Input



Features

  • ๐ŸŒŽ Phone Input Mask โ€“ Auto-formatting per selected country
  • โœ… Validation - Check phone number;
  • ๐Ÿ“ฑ Cross-Platform โ€“ Works seamlessly on iOS, Android and Web;
  • ๐Ÿงฉ Flexible Integration โ€“ Supports both React Native CLI & Expo;
  • ๐Ÿ‘จโ€๐Ÿ’ป Component Versatility - Works with functional & class components;
  • ๐ŸŽจ Modern UI - Custom component with sleek design;
  • ๐Ÿˆถ internationalization - Supports 32 languages;
  • ๐Ÿงช Test Ready โ€“ Smooth testing integration;
  • โ™ฟ Accessibility โ€“ Accessibility standards to screen readers.

Try it out


List of Contents


Old Versions


Installation

$ npm i --save react-native-international-phone-number

OR

$ yarn add react-native-international-phone-number

Additional config to WEB

  • Using React Native CLI:

Create a react-native.config.js file at the root of your react-native project with:

module.exports = {
  project: {
    ios: {},
    android: {},
  },
  assets: [
    './node_modules/react-native-country-select/lib/assets/fonts',
  ],
};

Then link the font to your native projects with:

npx react-native-asset
  • Using Expo:

  • Install expo-fonts: npx expo install expo-font;
  • Initialize the expo-font:
  import { useFonts } from 'expo-font';

  ...

  useFonts({
    'TwemojiMozilla': require('./node_modules/react-native-country-select/lib/assets/fonts/TwemojiMozilla.woff2'),
  });

  ...

Observation: you need to recompile your project after adding new fonts.


Basic Usage

  • Class Component:

import React from 'react';
import { View, Text } from 'react-native';
import PhoneInput, { isValidPhoneNumber } from 'react-native-international-phone-number';

export class App extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      selectedCountry: null,
      inputValue: ''
    }
  }

  function handleSelectedCountry(country) {
    this.setState({
      selectedCountry: country
    })
  }

  function handleInputValue(phoneNumber) {
    this.setState({
      inputValue: phoneNumber
    })
  }

  render(){
    return (
      <View style={{ width: '100%', flex: 1, padding: 24 }}>
        <PhoneInput
          value={this.state.inputValue}
          onChangePhoneNumber={this.handleInputValue}
          selectedCountry={this.state.selectedCountry}
          onChangeSelectedCountry={this.handleSelectedCountry}
        />
        <View style={{ marginTop: 10 }}>
          <Text>
            Country:{' '}
            {`${this.state.selectedCountry?.translations?.eng?.common} (${this.state.selectedCountry?.cca2})`}
          </Text>
          <Text>
            Phone Number: {`${this.state.selectedCountry?.idd?.root} ${this.state.inputValue}`}
          </Text>
          <Text>
            isValid:{' '}
            {isValidPhoneNumber(this.state.inputValue, this.state.selectedCountry)
              ? 'true'
              : 'false'}
          </Text>
        </View>
      </View>
    );
  }
}
  • Function Component:

import React, {useState} from 'react';
import {View, Text} from 'react-native';
import PhoneInput, {
  isValidPhoneNumber,
} from 'react-native-international-phone-number';

export default function App() {
  const [selectedCountry, setSelectedCountry] = useState(null);
  const [inputValue, setInputValue] = useState('');

  function handleInputValue(phoneNumber) {
    setInputValue(phoneNumber);
  }

  function handleSelectedCountry(country) {
    setSelectedCountry(country);
  }

  return (
    <View style={{width: '100%', flex: 1, padding: 24}}>
      <PhoneInput
        value={inputValue}
        onChangePhoneNumber={handleInputValue}
        selectedCountry={selectedCountry}
        onChangeSelectedCountry={handleSelectedCountry}
      />
      <View style={{marginTop: 10}}>
        <Text>
          Country:{' '}
          {`${selectedCountry?.translations?.eng?.common} (${selectedCountry?.cca2})`}
        </Text>
        <Text>
          Phone Number: {`${selectedCountry?.idd?.root} ${inputValue}`}
        </Text>
        <Text>
          isValid:{' '}
          {isValidPhoneNumber(inputValue, selectedCountry) ? 'true' : 'false'}
        </Text>
      </View>
    </View>
  );
}
  • Typescript

import React, {useState} from 'react';
import {View, Text} from 'react-native';
import PhoneInput, {
  ICountry,
  isValidPhoneNumber,
} from 'react-native-international-phone-number';

export default function App() {
  const [selectedCountry, setSelectedCountry] = useState<null | ICountry>(null);
  const [inputValue, setInputValue] = useState<string>('');

  function handleInputValue(phoneNumber: string) {
    setInputValue(phoneNumber);
  }

  function handleSelectedCountry(country: ICountry) {
    setSelectedCountry(country);
  }

  return (
    <View style={{width: '100%', flex: 1, padding: 24}}>
      <PhoneInput
        value={inputValue}
        onChangePhoneNumber={handleInputValue}
        selectedCountry={selectedCountry}
        onChangeSelectedCountry={handleSelectedCountry}
      />
      <View style={{marginTop: 10}}>
        <Text>
          Country:{' '}
          {`${selectedCountry?.translations?.eng?.common} (${selectedCountry?.cca2})`}
        </Text>
        <Text>
          Phone Number: {`${selectedCountry?.idd?.root} ${inputValue}`}
        </Text>
        <Text>
          isValid:{' '}
          {isValidPhoneNumber(inputValue, selectedCountry) ? 'true' : 'false'}
        </Text>
      </View>
    </View>
  );
}

Intermediate Usage

  • Typescript + useRef

import React, {useRef} from 'react';
import {View, Text} from 'react-native';
import PhoneInput, {
  ICountry,
  IPhoneInputRef,
} from 'react-native-international-phone-number';

export default function App() {
  const phoneInputRef = useRef<IPhoneInputRef>(null);

  function onSubmitRef() {
    Alert.alert(
      'Intermediate Result',
      `Country: ${inputRef.current?.selectedCountry?.translations?.eng?.common} \nPhone Number: ${inputRef.current?.fullPhoneNumber} \nisValid: ${inputRef.current?.isValid}`,
    );
  }

  return (
    <View style={{width: '100%', flex: 1, padding: 24}}>
      <PhoneInput ref={phoneInputRef} />
      <TouchableOpacity
        style={{
          width: '100%',
          paddingVertical: 12,
          backgroundColor: '#2196F3',
          borderRadius: 4,
          marginTop: 10,
        }}
        onPress={onSubmit}>
        <Text
          style={{
            color: '#F3F3F3',
            textAlign: 'center',
            fontSize: 16,
            fontWeight: 'bold',
          }}>
          Submit
        </Text>
      </TouchableOpacity>
    </View>
  );
}

Observation: Don't use the useRef hook combined with the useState hook to manage the phoneNumber and selectedCountry values. Instead, choose to use just one of them (useRef or useState).


Advanced Usage

  • React-Hook-Form + Typescript + Default Phone Number Value

import React, {useState, useEffect} from 'react';
import {View, Text, TouchableOpacity, Alert} from 'react-native';
import PhoneInput, {
  ICountry,
  isValidPhoneNumber,
} from 'react-native-international-phone-number';
import {Controller, FieldValues} from 'react-hook-form';

interface FormProps extends FieldValues {
  phoneNumber: string;
}

export default function App() {
  const [selectedCountry, setSelectedCountry] = useState<undefined | ICountry>(
    undefined,
  );

  function handleSelectedCountry(country: ICountry) {
    setSelectedCountry(country);
  }

  function onSubmit(form: FormProps) {
    const phoneNumber = `${selectedCountry?.idd?.root} ${form.phoneNumber}`;
    const isValid = isValidPhoneNumber(
      form.phoneNumber,
      selectedCountry as ICountry,
    );

    Alert.alert(
      'Advanced Result',
      `Country: ${selectedCountry?.translations?.eng?.common} \nPhone Number: ${phoneNumber} \nisValid: ${isValid}`,
    );
  }

  return (
    <View style={{width: '100%', flex: 1, padding: 24}}>
      <Controller
        name="phoneNumber"
        control={control}
        render={({field: {onChange, value}}) => (
          <PhoneInput
            defaultValue="+12505550199"
            value={value}
            onChangePhoneNumber={onChange}
            selectedCountry={selectedCountry}
            onChangeSelectedCountry={handleSelectedCountry}
          />
        )}
      />
      <TouchableOpacity
        style={{
          width: '100%',
          paddingVertical: 12,
          backgroundColor: '#2196F3',
          borderRadius: 4,
        }}
        onPress={handleSubmit(onSubmit)}>
        <Text
          style={{
            color: '#F3F3F3',
            textAlign: 'center',
            fontSize: 16,
            fontWeight: 'bold',
          }}>
          Submit
        </Text>
      </TouchableOpacity>
    </View>
  );
}

Observations:

  • You need to use a default value with the following format: +(country callling code)(area code)(number phone)
  • The lib has the mechanism to set the flag and mask of the supplied defaultValue. However, if the supplied defaultValue does not match any international standard, the input mask of the defaultValue will be set to "BR" (please make sure that the default value is in the format mentioned above).

Customizing lib

PhoneInput Styles (phoneInputStyles)

PropertyTypeDescription
containerViewStyleMain input container
flagContainerViewStyleFlag and dropdown container
flagTextStyleFlag emoji styling
caretTextStyleDropdown arrow
dividerViewStyleSeparator line
callingCodeTextStyleCountry calling code
inputTextStylePhone number input

Modal Styles (modalStyles)

PropertyTypeDescription
backdropViewStyleModal background overlay
containerViewStyleModal main container
contentViewStyleModal content area
dragHandleContainerViewStyleDrag Handle area
dragHandleIndicatorViewStyleDrag Handle Indicator
searchContainerViewStyleSearch input wrapper
searchInputTextStyleSearch input field
listViewStyleCountries list container
countryItemViewStyleIndividual country row
flagTextStyleCountry flag in list
countryInfoViewStyleCountry details container
callingCodeTextStyleCalling code in list
countryNameTextStyleCountry name in list
sectionTitleTextStyleSection headers
closeButtonViewStyleClose button container
closeButtonTextTextStyleClose button text
countryNotFoundContainerViewStyleNo results container
countryNotFoundMessageTextStyleNo results message

Component Props (PhoneInputProps)

PropTypeDescription
themeIThemeTheme configuration for the component
languageILanguageLanguage for country names and UI
defaultValuestringDefault phone number value (format: +(country code)(area code)(number))
valuestringControlled phone number value
onChangePhoneNumber(phoneNumber: string) => voidCallback when phone number changes
defaultCountryICountryCca2Default selected country (ISO 3166-1 alpha-2)
selectedCountryICountryCurrently selected country object
onChangeSelectedCountry(country: ICountry) => voidCallback when country selection changes
placeholderstringPlaceholder text for phone input
phoneInputPlaceholderTextColorstringColor of placeholder text
phoneInputSelectionColorstringColor of text selection
phoneInputStylesIPhoneInputStylesCustom styles for phone input component
modalStylesICountrySelectStylesCustom styles for country selection modal
disabledbooleanDisable the entire phone input
modalDisabledbooleanDisable only the country selection modal
customMaskstringCustom phone number mask (format like this: (###) ###-####)
visibleCountriesICountryCca2[]Array of country codes to show in modal
hiddenCountriesICountryCca2[]Array of country codes to hide from modal
popularCountriesICountryCca2[]Array of country codes to show in popular section
customCaret() => ReactNodeCustom dropdown arrow component
rtlbooleanEnable right-to-left layout
isFullScreenbooleanShow modal in full screen mode
modalType'bottomSheet' | 'popup'Type of modal presentation
modalDragHandleIndicatorComponent() => ReactNodeCustom drag handle indicator component
modalSearchInputPlaceholderTextColorstringColor of modal search placeholder text
modalSearchInputPlaceholderstringPlaceholder text for modal search input
modalSearchInputSelectionColorstringColor of modal search text selection
modalPopularCountriesTitlestringTitle for popular countries section
modalAllCountriesTitlestringTitle for all countries section
modalSectionTitleComponent() => ReactNodeCustom section title component
modalCountryItemComponent() => ReactNodeCustom country item component
modalCloseButtonComponent() => ReactNodeCustom close button component
modalSectionTitleDisabledbooleanDisable section titles in modal
modalNotFoundCountryMessagestringMessage when no countries found
disabledModalBackdropPressbooleanDisable modal close on backdrop press
removedModalBackdropbooleanRemove modal backdrop entirely
onModalBackdropPress() => voidCallback when modal backdrop is pressed
onModalRequestClose() => voidCallback when modal close is requested
showModalSearchInputbooleanShow search input in modal
showModalCloseButtonbooleanShow close button in modal
showModalScrollIndicatorbooleanShow scroll indicator in modal
refRef<IPhoneInputRef>Ref to access component methods

Functions

FunctionParametersReturn TypeDescription
getAllCountries()ICountry[]Returns an array of all available countries
getCountriesByCallingCode(callingCode: string)ICountry[] | undefinedReturns countries that match the given calling code
getCountryByCca2(cca2: string)ICountry | undefinedReturns a country by its ISO 3166-1 alpha-2 code
getCountriesByName(name: string, language: ILanguage)ICountry[] | undefinedReturns countries that match the given name in the specified language
getCountryByPhoneNumber(phoneNumber: string)ICountry | undefinedReturns the country that matches the given phone number
isValidPhoneNumber(phoneNumber: string, country: ICountry)booleanValidates if a phone number is valid for the given country

Supported languages

The language prop supports the following values:

CodeLanguage
araArabic
belBelarusian
breBreton
bulBulgarian
cesCzech
deuGerman
ellGreek
engEnglish
estEstonian
finFinnish
fraFrench
hebHebrew
hrvCroatian
hunHungarian
itaItalian
jpnJapanese
korKorean
nldDutch
perPersian
polPolish
porPortuguese
ronRomanian
rusRussian
slkSlovak
spaSpanish
srpSerbian
sweSwedish
turTurkish
ukrUkrainian
urdUrdu
zhoChinese
zho-HansSimplified Chinese
zho-HantTraditional Chinese

Testing

When utilizing this package, you may need to target the PhoneInput component in your automated tests. To facilitate this, we provide a testID props for the PhoneInput component. The testID can be integrated with popular testing libraries such as @testing-library/react-native or Maestro. This enables you to efficiently locate and interact with PhoneInput elements within your tests, ensuring a robust and reliable testing experience.

const phoneInput = getByTestId('countryPickerPhoneInput');
const flagContainerButton = getByTestId('countryPickerFlagContainerButton');
const countrySelect = getByTestId('countrySelectSearchInput');
const countrySelectBackdrop = getByTestId('countrySelectBackdrop');
const countrySelectList = getByTestId('countrySelectList');
const countrySelectSearchInput = getByTestId('countrySelectSearchInput');
const countrySelectItem = getByTestId('countrySelectItem');
const countrySelectCloseButton = getByTestId('countrySelectCloseButton');

Accessibility

Ensure your app is inclusive and usable by everyone by leveraging built-in React Native accessibility features. The accessibility props are covered by this package.


Contributing

  • Fork or clone this repository
  $ git clone https://github.com/AstrOOnauta/react-native-international-phone-number.git
  • Repair, Update and Enjoy ๐Ÿ› ๏ธ๐Ÿšงโš™๏ธ

  • Create a new PR to this repository


License

ISC



Thanks for stopping by! ๐Ÿ˜

Keywords

mobile

FAQs

Package last updated on 03 Aug 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with โšก๏ธ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.