GH GambleHub

Встроенная валидация и UX ошибок

1) Принципы

1. Предиктивная помощь, не наказание. Показываем, как ввести корректно, до ошибки.
2. Не терять данные. Любая ошибка не уничтожает введенное; поддерживаем «Отменить»/«Повторить».
3. Момент показа.

До ввода: helper text (правила и примеры).
Во время: мягкие хинты/маска/автоподстановка.
После (blur/submit): четкая ошибка с инструкцией «как исправить».
4. Экономия внимания. Одно сообщение — одна причина и действие.
5. Доступность. Текст + иконка/цвет, связь с полем через ARIA, фокус к первому ошибочному полю.


2) Слои валидации

Клиентская синхронная: формат, длина, обязательность, маска. Быстрая и дешевая.
Клиентская асинхронная: уникальность логина, проверка BIN/IBAN, API-подсказки. С дебаунсом.
Серверная: бизнес-правила, лимиты, риск-скоринг, авторизация/права. Истина последней инстанции.
Правило: даже при идеальной клиентской проверке сервер подтверждает и формирует окончательный текст.


3) Тайминги и дебаунс

Валидация на blur → мгновенный фидбек ≤ 100 мс.
Асинхронная проверка — дебаунс 250–400 мс после остановки ввода.
Подтверждение успешности — лаконичное («Ок») или зеленая иконка; без «салютов».
На `submit` показываем список ошибок и переносим фокус к первой.

js const debounce = (fn, ms=300)=>{let t;return (...a)=>{clearTimeout(t);t=setTimeout(()=>fn(...a),ms)}}

4) Копирайтинг ошибок

Шаблон: причина → как исправить → альтернатива (если есть).

Хорошо: «Пароль короче 8 символов. Добавьте еще символы или используйте фразу».
Хорошо: «IBAN выглядит некорректно. Проверьте длину и символы: A–Z, 0–9».
Плохо: «Неверный ввод».
Не вините пользователя; избегайте жаргона и кодов.
В чувствительных зонах (платежи/KYC) избегаем деталей, раскрывающих безопасность.


5) Паттерны показа сообщений

5.1 У поля (inline)

`aria-invalid="true"`, текст в `aria-describedby`.
Коротко, конкретно; без длинных абзацев.
Цвет + иконка, но смысл — в тексте.

5.2 Под формой (summary)

Список всех ошибок с якорями к полям.
Кнопка «Перейти к ошибке»/клик по пункту переносит фокус.

5.3 В процессе отправки

Блокируем повторное нажатие (state `busy`).
При таймауте 3–5 с — «Ожидаем подтверждение…» с безопасным повтором.


6) Маски, автоподсказки и корректоры

Маски не должны мешать вставке/редактированию. Разрешайте свободный ввод, нормализуйте под капотом.
Автоподсказки: показывайте примеры форматов, placeholder как подсказка, а не «обязательная» часть.
Нормализация: trimming пробелов, унификация регистров, авто-формат (например, `+1 (___) ___-____`) — но в исходные данные сохраняйте «чистую» версию.


7) Доступность (A11y)

Связь: `label` ↔ `input`, ошибки в `aria-describedby`.
Критичные — `role="alert"`, информационные — `role="status"`.
Возвращаем фокус к ошибочному полю, `:focus-visible` видим.
Контраст текста/иконок ≥ AA; смысл не зависит только от цвета.

html
<label for="email">Email</label>
<input id="email" name="email" aria-describedby="email-help email-err">
<small id="email-help">Например: user@domain.tld</small>
<p id="email-err" class="field-error" role="alert" hidden>Проверьте формат email</p>

8) Международные форматы и локализация

Имена/адреса: допускайте разные алфавиты, длины, апострофы, дефисы.
Даты/валюты/номера: используйте локальные форматы ввода и строгие внутренние структуры хранения (ISO/число центов).
Телефон: ввод в международном формате `+CC`, автоподсказка по стране.
Язык сообщений: короткие, культурно нейтральные; закладывайте +20–30% длины строки.


9) Безопасность и приватность

Не показывайте, что аккаунт существует/не существует — общий текст: «Если email зарегистрирован, мы отправим письмо».
Маскируйте чувствительные данные (PAN, паспорт).
На критичных шагах (ставка/платеж) используйте идемпотентность и «безопасные повторы».
Логи — с ID корреляции без PII в сообщениях.


10) Сохранение прогресса

Автосейв черновика (локально/на сервере).
При ошибке отправки — форма остается заполненной; предлагается повтор позже.
При многошаговых процессах (KYC) — сохраняйте завершенные шаги.


11) Асинхронная валидация

Дебаунс 250–400 мс; показываем «проверяем…» возле поля, не блокируя весь экран.
Ясная индикация успеха/неуспеха без «дерганий» макета.
Таймаут сети → «Не удалось проверить. Продолжить с риском?» (если допустимо) или «Повторить».

js const checkUsername = debounce(async (v)=>{
state.usernameChecking = true;
const ok = await api.unique('username', v).catch(()=>null);
state.usernameChecking = false;
state.usernameValid = ok === true;
}, 300);

12) Платежные формы и KYC (специфика)

Карты: формат PAN, срок, CVC — валидация по мере ввода; ошибки — без раскрытия причины отклонения банком.
A2A/кошельки: проверка допустимости по стране/лимитам, четкие тексты про комиссии/сроки.
KYC: пошаговые требования к фото/документам, предпросмотр, размер/тип файла, сроки проверки, приватность.
Ответственная игра: сообщения нейтральные, с действиями «Установить лимит»/«Помощь».


13) Антипаттерны

Показ ошибок «на каждый символ» без дебаунса.
Сброс формы при ошибке.
Сообщение «Неверный ввод» без указания поля/правила.
Критичная информация только цветом/иконкой.
Блокировка всей страницы ради проверки одного поля.
Отсутствие оффлайн-режима и повторов при сетевых сбоях.


14) Токены дизайн-системы (пример)

json
{
"validation": {
"debounceMs": 300,
"blurFeedbackMs": 100,
"asyncTimeoutMs": 5000,
"summaryMaxItems": 6
},
"a11y": {
"useAriaDescribedby": true,
"errorRole": "alert",
"statusRole": "status"
},
"visual": {
"fieldGap": 8,
"iconSize": 16,
"borderRadius": 10
}
}

15) Сниппеты реализации

Поле с inline-валидатором (формат + серверная проверка):
js const rules = {
email: v => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)          "Проверьте формат email"
};
async function validateEmail(v){
const fmt = rules.email(v);
if (fmt!== true) return fmt;
try {
const r = await fetch(`/api/email/check?v=${encodeURIComponent(v)}`);
const { allowed } = await r.json();
return allowed? true: "Этот email недоступен. Выберите другой.";
} catch {
return "Не удалось проверить. Повторите позже.";
}
}
Сводка ошибок с фокусом:
ts function focusFirstError() {
const err = document.querySelector('[aria-invalid="true"]');
if (err) err.focus({ preventScroll:false });
}
Сохранение черновика локально:
js const saveDraft = debounce(form => localStorage.setItem('draft', JSON.stringify(Object.fromEntries(new FormData(form)))), 500);
form.addEventListener('input', ()=>saveDraft(form));

16) Метрики и контроль

Time-to-Fix (время от ошибки до исправления).
Error rate по полям и по причинам (формат/лимиты/сервер).
Повторная отправка (retry success rate).
Доля брошенных форм и глубина шага.
Заполненность подсказками: CTR «Подробнее», частота скрытий подсказок.


17) QA-чек-лист

A11y

  • Фокус переходит к первому ошибочному полю; `aria-describedby`/`aria-invalid` выставлены.
  • Контраст ≥ AA; сообщения не зависят только от цвета.

Поведение

  • Встроенная валидация с дебаунсом; ошибки появляются не раньше blur (кроме критичных масок).
  • На submit формируется сводка, поля не очищаются.
  • Асинхронные проверки не блокируют страницу; есть таймаут и повтор.

Текст

  • Причина + как исправить; без кодов/вины.
  • Локализация не ломает макет; примеры актуальны.

Безопасность

  • Нет утечек PII в сообщениях; не раскрываем существование аккаунта.
  • Идемпотентность для критичных операций.

18) Документация в дизайн-системе

Компоненты: `FieldError`, `FormSummary`, `HelperText`, `BusyButton`.
Карты правил для типовых полей (email, телефон, пароль, адрес, IBAN, дата).
Гайды по дебаунсу, асинхронной проверке и оффлайн-поведению.
Шаблоны текстов для частых ошибок и примеры «до/после».


Краткое резюме

Встроенная валидация — это про предиктивную помощь, четкие инструкции и бережное отношение к данным. Проверяйте локально и на сервере, показывайте ошибки в нужный момент с конкретными действиями, уважайте доступность и приватность, сохраняйте прогресс и используйте дебаунс. Так формы становятся дружелюбными, а ошибки — быстрыми и исправимыми.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

Нажимая кнопку, вы соглашаетесь на обработку данных.