Trash Bin
files-sdk/trash-binFreeComponent
Lists, restores and permanently purges soft-deleted files (softDelete plugin).
Install it
npx shadcn@latest add https://files-sdk.dev/r/trash-bin.jsonSource
1"use client";23import type { TrashedFile, UseFilesResult } from "files-sdk/react";4import {5 Loader2Icon,6 RotateCcwIcon,7 Trash2Icon,8 TrashIcon,9} from "lucide-react";10import { useCallback, useEffect, useRef, useState } from "react";1112import { Button } from "@/components/ui/button";13import {14 Dialog,15 DialogContent,16 DialogDescription,17 DialogFooter,18 DialogHeader,19 DialogTitle,20} from "@/components/ui/dialog";21import { cn } from "@/lib/utils";2223export interface TrashBinProps {24 /** A `useFiles()` instance backed by a gateway with the `softDelete()` plugin. */25 files: UseFilesResult;26 /** Called after a successful restore or purge. */27 onChanged?: () => void;28 className?: string;29}3031const formatBytes = (bytes: number): string => {32 if (bytes === 0) {33 return "0 B";34 }35 const units = ["B", "KB", "MB", "GB", "TB"];36 const exponent = Math.min(37 Math.floor(Math.log(bytes) / Math.log(1024)),38 units.length - 139 );40 return `${(bytes / 1024 ** exponent).toFixed(exponent === 0 ? 0 : 1)} ${units[exponent]}`;41};4243/**44 * A recycle bin backed by the `softDelete()` plugin. Lists trashed objects and45 * restores or permanently purges them through the same `useFiles()` instance.46 * Purges (single + "empty trash") confirm first, since they're the only way the47 * bytes actually leave storage.48 */49export const TrashBin = ({ files, onChanged, className }: TrashBinProps) => {50 const [trashed, setTrashed] = useState<TrashedFile[]>([]);51 const [isLoading, setIsLoading] = useState(true);52 const [busy, setBusy] = useState<string>();53 // `null` = closed; `{ key }` = purge one; `{}` = empty the whole trash.54 const [pending, setPending] = useState<{ key?: string } | null>(null);5556 const filesRef = useRef(files);57 filesRef.current = files;5859 const refresh = useCallback(async () => {60 setIsLoading(true);61 try {62 setTrashed(await filesRef.current.trashed());63 } catch {64 // The hook mirrors the error to `files.error` for display.65 } finally {66 setIsLoading(false);67 }68 }, []);6970 useEffect(() => {71 void refresh();72 }, [refresh]);7374 const restore = useCallback(75 async (key: string) => {76 setBusy(key);77 try {78 await filesRef.current.restoreTrashed(key);79 await refresh();80 onChanged?.();81 } catch {82 // Mirrored to `files.error`.83 } finally {84 setBusy(undefined);85 }86 },87 [refresh, onChanged]88 );8990 const purge = useCallback(async () => {91// … truncated
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 |
