Package Exports
- react-phone-number-input
- react-phone-number-input/basic-input
- react-phone-number-input/flags
- react-phone-number-input/locale/en
- react-phone-number-input/locale/en.json
- react-phone-number-input/locale/fr
- react-phone-number-input/locale/ru
- react-phone-number-input/modules/countries
- react-phone-number-input/style.css
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-phone-number-input) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
react-phone-number-input
International phone number <input/> for React (iPhone style).
Screenshots
Native <select/>
Desktop
Mobile
Usage
import 'react-phone-number-input/style.css'
import PhoneInput from 'react-phone-number-input'
return (
<PhoneInput
placeholder="Enter phone number"
value={ this.state.phone }
onChange={ phone => this.setState({ phone }) } />
)The international phone number input utilizes libphonenumber-js international phone number parsing and formatting library.
I could also easily include all country flags in a form of <svg/> React elements as part of this library but the overall size of the bundle would then be about 3 MegaBytes (yeah, those SVGs turned out to be really huge) which is too much for a website. Therefore the default behaviour is a compromise: instead of pleloading the flags for all countries in the expanded list of countries only the flag for the currently selected country is shown. This way the user only downloads a single SVG image and is not forced to download the whole international flags bundle.
CSS
The CSS files for this React component must be included on a page too.
When using Webpack
import 'react-phone-number-input/style.css'And set up a postcss-loader with a CSS autoprefixer for supporting old web browsers (e.g. last 2 versions, iOS >= 7, Android >= 4).
When not using Webpack
Get the style.css file from this package, process it with a CSS autoprefixer for supporting old web browsers (e.g. last 2 versions, iOS >= 7, Android >= 4), and then include the autoprefixed CSS file on a page.
<head>
<link rel="stylesheet" href="/css/react-phone-number-input/style.css"/>
</head>Validation
This component is based on libphonenumber-js which is a rewrite of Google's libphonenumber library which doesn't enforce any validation rules when entering phone numbers in "as you type" mode (e.g. when phone number is too long or too short).
For the actual phone number validation use libphonenumber-js: either a loose validation via parseNumber(value) or a strict validation via isValidNumber(value).
Autocomplete
Make sure to wrap a <PhoneInput/> into a <form/> otherwise web-browser's "autocomplete" feature may not be working: a user will be selecting his phone number from the list but nothing will be happening.
Custom country <select/>
One can supply their own country <select/> component in case the native one doesn't fit the app. Here's an example of using react-responsive-ui <Select/> component.
import 'react-responsive-ui/style.css'
import PhoneInput from 'react-phone-number-input/react-responsive-ui'
return (
<PhoneInput
placeholder="Enter phone number"
value={ this.state.phone }
onChange={ phone => this.setState({ phone }) } />
)Without country select
Some people requested an exported minimal phone number input component without country <select/>.
import PhoneInput from `react-phone-number-input/basic-input`
class Example extends Component {
state = {
value: ''
}
render() {
// If `country` property is not passed
// then "International" format is used.
return (
<PhoneInput
country="US"
value={ this.state.value }
onChange={ value => this.setState({ value }) } />
)
}
}Bug reporting
If you think that the phone number parsing/formatting/validation engine malfunctions for a particular phone number then follow the bug reporting instructions in libphonenumber-js repo.
API
React component
The available props are
value— Phone number in E.164 format. E.g.+12223333333for USA.onChange— Updates thevalue.country— (optional) The country which is selected by default (can be set after a GeoIP lookup). E.g.US.countries— (optional) Only the specified countries will be selectable. E.g.['RU', 'KZ', 'UA'].flagsPath— (optional) A base URL path for national flag SVG icons. By default it loads flag icons fromflag-icon-cssgithub repo. I imagine someone might want to download those SVG flag icons and host them on their own servers instead.flags— (optional) Supplies<svg/>elements for flags instead of the default<img src="..."/>ones. This might be suitable if someone's making an application which is supposed to be able to work offline (a downloadable app, or an "internal" website):import flags from 'react-phone-number-input/flags'.flagComponent— (optional) A React component for displaying a country flag (replaces the default flag icons).displayInitialValueAsLocalNumber— If set totruewill displayvaluephone number in local format when the component mounts or whenvalueproperty is set (see the example on the demo page). The default behaviour isfalsemeaning that if initialvalueis set then it will be displayed in international format. The reason for such default behaviour is that the newer generation grows up when there are no stationary phones and therefore everyone inputs phone numbers as international ones in their smartphones so people gradually get more accustomed to writing phone numbers in international form rather than in local form.error— aStringerror message that should be shown.indicateInvalid—errorwon't be shown unlessindicateInvalidistrue. The reason for this additional boolean flag is to enable some advanced ("smart") form field error indication scenarios.
For the full list of all possible props see the source code. All other properties are passed through to the <input/> component.
Localization
Country names can be passed via the labels property. E.g. labels={{ RU: 'Россия', US: 'США', ... }}. This component comes pre-packaged with a couple of ready-made translations. Submit pull requests for adding new translations.
import ru from 'react-phone-number-input/locale/ru'
<PhoneInput ... labels={ru}/>Extensions
Some users asked for phone extension input feature. It can be activated by passing ext property (React.Element). The ext property is most likely gonna be a redux-form <Field/> (or simpler-redux-form <Field/>).
import React, { Component } from 'react'
import { Field, reduxForm } from 'redux-form'
import Phone from 'react-phone-number-input'
@reduxForm({
form: 'contact'
})
class Form extends Component {
render() {
const { handleSubmit } = this.props
const ext = (
<Field
name="ext"
component="input"
type="number"
noValidate
className={ className } />
)
return (
<form onSubmit={ handleSubmit }>
<Field
name="phone"
component={ Phone }
ext={ ext } />
<button type="submit">
Submit
</button>
</form>
);
}
}The code above hasn't been tested, but it most likely works. Phone extension input will appear to the right of the phone number input. One can always skip using ext property and add a completely separate form field for phone number extension input instead.
{ number, ext } object can be converted to RFC3966 string for storing it in a database.
import { formatRFC3966 } from 'libphonenumber-js'
formatRFC3966({ number: '+12133734253', ext: '123' })
// 'tel:+12133734253;ext=123'Use the accompanying parseRFC3966() function to convert an RFC3966 string into an object having shape { number, ext }.
import { parseRFC3966 } from 'libphonenumber-js'
parseRFC3966('tel:+12133734253;ext=123')
// { number: '+12133734253', ext: '123' }Customizing
One can use the /custom export to import a bare <PhoneInput/> component and supply it with custom properties such as country select component and phone number input field component.
import PhoneInput from 'react-phone-number-input/custom'
import InternationalIcon from 'react-phone-number-input/international-icon'
import labels from 'react-phone-number-input/locale/ru'
<PhoneInput
countrySelectComponent={...required...}
inputComponent={...optional...}
internationalIcon={InternationalIcon}
labels={labels}/>countrySelectComponent
React component for the country select. See CountrySelectNative and CountrySelectReactResponsiveUI for an example.
Receives properties:
name : string?— HTMLnameattribute.value : string?— The currently selected country code.onChange(value : string?)— Updates thevalue.options : object[]— The list of all selectable countries (including "International") each being an object of shape{ value : string?, label : string, icon : React.Component }.disabled : boolean?— HTMLdisabledattribute.tabIndex : (number|string)?— HTMLtabIndexattribute.className : string— CSS class name.
inputComponent
React component for the phone number input field. See InputSmart and InputBasic for an example.
Receives properties:
value : string— The parsed phone number. E.g.:"","+","+123","123".onChange(value : string)— Updates thevalue.country : string?— The currently selected country.undefinedmeans "International" (no country selected).metadata : object—libphonenumber-jsmetadata.- All other properties should be passed through to the underlying
<input/>.
Must also implement .focus() method.
Reducing bundle size
By default all countries are included which means that libphonenumber-js loads the default metadata having the size of 75 kilobytes. This really isn't much but for those who still want to reduce that to a lesser size by generating their own reduced metadata set there is react-phone-number-input/custom export.
var PhoneInput = require('react-phone-number-input/custom').default
var metadata = require('./metadata.min.json')
module.exports = function Phone(props) {
return <PhoneInput { ...props } metadata={ metadata }/>
}For generating custom metadata see the guide in libphonenumber-js repo.
Module not found: Error: Can't resolve 'libphonenumber-js/metadata.min'
This error means that your Webpack is misconfigured to exclude .json file extension from the list of the resolved ones. To fix that add it back to resolve.extensions.
{
resolve: {
extensions: [".js", ".json", ...]
}
}If you're using Webpack 1 then upgrade to a newer version.
CDN
One can use any npm CDN service, e.g. unpkg.com or jsdelivr.net
<!-- `libphonenumber-js` (is used internally by `react-phone-number-input`). -->
<script src="https://unpkg.com/libphonenumber-js@1.2.15/bundle/libphonenumber-js.min.js"></script>
<!-- Either `react-phone-number-input` with "native" country `<select/>`. -->
<script src="https://unpkg.com/react-phone-number-input@2.0.0/bundle/react-phone-number-input-native.js"></script>
<!-- Or `react-phone-number-input` with `react-responsive-ui` `<Select/>`. -->
<script src="https://unpkg.com/react-phone-number-input@2.0.0/bundle/react-phone-number-input-react-responsive-ui.js"></script>
<!-- Styles for the component. -->
<link rel="stylesheet" href="https://unpkg.com/react-phone-number-input@2.0.0/bundle/style.css"/>
<!-- Styles for `react-responsive-ui` `<Select/> -->
<!-- (only if `react-responsive-ui` `<Select/>` is used). -->
<link rel="stylesheet" href="https://unpkg.com/react-responsive-ui@0.13.8/bundle/style.css"/>
<script>
var PhoneInput = window['react-phone-number-input']
</script>Advertisement
React Responsive UI component library.