more fix and update

This commit is contained in:
lendry
2026-06-24 20:15:19 +03:00
parent dcab6557d3
commit 9727cf3f35
53 changed files with 3479 additions and 494 deletions

View File

@@ -65,34 +65,71 @@ export function toE164(country: CountryOption, digits: string) {
return `${country.code}${digits.replace(/\D/g, '').slice(0, country.maxDigits)}`;
}
export function parseE164Phone(e164: string): { country: CountryOption; digits: string } {
if (!e164) {
return { country: phoneCountries[0], digits: '' };
}
const sorted = [...phoneCountries].sort((a, b) => b.code.length - a.code.length);
for (const country of sorted) {
if (e164.startsWith(country.code)) {
return { country, digits: e164.slice(country.code.length).replace(/\D/g, '') };
}
}
return { country: phoneCountries[0], digits: e164.replace(/\D/g, '') };
}
const phoneThemes = {
dark: {
shell: 'border-[#555762] bg-transparent text-white focus-within:border-[#7b7f8f] focus-within:ring-white/10',
trigger: 'text-white hover:bg-[#2a2c36]',
chevron: 'text-[#8f92a0]',
input: 'text-white placeholder:text-[#8f92a0]',
clear: 'text-[#8f92a0] hover:bg-[#2a2c36] hover:text-white'
},
light: {
shell: 'border-[#eceef4] bg-white text-[#111827] focus-within:border-[#c7cad6] focus-within:ring-[#eceef4]',
trigger: 'text-[#111827] hover:bg-[#f4f5f8]',
chevron: 'text-[#667085]',
input: 'text-[#111827] placeholder:text-[#667085]',
clear: 'text-[#667085] hover:bg-[#f4f5f8] hover:text-[#111827]'
}
} as const;
export function PhoneInput({
country,
value,
onCountryChange,
onValueChange,
className
className,
variant = 'dark',
required = true
}: {
country: CountryOption;
value: string;
onCountryChange: (country: CountryOption) => void;
onValueChange: (digits: string) => void;
className?: string;
variant?: keyof typeof phoneThemes;
required?: boolean;
}) {
const maskedValue = formatPhoneNumber(value, country);
const theme = phoneThemes[variant];
return (
<div
className={cn(
'flex h-[58px] w-full items-center rounded-2xl border border-[#555762] bg-transparent text-white transition focus-within:border-[#7b7f8f] focus-within:ring-4 focus-within:ring-white/10',
'flex h-[58px] w-full items-center rounded-2xl border transition focus-within:ring-4',
variant === 'light' ? 'h-11' : '',
theme.shell,
className
)}
>
<Popover>
<PopoverTrigger asChild>
<button type="button" className="flex h-full shrink-0 items-center gap-2 rounded-l-2xl px-4 text-white outline-none hover:bg-[#2a2c36]" aria-label="Выбрать страну">
<button type="button" className={cn('flex h-full shrink-0 items-center gap-2 rounded-l-2xl px-4 outline-none', theme.trigger)} aria-label="Выбрать страну">
<FlagIcon src={country.flagSrc} />
<span className="text-base font-semibold">{country.code}</span>
<ChevronDown className="h-4 w-4 text-[#8f92a0]" />
<ChevronDown className={cn('h-4 w-4', theme.chevron)} />
</button>
</PopoverTrigger>
<PopoverContent className="w-80 p-1">
@@ -122,16 +159,16 @@ export function PhoneInput({
</Popover>
<input
className="h-full min-w-0 flex-1 bg-transparent px-1 text-lg text-white outline-none placeholder:text-[#8f92a0]"
className={cn('h-full min-w-0 flex-1 bg-transparent px-1 text-lg outline-none', variant === 'light' ? 'text-base' : '', theme.input)}
inputMode="tel"
placeholder={country.code === '+375' ? '(29) 123-45-67' : '(999) 123-45-67'}
value={maskedValue}
onChange={(event) => onValueChange(event.target.value.replace(/\D/g, '').slice(0, country.maxDigits))}
required
required={required}
/>
{value ? (
<button type="button" className="mr-3 flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-[#8f92a0] hover:bg-[#2a2c36] hover:text-white" onClick={() => onValueChange('')} aria-label="Очистить телефон">
<button type="button" className={cn('mr-3 flex h-8 w-8 shrink-0 items-center justify-center rounded-full', theme.clear)} onClick={() => onValueChange('')} aria-label="Очистить телефон">
<X className="h-4 w-4" />
</button>
) : null}