function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
import Metadata from './metadata.js';
|
import PhoneNumber from './PhoneNumber.js';
|
import AsYouTypeState from './AsYouTypeState.js';
|
import AsYouTypeFormatter, { DIGIT_PLACEHOLDER } from './AsYouTypeFormatter.js';
|
import AsYouTypeParser, { extractFormattedDigitsAndPlus } from './AsYouTypeParser.js';
|
import getCountryByCallingCode from './helpers/getCountryByCallingCode.js';
|
import getCountryByNationalNumber from './helpers/getCountryByNationalNumber.js';
|
import isObject from './helpers/isObject.js';
|
var USE_NON_GEOGRAPHIC_COUNTRY_CODE = false;
|
|
var AsYouType = /*#__PURE__*/function () {
|
/**
|
* @param {(string|object)?} [optionsOrDefaultCountry] - The default country used for parsing non-international phone numbers. Can also be an `options` object.
|
* @param {Object} metadata
|
*/
|
function AsYouType(optionsOrDefaultCountry, metadata) {
|
_classCallCheck(this, AsYouType);
|
|
this.metadata = new Metadata(metadata);
|
|
var _this$getCountryAndCa = this.getCountryAndCallingCode(optionsOrDefaultCountry),
|
_this$getCountryAndCa2 = _slicedToArray(_this$getCountryAndCa, 2),
|
defaultCountry = _this$getCountryAndCa2[0],
|
defaultCallingCode = _this$getCountryAndCa2[1]; // `this.defaultCountry` and `this.defaultCallingCode` aren't required to be in sync.
|
// For example, `this.defaultCountry` could be `"AR"` and `this.defaultCallingCode` could be `undefined`.
|
// So `this.defaultCountry` and `this.defaultCallingCode` are totally independent.
|
|
|
this.defaultCountry = defaultCountry;
|
this.defaultCallingCode = defaultCallingCode;
|
this.reset();
|
}
|
|
_createClass(AsYouType, [{
|
key: "getCountryAndCallingCode",
|
value: function getCountryAndCallingCode(optionsOrDefaultCountry) {
|
// Set `defaultCountry` and `defaultCallingCode` options.
|
var defaultCountry;
|
var defaultCallingCode; // Turns out `null` also has type "object". Weird.
|
|
if (optionsOrDefaultCountry) {
|
if (isObject(optionsOrDefaultCountry)) {
|
defaultCountry = optionsOrDefaultCountry.defaultCountry;
|
defaultCallingCode = optionsOrDefaultCountry.defaultCallingCode;
|
} else {
|
defaultCountry = optionsOrDefaultCountry;
|
}
|
}
|
|
if (defaultCountry && !this.metadata.hasCountry(defaultCountry)) {
|
defaultCountry = undefined;
|
}
|
|
if (defaultCallingCode) {
|
/* istanbul ignore if */
|
if (USE_NON_GEOGRAPHIC_COUNTRY_CODE) {
|
if (this.metadata.isNonGeographicCallingCode(defaultCallingCode)) {
|
defaultCountry = '001';
|
}
|
}
|
}
|
|
return [defaultCountry, defaultCallingCode];
|
}
|
/**
|
* Inputs "next" phone number characters.
|
* @param {string} text
|
* @return {string} Formatted phone number characters that have been input so far.
|
*/
|
|
}, {
|
key: "input",
|
value: function input(text) {
|
var _this$parser$input = this.parser.input(text, this.state),
|
digits = _this$parser$input.digits,
|
justLeadingPlus = _this$parser$input.justLeadingPlus;
|
|
if (justLeadingPlus) {
|
this.formattedOutput = '+';
|
} else if (digits) {
|
this.determineTheCountryIfNeeded(); // Match the available formats by the currently available leading digits.
|
|
if (this.state.nationalSignificantNumber) {
|
this.formatter.narrowDownMatchingFormats(this.state);
|
}
|
|
var formattedNationalNumber;
|
|
if (this.metadata.hasSelectedNumberingPlan()) {
|
formattedNationalNumber = this.formatter.format(digits, this.state);
|
}
|
|
if (formattedNationalNumber === undefined) {
|
// See if another national (significant) number could be re-extracted.
|
if (this.parser.reExtractNationalSignificantNumber(this.state)) {
|
this.determineTheCountryIfNeeded(); // If it could, then re-try formatting the new national (significant) number.
|
|
var nationalDigits = this.state.getNationalDigits();
|
|
if (nationalDigits) {
|
formattedNationalNumber = this.formatter.format(nationalDigits, this.state);
|
}
|
}
|
}
|
|
this.formattedOutput = formattedNationalNumber ? this.getFullNumber(formattedNationalNumber) : this.getNonFormattedNumber();
|
}
|
|
return this.formattedOutput;
|
}
|
}, {
|
key: "reset",
|
value: function reset() {
|
var _this = this;
|
|
this.state = new AsYouTypeState({
|
onCountryChange: function onCountryChange(country) {
|
// Before version `1.6.0`, the official `AsYouType` formatter API
|
// included the `.country` property of an `AsYouType` instance.
|
// Since that property (along with the others) have been moved to
|
// `this.state`, `this.country` property is emulated for compatibility
|
// with the old versions.
|
_this.country = country;
|
},
|
onCallingCodeChange: function onCallingCodeChange(callingCode, country) {
|
_this.metadata.selectNumberingPlan(country, callingCode);
|
|
_this.formatter.reset(_this.metadata.numberingPlan, _this.state);
|
|
_this.parser.reset(_this.metadata.numberingPlan);
|
}
|
});
|
this.formatter = new AsYouTypeFormatter({
|
state: this.state,
|
metadata: this.metadata
|
});
|
this.parser = new AsYouTypeParser({
|
defaultCountry: this.defaultCountry,
|
defaultCallingCode: this.defaultCallingCode,
|
metadata: this.metadata,
|
state: this.state,
|
onNationalSignificantNumberChange: function onNationalSignificantNumberChange() {
|
_this.determineTheCountryIfNeeded();
|
|
_this.formatter.reset(_this.metadata.numberingPlan, _this.state);
|
}
|
});
|
this.state.reset({
|
country: this.defaultCountry,
|
callingCode: this.defaultCallingCode
|
});
|
this.formattedOutput = '';
|
return this;
|
}
|
/**
|
* Returns `true` if the phone number is being input in international format.
|
* In other words, returns `true` if and only if the parsed phone number starts with a `"+"`.
|
* @return {boolean}
|
*/
|
|
}, {
|
key: "isInternational",
|
value: function isInternational() {
|
return this.state.international;
|
}
|
/**
|
* Returns the "calling code" part of the phone number when it's being input
|
* in an international format.
|
* If no valid calling code has been entered so far, returns `undefined`.
|
* @return {string} [callingCode]
|
*/
|
|
}, {
|
key: "getCallingCode",
|
value: function getCallingCode() {
|
// If the number is being input in national format and some "default calling code"
|
// has been passed to `AsYouType` constructor, then `this.state.callingCode`
|
// is equal to that "default calling code".
|
//
|
// If the number is being input in national format and no "default calling code"
|
// has been passed to `AsYouType` constructor, then returns `undefined`,
|
// even if a "default country" has been passed to `AsYouType` constructor.
|
//
|
if (this.isInternational()) {
|
return this.state.callingCode;
|
}
|
} // A legacy alias.
|
|
}, {
|
key: "getCountryCallingCode",
|
value: function getCountryCallingCode() {
|
return this.getCallingCode();
|
}
|
/**
|
* Returns a two-letter country code of the phone number.
|
* Returns `undefined` for "non-geographic" phone numbering plans.
|
* Returns `undefined` if no phone number has been input yet.
|
* @return {string} [country]
|
*/
|
|
}, {
|
key: "getCountry",
|
value: function getCountry() {
|
var digits = this.state.digits; // Return `undefined` if no digits have been input yet.
|
|
if (digits) {
|
return this._getCountry();
|
}
|
}
|
/**
|
* Returns a two-letter country code of the phone number.
|
* Returns `undefined` for "non-geographic" phone numbering plans.
|
* @return {string} [country]
|
*/
|
|
}, {
|
key: "_getCountry",
|
value: function _getCountry() {
|
var country = this.state.country;
|
/* istanbul ignore if */
|
|
if (USE_NON_GEOGRAPHIC_COUNTRY_CODE) {
|
// `AsYouType.getCountry()` returns `undefined`
|
// for "non-geographic" phone numbering plans.
|
if (country === '001') {
|
return;
|
}
|
}
|
|
return country;
|
}
|
}, {
|
key: "determineTheCountryIfNeeded",
|
value: function determineTheCountryIfNeeded() {
|
// Suppose a user enters a phone number in international format,
|
// and there're several countries corresponding to that country calling code,
|
// and a country has been derived from the number, and then
|
// a user enters one more digit and the number is no longer
|
// valid for the derived country, so the country should be re-derived
|
// on every new digit in those cases.
|
//
|
// If the phone number is being input in national format,
|
// then it could be a case when `defaultCountry` wasn't specified
|
// when creating `AsYouType` instance, and just `defaultCallingCode` was specified,
|
// and that "calling code" could correspond to a "non-geographic entity",
|
// or there could be several countries corresponding to that country calling code.
|
// In those cases, `this.country` is `undefined` and should be derived
|
// from the number. Again, if country calling code is ambiguous, then
|
// `this.country` should be re-derived with each new digit.
|
//
|
if (!this.state.country || this.isCountryCallingCodeAmbiguous()) {
|
this.determineTheCountry();
|
}
|
} // Prepends `+CountryCode ` in case of an international phone number
|
|
}, {
|
key: "getFullNumber",
|
value: function getFullNumber(formattedNationalNumber) {
|
var _this2 = this;
|
|
if (this.isInternational()) {
|
var prefix = function prefix(text) {
|
return _this2.formatter.getInternationalPrefixBeforeCountryCallingCode(_this2.state, {
|
spacing: text ? true : false
|
}) + text;
|
};
|
|
var callingCode = this.state.callingCode;
|
|
if (!callingCode) {
|
return prefix("".concat(this.state.getDigitsWithoutInternationalPrefix()));
|
}
|
|
if (!formattedNationalNumber) {
|
return prefix(callingCode);
|
}
|
|
return prefix("".concat(callingCode, " ").concat(formattedNationalNumber));
|
}
|
|
return formattedNationalNumber;
|
}
|
}, {
|
key: "getNonFormattedNationalNumberWithPrefix",
|
value: function getNonFormattedNationalNumberWithPrefix() {
|
var _this$state = this.state,
|
nationalSignificantNumber = _this$state.nationalSignificantNumber,
|
complexPrefixBeforeNationalSignificantNumber = _this$state.complexPrefixBeforeNationalSignificantNumber,
|
nationalPrefix = _this$state.nationalPrefix;
|
var number = nationalSignificantNumber;
|
var prefix = complexPrefixBeforeNationalSignificantNumber || nationalPrefix;
|
|
if (prefix) {
|
number = prefix + number;
|
}
|
|
return number;
|
}
|
}, {
|
key: "getNonFormattedNumber",
|
value: function getNonFormattedNumber() {
|
var nationalSignificantNumberMatchesInput = this.state.nationalSignificantNumberMatchesInput;
|
return this.getFullNumber(nationalSignificantNumberMatchesInput ? this.getNonFormattedNationalNumberWithPrefix() : this.state.getNationalDigits());
|
}
|
}, {
|
key: "getNonFormattedTemplate",
|
value: function getNonFormattedTemplate() {
|
var number = this.getNonFormattedNumber();
|
|
if (number) {
|
return number.replace(/[\+\d]/g, DIGIT_PLACEHOLDER);
|
}
|
}
|
}, {
|
key: "isCountryCallingCodeAmbiguous",
|
value: function isCountryCallingCodeAmbiguous() {
|
var callingCode = this.state.callingCode;
|
var countryCodes = this.metadata.getCountryCodesForCallingCode(callingCode);
|
return countryCodes && countryCodes.length > 1;
|
} // Determines the country of the phone number
|
// entered so far based on the country phone code
|
// and the national phone number.
|
|
}, {
|
key: "determineTheCountry",
|
value: function determineTheCountry() {
|
this.state.setCountry(getCountryByCallingCode(this.isInternational() ? this.state.callingCode : this.defaultCallingCode, {
|
nationalNumber: this.state.nationalSignificantNumber,
|
defaultCountry: this.defaultCountry,
|
metadata: this.metadata
|
}));
|
}
|
/**
|
* Returns a E.164 phone number value for the user's input.
|
*
|
* For example, for country `"US"` and input `"(222) 333-4444"`
|
* it will return `"+12223334444"`.
|
*
|
* For international phone number input, it will also auto-correct
|
* some minor errors such as using a national prefix when writing
|
* an international phone number. For example, if the user inputs
|
* `"+44 0 7400 000000"` then it will return an auto-corrected
|
* `"+447400000000"` phone number value.
|
*
|
* Will return `undefined` if no digits have been input,
|
* or when inputting a phone number in national format and no
|
* default country or default "country calling code" have been set.
|
*
|
* @return {string} [value]
|
*/
|
|
}, {
|
key: "getNumberValue",
|
value: function getNumberValue() {
|
var _this$state2 = this.state,
|
digits = _this$state2.digits,
|
callingCode = _this$state2.callingCode,
|
country = _this$state2.country,
|
nationalSignificantNumber = _this$state2.nationalSignificantNumber; // Will return `undefined` if no digits have been input.
|
|
if (!digits) {
|
return;
|
}
|
|
if (this.isInternational()) {
|
if (callingCode) {
|
return '+' + callingCode + nationalSignificantNumber;
|
} else {
|
return '+' + digits;
|
}
|
} else {
|
if (country || callingCode) {
|
var callingCode_ = country ? this.metadata.countryCallingCode() : callingCode;
|
return '+' + callingCode_ + nationalSignificantNumber;
|
}
|
}
|
}
|
/**
|
* Returns an instance of `PhoneNumber` class.
|
* Will return `undefined` if no national (significant) number
|
* digits have been entered so far, or if no `defaultCountry` has been
|
* set and the user enters a phone number not in international format.
|
*/
|
|
}, {
|
key: "getNumber",
|
value: function getNumber() {
|
var _this$state3 = this.state,
|
nationalSignificantNumber = _this$state3.nationalSignificantNumber,
|
carrierCode = _this$state3.carrierCode,
|
callingCode = _this$state3.callingCode; // `this._getCountry()` is basically same as `this.state.country`
|
// with the only change that it return `undefined` in case of a
|
// "non-geographic" numbering plan instead of `"001"` "internal use" value.
|
|
var country = this._getCountry();
|
|
if (!nationalSignificantNumber) {
|
return;
|
} // `state.country` and `state.callingCode` aren't required to be in sync.
|
// For example, `country` could be `"AR"` and `callingCode` could be `undefined`.
|
// So `country` and `callingCode` are totally independent.
|
|
|
if (!country && !callingCode) {
|
return;
|
} // By default, if `defaultCountry` parameter was passed when
|
// creating `AsYouType` instance, `state.country` is gonna be
|
// that `defaultCountry`, which doesn't entirely conform with
|
// `parsePhoneNumber()`'s behavior where it attempts to determine
|
// the country more precisely in cases when multiple countries
|
// could correspond to the same `countryCallingCode`.
|
// https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/103#note_1417192969
|
//
|
// Because `AsYouType.getNumber()` method is supposed to be a 1:1
|
// equivalent for `parsePhoneNumber(AsYouType.getNumberValue())`,
|
// then it should also behave accordingly in cases of `country` ambiguity.
|
// That's how users of this library would expect it to behave anyway.
|
//
|
|
|
if (country) {
|
if (country === this.defaultCountry) {
|
// `state.country` and `state.callingCode` aren't required to be in sync.
|
// For example, `state.country` could be `"AR"` and `state.callingCode` could be `undefined`.
|
// So `state.country` and `state.callingCode` are totally independent.
|
var metadata = new Metadata(this.metadata.metadata);
|
metadata.selectNumberingPlan(country);
|
|
var _callingCode = metadata.numberingPlan.callingCode();
|
|
var ambiguousCountries = this.metadata.getCountryCodesForCallingCode(_callingCode);
|
|
if (ambiguousCountries.length > 1) {
|
var exactCountry = getCountryByNationalNumber(nationalSignificantNumber, {
|
countries: ambiguousCountries,
|
defaultCountry: this.defaultCountry,
|
metadata: this.metadata.metadata
|
});
|
|
if (exactCountry) {
|
country = exactCountry;
|
}
|
}
|
}
|
}
|
|
var phoneNumber = new PhoneNumber(country || callingCode, nationalSignificantNumber, this.metadata.metadata);
|
|
if (carrierCode) {
|
phoneNumber.carrierCode = carrierCode;
|
} // Phone number extensions are not supported by "As You Type" formatter.
|
|
|
return phoneNumber;
|
}
|
/**
|
* Returns `true` if the phone number is "possible".
|
* Is just a shortcut for `PhoneNumber.isPossible()`.
|
* @return {boolean}
|
*/
|
|
}, {
|
key: "isPossible",
|
value: function isPossible() {
|
var phoneNumber = this.getNumber();
|
|
if (!phoneNumber) {
|
return false;
|
}
|
|
return phoneNumber.isPossible();
|
}
|
/**
|
* Returns `true` if the phone number is "valid".
|
* Is just a shortcut for `PhoneNumber.isValid()`.
|
* @return {boolean}
|
*/
|
|
}, {
|
key: "isValid",
|
value: function isValid() {
|
var phoneNumber = this.getNumber();
|
|
if (!phoneNumber) {
|
return false;
|
}
|
|
return phoneNumber.isValid();
|
}
|
/**
|
* @deprecated
|
* This method is used in `react-phone-number-input/source/input-control.js`
|
* in versions before `3.0.16`.
|
*/
|
|
}, {
|
key: "getNationalNumber",
|
value: function getNationalNumber() {
|
return this.state.nationalSignificantNumber;
|
}
|
/**
|
* Returns the phone number characters entered by the user.
|
* @return {string}
|
*/
|
|
}, {
|
key: "getChars",
|
value: function getChars() {
|
return (this.state.international ? '+' : '') + this.state.digits;
|
}
|
/**
|
* Returns the template for the formatted phone number.
|
* @return {string}
|
*/
|
|
}, {
|
key: "getTemplate",
|
value: function getTemplate() {
|
return this.formatter.getTemplate(this.state) || this.getNonFormattedTemplate() || '';
|
}
|
}]);
|
|
return AsYouType;
|
}();
|
|
export { AsYouType as default };
|
//# sourceMappingURL=AsYouType.js.map
|