85Build a date picker with keyboard navigation and disabled dates
mediumAbout 45 minutesCodingreactdatesaccessibilitykeyboard
Problem
Build <DatePicker value="2026-10-14" onChange={fn} min max isDateDisabled />. Dates are ISO strings ("YYYY-MM-DD").
Render one month:
- an
<h2>with the month and year, for exampleOctober 2026, and buttons labelledPrevious monthandNext month; - a
<table role="grid">with weekday headers (Su to Sa) and one row per week; days of other months are empty cells; - each day is a
<button data-date="2026-10-01">witharia-selected="true"on the selected date andaria-disabled="true"on disabled dates (beforemin, aftermax, or whereisDateDisabled(iso)is true).
Requirements
- Clicking an enabled day calls
onChange(iso). Disabled days do nothing (but stay focusable for keyboard users). - Only one day is in the Tab order (roving
tabIndex): the focused day, which starts at the selected date. - Keyboard on a day:
ArrowLeft/ArrowRightmove one day,ArrowUp/ArrowDownone week,Home/Endto the start or end of the week,PageUp/PageDownone month (keeping the day, clamped to the month's length),Enterselects. Moving into another month shows that month and keeps focus on the new day. - No timezone bugs:
2026-03-29must stay2026-03-29in every timezone.
Try it yourself
Write your solution, run it, then submit to check it against the tests.
App.jsxReact + DOM
Step-by-step
Parse "YYYY-MM-DD" into Date.UTC(y, m - 1, d) and read it back with getUTCFullYear, getUTCMonth and getUTCDate. Local-time Dates shift by an hour across daylight-saving changes, which turns some dates into the previous day. toISOString().slice(0, 10) formats a UTC date back to an ISO string.
Unlock the full solution
What's inside
- Step-by-step
- Approach
- Solution
- Complexity
- Edge cases
- Follow-up questions
- Tests
Includes 2 code listings, 5 edge cases, 4 follow-up questions.
One-time payment by UPI, card or net banking. Launch price.