Skip to main content
0.67.0
View Zag.js on Github
Join the Discord server

Timer

The timer machine is used to record the time elapsed from zero or since a specified target time.

02
:
00
:
00
:
10

Features

  • Countdown from a specified time.
  • Use as stopwatch to record the time elapsed.
  • Control the timer with start, stop, and resume buttons.
  • Set the tick interval for the timer.

Installation

To use the Timer machine in your project, run the following command in your command line:

npm install @zag-js/timer @zag-js/react # or yarn add @zag-js/timer @zag-js/react

Anatomy

To set up the Timer correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

No anatomy available for timer

Usage

First, import the timer package into your project

import * as timer from "@zag-js/timer"

The Timer package exports these functions:

  • machine — The state machine logic for the Time Picker widget.
  • connect — The function that translates the machine's state to JSX attributes and event handlers.
  • parse — The function to parse a date time string or object into a Time object.

You'll also need to provide a unique id to the useMachine hook. This is used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the Time Picker machine in your project 🔥

import { normalizeProps, useMachine } from "@zag-js/react" import * as timer from "@zag-js/timer" export function Countdown() { const [state, send] = useMachine( timer.machine({ id: useId(), countdown: true, autoStart: true, startMs: timer.parse({ days: 2, seconds: 10 }), onComplete() { console.log("Timer completed") }, }), ) const api = timer.connect(state, send, normalizeProps) return ( <div> <div {...api.getRootProps()}> <div {...api.getItemProps({ type: "days" })}> {api.formattedTime.days} </div> <div {...api.getSeparatorProps()}>:</div> <div {...api.getItemProps({ type: "hours" })}> {api.formattedTime.hours} </div> <div {...api.getSeparatorProps()}>:</div> <div {...api.getItemProps({ type: "minutes" })}> {api.formattedTime.minutes} </div> <div {...api.getSeparatorProps()}>:</div> <div {...api.getItemProps({ type: "seconds" })}> {api.formattedTime.seconds} </div> </div> <div style={{ display: "flex", gap: "4px" }}> <button onClick={api.start}>START</button> <button onClick={api.pause}>PAUSE</button> <button onClick={api.resume}>RESUME</button> <button onClick={api.reset}>RESET</button> </div> </div> ) }

Setting the start value

Set the startMs property to the timer machine's context to set the start time in milliseconds.

const [state, send] = useMachine( timer.machine({ startMs: 1000 * 60 * 60, // 1 hour }), )

Alternatively, you can also use the timer.parse function to convert a date time string or object into milliseconds

const [state, send] = useMachine( timer.machine({ startMs: timer.parse("2021-01-01T12:00:00Z"), // startMs: timer.parse({ hours: 12, minutes: 0, seconds: 0 }), }), )

Auto starting the timer

Set the autoStart property to true in the timer machine's context to start the timer automatically when the component mounts.

const [state, send] = useMachine( timer.machine({ autoStart: true, }), )

Usage as countdown timer

To use the timer as a countdown timer, set the countdown property to true in the timer machine's context.

const [state, send] = useMachine( timer.machine({ countdown: true, }), )

Setting the target value

To set the target value of the countdown timer, pass the targetMs property in the timer machine's context. The timer stops automatically when the targetMs is reached.

When targetMs is set and countdown=true, the timer ticks down to zero from the specified target time.

const [state, send] = useMachine( timer.machine({ countdown: true, targetMs: 1000 * 60 * 60, // 1 hour }), )

When targetMs is set and countdown=false|undefined, the timer ticks up to the specified target time.

const [state, send] = useMachine( timer.machine({ targetMs: 1000 * 60 * 60, // 1 hour }), )

Setting the tick interval

Set the interval property to the timer machine's context to set the tick interval in milliseconds.

const [state, send] = useMachine( timer.machine({ interval: 1000, // 1 second }), )

Listening to tick events

When the timer ticks, the onTick callback is invoke. You can listen to this event and update your UI accordingly.

const [state, send] = useMachine( timer.machine({ onTick(details) { // details => { value, segments } console.log(details) }, }), )

Listening for completion events

When the timer reaches the target time, the onComplete callback is invoked.

const [state, send] = useMachine( timer.machine({ countdown: true, targetMs: 1000 * 60 * 60, // 1 hour onComplete() { console.log("Timer completed") }, }), )

Starting and Stopping the timer

To start the timer, send the api.start() callback

api.start()

To stop the timer, send the api.stop() callback

api.stop()

Pausing and Resuming the timer

To pause the timer, send the api.pause() callback

api.pause()

To resume the timer, send the api.resume() callback

api.resume()

Methods and Properties

Machine Context

The time picker machine exposes the following context properties:

  • countdownbooleanWhether the timer should countdown, decrementing the timer on each tick.
  • startMsnumberThe total duration of the timer in milliseconds.
  • targetMsnumberThe minimum count of the timer in milliseconds.
  • autoStartbooleanWhether the timer should start automatically
  • intervalnumberThe interval in milliseconds to update the timer count.
  • onTick(details: TickDetails) => voidFunction invoked when the timer ticks
  • onComplete() => voidFunction invoked when the timer is completed
  • idstringThe unique identifier of the machine.
  • getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The time picker api exposes the following methods:

  • runningbooleanWhether the timer is running.
  • pausedbooleanWhether the timer is paused.
  • timeTime<number>The formatted timer count value.
  • formattedTimeTime<string>The formatted time parts of the timer count.
  • start() => voidFunction to start the timer.
  • pause() => voidFunction to pause the timer.
  • resume() => voidFunction to resume the timer.
  • reset() => voidFunction to reset the timer.
  • restart() => voidFunction to restart the timer.
  • progressPercentnumberThe progress percentage of the timer.

Edit this page on GitHub

Proudly made in🇳🇬by Segun Adebayo

Copyright © 2024
On this page