shadcn.io is not affiliated with official shadcn/ui
On-Call Rotation Calendar Block for React
October 2026 with the on-call person in every day, a ring on each Monday handoff, an escalation chain for the chosen day and two swap requests that rewrite the month when approved.
Installation
Overview
Show who holds the pager on every day with this on-call rotation for React with Base UI. A hairline frame with a plus mark on each corner holds October 2026 as a table, Monday first, whose cells carry the day's primary as initials and a first name, with a ring on each Monday when the pager changes hands at 09:00. Nobody typed the cells: a five-person order and a start date give the person for any week by simple arithmetic, so changing the order or the date redraws the whole month. Choosing a day, with a click or the arrow keys, Home and End, shows its escalation chain at the end of the frame: the primary, the secondary who is next in the order and the manager, each as an Avatar with a name. Under it, two swap requests have Approve and Decline Buttons: approving moves the day to the person who offered, in the month, in the chain and in the count of days each person holds under the month, and Undo puts it back. The bands are ruled by Guides and a Badge marks today. It's built from Avatar, Badge, Button and Guides, with a CSS entrance only. For incident teams, support rotas and any group that passes a duty along in turn.
FAQ
How is the person for each day worked out?
slotOf counts the whole weeks between START (a Monday) and the Monday of the day, then takes that number modulo the length of ORDER. The person at that place holds the pager for the week, and the secondary is the next one in the list. Weeks before the start date still work because the remainder is kept positive.
What do the swap requests do?
Each request in REQUESTS names a day and the person who will cover it. Approving adds it to a list of approved swaps; coverOf then returns that person for the day, so the cell, the chain and the counts all change at once. A swapped day is drawn with a filled chip and its name says "by swap". Declining leaves the day as it was, and Undo clears either answer.
How do I move around with the keyboard?
The month is one tab stop. The arrow keys move a day or a week, Home and End go to the start and end of the week, and Enter or Space chooses the day. Each day is a button named with its date, who is on call and whether it is a handoff, and the grid keeps its left-to-right order in right-to-left languages.
Why is today always 14 October?
Nothing in the block reads the clock. AS_OF is the one moment it treats as now, so the Today ring and the opening day come from it and the block looks the same on any date.
What stays local, and how do I wire it up?
Everything. Approving a swap only changes state in the page; nothing is paged, saved or sent. To make it real, load the rotation and the requests from your paging service, send the answer back when a button is pressed and keep the rest of the component as it is.