feat(forms): TextInput с type=email — авто-pattern для TLD-проверки

Раньше явный validateEmail вызывался только в LoginPage и SignupForm.
Остальные формы (Counterparties, Employees, SuperAdminOrgCreate,
SuperAdminOrgEmployees, SuperAdminSetup) использовали голый
<TextInput type="email">, который пропускает «name@domain» без TLD.

Сделал общий TextInput строже: если type=email и pattern не задан явно,
автоматически проставляется pattern=[^@\s]+@[^@\s]+\.[A-Za-z]{2,}
(требует домен верхнего уровня минимум 2 буквы) + title с понятным
текстом подсказки. localizeNativeValidation (уже подключён к TextInput
через useEffect) переведёт patternMismatch в русское сообщение из
title-атрибута.

Это покрывает все формы с email-полем единообразно — отдельно править
каждую страницу не пришлось. Серверный AuthorizationController + signup
тоже проверяют email через свой validateEmail (food-market.web/lib/
validation.ts) — клиент и сервер консистентны.
This commit is contained in:
nns 2026-05-06 11:21:43 +05:00
parent a6ecc65b97
commit 0e4b7868c9

View file

@ -36,7 +36,15 @@ export function TextInput(props: InputHTMLAttributes<HTMLInputElement>) {
useEffect(() => {
if (ref.current) localizeNativeValidation(ref.current)
}, [])
return <input ref={ref} {...props} className={cn(inputClass, props.className)} />
// Email type без явного pattern — добавляем строгий pattern (требует TLD ≥2),
// чтобы name@domain без точки/зоны не проходил. title задаёт текст подсказки;
// localizeNativeValidation подставит его при patternMismatch.
const extraProps: InputHTMLAttributes<HTMLInputElement> = {}
if (props.type === 'email' && !props.pattern) {
extraProps.pattern = '[^@\\s]+@[^@\\s]+\\.[A-Za-z]{2,}'
extraProps.title = props.title ?? 'Введите корректный email с доменной зоной (например, name@example.kz)'
}
return <input ref={ref} {...props} {...extraProps} className={cn(inputClass, props.className)} />
}
export function TextArea(props: TextareaHTMLAttributes<HTMLTextAreaElement>) {