shadcn.io is not affiliated with official shadcn/ui
Meeting Schedule Dashboard Block for React
A day on a time axis from 08:00 to 18:00 with nine meetings placed by start and length, overlaps side by side marked Conflict, a now line, and a meeting-length select that marks and lists the free slots.
Installation
Overview
See where a day's meetings collide and where there is room, with this meeting schedule panel for React with Base UI. A hairline frame with a plus mark on each corner draws Monday 19 Oct 2026 on Agendawell as a vertical axis from 08:00 to 18:00. Nine meetings sit at their start and length; those that overlap stand side by side in columns and say "Conflict" with how many are in the clash, and a line marks now at a typed 11:15. A Native Select in the header sets the meeting length to 15, 30 or 60 minutes, and the free slots from now to the end of the day are marked on the axis with dashed boxes and listed in the side cell. Pressing a meeting opens it in the side cell with its time, place and who is invited as Avatar initials, and a Button to join that does nothing in this demo and says so. It's built from Native Select, Button, Avatar, Badge and Guides. For calendars and scheduling tools.
FAQ
How do I fill it with my calendar?
Edit MEETINGS: each is made with meeting(id, title, start, length, place, attendees), where the start is minutes after midnight (at(9, 30) is 09:30) and the length is in minutes. OPEN, CLOSE and NOW set the working day and the now line, and HOUR is the height of an hour on the axis. The columns, the conflicts, the free slots and the header sentence are all worked out from the meetings.
How are conflicts found?
Two meetings conflict when one starts before the other ends. Meetings that overlap in a run are laid out in columns, each in the first column that is free when it starts, and each one shows how many meetings are in its clash. The header counts the runs with more than one meeting.
How are the free slots worked out?
Meetings are merged into busy runs, a meeting that ends as another starts counting as one run, and the gaps between them within the working day are the free time. A gap is clipped to start no earlier than now and kept only if it holds at least the length you chose, so switching from 30 to 60 minutes leaves fewer slots.
What does Join do?
Nothing in this demo: it says so in the status line. In your app, open the meeting's call link from the handler, or render the button as a link.