Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-native-international-phone-number

Package Overview
Dependencies
Maintainers
1
Versions
53
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.8.3
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

React Native International Phone Number Input Lib preview

React Native International Phone Number Input



Features

  • 📱 Works with iOS, Android (Cross-platform), Expo and Web;
  • 🎨 Lib with UI customizable;
  • 🌎 Phone Input Mask according with the selected country;
  • 👨‍💻 Functional and class component support;
  • 🈶 22 languages supported.

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

  • 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-international-phone-number/lib/assets/fonts',
  ],
};

Then link the font to your native projects with:

npx react-native-asset
  • Using Expo:

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

  ...

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

  ...

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

  • Using Web:

Change the app.json file to:

  ...

  "web": {
    ...
    "output": "single",
    ...
  },
  ...

Basic Usage

  • Class Component:

import React from 'react';
import { View, Text } from 'react-native';
import PhoneInput 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?.name?.en} (${this.state.selectedCountry?.cca2})`}
          </Text>
          <Text>
            Phone Number: {`${this.state.selectedCountry?.callingCode} ${this.state.inputValue}`}
          </Text>
        </View>
      </View>
    );
  }
}
  • Function Component:

import React, { useState } from 'react';
import { View, Text } from 'react-native';
import PhoneInput 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?.name?.en} (${selectedCountry?.cca2})`}
        </Text>
        <Text>
          Phone Number:{' '}
          {`${selectedCountry?.callingCode} ${inputValue}`}
        </Text>
      </View>
    </View>
  );
}
  • Typescript

import React, { useState } from 'react';
import { View, Text } from 'react-native';
import PhoneInput, {
  ICountry,
} 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?.name?.en} (${selectedCountry?.cca2})`}
        </Text>
        <Text>
          Phone Number:{' '}
          {`${selectedCountry?.callingCode} ${inputValue}`}
        </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',
      `${phoneInputRef.current?.selectedCountry?.callingCode} ${phoneInputRef.current?.value}`
    );
  }

  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,
} 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) {
    Alert.alert(
      'Advanced Result',
      `${selectedCountry?.callingCode} ${form.phoneNumber}`
    );
  }

  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:

  1. You need to use a default value with the following format: +(country callling code)(area code)(number phone)
  2. 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

Custom lib styles
  • Dark Mode:

  ...
  <PhoneInput
    ...
    theme="dark"
  />
  ...
  • Custom Lib Styles:

  ...
  <PhoneInput
    ...
    phoneInputStyles={{
      container: {
        backgroundColor: '#575757',
        borderWidth: 1,
        borderStyle: 'solid',
        borderColor: '#F3F3F3',
      },
      flagContainer: {
        borderTopLeftRadius: 7,
        borderBottomLeftRadius: 7,
        backgroundColor: '#808080',
        justifyContent: 'center',
      },
      flag: {},
      caret: {
        color: '#F3F3F3',
        fontSize: 16,
      },
      divider: {
        backgroundColor: '#F3F3F3',
      }
      callingCode: {
        fontSize: 16,
        fontWeight: 'bold',
        color: '#F3F3F3',
      },
      input: {
        color: '#F3F3F3',
      },
    }}
    modalStyles={{
      modal: {
        backgroundColor: '#333333',
        borderWidth: 1,
      },
      backdrop: {},
      divider: {
        backgroundColor: 'transparent',
      },
      countriesList: {},
      searchInput: {
        borderRadius: 8,
        borderWidth: 1,
        borderColor: '#F3F3F3',
        color: '#F3F3F3',
        backgroundColor: '#333333',
        paddingHorizontal: 12,
        height: 46,
      },
      countryButton: {
        borderWidth: 1,
        borderColor: '#F3F3F3',
        backgroundColor: '#666666',
        marginVertical: 4,
        paddingVertical: 0,
      },
      noCountryText: {},
      noCountryContainer: {},
      flag: {
        color: '#FFFFFF',
        fontSize: 20,
      },
      callingCode: {
        color: '#F3F3F3',
      },
      countryName: {
        color: '#F3F3F3',
      },
    }}
  />
  ...
  • Custom Caret:

  ...
  <PhoneInput
    ...
    customCaret={<Icon name="chevron-down" size={30} color="#000000" />}  // react-native-vector-icons
  />
  ...
  • Custom Placeholders/Messages:

  ...
  <PhoneInput
    ...
    placeholder="Custom Phone Input Placeholder"
    modalSearchInputPlaceholder="Custom Modal Search Input Placeholder"
    modalNotFoundCountryMessage="Custom Modal Not Found Country Message"
  />
  ...
  • Custom Modal Height:

  ...
  <PhoneInput
    ...
    modalHeight="80%"
  />
  ...
  • Country Modal Disabled Mode:

  ...
  <PhoneInput
    ...
    modalDisabled
  />
  ...
  • Phone Input Disabled Mode:

  ...
  <PhoneInput
    ...
    disabled
  />
  ...
  • Custom Disabled Mode Style:

  const [isDisabled, setIsDisabled] = useState<boolean>(true)
  ...
  <PhoneInput
    ...
    containerStyle={ isDisabled ? { backgroundColor: 'yellow' } : {} }
    disabled={isDisabled}
  />
  ...
  • Change Default Language:

  ...
  <PhoneInput
    ...
    language="pt"
  />
  ...
  • Custom Phone Mask:

  ...
  <PhoneInput
    ...
    customMask={['#### ####', '##### ####']}
  />
  ...
  • Custom Default Flag/Country:

  ...
  <PhoneInput
    ...
    defaultCountry="CA"
  />
  ...
  • Default Phone Number Value:

  ...
  <PhoneInput
    ...
    defaultValue="+12505550199"
  />
  ...

Observations:

  1. You need to use a default value with the e164 format: +(country callling code)(area code)(number phone)
  2. 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).
  • Show Only Some Countries Inside Modal:

  ...
  <PhoneInput
    ...
    showOnly={['BR', 'PT', 'CA', 'US']}
  />
  ...
  • Exclude Some Countries Inside Modal:

  ...
  <PhoneInput
    ...
    excludedCountries={['BR', 'PT', 'CA', 'US']}
  />
  ...
  ...
  <PhoneInput
    ...
    popularCountriess={['BR', 'PT', 'CA', 'US']}
    popularCountriesSectionTitle='Suggested'
    restOfCountriesSectionTitle='All'
  />
  ...
  • Right to Left Input:

  import { I18nManager } from "react-native";

  ...
  <PhoneInput
    ...
    rtl={I18nManager.isRTL}
  />
  ...
  • Don't allow Zero After Calling Code:

  ...
  <PhoneInput
    ...
    allowZeroAfterCallingCode={false}
  />
  ...

Component Props (PhoneInputProps)

  • language?: ILanguage;
  • customMask?: string[];
  • defaultValue?: string;
  • value?: string;
  • onChangePhoneNumber?: (phoneNumber: string) => void;
  • defaultCountry?: ICountryCca2;
  • selectedCountry?: ICountry;
  • onChangeSelectedCountry?: (country: ICountry) => void;
  • showOnly?: ICountryCca2[];
  • excludedCountries?: ICountryCca2[];
  • popularCountries?: ICountryCca2[];
  • popularCountriesSectionTitle?: string;
  • restOfCountriesSectionTitle?: string;
  • rtl?: boolean;
  • disabled?: boolean;
  • modalDisabled?: boolean;
  • modalHeight?: number | string;
  • theme?: ITheme;
  • phoneInputStyles?: IPhoneInputStyles;
  • modalStyles?: IModalStyles;
  • modalSearchInputPlaceholder?: string;
  • modalSearchInputPlaceholderTextColor?: string;
  • modalSearchInputSelectionColor?: string;
  • modalNotFoundCountryMessage?: string;
  • customCaret?: ReactNode;
  • ref?: Ref<IPhoneInputRef>;
  • allowZeroAfterCallingCode?: boolean

Functions

  • getAllCountries: () => ICountry[];
  • getCountriesByCallingCode: (callingCode: string) => ICountry[] | undefined;
  • getCountryByCca2: (cca2: string) => ICountry | undefined;
  • getCountriesByName: (name: string, language: ILanguage) => ICountry[] | undefined;
  • getCountryByPhoneNumber: (phoneNumber: string) => ICountry | undefined;

🎌 Supported languages 🎌

  "name": {
    "bg": "Bulgarian",
    "by": "Belarusian",
    "cn": "Chinese",
    "cz": "Czech",
    "de": "German",
    "ee": "Estonian",
    "el": "Greek",
    "en": "English",
    "es": "Espanol",
    "fr": "French",
    "he": "Hebrew",
    "it": "Italian",
    "jp": "Japanese",
    "nl": "Dutch",
    "pl": "Polish",
    "pt": "Portuguese",
    "ro": "Romanian",
    "ru": "Russian",
    "ua": "Ukrainian",
    "zh": "Chinese (Simplified)",
    "ar": "Arabic",
    "tr": "Turkish"
  },

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

FAQs

Package last updated on 26 Nov 2024

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

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc