Upload Progress
files-sdk/upload-progressFreeComponent
Per-file and aggregate progress for in-flight uploads.
Install it
npx shadcn@latest add https://files-sdk.dev/r/upload-progress.jsonSource
1"use client";23import type { FileUploadState, UseFilesResult } from "files-sdk/react";4import { CheckCircle2Icon, Loader2Icon, XCircleIcon } from "lucide-react";56import { Progress } from "@/components/ui/progress";7import { cn } from "@/lib/utils";89export interface UploadProgressProps {10 /** A `useFiles()` instance — reads its ambient `uploads` / `progress`. */11 files: UseFilesResult;12 className?: string;13}1415const StatusIcon = ({ status }: { status: FileUploadState["status"] }) => {16 if (status === "success") {17 return <CheckCircle2Icon className="size-4 text-primary" />;18 }19 if (status === "error" || status === "aborted") {20 return <XCircleIcon className="size-4 text-destructive" />;21 }22 return <Loader2Icon className="size-4 animate-spin text-muted-foreground" />;23};2425const UploadRow = ({ upload }: { upload: FileUploadState }) => (26 <li className="flex flex-col gap-1.5">27 <div className="flex items-center gap-2 text-sm">28 <StatusIcon status={upload.status} />29 <span className="min-w-0 flex-1 truncate">{upload.name}</span>30 <span className="text-muted-foreground text-xs">31 {Math.round(upload.progress * 100)}%32 </span>33 </div>34 <Progress35 className={cn(36 upload.status === "error" && "bg-destructive/20",37 upload.status === "aborted" && "opacity-50"38 )}39 value={upload.progress * 100}40 />41 </li>42);4344/**45 * Renders the ambient upload state of a `useFiles()` instance: one row per file46 * plus an aggregate bar when several are in flight. Returns `null` when idle.47 */48export const UploadProgress = ({ files, className }: UploadProgressProps) => {49 const { progress, uploads } = files;5051 if (!uploads.length) {52 return null;53 }5455 return (56 <div className={cn("flex flex-col gap-3", className)}>57 {uploads.length > 1 && (58 <div className="flex flex-col gap-1.5">59 <div className="flex items-center justify-between text-muted-foreground text-xs">60 <span>{uploads.length} files</span>61 <span>{Math.round(progress.fraction * 100)}%</span>62 </div>63 <Progress value={progress.fraction * 100} />64 </div>65 )}66 <ul className="flex flex-col gap-2">67 {uploads.map((upload, index) => (68 <UploadRow69 key={upload.key ?? `${upload.name}-${index}`}70 upload={upload}71 />72 ))}73 </ul>74 </div>75 );76};
What it pulls in
npm packages
Other registry items
Files it writes
More from files-sdk
All 12 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Capabilities Badgescapabilities-badges | files-sdk | Components | Free | 2 deps | |
| Dropzonedropzone | files-sdk | Components | Free | 2 deps | |
| File Actionsfile-actions | files-sdk | Components | Free | 2 deps | |
| File Browserfile-browser | files-sdk | Components | Free | 2 deps | |
| File Listfile-list | files-sdk | Components | Free | 2 deps | |
| File Previewfile-preview | files-sdk | Components | Free | 2 deps | |
| File Searchfile-search | files-sdk | Components | Free | 2 deps | |
| Multipart Uploadermultipart-uploader | files-sdk | Components | Free | 2 deps |
