Countdown timer component with color and progress animation based on SVG

Jul 23, 2020
Countdown timer component with color and progress animation based on SVG

React/React Native Countdown Circle Timer

React/React Native countdown timer component in a circle shape with color and progress animation.




Lightweight React/React Native countdown timer component with color and progress animation based on SVG

  • Countdown animation independently optimized for the Web and Mobile
  • Transition between colors during the countdown
  • Fully customizable content in the center of the circle
  • a11y support
  • Built-in and ready-to-use TypeScript type definitions.


yarn add react-countdown-circle-timer

Check out the full documentation for demos and use cases.

React Native

yarn add react-native-countdown-circle-timer

This component has a peer dependency on react-native-svg. Read the full documentation for the installation guide, as well as demos and use cases.

Props for both React/React Native

Prop NameTypeDefaultDescription
durationnumberrequiredCountdown duration in seconds
colorsstring | [color HEX: string, transition duration: number 0 ~ 1][]requiredSingle color as a string in HEX format or an array of tuples: 1st param - color in HEX format; 2nd param - time to transition to next color represented as a fraction of the total duration
initialRemainingTimenumber-Sets the initial remaining time when the countdown starts. By default the countdown starts at the duration provided.
sizenumber180Width and height of the SVG element
strokeWidthnumber12Path stroke width
strokeLinecapround | squareroundPath stroke line cap
trailColorstring#d9d9d9Circle trail color - takes any valid color format (HEX, rgb, rgba, etc.)
rotationclockwise | counterclockwiseclockwiseProgress path rotation direction
isPlayingbooleanfalsePlay and pause animation
* isLinearGradientbooleanfalse* Apples linear gradient on top of the circle. The gradient doesn't follow the circle path. Works best with two colors.
gradientUniqueKeystring-Unique ID for the linearGradient element. It takes random ID if it's not provided.
childrenReactNode | function({ remainingTime: number, elapsedTime: number }): number|string|ReactNode-Render function or component to customize the time/content in the center of the circle. The content is centered using flexbox.
onCompletefunction(totalElapsedTime: number): void | [shouldRepeat: boolean, delay: number]-On complete handler. It can be used to repeat the countdown by returning an array where the first element shouldRepeat indicates if the loop should start over and second element delay specifies the delay before looping again in milliseconds. The callback receives as an argument the total elapsed time in seconds.
ariaLabelstringCountdown timerAria label for the whole component
renderAriaTimefunction({ remainingTime: number, elapsedTime: number }): string-Render prop function to customize the text message that will be read by the screen reader during the countdown.


Change duration and/or initialRemainingTime once component is mounted

Once the component is mounted duration and initialRemainingTime can not be changed to avoid any issues computing colors and progress. To set new values for any of the two props just pass a new key prop to CountdownCircleTimer component and the timer will start over with the new values provided.

Restart timer at any given time

Pass a key prop to CountdownCircleTimer and change the key when the timer should be restarted.

Repeat timer when countdown is completed

Return an array from onComplete handler, which indicates if the animation should be repeated. Example:

const UrgeWithPleasureComponent = () => ( <CountdownCircleTimer onComplete={() => { // do your stuff here return [true, 1500] // repeat animation in 1.5 seconds }} isPlaying duration={10} colors="#A30000" /> )

Set the initial remaining time different then the duration provided

Pass the remaining time to initialRemainingTime prop. Example:

const UrgeWithPleasureComponent = () => ( <CountdownCircleTimer isPlaying duration={60} initialRemainingTime={15} colors="#A30000" /> )

In the example above, the countdown will start at 15 seconds (one quarter before it's done) and it will animate for 15 seconds until reaches 0.

Time formatting functions

children prop of CountdownCircleTimer component will receive as a prop remainingTime in seconds. Below are few function that can be used to get different time formatting:

  • Format mm:ss (minutes and seconds)
const children = ({ remainingTime }) => { const minutes = Math.floor((remainingTime % 3600) / 60) const seconds = remainingTime % 60 return `${minutes}:${seconds}` }
  • Format hh:mm:ss (hours, minutes and seconds)
const children = ({ remainingTime }) => { const hours = Math.floor(remainingTime / 3600) const minutes = Math.floor((remainingTime % 3600) / 60) const seconds = remainingTime % 60 return `${hours}:${minutes}:${seconds}` }