NEW
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
shadcn registry is live·
Learn more
Skip to content
Docs

Progress

A sample progress graph for widgets/presentation. This is not a full-fledged chart library. Just use for presentation or as an interactive part of the app.

Loading...

Installation

CLI

pnpm dlx shadcn@latest add https://animata.design/r/graphs/progress.json

Manual

Run the following command

It will create a new file called progress.tsx inside the components/animata/graphs directory.

mkdir -p components/animata/graphs && touch components/animata/graphs/progress.tsx

Paste the code

Open the newly created file and paste the following code:

import { useEffect, useRef, useState } from "react";
 
import { cn } from "@/lib/utils";
 
export default function Progress({ progress }: { progress: number }) {
  const [width, setWidth] = useState(0);
 
  const barWidth = 2;
  const gap = 2;
 
  const bars = Math.floor(width / (barWidth + gap));
  const containerRef = useRef<HTMLDivElement>(null);
 
  useEffect(() => {
    setWidth(containerRef.current?.offsetWidth ?? 0);
  }, []);
 
  const [shouldUseValue, setShouldUseValue] = useState(false);
 
  useEffect(() => {
    const timeout = setTimeout(() => {
      // This is a hack to force the animation to run for the first time.
      // We can use framer-motion to achieve this but just keeping it simple for now.
      setShouldUseValue(true);
    }, 250);
    return () => clearTimeout(timeout);
  }, []);
 
  return (
    <div
      ref={containerRef}
      className="relative flex h-[12px] w-full min-w-4 flex-wrap gap-[2px] overflow-hidden"
    >
      {Array.from(Array(bars)).map((_, index) => {
        const highlight = shouldUseValue ? index / bars < progress / 100 : 0;
        return (
          <div
            className={cn("h-full w-[2px] rounded-[1px] transition", {
              "bg-blue-100 duration-75 group-hover/progress:rounded group-hover/progress:bg-zinc-50 group-active/progress:rounded group-active/progress:bg-zinc-50":
                highlight,
              "bg-zinc-900/30 duration-300 group-hover/progress:scale-75 group-hover/progress:bg-zinc-900/15 group-active/progress:scale-75 group-active/progress:bg-zinc-900/15":
                !highlight,
            })}
            style={{
              transitionDelay: highlight ? `${index * 6}ms` : "0ms",
            }}
            key={`bar_${index}`}
          />
        );
      })}
    </div>
  );
}

Credits

Built by hari