useDateField для ввода даты

useDateField — хук из библиотеки React Aria, предназначенный для создания полностью доступного компонента ввода даты. Он реализует сложную логику работы с датами: разбиение значения на сегменты, управление клавиатурной навигацией, поддержку локализации, а также взаимодействие со вспомогательными технологиями.

Компонент поля даты состоит из отдельных сегментов (день, месяц, год и другие части), каждый из которых редактируется независимо. Такое представление делает ввод даты более удобным и позволяет точно контролировать структуру значения.

useDateField отвечает за:

  • управление состоянием сегментов даты
  • синхронизацию с календарными системами
  • поддержку различных форматов дат
  • доступность для screen reader
  • обработку клавиатурных событий
  • корректное взаимодействие с фокусом

Для полноценной работы хук обычно используется совместно с состоянием из библиотеки React Stately.


Архитектура поля даты

Поле даты в системе React Aria состоит из нескольких уровней:

1. Контейнер поля

Главный элемент, который объединяет все сегменты.

2. Сегменты даты

Отдельные части значения:

  • день
  • месяц
  • год
  • час
  • минута
  • секунда
  • AM/PM (для 12-часового формата)

3. Управление состоянием

Состояние управляется хуком useDateFieldState.

4. Сегментный ввод

Каждый сегмент редактируется с помощью useDateSegment.

Схематически структура выглядит следующим образом:

DateField
 ├─ DateSegment (day)
 ├─ DateSegment (month)
 ├─ DateSegment (year)
 └─ DateSegment (literal separators)

Сегменты могут содержать как редактируемые значения, так и статические разделители (например / или .).


Установка зависимостей

Для создания поля даты требуется несколько пакетов:

npm install @react-aria/datepicker
npm install @react-stately/datepicker
npm install @internationalized/date

Каждый пакет отвечает за отдельную часть системы:

Пакет Назначение
React Aria доступность и поведение
React Stately управление состоянием
internationalized/date работа с календарями и датами

Базовое использование useDateField

Минимальная реализация компонента поля даты включает три ключевых элемента:

  • состояние
  • хук useDateField
  • рендер сегментов

Пример компонента

import {useRef} from "react";
import {useDateField} from "@react-aria/datepicker";
import {useDateFieldState} from "@react-stately/datepicker";
import {useLocale} from "@react-aria/i18n";

function DateField(props) {
  let {locale} = useLocale();
  let state = useDateFieldState({
    ...props,
    locale
  });

  let ref = useRef();
  let {fieldProps} = useDateField(props, state, ref);

  return (
    <div {...fieldProps} ref={ref}>
      {state.segments.map((segment, i) => (
        <DateSegment key={i} segment={segment} state={state} />
      ))}
    </div>
  );
}

В данном коде:

  • useDateFieldState хранит значение даты и управляет сегментами
  • useDateField обеспечивает доступность
  • state.segments содержит список сегментов для отображения

Работа сегментов даты

Каждый сегмент представляет отдельную часть даты. Он может быть:

  • редактируемым
  • статическим

Для работы с сегментами используется хук useDateSegment.

Компонент сегмента

import {useRef} from "react";
import {useDateSegment} from "@react-aria/datepicker";

function DateSegment({segment, state}) {
  let ref = useRef();
  let {segmentProps} = useDateSegment(segment, state, ref);

  return (
    <span {...segmentProps} ref={ref}>
      {segment.text}
    </span>
  );
}

Сегмент автоматически получает:

  • клавиатурную навигацию
  • управление фокусом
  • редактирование чисел
  • ARIA-атрибуты

Типы сегментов

React Aria разделяет сегменты на несколько типов.

Тип Назначение
day день месяца
month месяц
year год
hour часы
minute минуты
second секунды
dayPeriod AM/PM
literal разделители

Пример массива сегментов:

[
  { type: "day", text: "12" },
  { type: "literal", text: "/" },
  { type: "month", text: "05" },
  { type: "literal", text: "/" },
  { type: "year", text: "2026" }
]

Управление значением даты

Состояние поля даты может управляться:

  • автоматически
  • вручную через controlled value

Controlled режим

<DateField
  value={date}
  onCha nge={setDate}
/>

В этом случае:

  • value хранит текущее значение
  • onChange вызывается при изменении

Тип значения — объект из библиотеки @internationalized/date.


Использование CalendarDate

Для хранения дат применяется специализированный тип:

import {CalendarDate} from "@internationalized/date";

let date = new CalendarDate(2026, 3, 16);

Преимущества такого подхода:

  • независимость от часовых поясов
  • поддержка разных календарных систем
  • безопасная арифметика дат

Клавиатурная навигация

useDateField реализует богатую систему клавиатурного управления.

Основные клавиши

Клавиша Действие
ArrowLeft переход к предыдущему сегменту
ArrowRight переход к следующему сегменту
ArrowUp увеличение значения
ArrowDown уменьшение значения
Tab переход между элементами интерфейса
цифры ввод значения

Пример поведения

Если фокус находится на сегменте дня:

ArrowUp → 15 → 16
ArrowDown → 15 → 14

Обработка неполных значений

Ввод даты может быть частичным. Например:

__/__/2026

React Aria корректно обрабатывает такие состояния:

  • сегменты имеют placeholder
  • неполные значения остаются валидными
  • пользователь может редактировать любую часть

Локализация

useDateField автоматически адаптируется под локаль.

Локаль влияет на:

  • порядок сегментов
  • формат даты
  • разделители
  • календарную систему

Пример различий

Локаль Формат
США MM/DD/YYYY
Германия DD.MM.YYYY
Япония YYYY/MM/DD

Локаль определяется через useLocale.

import {useLocale} from "@react-aria/i18n";

let {locale} = useLocale();

Ограничения значений

Поле даты поддерживает ограничения диапазона.

Минимальная и максимальная дата

<DateField
  minValue={new CalendarDate(2020,1,1)}
  maxValue={new CalendarDate(2030,12,31)}
/>

Если пользователь пытается выйти за пределы диапазона:

  • значение блокируется
  • сегмент становится недоступным для увеличения

Проверка валидности

useDateFieldState содержит встроенную систему валидации.

Состояние предоставляет свойства:

  • isInvalid
  • validationErrors

Пример:

if (state.isInvalid) {
  console.log(state.validationErrors);
}

Управление фокусом

Фокус автоматически перемещается между сегментами.

Особенности реализации:

  • каждый сегмент является focusable элементом
  • фокус визуально выделяет текущую часть даты
  • стрелки позволяют перемещаться внутри поля

Это улучшает доступность и скорость редактирования.


Интеграция с календарём

useDateField часто используется вместе с календарём.

Типичная структура компонента:

DatePicker
 ├─ DateField
 └─ Calendar

Поле отвечает за текстовый ввод, а календарь — за выбор даты мышью.

Обе части используют общее состояние.


Поддержка разных календарных систем

Библиотека @internationalized/date позволяет работать с различными календарями:

  • григорианский
  • японский
  • исламский
  • буддийский

Пример:

import {JapaneseCalendar} from "@internationalized/date";

Это позволяет создавать международные интерфейсы без изменения логики компонента.


Кастомизация отображения сегментов

Сегменты можно стилизовать по их типу.

<span
  {...segmentProps}
  className={`segment-${segment.type}`}
>
  {segment.text}
</span>

Пример CSS:

.segment-day {
  font-weight: bold;
}

.segment-month {
  color: blue;
}

Плейсхолдеры сегментов

Если значение сегмента отсутствует, отображается placeholder.

Примеры:

DD/MM/YYYY
MM-DD-YYYY

Это обеспечивает:

  • понятную структуру ввода
  • подсказку пользователю
  • корректную локализацию

Работа с временем

useDateField поддерживает и временные сегменты.

Пример формата:

12/05/2026 14:30

Добавляются дополнительные типы сегментов:

  • hour
  • minute
  • second
  • dayPeriod

Синхронизация сегментов

Изменение одного сегмента может влиять на другие.

Пример:

31 февраля → автоматически корректируется

Система:

  • проверяет корректность даты
  • синхронизирует значения
  • предотвращает невозможные комбинации

ARIA-атрибуты

useDateField автоматически добавляет необходимые атрибуты:

  • role="group"
  • aria-labelledby
  • aria-describedby
  • aria-invalid

Это обеспечивает поддержку:

  • screen reader
  • навигации клавиатурой
  • доступности для пользователей с ограничениями

Производительность

Несмотря на сложную внутреннюю логику, useDateField оптимизирован:

  • минимальное количество перерендеров
  • мемоизация сегментов
  • эффективное управление состоянием

Каждый сегмент обновляется только при необходимости.


Типичная структура полноценного компонента

Полный компонент обычно включает:

DateField
 ├─ Label
 ├─ Segments
 ├─ Validation message
 └─ Description

Пример структуры JSX:

<label>Date</label>
<DateField />
<p>Select a date</p>

Расширенные возможности

useDateField поддерживает:

  • ввод даты и времени
  • диапазоны дат
  • ограничение по времени
  • кастомные форматы
  • различные календарные системы
  • интеграцию с DatePicker

Это делает его базовым инструментом для создания сложных компонентов работы с датами в экосистеме React Aria.