Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Session Timeout Dialog Block for Svelte

A bank's accounts page with an alert dialog shown open that warns before an idle session ends: a one-minute clock with a draining bar, Stay signed in and Sign out now, and a signed-out view at zero.

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

Warn before a quiet session ends, and let people keep it, with this timeout dialog for Svelte with Ark UI. It opens from the accounts page of Copperfen, an online bank: the page, a balance and two transactions, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner, and its header holds an outline Simulate idle Button. The Alert Dialog centres a title, a sentence, large digits from the Timer counting down from a minute, and a thin bar along its top edge that drains over the same minute. Stay signed in, the only Shine Button, has first focus and starts the clock again; Sign out now is outline. At zero the same dialog says you were signed out and offers Sign in again, and the page veils its account. For preview the dialog is drawn open in place when the page loads, its clock stopped at 1:00; the Simulate idle button opens the real Alert Dialog, where the clock runs. For banking, health, admin tools and any app that ends idle sessions.

FAQ

Why is the dialog already open, and why is its clock stopped?

So you can see it without a click, and so a poster never ages. On load the alert dialog is a copy drawn in place over the page: a native dialog element with the alert dialog role that isn't modal, so nothing is trapped or focused, its digits stopped at 1:00 and its bar full. The Simulate idle button opens the real Alert Dialog, modal, with its focus trap, Escape and focus return, and there the clock runs from the moment it opens and starts over each time. The copy stays closed until a reload. Both show the same TimeoutFields component and share the block's state. In your app keep the Alert Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

Does a screen reader hear the clock?

Not every second. The digits are hidden from assistive technology, and a polite status line speaks only at 30 seconds, at 10 seconds and when the session ends. That line lives inside the dialog, because a modal hides the rest of the page from a screen reader. The sentence in the dialog carries the rule in words, and the person can always extend it with a button, which is the first control focused, so the time limit can be turned off or extended as WCAG 2.2.1 asks.

What stays local, and how do I wire it for real?

Nothing signs out. At zero, or on Sign out now, the page's account is veiled with a note and the header's button becomes Sign in again, which lifts the veil. In your app call your sign-out and refresh endpoints from leave and keep, reset the clock on real activity (key presses and pointer moves, throttled), and share the session's state between tabs, for instance with a BroadcastChannel, so one tab's warning doesn't contradict another's. A real app also resets on activity: here only a button extends the session.

What does Escape do?

It closes the warning and the session goes on, and the polite status says so. It never signs anyone out. An alert dialog is also the kind that a click outside doesn't close, because the question needs an answer, and first focus lands on Stay signed in rather than on a way to leave.

What if I prefer reduced motion?

The bar along the top is left out and the digits still run: the time still passes, so the number has to keep moving, but nothing slides.

Is it accessible from the keyboard?

Yes. The real alert dialog is named by its title and described by its sentence, first focus lands on Stay signed in, and Escape returns focus to the header's button. After a result, focus goes to the header's button again, whichever one it is now. The trigger is the Simulate idle button wrapped in AlertDialogTrigger with asChild, and the dialog is controlled with open and onOpenChange; first focus is set with initialFocusEl. The copy shown on load moves no focus.