All questions

Calendar Scheduler

Premium

Calendar Scheduler

Build an accessible week scheduler in React. The starter already renders the complete 7-day by 10-hour calendar and four seeded events. Your job is to make its data, controls, announcements, and keyboard navigation work together.

Task

  1. Put events and the live-region status in React state. New ids must start at 5 and increase monotonically.
  2. Selecting an empty cell adds { id, day, hour, title: 'Meeting' }. Selecting a booked cell removes that event. Guard the add path so a programmatic duplicate cannot overwrite a booking.
  3. Keep every cell a native <button>. Empty cells are named Add Meeting on {FullDay} at {hour}:00; booked cells are named Remove {title} from {FullDay} at {hour}:00.
  4. Announce exactly {title} added on {FullDay} at {hour}:00. or {title} removed from {FullDay} at {hour}:00. in the role="status" region.
  5. Add spatial keyboard movement: Left/Right change day, Up/Down change hour, Home goes to Monday in the current hour, and End goes to Sunday. Movement clamps at the calendar edges and keeps focus on the target button.

Required behavior

  • Initial bookings are Standup at Monday 9:00, 1:1 at Tuesday 14:00, Design at Thursday 11:00, and Review at Friday 16:00.
  • Activating Wednesday 10:00 creates Meeting with id 5, color class e0, and the add announcement. Activating it again removes it and announces removal.
  • Colors are stable: use (event.id - 1) % 4, so removing one event never recolors another.
  • Native button behavior supplies click, Enter, and Space activation. Do not add duplicate key handlers for activation.
  • Arrow/Home/End handlers call preventDefault() only when they handle one of those keys.

Constraints

  • Treat the event array as the single source of truth; do not patch a cell's classes or text directly.
  • Preserve the supplied markup, copy, class names, data-cell coordinates, and persistent styles.css.
  • Keep the exercise dependency-free.
WE’RE LISTENING

Help make UIReady better

Found a bug or have an idea? Tell us about it.

Up to 3 files · 5 MiB each · JPG, PNG, WebP, MP4, WebM, MP3, M4A or WAV