Skip to main content

Accessibility

Keyboard navigation, ARIA attributes, and screen reader support in @gentleduck/calendar.

ARIA roles and attributes

ElementRole / AttributeValue
Grid containerrole="grid"-
Grid containeraria-roledescription"calendar"
Day cellrole="gridcell"-
Day cellaria-labelFull date (e.g. "Saturday, March 14, 2026")
Day cellaria-selectedtrue when selected
Day cellaria-disabledtrue when disabled
Day cellaria-current"date" for today
Nav wrapperrole="navigation"Set by the CalendarNav primitives compound component, not by the hook
Nav buttonaria-label"Go to previous month" / "Go to next month" (from getNavProps)
Nav buttondisabledtrue when navigation in that direction is not allowed (from getNavProps)
Month headeraria-live"polite"

Keyboard navigation

KeyAction
ArrowLeft / ArrowRightMove focus +/- 1 day
ArrowUp / ArrowDownMove focus +/- 1 week
PageUp / PageDownMove focus +/- 1 month
Shift+PageUp / Shift+PageDownMove focus +/- 1 year
Home / EndMove to start/end of week
Enter / SpaceSelect focused date
EscapeDismiss (calls onDismiss)

Focus auto-advances the displayed month when crossing boundaries. For example, pressing ArrowRight on the last day of the month moves focus to the first day of the next month and updates the displayed month.


Roving tabIndex

Only the currently focused date has tabIndex=0. All other days have tabIndex=-1. This means:

  • Tab moves focus into the calendar grid (to the focused date), then out
  • Arrow keys move focus between days within the grid
  • The user never has to tab through every day cell

Screen reader announcements

The useAnnouncer hook (used internally by useCalendar) creates an aria-live="polite" region that announces:

  • Month navigation changes (e.g. "March 2026")
  • Selection changes (e.g. "Selected Saturday, March 14, 2026")

When using compound components, the announcer portal is rendered automatically inside Calendar.Root.