Download Button
A dynamic button with real-time download status and progress tracking.
Installation
- 1
Install Shadcn Components
npx shadcn@latest add button
- 2
lib/utils.ts
import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) }
- 3
Copy the source code
@/components/ui/download-button.tsx
"use client" import { Download, Loader2, CheckCircle } from "lucide-react" import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" interface DownloadButtonProps { downloadStatus: "idle" | "downloading" | "downloaded" | "complete" progress: number onClick: () => void className?: string } export default function DownloadButton({ downloadStatus, progress, onClick, className }: DownloadButtonProps) { return ( <Button onClick={onClick} className={cn( "rounded-xl w-40 relative overflow-hidden select-none", downloadStatus === "downloading" && "bg-primary/50 hover:bg-primary/50", downloadStatus !== "idle" && "pointer-events-none", className, )} > {downloadStatus === "idle" && ( <> <Download className="h-4 w-4" /> Download </> )} {downloadStatus === "downloading" && ( <div className="z-[5] flex items-center justify-center"> <Loader2 className="mr-2 h-4 w-4 animate-spin" /> {progress}% </div> )} {downloadStatus === "downloaded" && ( <> <CheckCircle className="h-4 w-4" /> <span className="t">Downloaded</span> </> )} {downloadStatus === "complete" && <span className="text-primary">Download</span>} {downloadStatus === "downloading" && ( <div className="absolute bottom-0 z-[3] h-full left-0 bg-primary inset-0 transition-all duration-200 ease-in-out" style={{ width: `${progress}%` }} /> )} </Button> ) }
Props
Prop | Type | Default | Description |
---|---|---|---|
className | string | undefined | Optional custom class names for styling. |
downloadStatus | "idle" | "downloading" | "downloaded" | "complete" | "idle" | Represents the current state of the download process. |
progress | number | 0 | Indicates the download progress percentage (0-100). |
onClick | () => void | undefined | Callback function triggered when the button is clicked. |