react-intl-tel-input
Version:
Telephone input component. Rewrite intl-tel-input in React.js.
501 lines (424 loc) • 12.2 kB
TypeScript
import React from 'react'
import { CountryData } from '../types'
export interface IntlTelInputProps {
/**
* Container CSS class name.
* @default 'intl-tel-input'
*/
containerClassName?: string
/**
* Text input CSS class name.
* @default ''
*/
inputClassName?: string
/**
* It's used as `input` field `name` attribute.
* @default ''
*/
fieldName?: string
/**
* It's used as `input` field `id` attribute.
* @default ''
*/
fieldId?: string
/**
* The value of the input field. Useful for making input value controlled from outside the component.
*/
value?: string
/**
* The value used to initialize input. This will only work on uncontrolled component.
* @default ''
*/
defaultValue?: string
/**
* Countries data can be configured, it defaults to data defined in `AllCountries`.
* @default AllCountries.getCountries()
*/
countriesData?: CountryData[] | null
/**
* Whether or not to allow the dropdown. If disabled, there is no dropdown arrow, and the selected flag is not clickable.
* Also we display the selected flag on the right instead because it is just a marker of state.
* @default true
*/
allowDropdown?: boolean
/**
* If there is just a dial code in the input: remove it on blur, and re-add it on focus.
* @default true
*/
autoHideDialCode?: boolean
/**
* Add or remove input placeholder with an example number for the selected country.
* @default true
*/
autoPlaceholder?: boolean
/**
* Change the placeholder generated by autoPlaceholder. Must return a string.
* @default null
*/
customPlaceholder?:
| ((placeholder: string, selectedCountryData: CountryData) => string)
| null
/**
* Don't display the countries you specify. (Array)
* @default []
*/
excludeCountries?: string[]
/**
* Format the input value during initialisation.
* @default true
*/
formatOnInit?: boolean
/**
* Display the country dial code next to the selected flag so it's not part of the typed number.
* Note that this will disable nationalMode because technically we are dealing with international numbers,
* but with the dial code separated.
* @default false
*/
separateDialCode?: boolean
/**
* Default country.
* @default ''
*/
defaultCountry?: string
/**
* GeoIp lookup function.
* @default null
*/
geoIpLookup?: (countryCode: string) => void
/**
* Don't insert international dial codes.
* @default true
*/
nationalMode?: boolean
/**
* Number type to use for placeholders.
* @default 'MOBILE'
*/
numberType?: string
/**
* The function which can catch the "no this default country" exception.
* @default null
*/
noCountryDataHandler?: (countryCode: string) => void
/**
* Display only these countries.
* @default []
*/
onlyCountries?: string[]
/**
* The countries at the top of the list. defaults to United States and United Kingdom.
* @default ['us', 'gb']
*/
preferredCountries?: string[]
/**
* Optional validation callback function. It returns validation status, input box value and selected country data.
* @default null
*/
onPhoneNumberChange?: (
isValid: boolean,
value: string,
selectedCountryData: CountryData,
fullNumber: string,
extension: string,
) => void
/**
* Optional validation callback function. It returns validation status, input box value and selected country data.
* @default null
*/
onPhoneNumberBlur?: (
isValid: boolean,
value: string,
selectedCountryData: CountryData,
fullNumber: string,
extension: string,
event: React.FocusEvent<HTMLInputElement>,
) => void
/**
* Optional validation callback function. It returns validation status, input box value and selected country data.
* @default null
*/
onPhoneNumberFocus?: (
isValid: boolean,
value: string,
selectedCountryData: CountryData,
fullNumber: string,
extension: string,
event: React.FocusEvent<HTMLInputElement>,
) => void
/**
* Allow main app to do things when a country is selected.
* @default null
*/
onSelectFlag?: (
currentNumber: string,
selectedCountryData: CountryData,
fullNumber: string,
isValid: boolean,
) => void
/**
* Disable this component.
* @default false
*/
disabled?: boolean
/**
* Static placeholder for input controller. When defined it takes priority over autoPlaceholder.
*/
placeholder?: string
/**
* Enable auto focus
* @default false
*/
autoFocus?: boolean
/**
* Set the value of the autoComplete attribute on the input.
* For example, set it to phone to tell the browser where to auto complete phone numbers.
* @default 'off'
*/
autoComplete?: string
/**
* Style object for the wrapper div. Useful for setting 100% width on the wrapper, etc.
*/
style?: React.CSSProperties
/**
* Render fullscreen flag dropdown when mobile useragent is detected.
* The dropdown element is rendered as a direct child of document.body
* @default true
*/
useMobileFullscreenDropdown?: boolean
/**
* Pass through arbitrary props to the tel input element.
* @default {}
*/
telInputProps?: React.InputHTMLAttributes<HTMLInputElement>
/**
* Format the number.
* @default true
*/
format?: boolean
/**
* Allow main app to do things when flag icon is clicked.
* @default null
*/
onFlagClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
}
export interface IntlTelInputState {
showDropdown: boolean
highlightedCountry: number
value: string
disabled: boolean
readonly: boolean
offsetTop: number
outerHeight: number
placeholder: string
title: string
countryCode: string
dialCode: string
cursorPosition: any
}
export default class IntlTelInput extends React.Component<
IntlTelInputProps,
IntlTelInputState
> {
//#region Properties
wrapperClass: {
[key: string]: boolean
}
defaultCountry?: string
autoCountry: string
tempCountry: string
startedLoadingAutoCountry: boolean
dropdownContainer?: React.ElementType | ''
isOpening: boolean
isMobile: boolean
preferredCountries: CountryData[]
countries: CountryData[]
countryCodes: {
[key: string]: string[]
}
windowLoaded: boolean
query: string
selectedCountryData?: CountryData
// prop copies
autoHideDialCode: boolean
nationalMode: boolean
allowDropdown: boolean
// refs
/**
* `<div>` HTML element of the `FlagDropDown` React component.
*/
flagDropDown: HTMLDivElement | null
/**
* `<input>` HTML element of the `TelInput` React component.
*/
tel: HTMLInputElement | null
// NOTE:
// The underscore.deferred package doesn't have known type definitions.
// The closest counterpart is jquery's Deferred object, which it claims to derive itself from.
// These two are equivalent if you log it in console:
//
// underscore.deferred
// var deferred = new _.Deferred()
//
// jquery
// var deferred = $.Deferred()
deferreds: JQuery.Deferred<any, any, any>[]
autoCountryDeferred: JQuery.Deferred<any, any, any>
utilsScriptDeferred: JQuery.Deferred<any, any, any>
//#endregion
//#region Methods
/**
* Updates flag when value of defaultCountry props change
*/
updateFlagOnDefaultCountryChange(countryCode?: string): void
getTempCountry(countryCode?: string): CountryData['iso2'] | 'auto'
/**
* set the input value and update the flag
*/
setNumber(number: string, preventFocus?: boolean): void
setFlagDropdownRef(ref: HTMLDivElement | null): void
setTelRef(ref: HTMLInputElement | null): void
/**
* select the given flag, update the placeholder and the active list item
*
* Note: called from setInitialState, updateFlagFromNumber, selectListItem, setCountry, updateFlagOnDefaultCountryChange
*/
setFlag(countryCode?: string, isInit?: boolean): void
/**
* get the extension from the current number
*/
getExtension(number?: string): string
/**
* format the number to the given format
*/
getNumber(number?: string, format?: string): string
/**
* get the input val, adding the dial code if separateDialCode is enabled
*/
getFullNumber(number?: string): string
/**
* try and extract a valid international dial code from a full telephone number
*/
getDialCode(number: string): string
/**
* check if the given number contains an unknown area code from
*/
isUnknownNanp(number?: string, dialCode?: string): boolean
/**
* add a country code to countryCodes
*/
addCountryCode(
countryCodes: {
[key: string]: string[]
},
iso2: string,
dialCode: string,
priority?: number,
): {
[key: string]: string[]
}
processAllCountries(): void
/**
* process the countryCodes map
*/
processCountryCodes(): void
/**
* process preferred countries - iterate through the preferences,
* fetching the country data for each one
*/
processPreferredCountries(): void
/**
* set the initial state of the input value and the selected flag
*/
setInitialState(): void
initRequests(): void
loadCountryFromLocalStorage(): string
loadAutoCountry(): void
cap(number?: string): string | undefined
removeEmptyDialCode(): void
/**
* highlight the next/prev item in the list (and ensure it is visible)
*/
handleUpDownKey(key?: number): void
/**
* select the currently highlighted item
*/
handleEnterKey(): void
/**
* find the first list item whose name starts with the query string
*/
searchForCountry(query: string): void
formatNumber(number?: string): string
/**
* update the input's value to the given val (format first if possible)
*/
updateValFromNumber(
number?: string,
doFormat?: boolean,
doNotify?: boolean,
): void
/**
* check if need to select a new flag based on the given number
*/
updateFlagFromNumber(number?: string, isInit?: boolean): void
/**
* filter the given countries using the process function
*/
filterCountries(
countryArray: string[],
processFunc: (iso2: string) => void,
): void
/**
* prepare all of the country data, including onlyCountries and preferredCountries options
*/
processCountryData(): void
handleOnBlur(event: React.FocusEvent<HTMLInputElement>): void
handleOnFocus(event: React.FocusEvent<HTMLInputElement>): void
bindDocumentClick(): void
unbindDocumentClick(): void
clickSelectedFlag(event: React.MouseEvent<HTMLDivElement, MouseEvent>): void
/**
* update the input placeholder to an
* example number from the currently selected country
*/
updatePlaceholder(props?: IntlTelInputProps): void
toggleDropdown(status?: boolean): void
/**
* check if an element is visible within it's container, else scroll until it is
*/
scrollTo(element: Element, middle?: boolean): void
/**
* replace any existing dial code with the new one
*
* Note: called from _setFlag
*/
updateDialCode(newDialCode?: string, hasSelectedListItem?: boolean): string
generateMarkup(): void
handleSelectedFlagKeydown(event: React.KeyboardEvent<HTMLDivElement>): void
/**
* validate the input val - assumes the global function isValidNumber (from libphonenumber)
*/
isValidNumber(number?: string): boolean
formatFullNumber(number?: string): string
notifyPhoneNumberChange(number?: string): void
/**
* remove the dial code if separateDialCode is enabled
*/
beforeSetNumber(
number?: string,
props?: IntlTelInputProps,
): string | undefined
handleWindowScroll(): void
handleDocumentKeyDown(event: KeyboardEvent): void
handleDocumentClick(event: MouseEvent): void
/**
* Either notify phoneNumber changed if component is controlled
*/
handleInputChange(event: React.FocusEvent<HTMLInputElement>): void
changeHighlightCountry(showDropdown: boolean, selectedIndex: number): void
loadUtils(): void
/**
* this is called when the geoip call returns
*/
autoCountryLoaded(): void
//#endregion
}