Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Interview Scheduler Calendar Block for React Aria

A hiring day of five interviews in time order where each interviewer Select disables the people who are busy or away with the reason, and a clash count that clears as you reassign.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Stop a hiring day from putting one person in two rooms, with this interview scheduler for React with React Aria. A hairline frame with a plus mark on each corner starts with a count of clashes and one sentence about the first of them, then lists the five interviews of Wednesday 14 October in time order: the time, the candidate's initials, the role, the round and format, and a status mark worked out from the block's fixed "now" of 10:30 (Done, In progress or Scheduled). Each interview has an interviewer in a Native Select whose options are disabled, with the reason written in the option, when that person is already in an overlapping interview ("Busy: Round 2 with M. T. at 10:00") or away ("Away: Out until 11:00"). One clash is typed in so the count starts at 1; reassigning clears it, and the polite status line says who now sits where. A finished interview keeps its interviewer, and Reset puts the typed day back. On a phone each row stacks to a time, the details and a full-width select. It's built from Native Select, Avatar, Badge, Button and Guides, with a CSS entrance only. For recruiters, panels, exam boards and any rota where one person cannot be in two places.

FAQ

How does the block know there is a clash?

Two interviews clash when they share an interviewer and their times overlap; back-to-back interviews do not. An interviewer is also in conflict when an interview overlaps a block in AWAY. problemsOf collects those interviews, the count and the sentence in the header come from it, and a row that is in conflict says why under its details.

Why are some people greyed out in the Select?

An option is disabled when choosing that person would create a clash, and its text says why. The person who currently sits in the interview is never disabled, even when they are the cause of a clash, so you can always see who it is and move them.

How do I load my own day?

Edit INTERVIEWS, INTERVIEWERS and AWAY (times are written with minutesOf("10:00")), and set START_PLAN, one character per interview naming who sits in it. Status, clashes and the options are all worked out from those. All times are UTC+1, and "now" comes from AS_OF, never from the clock.

How is it read by a screen reader?

Each select has a visible "Interviewer" label, the disabled options carry their reason as their text, and every change is announced by the polite status line ("Dagmar P. now interviews J. A. at 10:00. No clashes."). The status marks are decorative; the status is always written as a word in the row.

What stays local, and how do I wire it up?

Everything. Assignments are kept in the page and reset on reload; no calendar is changed and nobody is notified. To make it real, load the day's interviews and the interviewers' busy blocks from your calendar API into the same shapes, and send the new interviewer from assign to your hiring system.