shadcn.io is not affiliated with official shadcn/ui
World Clock Dialog Block for React
A team page with its clocks dialog shown open: one slider that moves your time while every city's local time, day and 24-hour strip follow, the best overlap worked out from the strips, cities to add and remove, and a button that copies one line per city.
Installation
Overview
Plan a meeting across zones with one slider, with this world clock dialog for React with Base UI. It opens from the Team page of Hourbridge, a remote-team tool: the page's header holds an outline Team clocks Button, and the page, six cards with initials and a local time each, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The wide Dialog has a Slider for your time across Friday 9 October in 15-minute steps. Each city's row recomputes its local time with the day marked ("Sat, +1 day") and a strip of the day's 24 hours with 09:00 to 17:00 there filled and the slider's moment marked; the header names the best overlap worked out from the strips ("Best overlap: 14:00 to 16:00 your time") and draws it as one more strip. Add a city swaps the rows for a Listbox of 12 more, and every city but yours has a Remove button. Copy meeting time is the only Shine Button: it copies one line per city and moves the team page's cards to that moment. Nothing ticks: it is a planner, not a clock. For preview the dialog is drawn open in place when the page loads; the header's button opens the real dialog.
FAQ
Why is the dialog already open, and what do I keep?
So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Team clocks button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same ClockFields component and share the block's state. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.
How are the times, the days and the overlap worked out?
Each zone's offset is read once with Intl.DateTimeFormat at noon UTC on the typed day, and a city's time is your time plus the difference between the two offsets, so 14:30 in London is 15:30 in Berlin and 09:30 in New York. A result below zero or past midnight gets the day marked, and the strips mark an hour as work when its middle falls between 09:00 and 17:00 there. The best overlap is the longest run of hours when every strip is at work; with no such hour the line says so. It does not use the clock: a real app would read each date's own offset, since daylight saving can move it.
Is it accessible from the keyboard?
Yes. The real dialog is named by its title and described by its sentence, focus starts on the slider, and Escape, Cancel and the close button return focus to Team clocks. The slider is named "Your time on Friday" with arrow, Home, End and Page keys and a value text such as "Fri 9 Oct, 14:30", and it keeps its direction in a right-to-left page since it is a time axis. Each row's time says whether it is working hours for a screen reader, the strips are decoration, and the cities live in a region you can scroll with the keyboard. Adding or removing a city is said in the status line with the new best overlap. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange.
What do Add a city and Remove do?
Add a city replaces the rows with a list of the 12 cities not yet tracked, each with its time at the slider's moment; picking one adds it and goes back. Up to six cities, and your own row (London here) can't be removed. The rows and the list share one box, so the dialog never changes height. The cities are typed in the file and are real IANA names shown as text.
What stays local, and how do I wire it for real?
Nothing is scheduled. Copy meeting time writes the lines to your clipboard (if the browser refuses, the status says so), closes the dialog and moves the six team cards behind it to the moment you chose, each in its own zone. In your app take the cities from the team's profiles, create the event with the chosen instant in UTC, and let each person's calendar show it in their own zone.
How does it look on a phone?
The strips become two-hour cells so a row stays readable in 320 pixels, and the slider and the best overlap come first. The copy shown on load docks to the foot of the page as a bottom sheet with its buttons pinned and the content scrolling above them. The real dialog keeps the Dialog's own phone layout, a sheet stuck to the bottom of the screen.
Related
- Pro
Time Zone Picker Dialog
Time and schedulingA preferences page with its time zone dialog shown open: a search over 14 zones in four regions, each row with its city, UTC offset and the time there at one typed moment, a button that reads this device's zone on a press, and the chosen zone printed back on the page.
- Pro
Schedule Meeting Dialog
Time and schedulingA month page with its new event dialog shown open: a title, a day from a folded calendar, a start time and length, guest emails as tags, and a day timeline that moves with the time and warns when the meeting clashes.
- Pro
Meeting RSVP Dialog
Time and schedulingA team calendar's week with its reply dialog shown open: the event, a three-way Going, Maybe or Can't go answer, an optional note, and the guests by answer with their counts, moving as you choose.
- Pro
Set Reminder Dialog
Time and schedulingA to-do list with its reminder dialog shown open: five quick chips, an inline calendar and a time in quarter hours, repeat and notify choices, and one plain sentence that always reads the choice back.
- Pro
A team intranet's profile page with its language and region dialog shown open: a Language tab with a searchable list of eight languages, a Region tab with country, first day of the week and clock, and a live preview that reformats a sample date, time, number and amount with Intl.
- Pro
Pomodoro Timer Dialog
Time and schedulingA focus timer's Today page with its dialog shown open: a Focus, Short break and Long break switch, a ring that fills with the digits inside it, Start and Pause, four session dots and durations that apply at the next start.