rn-phone-input-field
Version:
A React Native phone number input component built from scratch, featuring a text input for number entry, a custom dropdown for selecting country codes, and validation logic using regex or country-specific rules. It supports formatting, localization, and s
138 lines (137 loc) • 5.74 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isValidForCountry = exports.sanitizePhoneInputValue = exports.getMaxNationalNumberLength = exports.parsePhoneValue = exports.toSelectedCountryPayload = exports.getCountryByCode = exports.normalizePhoneRegex = exports.normalizeCallingCode = exports.normalizeDigits = void 0;
var constants_1 = __importDefault(require("../constants/constants"));
var countryUtils_1 = require("../constants/countryUtils");
var NON_DIGIT_REGEX = /\D/g;
var MAX_PHONE_NUMBER_LENGTH = 20;
var normalizeDigits = function (value) {
return String(value || '').replace(NON_DIGIT_REGEX, '');
};
exports.normalizeDigits = normalizeDigits;
var normalizeCallingCode = function (callingCode) {
return (0, exports.normalizeDigits)(callingCode);
};
exports.normalizeCallingCode = normalizeCallingCode;
var normalizePhoneRegex = function (regex) {
return String(regex || '').replace(/(^|[^\\])d\{/g, '$1\\d{');
};
exports.normalizePhoneRegex = normalizePhoneRegex;
var countriesByCallingCode = (0, countryUtils_1.getCountries)().sort(function (left, right) {
return (0, exports.normalizeCallingCode)(right.callingCode).length -
(0, exports.normalizeCallingCode)(left.callingCode).length;
});
var getCountryByCode = function (code) {
var fallback = constants_1.default.US;
if (!code) {
return fallback;
}
return constants_1.default[code.toUpperCase()] || fallback;
};
exports.getCountryByCode = getCountryByCode;
var toSelectedCountryPayload = function (country) { return ({
countryCode: country.countryCode,
callingCode: country.callingCode,
}); };
exports.toSelectedCountryPayload = toSelectedCountryPayload;
var parsePhoneValue = function (value, defaultCountry) {
var rawValue = String(value || '').trim();
var digits = (0, exports.normalizeDigits)(rawValue);
if (!digits) {
return {
country: defaultCountry ? (0, exports.getCountryByCode)(defaultCountry) : undefined,
nationalNumber: '',
};
}
var hasInternationalPrefix = rawValue.startsWith('+');
var matchedCountry = countriesByCallingCode.find(function (country) {
var callingCode = (0, exports.normalizeCallingCode)(country.callingCode);
if (!callingCode || !digits.startsWith(callingCode)) {
return false;
}
return hasInternationalPrefix || callingCode.length > 1;
});
if (!matchedCountry) {
return {
country: defaultCountry ? (0, exports.getCountryByCode)(defaultCountry) : undefined,
nationalNumber: digits,
};
}
var callingCode = (0, exports.normalizeCallingCode)(matchedCountry.callingCode);
return {
country: matchedCountry,
nationalNumber: digits.slice(callingCode.length),
};
};
exports.parsePhoneValue = parsePhoneValue;
var readQuantifier = function (pattern, startIndex) {
if (pattern[startIndex] !== '{') {
return { repeat: 1, nextIndex: startIndex };
}
var endIndex = pattern.indexOf('}', startIndex);
if (endIndex === -1) {
return { repeat: 1, nextIndex: startIndex };
}
var _a = pattern
.slice(startIndex + 1, endIndex)
.split(',')
.map(function (value) { return Number(value); }), min = _a[0], max = _a[1];
return {
repeat: Number.isFinite(max) ? max : min,
nextIndex: endIndex + 1,
};
};
var calculateMaxPatternLength = function (pattern) {
var maxLength = 0;
var index = 0;
while (index < pattern.length) {
var token = pattern[index];
if (token === '\\') {
var quantifier = readQuantifier(pattern, index + 2);
maxLength += quantifier.repeat;
index = quantifier.nextIndex;
continue;
}
if (token === '[') {
var endIndex = pattern.indexOf(']', index + 1);
if (endIndex === -1) {
index += 1;
continue;
}
var quantifier = readQuantifier(pattern, endIndex + 1);
maxLength += quantifier.repeat;
index = quantifier.nextIndex;
continue;
}
if (/\d/.test(token)) {
var quantifier = readQuantifier(pattern, index + 1);
maxLength += quantifier.repeat;
index = quantifier.nextIndex;
continue;
}
index += 1;
}
return maxLength;
};
var getMaxNationalNumberLength = function (country) {
var nationalPattern = (0, exports.normalizePhoneRegex)(country.regex)
.replace(/^\^/, '')
.replace(/\$$/, '')
.replace(/^\([^)]*\)\?/, '');
var maxLength = calculateMaxPatternLength(nationalPattern);
return maxLength || MAX_PHONE_NUMBER_LENGTH;
};
exports.getMaxNationalNumberLength = getMaxNationalNumberLength;
var sanitizePhoneInputValue = function (value, country) { return (0, exports.normalizeDigits)(value).slice(0, (0, exports.getMaxNationalNumberLength)(country)); };
exports.sanitizePhoneInputValue = sanitizePhoneInputValue;
var isValidForCountry = function (country, value) {
var digits = (0, exports.normalizeDigits)(value);
var callingCode = (0, exports.normalizeCallingCode)(country.callingCode);
var valuesToTest = [digits, "".concat(callingCode).concat(digits), "+".concat(callingCode).concat(digits)];
var regex = new RegExp((0, exports.normalizePhoneRegex)(country.regex));
return valuesToTest.some(function (candidate) { return regex.test(candidate); });
};
exports.isValidForCountry = isValidForCountry;