Flip clock
8starlabs-ui/flip-clockFreeComponent
A flip clock component
Install it
npx shadcn@latest add https://ui.8starlabs.com/r/flip-clock.jsonSource
1"use client";23import { cn } from "@/lib/utils";4import { cva, VariantProps } from "class-variance-authority";5import {6 FC,7 HTMLAttributes,8 memo,9 ReactNode,10 useEffect,11 useState12} from "react";1314const flipUnitVariants = cva(15 "relative subpixel-antialiased perspective-[1000px] rounded-md overflow-hidden",16 {17 variants: {18 size: {19 sm: "w-10 min-w-10 h-14 text-3xl", // Small (Compact UI)20 md: "w-14 min-w-14 h-20 text-5xl", // Medium (Standard sidebar/header)21 lg: "w-17 min-w-17 h-24 text-6xl", // Large (Focus/Hero)22 xl: "w-22 min-w-22 h-32 text-8xl" // Extra Large (Dashboard/Landing)23 },24 variant: {25 default: "bg-primary text-primary-foreground",26 secondary: "bg-secondary text-secondary-foreground",27 destructive: "bg-destructive text-destructive-foreground",28 outline: "border border-input bg-background text-foreground",29 muted: "bg-muted text-muted-foreground"30 }31 },32 defaultVariants: {33 size: "md",34 variant: "default"35 }36 }37);3839interface FlipUnitProps40 extends HTMLAttributes<HTMLDivElement>,41 VariantProps<typeof flipUnitVariants> {42 digit: number | string;43}4445const commonCardStyle = cn(46 "absolute inset-x-0 overflow-hidden h-1/2 bg-inherit text-inherit"47);4849const FlipUnit: FC<FlipUnitProps> = memo(function FlipUnit({50 digit,51 size,52 variant,53 className54}: FlipUnitProps) {55 const [prevDigit, setPrevDigit] = useState(digit);56 const [flipping, setFlipping] = useState(false);5758 useEffect(() => {59 if (digit !== prevDigit) {60 setFlipping(true);61 // Wait for the full animation (0.3s top + 0.3s bottom) before resetting62 const timer = setTimeout(() => {63 setFlipping(false);64 setPrevDigit(digit);65 }, 550); // Slightly less than 600ms to ensure smoothness66 return () => clearTimeout(timer);67 }68 }, [digit, prevDigit]);6970 return (71 <div className={cn(flipUnitVariants({ size, variant }), className)}>72 {/* 1. Background Top (The NEW digit waiting) */}73 <div className={cn(commonCardStyle, "rounded-t-lg top-0")}>74 <DigitSpan position="top">{digit}</DigitSpan>75 </div>7677 {/* 2. Background Bottom (The OLD digit staying) */}78 <div className={cn(commonCardStyle, "rounded-b-lg translate-y-full")}>79 <DigitSpan position="bottom">{prevDigit}</DigitSpan>80 </div>8182 {/* 3. Top Flap (The OLD digit falling down) */}83 <div84 className={cn(85// … truncated
Files it writes
More from 8starlabs-ui
All 74 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Buttonbutton | 8starlabs-ui | Components | Free | 2 deps | |
| Collapsiblecollapsible | 8starlabs-ui | Components | Free | 1 dep | |
| Dropdown Menudropdown-menu | 8starlabs-ui | Components | Free | 2 deps | |
| Heatmapheatmap | 8starlabs-ui | Components | Free | no deps | |
| Inputinput | 8starlabs-ui | Components | Free | no deps | |
| JSON Viewerjson-viewer | 8starlabs-ui | Components | Free | 1 dep · 3 files | |
| Labellabel | 8starlabs-ui | Components | Free | no deps | |
| Marquee componentmarquee | 8starlabs-ui | Components | Free | no deps |
