diff --git a/src/food-market.public/src/components/PhoneInput.tsx b/src/food-market.public/src/components/PhoneInput.tsx index 2cfd641..3a146cc 100644 --- a/src/food-market.public/src/components/PhoneInput.tsx +++ b/src/food-market.public/src/components/PhoneInput.tsx @@ -7,6 +7,17 @@ function extractDigits(value: string): string { return d.slice(0, 10) } +/** Парсит сырой ввод инпута, отбрасывая префикс «+7 ». Без этого «7» из + * префикса попадает в подсчёт и при нажатии не-цифры появляется лишняя «7». */ +function parseRawInput(raw: string): string { + if (raw.startsWith('+7 ')) raw = raw.slice(3) + else if (raw.startsWith('+7')) raw = raw.slice(2) + else if (raw.startsWith('+')) raw = raw.slice(1) + let d = raw.replace(/\D/g, '') + if (d.length === 11 && (d[0] === '7' || d[0] === '8')) d = d.slice(1) + return d.slice(0, 10) +} + function formatLocal(d: string): string { if (d.length === 0) return '' if (d.length <= 3) return d @@ -27,7 +38,7 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph const display = `+7 ${formatLocal(digits)}`.trimEnd() const handleChange = (e: React.ChangeEvent) => { - const d = extractDigits(e.target.value) + const d = parseRawInput(e.target.value) onChange(d.length > 0 ? `+7${d}` : '') } diff --git a/src/food-market.web/src/components/PhoneInput.tsx b/src/food-market.web/src/components/PhoneInput.tsx index 4bd8bb0..7ecabd1 100644 --- a/src/food-market.web/src/components/PhoneInput.tsx +++ b/src/food-market.web/src/components/PhoneInput.tsx @@ -3,12 +3,25 @@ import { cn } from '@/lib/utils' const inputClass = 'w-full h-10 rounded-md border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-900 px-3 text-sm leading-none focus:outline-none focus:ring-2 focus:ring-[var(--color-brand)] disabled:opacity-60 disabled:bg-slate-50 dark:disabled:bg-slate-800/60 tabular-nums' -/** Извлекает 10 цифр KZ-номера (после +7) из любого формата. - * "+7 700 123 45 67" → "7001234567", "8(707)1234567" → "0712345670"… */ +/** Извлекает 10 цифр KZ-номера (после +7) из каноничного значения «+7XXXXXXXXXX». */ function extractDigits(value: string): string { if (!value) return '' let d = value.replace(/\D/g, '') - // 11 цифр и ведущая 7 или 8 — это код страны, отрезаем. + if (d.length === 11 && (d[0] === '7' || d[0] === '8')) d = d.slice(1) + return d.slice(0, 10) +} + +/** Парсит сырой ввод инпута (то что показано на экране, например «+7 700 1») + * и достаёт реально введённые юзером цифры (после «+7 »). Критично: «+7 » + * префикс отбрасывается ДО извлечения цифр, иначе «7» из префикса попадает + * в подсчёт и при нажатии не-цифры на пустом поле появляется «7». */ +function parseRawInput(raw: string): string { + // Снимаем именно наш префикс — в любом из трёх возможных промежуточных видов. + if (raw.startsWith('+7 ')) raw = raw.slice(3) + else if (raw.startsWith('+7')) raw = raw.slice(2) + else if (raw.startsWith('+')) raw = raw.slice(1) + let d = raw.replace(/\D/g, '') + // Кейс paste «8 700 …» или «7 700 …» без нашего префикса. if (d.length === 11 && (d[0] === '7' || d[0] === '8')) d = d.slice(1) return d.slice(0, 10) } @@ -41,8 +54,8 @@ export function PhoneInput({ value, onChange, className, disabled, ...rest }: Ph const display = `+7 ${formatLocal(digits)}`.trimEnd() const handleChange = (e: React.ChangeEvent) => { - const d = extractDigits(e.target.value) - onChange(d.length === 10 ? `+7${d}` : d.length > 0 ? `+7${d}` : '') + const d = parseRawInput(e.target.value) + onChange(d.length > 0 ? `+7${d}` : '') } const handleKeyDown = (e: React.KeyboardEvent) => {