From b3daa889f45ad71edf334df6b05edf692fdfd4de Mon Sep 17 00:00:00 2001 From: nns Date: Tue, 13 Oct 2026 18:00:37 +0500 Subject: [PATCH] =?UTF-8?q?fix(=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F/iOS):=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=20=D1=84=D0=BE=D0=BA=D1=83=D1=81=D0=B0=20=D0=BA=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B2=D0=BE=D0=B9=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BA=D0=B5=20=D0=BF=D1=80=D0=B8=20=D0=BE=D1=82=D0=BA=D1=80?= =?UTF-8?q?=D1=8B=D1=82=D0=BE=D0=B9=20=D0=BA=D0=BB=D0=B0=D0=B2=D0=B8=D0=B0?= =?UTF-8?q?=D1=82=D1=83=D1=80=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit iOS Safari: если набрать пароль и, НЕ скрывая клавиатуру, нажать кнопку — фокус не переходил на первое поле с ошибкой (email), оставался в пароле. Причина: focusFirstError откладывал el.focus() через setTimeout(150) — вне пользовательского жеста iOS игнорирует программный перенос фокуса (тем более из поля с открытой клавиатурой). Теперь focus() вызывается СИНХРОННО в обработчике жеста (pointerup/click/Enter) с preventScroll, а плавная прокрутка к полю — отдельно. Тап/свайп из 87a4666 не затронуты. Проверено на WebKit-движке (Playwright webkit, hasTouch, iPhone-вьюпорт): пароль в фокусе → тап по кнопке → фокус переходит на email; и на Chromium (тап/свайп/долгое нажатие, первое касание, один запрос) — регрессий нет. Co-Authored-By: Claude Opus 4.8 --- src/food-market.public/src/components/SignupForm.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/food-market.public/src/components/SignupForm.tsx b/src/food-market.public/src/components/SignupForm.tsx index 7356ef1..b3afd50 100644 --- a/src/food-market.public/src/components/SignupForm.tsx +++ b/src/food-market.public/src/components/SignupForm.tsx @@ -103,13 +103,15 @@ export default function SignupForm({ defaultPlan = 'start' }: Props) { const focusFirstError = (errs: FieldErrors) => { const firstKey = FIELD_ORDER.find((k) => errs[k]) if (!firstKey) return - // На 1280×665 верхние поля часто выше вьюпорта — сначала проскроллим к полю, - // затем сфокусируем (focus сам по себе прокручивает неплавно/неточно). const el = document.getElementById(`signup-${firstKey}`) if (el) { + // Фокус СИНХРОННО, в рамках пользовательского жеста (pointerup/click/Enter). + // iOS Safari игнорирует программный перенос фокуса, отложенный через + // setTimeout или с уже открытой клавиатурой в другом поле, — поэтому + // focus() вызываем сразу. preventScroll убирает резкий прыжок, а плавную + // прокрутку к полю делаем отдельно. + el.focus({ preventScroll: true }) el.scrollIntoView({ behavior: 'smooth', block: 'center' }) - // Фокус после старта прокрутки — иначе браузер перебьёт плавный скролл. - setTimeout(() => el.focus({ preventScroll: true }), 150) } }