Focus Timer
A focus timer whose ring (or 60 ticks) drains as time runs, with presets, start/pause and reset.
Overview
A big mm:ss reading sits inside a ring that empties as the session runs; the colon blinks while it counts. Switch the face to sixty clock ticks that go out one by one.
Presets set the length, the main button reads Start, Pause, Resume or Again depending on state, and reset is one tap. Timing runs on requestAnimationFrame, so it pauses with the tab.
When to use
- Focus and pomodoro tools, workout rests, timed exams.
- Any short countdown the user starts themselves.
When not to use
- Deadlines days away: show a date and a relative time.
- Server-driven countdowns that must match other clients: drive left from your server time.
Installation
pnpm dlx shadcn@latest add https://sundaeui.dev/r/focus-timer.jsonnpx shadcn@latest add https://sundaeui.dev/r/focus-timer.jsonyarn dlx shadcn@latest add https://sundaeui.dev/r/focus-timer.jsonbunx --bun shadcn@latest add https://sundaeui.dev/r/focus-timer.jsonWorks in any React project. Files are written to components/sundae/. Read the source in the stage’s Code view. Pro assets need a personal token. See authenticated installs.
- No dependencies beyond React 18 or later.
- Copy focus-timer.tsx and focus-timer.css into components/sundae/.
- The CSS file is imported by the component, so no extra configuration is needed.
- Import the component and use it as shown below.
Usage
import { FocusTimer } from '@/components/sundae/focus-timer'
<FocusTimer minutes={25} presets={[5, 15, 25, 50]} onComplete={notify} />Props
| Prop | Type | Default |
|---|---|---|
minutesStarting length. | number | 25 |
presetsQuick lengths in minutes. | number[] | [5, 15, 25] |
displayFace style. | 'ring' | 'ticks' | 'ring' |
onCompleteCalled when the timer reaches zero. | () => void | — |
autoStartStart on mount. | boolean | false |
speedSeconds per real second. For demos. | number | 1 |
fillSurface: dark or light. | 'dark' | 'light' | 'dark' |
Accessibility
- The reading is role="timer" with a spoken label ("4 minutes 12 seconds left"); it does not announce every second.
- Start, pause, reset, preset changes and completion are announced once in a polite live region.
- Presets are toggle buttons (aria-pressed). Reduced motion stops the colon blink and ring easing.
Customization
- --fg colours the ring and main button.
- Pass any presets; the row centres itself.
Keyboard
- Tab
- Move between presets, start and reset
- Enter / Space
- Pick a preset, start or pause, reset
FAQ
- Does it keep running in a background tab?
- No, requestAnimationFrame pauses with the tab. For background timing, store the end time and compute the remainder on focus.
- Can it play a sound at the end?
- Yes, from onComplete. Browsers allow audio there because the timer was started by a click.
- Is Focus Timer free?
- Focus Timer is part of Sundae Pro. The live preview is open to everyone; the source installs with a Pro account.
- How do I install Focus Timer?
- Run npx shadcn@latest add https://sundaeui.dev/r/focus-timer.json. The files are written to components/sundae/. It has no dependencies beyond React 18 or later.
- Does Focus Timer support keyboard and screen readers?
- The reading is role="timer" with a spoken label ("4 minutes 12 seconds left"); it does not announce every second. Start, pause, reset, preset changes and completion are announced once in a polite live region.
- Does Focus Timer respect reduced motion?
- Presets are toggle buttons (aria-pressed). Reduced motion stops the colon blink and ring easing.
More like this
All components →Time Tracker
Components · RefinedDownload Button
Components · RefinedNext Meeting Card
Components · RefinedTask List
Components · RefinedAlarm List
Components · RefinedToast Stack
Components · Refined