Формы являются одним из ключевых элементов интерфейсов веб-приложений, и их правильная реализация напрямую влияет на юзабилити и доступность. Preact, как легковесная альтернатива React, предоставляет удобные инструменты для управления состоянием форм и взаимодействия с пользователем, при этом сохраняя совместимость с современными стандартами доступности (ARIA, WCAG).
В Preact формы могут быть контролируемыми и неконтролируемыми, аналогично React. Контролируемые формы используют состояние компонента для хранения значений полей:
import { h } from 'preact';
import { useState } from 'preact/hooks';
function ContactForm() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
console.log({ name, email });
};
return (
<form onSub mit={handleSubmit}>
<label htmlFor="name">Имя</label>
<input
id="name"
type="text"
value={name}
onIn put={(e) => setName(e.target.value)}
/>
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
value={email}
onIn put={(e) => setEmail(e.target.value)}
/>
<button type="submit">Отправить</button>
</form>
);
}
Ключевые моменты:
onInput вместо onChange
обеспечивает синхронное обновление состояния.htmlFor у <label> связывает
метку с полем ввода, что важно для доступности.Для улучшения взаимодействия с экранными читалками и вспомогательными технологиями применяются атрибуты ARIA:
aria-label — добавляет текстовую метку для элементов
без видимого лейбла.aria-labelledby — связывает элемент с существующей
меткой.aria-describedby — указывает на элемент с описанием,
например, текст ошибки.Пример:
<input
id="password"
type="password"
aria-label="Пароль"
aria-describedby="passwordHelp"
/>
<small id="passwordHelp">Пароль должен содержать не менее 8 символов</small>
Доступность форм требует, чтобы ошибки были очевидны и информативны:
function FormField({ label, id, value, onInput, error }) {
return (
<div>
<label htmlFor={id}>{label}</label>
<input id={id} value={value} onIn put={onInput} aria-invalid={!!error} aria-describedby={error ? `${id}-error` : undefined} />
{error && <span id={`${id}-error`} role="alert">{error}</span>}
</div>
);
}
Особенности реализации:
aria-invalid сигнализирует о некорректном вводе.role="alert" позволяет экранным читалкам мгновенно
уведомлять о новой ошибке.id для связи поля с
сообщением об ошибке.Для доступности форм критически важно обеспечить корректную работу с клавиатурой:
Tab перемещает фокус между интерактивными
элементами.Enter отправляет форму при нахождении на кнопке типа
submit.Space активирует чекбоксы и радио-кнопки.Пример доступного радио-группирования:
<fieldset>
<legend>Выберите вариант</legend>
<label>
<input type="radio" name="option" value="1" /> Вариант 1
</label>
<label>
<input type="radio" name="option" value="2" /> Вариант 2
</label>
</fieldset>
<fieldset> и
<legend> обеспечивает логическую группировку и
улучшает навигацию для экранных читалок.В Preact формы часто создаются динамически, например, при добавлении повторяющихся полей:
const [fields, setFields] = useState([{ value: '' }]);
const addField = () => setFields([...fields, { value: '' }]);
fields.map((field, index) => (
<input
key={index}
value={field.value}
onIn put={(e) => {
const newFields = [...fields];
newFields[index].value = e.target.value;
setFields(newFields);
}}
aria-label={`Поле ${index + 1}`}
/>
))
Для мобильных пользователей:
<input type="email">,
<input type="tel"> и другие типы для оптимизации
клавиатуры.autocomplete для упрощения ввода:<input type="email" autocomplete="email" />
onInput и onChange
корректно работают на мобильных устройствах.tabindex) в сложных формах.<fieldset> и <legend>.Preact обеспечивает полную совместимость с веб-стандартами, позволяя создавать быстрые и доступные формы без лишнего кода. Правильное использование контролируемых компонентов, ARIA-атрибутов и динамических структур обеспечивает соответствие форм требованиям WCAG и повышает удобство для всех пользователей.