Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

World Clock Dialog Block for Ark UI

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.

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

Plan a meeting across zones with one slider, with this world clock dialog for React with Ark 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 the button wrapped in DialogTrigger with asChild, 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.