more fix and update
This commit is contained in:
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user