|
|
|
@ -3,6 +3,7 @@ |
|
|
|
import { |
|
|
|
AsYouTypeFormatter, |
|
|
|
PhoneNumberFormat, |
|
|
|
PhoneNumberType, |
|
|
|
PhoneNumberUtil, |
|
|
|
} from "google-libphonenumber"; |
|
|
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; |
|
|
|
@ -139,30 +140,46 @@ function readPhoneValue(value: unknown, fallbackCode: string): PhoneValueParts { |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
function getMaxLengthForCountry(codeValue: string): number { |
|
|
|
export function getMaxDigitsForCountry(codeValue: string): number { |
|
|
|
try { |
|
|
|
const cleanCode = codeValue.replace(/[^\d]/g, ""); |
|
|
|
if (!cleanCode) return 18; |
|
|
|
if (cleanCode === "98") return 12; // 3 + 1 + 3 + 1 + 4 = 12 chars
|
|
|
|
if (!cleanCode) return 15; |
|
|
|
if (cleanCode === "98") return 10; |
|
|
|
const countryCode = Number(cleanCode); |
|
|
|
const regionCode = phoneUtil.getRegionCodeForCountryCode(countryCode); |
|
|
|
if (!regionCode || regionCode === "ZZ") return 18; |
|
|
|
|
|
|
|
const exampleMobile = phoneUtil.getExampleNumberForType( |
|
|
|
regionCode, |
|
|
|
1, // MOBILE
|
|
|
|
); |
|
|
|
const exampleGeneral = phoneUtil.getExampleNumber(regionCode); |
|
|
|
|
|
|
|
const lenMobile = exampleMobile |
|
|
|
? String(exampleMobile.getNationalNumber()).length |
|
|
|
: 0; |
|
|
|
const lenGeneral = exampleGeneral |
|
|
|
? String(exampleGeneral.getNationalNumber()).length |
|
|
|
: 0; |
|
|
|
const baseLen = Math.max(lenMobile, lenGeneral, 8); |
|
|
|
if (!regionCode || regionCode === "ZZ") return 15; |
|
|
|
|
|
|
|
const types = [ |
|
|
|
PhoneNumberType.MOBILE, |
|
|
|
PhoneNumberType.FIXED_LINE, |
|
|
|
PhoneNumberType.FIXED_LINE_OR_MOBILE, |
|
|
|
PhoneNumberType.PERSONAL_NUMBER, |
|
|
|
]; |
|
|
|
let maxDigits = 0; |
|
|
|
for (const t of types) { |
|
|
|
const ex = phoneUtil.getExampleNumberForType(regionCode, t); |
|
|
|
if (ex) { |
|
|
|
const len = String(ex.getNationalNumber()).length; |
|
|
|
if (len > maxDigits) maxDigits = len; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!maxDigits) { |
|
|
|
const ex = phoneUtil.getExampleNumber(regionCode); |
|
|
|
if (ex) maxDigits = String(ex.getNationalNumber()).length; |
|
|
|
} |
|
|
|
return maxDigits || 15; |
|
|
|
} catch { |
|
|
|
return 15; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return baseLen + 6; |
|
|
|
function getMaxLengthForCountry(codeValue: string): number { |
|
|
|
try { |
|
|
|
const cleanCode = codeValue.replace(/[^\d]/g, ""); |
|
|
|
if (!cleanCode) return 18; |
|
|
|
if (cleanCode === "98") return 12; // 3 + 1 + 3 + 1 + 4 = 12 chars
|
|
|
|
const maxDigits = getMaxDigitsForCountry(codeValue); |
|
|
|
return maxDigits + 5; |
|
|
|
} catch { |
|
|
|
return 18; |
|
|
|
} |
|
|
|
@ -191,7 +208,7 @@ function getCountryPlaceholder( |
|
|
|
const example = |
|
|
|
phoneUtil.getExampleNumberForType( |
|
|
|
regionCode, |
|
|
|
1, // MOBILE
|
|
|
|
PhoneNumberType.MOBILE, |
|
|
|
) || phoneUtil.getExampleNumber(regionCode); |
|
|
|
|
|
|
|
if (!example) { |
|
|
|
@ -214,16 +231,26 @@ function formatPhoneNumberAsYouType( |
|
|
|
codeValue: string, |
|
|
|
): string { |
|
|
|
const cleanCode = codeValue.replace(/[^\d]/g, ""); |
|
|
|
const rawDigits = rawInput.replace(/\D/g, ""); |
|
|
|
let rawDigits = rawInput.replace(/\D/g, ""); |
|
|
|
if (!rawDigits) return ""; |
|
|
|
|
|
|
|
// Strip leading domestic trunk 0 (except for Italy +39 which retains leading zero)
|
|
|
|
if (cleanCode !== "39" && rawDigits.startsWith("0")) { |
|
|
|
rawDigits = rawDigits.replace(/^0+/, ""); |
|
|
|
} |
|
|
|
if (!rawDigits) return ""; |
|
|
|
|
|
|
|
const maxDigits = getMaxDigitsForCountry(codeValue); |
|
|
|
if (rawDigits.length > maxDigits) { |
|
|
|
rawDigits = rawDigits.slice(0, maxDigits); |
|
|
|
} |
|
|
|
|
|
|
|
// Special telegram-style handling for Iran (+98): 3 - 3 - 4 (e.g. 912 345 6789)
|
|
|
|
if (cleanCode === "98") { |
|
|
|
const digits = rawDigits.startsWith("0") ? rawDigits.slice(1) : rawDigits; |
|
|
|
const max10 = digits.slice(0, 10); |
|
|
|
if (max10.length <= 3) return max10; |
|
|
|
if (max10.length <= 6) return `${max10.slice(0, 3)} ${max10.slice(3)}`; |
|
|
|
return `${max10.slice(0, 3)} ${max10.slice(3, 6)} ${max10.slice(6)}`; |
|
|
|
if (rawDigits.length <= 3) return rawDigits; |
|
|
|
if (rawDigits.length <= 6) |
|
|
|
return `${rawDigits.slice(0, 3)} ${rawDigits.slice(3)}`; |
|
|
|
return `${rawDigits.slice(0, 3)} ${rawDigits.slice(3, 6)} ${rawDigits.slice(6)}`; |
|
|
|
} |
|
|
|
|
|
|
|
const countryCode = Number(cleanCode); |
|
|
|
|