Accessibility
For designers
Section titled “For designers”- Keep labels visible and outside the field in every state.
- Keep format guidance (for example,
DD/MM/YYYY) visible in helper text at all times. - Treat the calendar trigger as an interactive button with a minimum 44x44px target.
- Maintain visible focus across field, trigger, month controls, and day cells, including high-contrast mode.
- Pair error color with icon and descriptive message, never color alone.
For developers
Section titled “For developers”The date picker follows the WAI-ARIA Date Picker Dialog pattern.
To ensure the Date Picker meets WCAG 2.1 AA and supports assistive technologies, follow these implementation standards:
- Text input is mandatory
- Do not remove typed date entry.
- Users must be able to complete the task without traversing day-by-day cells.
- Labels and descriptions
- Associate input and label with
for/id. - Link helper text and error text through
aria-describedby. - Announce error updates with
aria-live="polite".
- Associate input and label with
- Calendar semantics
- Use a
<button>for trigger and for each day cell. - Use
aria-expandedon trigger. - Expose day metadata with
aria-label,aria-selected,aria-disabled, andaria-current="date".
- Use a
- Focus and keyboard behavior
- Trap focus while popup is open.
- On open, move focus to selected date or current month context.
- On close (selection, Escape, outside click), return focus to trigger.
- Arrow keys move days, Enter/Space selects, Escape closes, PageUp/PageDown switches month.
- Tab closes popup and moves to the next page focus target.
- Mobile input mode
- Use
inputmode="numeric"to surface the numeric keyboard on mobile.
- Use
Roles and attributes
Section titled “Roles and attributes”| Element | Attributes |
|---|---|
| Trigger button | aria-haspopup="dialog", aria-expanded, aria-controls, and an accessible name (for example, aria-label="Choose date"). |
| Popup container | role="dialog", clear labeling via aria-label or aria-labelledby. |
| Calendar grid | role="grid" and aria-labelledby pointing to the visible month/year heading. |
| Week rows | role="row" |
| Day cells / button | Cell wrapper with role="gridcell"; day as a native <button>. Use aria-selected="true" for the chosen date and aria-current="date" for today. |
Keyboard interaction
Section titled “Keyboard interaction”| Key | Action |
|---|---|
| Enter / Space | Open picker from trigger, or select focused day |
| Arrow keys | Move day focus in the calendar grid |
| Home / End | Move focus to first / last focusable day |
| Escape | Close the popup and return focus to the trigger button |
Announcements
Section titled “Announcements”- Update the trigger label to the selected date after selection.
- Keep month/year text connected to the grid with
aria-labelledbyso context is announced while navigating. - Ensure disabled days are not focusable and keep native
disabledsemantics.