Role and semantics
Section titled “Role and semantics”The grid is the APG date picker grid: a table with role="grid", named by the header. Each day is a button that reads the full date (“Tuesday, 27 October 2026”); today, a status label and “unavailable” are added to the name. The selected day’s cell has aria-selected. Weekday headers are short; the full name is read through abbr.
Keyboard
Section titled “Keyboard”| Key | Behaviour |
|---|---|
| Tab | Enters on the selected day (or today); the next Tab leaves the grid. |
| Left and right arrow | One day back or forward; reversed in right-to-left text. |
| Up and down arrow | One week back or forward. |
| Home, End | First or last day of the week. |
| Page Up, Page Down | One month back or forward. |
| Shift + Page Up, Shift + Page Down | One year back or forward. |
| Enter, Space | Selects the focused day. |
Focus is roving: the grid has one tab stop. The focused day gets a 2 px color-focus-ring ring.
Screen reader output
Section titled “Screen reader output”| Example | Output |
|---|---|
| Day | “Tuesday, 27 October 2026, button” |
| Today | “Wednesday, 28 October 2026, today” |
| Unavailable | “Tuesday, 20 October 2026, unavailable, dimmed” |
| Month change | “November 2026”, polite announcement |
Contrast
Section titled “Contrast”Day digits have 4.5:1; the selected day on the primary fill has 4.5:1; the today ring has 3:1. An unavailable day is set apart by a strike-through, not colour alone.
WCAG 2.2
Section titled “WCAG 2.2”| Criterion | How Calendar meets it | What product teams must do |
|---|---|---|
| 1.3.1 Info and relationships | A table, column headers and a named grid. | — |
| 1.4.1 Use of colour | Unavailable days are struck through; status is read by name. | Explain statuses in text too. |
| 2.1.1 Keyboard | APG grid keys. | — |
| 2.5.8 Target size (minimum) | Days are 40 px. | — |