GH GambleHub

Маски вводу та UX-форми

1) Принципи

1. Допомагати, не карати. Маска направляє введення і знижує помилки, але не блокує друк і вставку.
2. Дані ≠ відображення. Зберігаємо «сирі» нормалізовані значення, форматуємо тільки в UI.
3. Передбачуваний курсор. Будь-яка автопідстановка не «стрибає» caret і не ламає undo/redo.
4. Локаль і пристрій. Клавіатури, роздільники, календар і валюти - по регіону і платформі.
5. Доступність і приватність. Текст + іконка/колір; чутливі поля маскуємо, але не заважаємо менеджерам паролів/автозаповнення.

2) Коли маска доречна (і коли ні)

Використовувати:
  • Формати зі стійкою структурою: телефон, IBAN, PAN (карти), CVC, дата, час, індекс, OTP.
  • Грошові суми з роздільниками (при друку - «чисте» введення, при блюрі - формат).
  • Коди (реф. коди, промо), фіксовані довжини.
Уникати:
  • Імена/адреси/Email (маска обмежує допустимі символи/мови).
  • Складні вільні поля (коментарі, назви компаній).
  • Введення з потенційно невідомим форматом (міжнародні номери без країни).

3) Маска vs автоформат vs валідація

Маска - підказка структури «на льоту» (дужки, дефіси); не повинна ламати введення/вставку.
Автоформат - застосовуємо при блюрі/втраті фокусу (тисячі, прогалини IBAN).
Валідація - логіка коректності (довжина, контрольні суми), показ помилок після «blur» або «submit».

Правило: маска не замінює валідацію, а автоформат не повинен змінювати сенс введеного.

4) Клавіатури та атрибути HTML

Підберіть коректні типи/режими, щоб прискорити введення і знизити помилки:
Поле`type``inputmode``autocomplete`Примітка
Телефон`tel``tel``tel`Показує цифрову клавіатуру на мобілках
Email`email``email``email`Валідація формату браузером
Сума`text``decimal``off`Локальні роздільники; зберігати число в «центах»
Дата`date`/`text``numeric``bday`/`cc-exp`Нативні пікери там, де доречно
Карта PAN`text``numeric``cc-number`Токенізація; блокувати логування
Ім'я власника`text``latin`/`text``cc-name`Без автокапса на десктопі
IBAN`text``latin`/`text``off`Uppercase, без пробілів в значенні
OTP (6 цифр)`text``numeric``one-time-code`Автозаповнення СМС на iOS/Android

5) Карет, копіпаст і нормалізація

Не ламати caret: при авто-вставці символів (пробіли/дужки) коригуйте позицію курсора.
Копіпаст: при вставці очищайте від пробілів/дефісів → валідуйте → відображайте з форматуванням.
Нормалізація: триммінг, заміна «кривих» символів («O'→'0» не можна!), переведення у верхній регістр для IBAN, єдиний формат дати в сховищі (ISO).

Приклад нормалізації PAN/IBAN:
js const clean = s => s. replace(/[^\da-zA-Z]/g,'');
const normalizePAN = s => clean(s). slice (0.19) ;//no spaces/hyphens const normalizeIBAN = s => clean (s). toUpperCase();   // A–Z0–9

6) Числа, валюти і локалі

Введення «як друкується» (допуск','або'.'як роздільника), зберігання в minor units (копійки/центи).
Відображення по локалі (угруповання тисяч) на блюрі/після сабміту; у фокусі показуйте «сире» значення для зручності редагування.
Явно вказуйте валюту і фіксуйте точність (наприклад, 2 знаки).

js function parseMoney(input) {
//resolve both comma and period as decimal const s = input. replace(/\s/g,''). replace(',', '.');
const num = Number(s);
if (Number. isNaN(num)) return null;
return Math. round(num 100); // cents
}

function formatMoney(cents, locale='ru-RU', currency='RUB') {
return (cents/100). toLocaleString(locale, { style:'currency', currency });
}

7) Дати і час

Якщо нативні пікери незручні/різні на платформах - використовуйте текстове поле з маскою'DD. MM. YYYY', але зберігайте ISO'YYYY-MM-DD'.
Перевірка реальності дат (29. 02, діапазони), таймзони - на сервері.
Додайте кнопки «Сьогодні», «Зараз», «Очистити».

8) Телефони та країни

Два поля: країна (+ код) і номер або «розумна» маска по обраній країні.
При вставці повного'+ CC...'автозаповніть країну.
Зберігайте E.164 ('+ CCXXXXXXXXX'), показуйте локально з пробілами.

9) Платіжні реквізити: PAN/IBAN/CVC/EXP

PAN: групування 4-4-4-4/4; у значенні - тільки цифри; Luhn-check; ніяких логів/аналітики з PAN.
CVC: ' password'-стиль (приховано),'autocomplete =» cc-csc»', не зберігати в чернетки.
EXP: 'MM/YY', авто-вставка '/' після 2 цифр, перевірка діапазону 01-12 і розумного року.
IBAN: upper-case, пробіли тільки в UI; перевірка довжини по країні і контрольної суми.

10) ОТР/код підтвердження

6 (або N) осередків з автофокусом і авто-переходом, вставка з буфера розпізнає весь код.
' autocomplete =» one-time-code»', на мобільних - автовидобування з СМС.
Бекап-введення без спліт-полів (одне поле) - для скрінрідерів.

html
<div class="otp" role="group" aria-label="Код из SMS">
<input inputmode="numeric" maxlength="1">
<input inputmode="numeric" maxlength="1">
<!-- … -->
</div>

11) Маски і a11y

Лейбл обов'язковий ('< label for>'), placeholder - приклад, а не заміна.
Пояснюйте правило поруч: helper text з прикладом ("Формат: + CC ХХХ ХХХ-ХХ-ХХ").
Помилки зв'язуйте через'aria-describedby', критичні -'role = «alert»'.
Контраст тексту і контурів ≥ AA,':focus-visible'не приховувати.

12) Приватність і безпека

Чутливі поля: не логувати, не писати в RUM, не зберігати в чернетки (PAN, CVC, паспорт).
Маски та форматування не повинні розкривати валідність облікового запису («Якщо email зареєстрований...» - нейтральне формулювання).
Ідемпотентність і retry для критичних сабмітів (платіж/ставка).

13) Поведінка форм і продуктивність

Дебаунс асинхронних перевірок (250-400 мс), видима індикація «Перевіряємо»....
Не блокуйте весь екран заради одного поля; локальний спінер/скелет.
Батчіть зміни DOM; анімуйте тільки'transform/opacity'.
На мобільних - уникайте «стрибків» при появі клавіатури (safe-area, viewport meta).

14) Код-сніпети

М'яка маска телефону (без ломки вставки):
js function formatPhoneVisible(value) {
const d = value. replace(/\D/g,''). slice(0,15);
if (!d) return '';
if (d. startsWith('7')          d. startsWith('8')) {
return d. replace(/^([78])? (\d{3})(\d{3})(\d{2})(\d{2})./, '+7 ($2) $3-$4-$5');
}
// generic E.164 grouping: +CC XXX XXX XX XX return d. replace(/^(\d{1,3})(\d{0,3})(\d{0,3})(\d{0,2})(\d{0,2})./, (m,c1,c2,c3,c4,c5)=>
`+${c1}${c2?` ${c2}`:''}${c3?` ${c3}`:''}${c4?` ${c4}`:''}${c5?` ${c5}`:''}`.trim());
}

const input = document. querySelector('#phone');
input. addEventListener('input', e => {
const raw = e. target. value;
const pos = e. target. selectionStart;
const digitsBefore = raw. slice(0,pos). replace(/\D/g,''). length;
const cleaned = raw. replace(/[^\d+]/g,'');
const visible = formatPhoneVisible(cleaned);
e. target. value = visible;
// restore caret by counting digits let p = 0, count = 0;
while (p < e. target. value. length && count < digitsBefore) { if (/\d/.test(e. target. value[p])) count++; p++; }
e. target. setSelectionRange(p, p);
});
Сума: «сире у фокусі → формат при блюрі»:
js const amount = document. getElementById('amount');
let cents = null;

amount. addEventListener('focus', () => {
if (cents!=null) amount. value = String(cents/100). replace('.', ',');
});
amount. addEventListener('blur', () => {
const v = parseMoney(amount. value) ;//from section 6 if (v = = null) return; cents = v;
amount. value = formatMoney(cents, 'ru-RU', 'RUB');
});
IBAN: upper-case і групування при блюрі:
js const iban = document. getElementById('iban');
iban. addEventListener('input', () => iban. value = iban. value. toUpperCase());
iban. addEventListener('blur', () => {
const raw = normalizeIBAN(iban. value);
iban. dataset. raw = raw ;//for iban submission. value = raw. replace(/(.{4})/g,'$1 '). trim () ;//view only
});

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

json
{
"input": {
"radius": 10,
"height": { "sm": 36, "md": 40, "lg": 48 },
"gap": 8,
"icon": 16
},
"mask": {
"debounceMs": 300,
"otpLength": 6,
"moneyPrecision": 2,
"phoneMaxDigits": 15
},
"a11y": {
"focusRing": { "width": 2, "offset": 2 },
"contrastAA": true
}
}
CSS-пресети:
css
.input { height:40px; padding:0 12px; border-radius:10px; }
.input:focus-visible { outline:2px solid var(--focus-ring); outline-offset:2px; }
.field-error { color: var(--role-danger); font-size:.875rem; margin-top:6px; }
.otp input { width:40px; text-align:center; }

16) Специфіка iGaming

Платежі/висновки: PAN/IBAN/amount з м'якими масками; сувора ідемпотентність і відсутність логів чутливих полів; підказки про комісії і терміни.
KYC: маски для дат, паспортних номерів (без «жорсткої» фільтрації - облік різних форматів), розмір/тип файлу, перегляд.
Ліміти та відповідальна гра: зрозумілі суми/періоди (дні/тижні/місяці), хелпери поруч, контраст AAA.
Ставки: швидке введення суми (кнопки-пресети + поле), у фокусі «сире» число, при блюрі формат по локалі; недопуск «, «...../подвійного роздільника.

17) Анти-патерни

Жорсткі маски, що забороняють допустимі символи/вставку.
Стрибаючий caret при автоформаті; пропажа виділення/undo.
Placeholder замість лейблу.
Авто-додавання валюти всередину значення (ламає копіпаст).
Помилки «на кожен символ» без дебаунсу.
Локалезалежні формати в сховищі (зберігайте ISO/числа).
Логування PAN/паспортних номерів і показ «занадто чесних» причин відхилення.

18) Метрики та експерименти

Error rate по полях (до/після маски).
Time-to-Complete форми і повторні відправки.
Частка невдалих вставок (копіпаст) і «відкатів» (undo).
CTR підказок/прикладів, частка автозаповнень.
Abandon rate на кроці платежу/КУС.

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

Введення та caret

  • Вставка з буфера не ламається, пробіли/дефіси очищаються коректно.
  • Caret залишається передбачуваним після автоформату.

Локаль і формат

  • Суми допускають', '/'.'; зберігання в minor units.
  • Дати парсяться і валідуються; зберігання в ISO.

A11y

  • Лейбли і'aria-describedby'підключені;'role = «alert»'для критичних.
  • Контраст і фокус-кільця відповідають AA.

Безпека

  • Чутливі поля не логуються/не кешуються.
  • Ідемпотентність і retry на критичних кроках.

UX

  • Placeholder - приклад, не лейбл; helper поруч.
  • Маски не перешкоджають друку на мобільних; коректні клавіатури («inputmode»).

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

Компоненти: `MaskedInput`, `MoneyInput`, `PhoneInput`, `OtpInput`, `IbanInput`.
Токени масок (довжини/шаблони), правила caret/вставки, локалізація чисел/дат.
Гайди по приватності (чого не логувати), по доступності і по автоформату vs блюр.
«Do/Don't» з реальними прикладами і метриками до/після.

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

Маски і форми хороші, коли вони прискорюють введення, зберігають дані чистими і не заважають. Форматуйте дбайливо, нормалізуйте на вході, зберігайте в стабільних видах, враховуйте локалі і доступність. Тоді форми стають швидкими і зрозумілими - особливо в чутливих сценаріях платежів, KYC і ставок.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.