/react-compound-timer

Create timers easily with React!

Primary LanguageTypeScript

react-compound-timer

Timer compound component for react to make building timers less painfull. It incapsulates all timer logic - you should only think about rendering!

See Working Examples

Forward Count

Just render a simple timer and start counting forward from 0. Use compound components to render time units. You can see all avaliable time units in this example.

<Timer>
    <Timer.Days /> days
    <Timer.Hours /> hours
    <Timer.Minutes /> minutes
    <Timer.Seconds /> seconds
    <Timer.Milliseconds /> milliseconds
</Timer>

Backward Count

The same simple timer, but counting backward.

<Timer
    initialTime={55000}
    direction="backward"
>
    {() => (
        <React.Fragment>
            <Timer.Days /> days
            <Timer.Hours /> hours
            <Timer.Minutes /> minutes
            <Timer.Seconds /> seconds
            <Timer.Milliseconds /> milliseconds
        </React.Fragment>
    )}
</Timer>

Controls

Get action functions from props and use them to control your timer.

<Timer
    initialTime={55000}
>
    {({ start, resume, pause, stop, reset, timerState }) => (
        <React.Fragment>
            <div>
                <Timer.Days /> days
                <Timer.Hours /> hours
                <Timer.Minutes /> minutes
                <Timer.Seconds /> seconds
                <Timer.Milliseconds /> milliseconds
            </div>
            <div>{timerState}</div>
            <br />
            <div>
                <button onClick={start}>Start</button>
                <button onClick={pause}>Pause</button>
                <button onClick={resume}>Resume</button>
                <button onClick={stop}>Stop</button>
                <button onClick={reset}>Reset</button>
            </div>
        </React.Fragment>
    )}
</Timer>

No autoplay

You can just render a timer, and then start it only by using action function 'start' from props.

<Timer
    initialTime={55000}
    startImmediately={false}
>
    {({ start, resume, pause, stop, reset, timerState }) => (
        <React.Fragment>
            <div>
                <Timer.Days /> days
                <Timer.Hours /> hours
                <Timer.Minutes /> minutes
                <Timer.Seconds /> seconds
                <Timer.Milliseconds /> milliseconds
            </div>
            <div>{timerState}</div>
            <br />
            <div>
                <button onClick={start}>Start</button>
                <button onClick={pause}>Pause</button>
                <button onClick={resume}>Resume</button>
                <button onClick={stop}>Stop</button>
                <button onClick={reset}>Reset</button>
            </div>
        </React.Fragment>
    )}
</Timer>

With hooks

Write your own hooks on timer actions.

<Timer
    initialTime={55000}
    startImmediately={false}
    onStart={() => console.log('onStart hook')}
    onResume={() => console.log('onResume hook')}
    onPause={() => console.log('onPause hook')}
    onStop={() => console.log('onStop hook')}
    onReset={() => console.log('onReset hook')}
>
    {({ start, resume, pause, stop, reset, timerState }) => (
        <React.Fragment>
            <div>
                <Timer.Days /> days
                <Timer.Hours /> hours
                <Timer.Minutes /> minutes
                <Timer.Seconds /> seconds
                <Timer.Milliseconds /> milliseconds
            </div>
            <div>{timerState}</div>
            <br />
            <div>
                <button onClick={start}>Start</button>
                <button onClick={pause}>Pause</button>
                <button onClick={resume}>Resume</button>
                <button onClick={stop}>Stop</button>
                <button onClick={reset}>Reset</button>
            </div>
        </React.Fragment>
    )}
</Timer>

Last Unit Property

Control your last unit. For example, 1 minute 30 seconds can be 90 seconds, if you set lastUnit as 'seconds'. It means that minutes, hours and days will not be computed.

<Timer
    initialTime={60000 * 60 * 48 + 5000}
    lastUnit="h"
    direction="backward"
>
    {() => (
        <React.Fragment>
            <Timer.Days /> days
            <Timer.Hours /> hours
            <Timer.Minutes /> minutes
            <Timer.Seconds /> seconds
            <Timer.Milliseconds /> milliseconds
        </React.Fragment>
    )}
</Timer>

With checkpoints

If you need to call some functions on certain time - provide checkpoints property. It is an array of objects. Each object contains time and callback, that will be fired, when timer intersects checkpoint's time.

<Timer
    initialTime={60000 * 60 * 48 + 5000}
    direction="backward"
    checkpoints={[
        {
            time: 60000 * 60 * 48,
            callback: () => console.log('Checkpoint A'),
        },
        {
            time: 60000 * 60 * 48 - 5000,
            callback: () => console.log('Checkpoint B'),
        }
    ]}
>
    {() => (
        <React.Fragment>
            <Timer.Days /> days
            <Timer.Hours /> hours
            <Timer.Minutes /> minutes
            <Timer.Seconds /> seconds
            <Timer.Milliseconds /> milliseconds
        </React.Fragment>
    )}
</Timer>