Работа со временем в пользовательских интерфейсах требует точности, локализации и доступности. В веб-приложениях время может отображаться в различных форматах: 12-часовом и 24-часовом, с указанием секунд, с использованием локализованных обозначений периода суток, а также с различными правилами форматирования в зависимости от региона пользователя.
Библиотека React Aria предоставляет инструменты для создания доступных и локализованных компонентов работы со временем. В основе этих инструментов лежит интеграция с библиотеками React Stately и @internationalized/date, которые обеспечивают корректное представление временных значений, работу с часовыми поясами и автоматическое форматирование на основе локали.
В React Aria временные значения представляются не обычными объектами
JavaScript Date, а специализированными структурами из
пакета @internationalized/date. Основным типом является
Time.
import {Time} from '@internationalized/date';
let time = new Time(14, 30);
Объект Time содержит:
Такой подход позволяет:
Структура объекта:
Time {
hour
minute
second
millisecond
}
Каждая часть времени может быть изменена независимо.
Компонент TimeField предназначен для ввода времени. Он
автоматически разбивает время на сегменты (часы, минуты, секунды) и
обеспечивает корректную навигацию между ними.
Пример использования:
import {useTimeField} from 'react-aria';
import {useTimeFieldState} from 'react-stately';
import {Time} from '@internationalized/date';
function TimeField(props) {
let state = useTimeFieldState({
...props,
defaultValue: new Time(9, 30)
});
let ref = React.useRef();
let {labelProps, fieldProps} = useTimeField(props, state, ref);
return (
<div>
<label {...labelProps}>Время</label>
<div {...fieldProps} ref={ref}>
{state.segments.map(segment => (
<span key={segment.type}>{segment.text}</span>
))}
</div>
</div>
);
}
TimeField автоматически учитывает:
React Aria разбивает время на сегменты. Каждый сегмент представляет часть временного значения.
Типы сегментов:
| Сегмент | Описание |
|---|---|
| hour | часы |
| minute | минуты |
| second | секунды |
| dayPeriod | AM / PM |
| literal | разделители |
Пример отображения времени:
14 : 30
Разбивка сегментов:
hour → "14"
literal → ":"
minute → "30"
Сегментированная модель обеспечивает:
React Aria автоматически использует Intl API браузера для определения формата времени в зависимости от локали.
Примеры:
2:30 PM
14:30
14:30
Формат определяется через locale.
useTimeFieldState({
locale: 'en-US'
})
Изменение локали автоматически меняет:
Формат времени определяется параметром hourCycle.
Возможные значения:
| Значение | Формат |
|---|---|
| h11 | 0–11 |
| h12 | 1–12 |
| h23 | 0–23 |
| h24 | 1–24 |
Пример установки 24-часового формата:
useTimeFieldState({
hourCycle: 24
})
В результате:
14:30
Для 12-часового формата:
hourCycle: 12
Отображение:
2:30 PM
Для преобразования временного значения в строку используется
DateFormatter.
import {DateFormatter} from '@internationalized/date';
let formatter = new DateFormatter('ru-RU', {
hour: 'numeric',
minute: '2-digit'
});
formatter.format(new Date());
Опции форматирования:
| Опция | Назначение |
|---|---|
| hour | формат часов |
| minute | формат минут |
| second | секунды |
| hour12 | использование AM/PM |
Пример с секундами:
let formatter = new DateFormatter('ru-RU', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
Результат:
14:30:05
Компонент может ограничивать шаг изменения времени.
Параметр:
granularity
Возможные значения:
| Значение | Описание |
|---|---|
| hour | изменение часов |
| minute | минуты |
| second | секунды |
Пример:
useTimeFieldState({
granularity: 'minute'
})
Это означает, что пользователь может редактировать:
часы + минуты
Для секунд:
granularity: 'second'
Отображение:
14:30:15
React Aria позволяет задавать минимальное и максимальное время.
Параметры:
minValue
maxValue
Пример:
import {Time} from '@internationalized/date';
useTimeFieldState({
minValue: new Time(9, 0),
maxValue: new Time(18, 0)
});
Разрешённый диапазон:
09:00 — 18:00
Попытка выйти за пределы диапазона будет предотвращена.
Для отображения секунд необходимо указать
granularity: "second".
useTimeFieldState({
granularity: "second"
})
Формат отображения:
14:30:45
Сегменты:
hour
minute
second
Это часто используется для:
React Aria использует контролируемую модель компонентов.
Пример:
function Example() {
let [value, setValue] = React.useState(new Time(10, 0));
return (
<TimeField
value={value}
onCha nge={setValue}
/>
);
}
При изменении сегмента вызывается:
onChange(newTime)
Это позволяет:
Компонент TimeField полностью поддерживает клавиатурную
навигацию.
Основные действия:
| Клавиша | Действие |
|---|---|
| Tab | переход между сегментами |
| ArrowUp | увеличение значения |
| ArrowDown | уменьшение |
| ArrowLeft | предыдущий сегмент |
| ArrowRight | следующий сегмент |
При достижении максимального значения происходит циклический переход.
Пример:
23 → 00
React Aria реализует требования спецификации ARIA для работы со временем.
Используются:
role="spinbutton"aria-valuenowaria-valueminaria-valuemaxЭкранные читалки могут корректно озвучивать сегменты:
Часы: 14
Минуты: 30
Это обеспечивает:
TimePicker объединяет поле времени и выпадающий
список.
Структура компонента:
TimePicker
├─ TimeField
└─ Popover
└─ TimeList
Пример:
<TimePicker
label="Выберите время"
granularity="minute"
/>
Выпадающий список содержит значения времени с заданным шагом.
В React Aria время может использоваться совместно с часовыми поясами
через тип ZonedDateTime.
import {ZonedDateTime} from '@internationalized/date';
Это необходимо для:
Пример значения:
2024-05-10T14:30:00+05:00
Такой формат сохраняет:
Для хранения временных значений используется преобразование в строку.
Пример:
time.toString()
Результат:
14:30:00
Для восстановления:
parseTime("14:30:00")
Это позволяет:
Форматы времени в React Aria применяются в различных интерфейсах.
Планировщики встреч:
09:00 – начало
10:30 – окончание
Системы бронирования:
Время заезда: 14:00
Медиа-плееры:
00:02:35
Таймеры и секундомеры:
01:25:10
Благодаря сегментированной модели, локализации и поддержке доступности React Aria позволяет реализовывать сложные сценарии работы со временем без необходимости вручную обрабатывать форматирование, навигацию и правила локализации.