Browse Source

fix phone

master
mortezaei 8 hours ago
parent
commit
29e45e9c6f
  1. 24
      src/components/Componentes/question-phone.test.tsx
  2. 79
      src/components/Componentes/question-phone.tsx

24
src/components/Componentes/question-phone.test.tsx

@ -311,4 +311,28 @@ describe("QuestionPhone IP country detection and shimmer", () => {
).toBeNull();
expect(container.querySelector(".border-\\[\\#F2465F\\]")).toBeNull();
});
it("formats Tajikistan (+992) phone numbers and caps to 9 national digits without breaking spaces", async () => {
setStoredUserGeoRegion({ country: "Tajikistan", countryCode: "TJ", phoneCode: "+992" });
render(<QuestionPhone question={phoneQuestion1} countryCode="+992" />);
const input = screen.getByRole("textbox") as HTMLInputElement;
// Type initial digits
fireEvent.change(input, { target: { value: "91712" } });
expect(input.value).toBe("91 712");
// Complete 9-digit national number
fireEvent.change(input, { target: { value: "917123456" } });
expect(input.value).toBe("91 712 3456");
// Type overflow / extra digits (should be capped at 9 digits and NOT collapse/break)
fireEvent.change(input, { target: { value: "917123456789" } });
expect(input.value).toBe("91 712 3456");
// Test with leading 0 (e.g. 0917123456) -> strips leading 0 and formats correctly
fireEvent.change(input, { target: { value: "0917123456" } });
expect(input.value).toBe("91 712 3456");
});
});

79
src/components/Componentes/question-phone.tsx

@ -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);

Loading…
Cancel
Save