Countdown Timer
vinkas-ui/countdown-timerFreeBlock
A simple shadcn block type react component that displays countdown to a specific date.
Live preview
live · rendered by the registry
Rendered by vinkas-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.vinkas.com/r/countdown-timer.jsonSource
1"use client"23import { cn } from "@/lib/utils"4import NumberFlow from '@number-flow/react'5import { useEffect, useState } from "react"67type CountdownTimerProps = {8 date: Date,9 className?: string,10} & React.ComponentProps<"div">1112const SECOND = 100013const MINUTE = SECOND * 6014const HOUR = MINUTE * 6015const DAY = HOUR * 241617export const getTimeDiff = (target: Date, now: Date) => {18 let diff = Math.max(0, target.getTime() - now.getTime())1920 const days = Math.trunc(diff / DAY)21 diff %= DAY2223 const hours = Math.trunc(diff / HOUR)24 diff %= HOUR2526 const minutes = Math.trunc(diff / MINUTE)27 diff %= MINUTE2829 const seconds = Math.trunc(diff / SECOND)3031 return { days, hours, minutes, seconds }32}3334export default function CountdownTimer({ date, className, ...props }: CountdownTimerProps) {35 const [now, setNow] = useState<Date | null>(null)3637 useEffect(() => {38 let timeout: NodeJS.Timeout3940 const tick = () => {41 setNow(new Date())42 timeout = setTimeout(tick, 1000)43 }4445 tick()4647 return () => clearTimeout(timeout)48 }, [])4950 if (!now) return null5152 const { days, hours, minutes, seconds } = getTimeDiff(date, now)5354 return (55 <div className={cn("flex justify-around items-center text-center gap-2", className)} {...props}>56 <div className="flex flex-col gap-1">57 <NumberFlow className="text-lg font-bold" value={days} />58 <span className="text-sm text-muted-foreground">Days</span>59 </div>60 <div className="flex flex-col gap-1">61 <NumberFlow className="text-lg font-bold" value={hours} />62 <span className="text-sm text-muted-foreground">Hours</span>63 </div>64 <div className="flex flex-col gap-1">65 <NumberFlow className="text-lg font-bold" value={minutes} />66 <span className="text-sm text-muted-foreground">Minutes</span>67 </div>68 <div className="flex flex-col gap-1">69 <NumberFlow className="text-lg font-bold" value={seconds} />70 <span className="text-sm text-muted-foreground">Seconds</span>71 </div>72 </div>73 )74}
What it pulls in
npm packages
