WCAG 2.1 AA — release blocker
DatePicker must satisfy these on every render before it ships.
Web (React DOM)
- Trigger is a standard
<button>witharia-haspopup="dialog"andaria-expanded. - Calendar popup is rendered with
Popoverand the sharedCalendarDayPicker v10 grid. - Selected date receives
aria-selected="true"in the calendar grid. - Disabled dates are marked
aria-disabled="true". - The clear action (when
isClearable) has an accessible label and does not toggle the popover.
Keyboard
| Key | Action |
|---|---|
Tab | Move focus to/from the trigger. |
Enter / Space | Open the calendar from the trigger. |
Escape | Close the calendar popup. |
Arrow Left/Right | Move focus by one day. |
Arrow Up/Down | Move focus by one week. |
Page Up/Down | Go to previous/next month. |
Shift + Page Up/Down | Go to previous/next year. |
Home / End | Go to start/end of the week. |
Time selection
When showTimeSelect is enabled, the native time input is keyboard-accessible and announces the selected time through the browser.
Portal mode
DatePicker uses the shared Popover layer. If a modal date picker is needed, compose Calendar inside Dialog or Sheet explicitly.
React Native
- DatePicker is a Pressable stub on native. Use
@react-native-community/datetimepickerfor native date picking.
Dark mode
Calendar and DatePicker use component-level token classes. No react-datepicker CSS import is required.
Reduced motion
Calendar animations are minimal (CSS-based transitions of 150ms). No custom motion to manage.
Audit checklist
- Trigger is keyboard-focusable
- Enter/Space opens the calendar
- Escape closes the calendar
- Arrow keys navigate the calendar grid
- Selected date announced with
aria-selected - Disabled dates are
aria-disabled - Clear action is labelled
- Time input is keyboard-accessible when enabled
- 4.5:1 contrast on all interactive elements