Claude wrote a React DatePicker, but achieving WCAG accessibility took 3 more days
Claude generated a React DatePicker with ARIA attributes and keyboard navigation — in minutes. But when NVDA and VoiceOver were launched, serious problems…
AI-processed from Habr AI; edited by Hamidun News
The development team asked Claude to create a custom React DatePicker for a doctor's appointment booking form—with full support for keyboard navigation and screen readers. AI handled the first version quickly. Then came three days of refinement.
What Claude Did Well
Claude generated a working foundation for the component: JSX structure, basic ARIA attributes (`role="dialog"`, `aria-label`, `aria-live`), keyboard handlers for arrow navigation, and calendar grid logic. As a starting point—solid: the code compiled, looked visually correct, and manual testing didn't break anything. AI proved especially useful for boilerplate code: generating 42 grid cells, computing the first day of month offset, formatting dates for `aria-label`. This is work that's tedious to do by hand, and Claude handled it cleanly. The problem only became obvious after hooking up real assistive technologies.
Where It All Went Wrong
The real test started when NVDA on Windows and VoiceOver on macOS were launched. There were several issues:
- Focus trap didn't work — tabbing inside the dialog sent focus back to the main document
- Dates were read incorrectly — the screen reader said "1" instead of "Monday, June 1, 2026"
- Month switching was silent — the `aria-live` region didn't update when the month changed
- Escape closed but didn't return — after closing the calendar, focus was lost instead of returning to the trigger button
- Windows high contrast — the selected date was visually indistinct from the rest: the component relied on CSS color without state attributes
Each of these points in the generated code looked like "handler present"—but the behavior with a real screen reader differed from expectations.
How We Fixed It
The salvation was WAI-ARIA APG—W3C's official guide with a specific pattern for DatePicker dialogs. It doesn't just say "add `aria-modal`," but prescribes the exact sequence: which element receives focus on open, how to maintain the focus trap, where to return it on close, what `aria-label` is needed on month navigation buttons.
"Reading generated code doesn't mean checking accessibility.
Only a real screen reader reveals the truth."
The focus trap was rewritten using `querySelectorAll` with manual Tab and Shift+Tab interception. Each day cell got a full `aria-label` like "Wednesday, June 3, 2026" plus `aria-pressed="true"` for the selected state. For high contrast mode, we added `aria-selected` and outline via `outline` rather than just background color. The most subtle part was `aria-live`: the region must exist in the DOM before text is written to it, otherwise the screen reader ignores it. Claude inserted the region dynamically—this nuance only surfaced in testing.
What This Means
Claude accelerates writing accessible code but doesn't replace screen reader testing. The good news: once you've worked through WAI-ARIA APG once and documented the solutions, the next accessible component is written noticeably faster. AI takes on the boilerplate work—but skipping final verification with NVDA and VoiceOver is not an option.
Want to stop reading about AI and start using it?
AI News is a curated feed of AI/tech news. Hamidun Academy teaches you to use AI systematically in your work.