Skip to main content
Version: v0.30.x

PhoneField

PhoneField is a React Native phone number input: a country button with the flag and calling code, then the number, grouped the way that country writes it as the user types. The value is one string in E.164, such as '+972541234567', ready to store or send to an SMS service.

The country list is CountryPicker: searchable, in the device language, a bottom sheet on phones and a dropdown on the web. The field follows the iOS, Material or web design. No dependency and no metadata download: formats for about 50 countries add 2 KB.

import { PhoneField } from '@elik56a/react-native-pickers';
Loading…
<PhoneField label="Phone" defaultCountry="IL" value={phone} onChange={setPhone} />

Type 054 123 4567: the leading 0 is dropped, the number shows as 54-123-4567, and the value is +972541234567. Paste +44 7911 123456 and the field switches to the United Kingdom.

Try the props​

Platform
presentation
locale
error
<PhoneField
label="Phone"
preferred={['US', 'GB', 'IL']}
value={phone}
onChange={setPhone}
locale="en"
/>

Checking the number​

onChange passes the E.164 value and the details: the country, the digits after the calling code, and valid, whether the number has as many digits as that country's numbers do.

Loading…
<View style={{ gap: 8 }}>
  <PhoneField
    label="Mobile"
    preferred={['US', 'GB', 'CA']}
    value={phone}
    onChange={(value, info) => {
      setPhone(value);
      setDetails(info);
    }}
  />
  <Text>{details ? `${details.country} · ${details.valid ? 'looks right' : 'too short or too long'}` : 'Type a number'}</Text>
</View>

valid checks the length only, which catches most typos. For carrier checks, verify on your server, as with an SMS code.

Errors and helper text​

error shows the field as invalid: a red border and label, and the message under the field when it's a string. helperText is the line under the field while there's no error message, and required adds an asterisk to the label. Pair error with valid; in a form, set it on submit rather than while the user is still typing:

Loading…
<PhoneField
  label="Mobile"
  required
  helperText="We'll text you a code"
  error={phone !== '' && !valid && 'Enter a full number'}
  value={phone}
  onChange={(value, details) => {
    setPhone(value);
    setValid(details.valid);
  }}
/>

The country​

The country follows the number: a value or a pasted number with another calling code shows its own country. Before there is a number, defaultCountry picks it, or control it with country and onCountryChange, for example from the device region.

Countries sharing a calling code keep the one chosen: a US number with a Caribbean area code stays American. Picking another country keeps the digits and moves them to its calling code.

How numbers are formatted​

About 50 countries, those with the most phone users, have their own pattern: (201) 555-0123 in the US, 6 12 34 56 78 in France, 54-123-4567 in Israel. Countries sharing a calling code with one of them use its pattern, so Canada and the Caribbean look American. The rest are grouped in threes. Grouping is only for display; the value is always digits.

A leading 0, the trunk prefix most countries dial at home, is dropped, except in Italy, San Marino and the Vatican, where it's part of the number.

Utilities​

ExportDescription
parsePhone(international, current?){ country?, nationalNumber } for a number like '+44 7911 123456'
formatNationalNumber(digits, country)'2015550123', 'US' → '(201) 555-0123'
isValidPhone(digits, country)Whether the digits after the calling code have a valid length
toE164(digits, country)'541234567', 'IL' → '+972541234567'
const { country, nationalNumber } = parsePhone(user.phone);
const shown = country ? formatNationalNumber(nationalNumber, country) : user.phone;

Props​

PropTypeDefaultDescription
valuestring—The number in E.164, '' when empty. Leave it out to keep the number inside.
defaultValuestring''Starting number when value isn't set.
onChange(value: string, details: PhoneDetails) => void—Called as the user types or picks a country.
countryCountryCode—The country whose calling code is used.
defaultCountryCountryCode'US'Starting country when country isn't set.
onCountryChange(country: CountryCode) => void—Called when the user picks a country or pastes a number from another.
labelstring—Above the field, or on its border in Material. Screen readers hear Phone number without one.
placeholderstringan example, e.g. (123) 456-7890Shown while empty.
disabledbooleanfalse
errorstring | boolean—Shows the field as invalid, with the message under it when it's a string. See Errors and helper text.
helperTextstring—Shown under the field, replaced by the error message.
requiredbooleanfalseAdds an asterisk to the label and tells screen readers the field is required. The number isn't checked.
countries / exclude / preferredCountryCode[]—Which countries the list offers, and which come first. See CountryPicker.
preferredLabel / allCountriesLabelstring'Suggested' / 'All countries'Headers of the list.
localestringdevice localeLanguage of the country names.
presentation'auto' | 'dropdown' | 'bottomSheet' | 'modal' | 'inline''auto'Where the country list opens: a dropdown on the web, a bottom sheet on native.
countrySheetTitlestring'Country code'Title of the country sheet.
sheetPartial<SheetChromeProps>sheetProps.height: 0.8Options for the country sheet, as CountryPicker's.
theme / designSee Theming and Designs.
styleStyleProp<ViewStyle>—The field's container.
styles{ label, field, input, countryButton, dialCode, chevron, helperText }—Slot styles.
testIDstring—On the text input; the country button gets ${testID}-country.

Types​

interface PhoneDetails {
country: CountryCode;
nationalNumber: string; // digits after the calling code, e.g. '541234567'
valid: boolean; // has as many digits as the country's numbers do
}