useCalendarGrid — это хук из библиотеки React Aria,
предназначенный для управления доступностью и взаимодействием с
календарными сетками. Он предоставляет все необходимые атрибуты и
состояния для рендеринга календаря, учитывая спецификации ARIA для
интерактивных таблиц и дат. Основная задача хука — абстрагировать
сложную логику выбора дат и фокусировки, предоставляя готовый API для
компонентов календаря.
Импорт хука осуществляется следующим образом:
import { useCalendarGrid } from '@react-aria/calendar';
import { useLocale } from '@react-aria/i18n';
import { useCalendarState } from '@react-stately/calendar';
Для работы useCalendarGrid необходим объект состояния
календаря (CalendarState) из библиотеки React Stately. Этот
объект управляет текущей датой, выбранной датой и диапазоном, а также
навигацией по месяцам.
Пример создания состояния календаря:
const { locale } = useLocale();
const state = useCalendarState({ locale, visibleDuration: { months: 1 }, minValue: new Date(2023, 0, 1), maxValue: new Date(2025, 11, 31) });
useCalendarGridХук возвращает объект с ключевыми свойствами:
gridProps — атрибуты для контейнера
сетки календаря (role="grid", aria-labelledby,
обработка клавиатурной навигации).headerProps — атрибуты для строки
заголовка дней недели.weekDays — массив объектов с
информацией о днях недели (например, сокращённые названия дней).weeks — массив объектов, каждый из
которых представляет неделю и содержит массив дней с полной
информацией.getCellProps(day) — функция,
возвращающая атрибуты для конкретной ячейки дня
(role="gridcell", состояние aria-selected,
aria-disabled).Пример применения:
const { gridProps, headerProps, weeks, getCellProps } = useCalendarGrid({ state });
return (
<table {...gridProps}>
<thead {...headerProps}>
<tr>
{state.weekDays.map(day => <th key={day}>{day}</th>)}
</tr>
</thead>
<tbody>
{weeks.map((week, wi) => (
<tr key={wi}>
{week.map(day => {
const cellProps = getCellProps(day);
return <td key={day.date.toString()} {...cellProps}>{day.date.getDate()}</td>;
})}
</tr>
))}
</tbody>
</table>
);
Каждая ячейка календаря может находиться в нескольких состояниях:
selected) — если дата
соответствует выбранной дате или диапазону.disabled) — если дата
выходит за пределы minValue или maxValue, либо
находится вне активного месяца.focused) — для обработки
клавиатурной навигации. Хук автоматически управляет фокусом с помощью
ARIA и стрелок клавиатуры.today) — текущая
дата для визуального выделения.Все эти состояния автоматически добавляются в атрибуты ARIA через
getCellProps, обеспечивая корректную доступность для
скринридеров.
useCalendarGrid учитывает локализацию через объект
locale:
Пример:
const { locale } = useLocale();
const state = useCalendarState({ locale, ... });
const { weeks, getCellProps } = useCalendarGrid({ state });
weeks.forEach(week => {
week.forEach(day => {
const cell = getCellProps(day);
// cell['aria-label'] уже содержит локализованную строку даты
});
});
useCalendarGrid обеспечивает стандартное управление
стрелками:
Эта навигация реализована без необходимости вручную отслеживать фокус и события клавиатуры, что упрощает интеграцию и поддерживает ARIA-совместимость.
Хотя useCalendarGrid отвечает за логику и доступность,
визуальное оформление полностью на стороне разработчика:
getCellProps.state.Пример добавления кастомного класса для сегодняшнего дня:
<td
key={day.date.toString()}
{...getCellProps(day)}
className={day.isToday ? 'today' : ''}
>
{day.date.getDate()}
</td>
useCalendarGrid полностью совместим с диапазонами
дат:
state.selectionMode = 'range' ячейки
автоматически получают атрибуты aria-selected и визуальные
индикаторы для начала, конца и промежуточных дат.useDatePicker или useCalendar, для
построения сложных интерфейсов выбора дат.useCalendarGrid генерирует их автоматически.<table> с role="grid" для корректной
доступности.getCellProps для
корректного взаимодействия с клавиатурой и скринридерами.visibleDuration в состоянии календаря.useCalendarGrid предоставляет мощный инструмент для
построения доступных и локализованных календарных интерфейсов в React,
позволяя сосредоточиться на дизайне и пользовательском опыте, не
погружаясь в тонкости ARIA и управления фокусом.