UNPKG

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
"use strict"; 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;