mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-08-30 07:38:12 +00:00
feat: implement input length constraints and enhanced validation for international phone numbers
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { z } from 'zod';
|
||||
import { AsYouType, getCountryCallingCode, isValidPhoneNumber, parsePhoneNumberFromString, type CountryCode } from 'libphonenumber-js';
|
||||
import { AsYouType, Metadata, getCountryCallingCode, isValidPhoneNumber, parsePhoneNumberFromString, type CountryCode } from 'libphonenumber-js';
|
||||
|
||||
/**
|
||||
* Accepts any international number in E.164 (`+<country><number>`) or a
|
||||
@@ -10,8 +10,9 @@ export const phoneNumber = z
|
||||
.string()
|
||||
.trim()
|
||||
.transform((v) => parsePhoneNumberFromString(v, 'ET')?.number ?? v)
|
||||
.refine((v) => isValidPhoneNumber(v), {
|
||||
message: 'Enter a valid phone number',
|
||||
.superRefine((v, ctx) => {
|
||||
if (!v) ctx.addIssue({ code: 'custom', message: 'Phone number is required' });
|
||||
else if (!isValidPhoneNumber(v)) ctx.addIssue({ code: 'custom', message: 'Enter a valid phone number' });
|
||||
});
|
||||
|
||||
/** Same rules, but blank is allowed. */
|
||||
@@ -67,3 +68,21 @@ export function formatNational(digits: string, country: CountryCode): string {
|
||||
const formatted = new AsYouType().input(prefix + digits);
|
||||
return formatted.startsWith(prefix) ? formatted.slice(prefix.length).trimStart() : digits;
|
||||
}
|
||||
|
||||
const metadata = new Metadata();
|
||||
|
||||
/** Longest national number the country's numbering plan allows. */
|
||||
export function maxNationalLength(country: CountryCode): number {
|
||||
metadata.selectNumberingPlan(country);
|
||||
return Math.max(...(metadata.numberingPlan?.possibleLengths() ?? [15]));
|
||||
}
|
||||
|
||||
/**
|
||||
* True when the typed digits exceed the country's longest number. Judged on
|
||||
* the national part once it parses, so a trunk prefix (0911223344) or typed
|
||||
* country code (251911223344) isn't counted against the limit.
|
||||
*/
|
||||
export function exceedsMaxLength(digits: string, country: CountryCode): boolean {
|
||||
const national = parsePhoneNumberFromString(digits, country)?.nationalNumber ?? digits;
|
||||
return national.length > maxNationalLength(country);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user