Работа со временем в пользовательских интерфейсах требует строгой проверки вводимых значений. Ошибки формата, выход за допустимые границы, несовместимость со связанными значениями и несоответствие бизнес-правилам могут привести к неправильной работе приложения.
Библиотека React Aria предоставляет инфраструктуру для создания доступных и управляемых компонентов ввода времени с поддержкой встроенной и пользовательской валидации. Валидация интегрируется в архитектуру управления состоянием и обеспечивает:
Компоненты ввода времени в React Aria построены на разделении логики и представления. Основные элементы архитектуры:
React Aria Hooks
Обеспечивают доступность, обработку взаимодействия и передачу ARIA-атрибутов.
React Stately
Управляет состоянием значения времени, сегментами ввода и состоянием валидации.
DateValue / TimeValue
Типы данных из пакета @internationalized/date,
используемые для хранения времени независимо от часовых поясов.
Пример используемых зависимостей:
import {useTimeField} from 'react-aria';
import {useTimeFieldState} from 'react-stately';
import {Time} from '@internationalized/date';
Состояние компонента содержит:
React Aria поддерживает валидацию, аналогичную HTML-формам. Она реализуется через свойства компонентов и автоматически синхронизируется со стандартными механизмами браузера.
Ключевые параметры:
| Свойство | Назначение |
|---|---|
| minValue | минимально допустимое время |
| maxValue | максимально допустимое время |
| isRequired | обязательность поля |
| validate | пользовательская функция проверки |
| validationState | явное состояние валидности |
Система автоматически отслеживает изменения значения и проверяет соответствие заданным ограничениям.
Одним из наиболее распространённых видов проверки является ограничение диапазона.
В интерфейсах часто необходимо:
Пример настройки диапазона:
let state = useTimeFieldState({
minValue: new Time(9, 0),
maxValue: new Time(18, 0)
});
В этом случае пользователь может вводить значения только между 09:00 и 18:00.
При попытке выйти за пределы диапазона состояние компонента становится невалидным.
Если поле времени должно быть заполнено, используется свойство
isRequired.
let state = useTimeFieldState({
isRequired: true
});
Особенности поведения:
requiredaria-required="true"Это обеспечивает совместимость со стандартными HTML-формами и средствами доступности.
Бизнес-логика часто требует более сложных проверок, которые невозможно выразить через диапазоны.
Для этого используется свойство validate.
Функция получает текущее значение времени и возвращает текст ошибки.
let state = useTimeFieldState({
validate(value) {
if (value && value.hour < 12) {
return "Время должно быть после полудня";
}
}
});
Особенности пользовательской проверки:
null, если ошибок нетСообщение автоматически связывается с полем через ARIA-атрибуты.
React Aria предоставляет три основных состояния:
| Состояние | Описание |
|---|---|
| valid | значение корректно |
| invalid | обнаружена ошибка |
| pending | состояние проверки |
В интерфейсе состояние передаётся через свойство
validationState.
validationState="invalid"
Компонент автоматически добавляет:
aria-invalidСообщение об ошибке связывается с элементом ввода через
aria-describedby.
Это позволяет экранным дикторам корректно объявлять проблему пользователю.
Пример структуры компонента:
<div>
<TimeField />
<span id="error-message">
Неверное время
</span>
</div>
React Aria автоматически связывает сообщение с элементом поля.
Компоненты времени в React Aria используют сегментированный ввод.
Вместо одного текстового поля время разбивается на отдельные сегменты:
Каждый сегмент валидируется отдельно.
Например:
Если пользователь вводит недопустимое значение, сегмент автоматически корректируется или отклоняется.
В некоторых интерфейсах требуется ввод времени с фиксированным шагом.
Например:
В React Aria используется свойство granularity.
granularity="minute"
Дополнительно можно управлять шагом при помощи пользовательской логики.
Пример ограничения на интервалы 15 минут:
validate(value) {
if (value.minute % 15 !== 0) {
return "Время должно быть кратно 15 минутам";
}
}
Валидация тесно связана с обработкой событий изменения.
Основные события:
onChangeonBluronFocusПример:
function handleChange(time) {
console.log(time);
}
После изменения значения:
React Aria позволяет интегрировать компоненты времени в стандартные HTML-формы.
Особенности интеграции:
Пример:
<form>
<TimeField name="appointmentTime" />
</form>
При отправке формы значение автоматически сериализуется.
Иногда требуется проверка времени на стороне сервера.
Примеры:
Для таких случаев используется асинхронная логика внутри
onChange.
async function validateTime(time) {
let available = await checkTime(time);
if (!available) {
setError("Время занято");
}
}
Асинхронная проверка обычно сопровождается состоянием
pending.
Многие формы используют диапазон времени:
Валидация должна учитывать связь между полями.
Пример проверки:
validate(value) {
if (value.compare(endTime) > 0) {
return "Начало не может быть позже окончания";
}
}
Для второго поля выполняется зеркальная проверка.
В React Aria значения времени представлены через объекты
Time.
Они не привязаны к часовому поясу, что упрощает валидацию.
Однако при работе с датами используется тип
ZonedDateTime, где проверки могут учитывать:
Валидация времени в таких случаях выполняется после преобразования к нужной зоне.
Иногда приложение должно управлять состоянием ошибок вручную.
Пример:
let [error, setError] = useState(null);
<TimeField
validationState={error ? "invalid" : "valid"}
errorMessage={error}
/>
Такой подход используется при сложной бизнес-логике или серверной проверке.
React Aria автоматически реализует рекомендации WAI-ARIA.
При ошибке добавляются:
aria-invalid="true"aria-describedbyСообщения об ошибках становятся частью доступного описания элемента.
Это обеспечивает корректное восприятие интерфейса пользователями вспомогательных технологий.
Наиболее распространённые сценарии:
Рабочие часы
Проверка диапазона:
09:00 — 18:00
Бронирование
Проверка доступности временного слота.
Интервалы
Проверка кратности:
каждые 30 минут
Связанные поля
Проверка последовательности:
startTime < endTime
Минимальное время
Запрет выбора времени раньше текущего.
Валидация выполняется при каждом изменении значения.
Чтобы избежать лишних вычислений:
Такая оптимизация особенно важна в формах с большим количеством временных полей.
React Aria допускает создание собственных компонентов поверх базовых хуков.
Валидация может быть вынесена в отдельный модуль:
function validateBusinessTime(time) {
if (time.hour < 10) {
return "Рабочий день начинается в 10:00";
}
}
После этого функция используется во всех компонентах времени приложения.
Это обеспечивает:
При работе с API важно соблюдать единый формат времени.
Обычно используется:
HH:mm:ssПеред отправкой значение преобразуется:
time.toString()
Валидация на клиенте уменьшает количество ошибок при отправке данных и снижает нагрузку на серверную проверку.