File Actions
files-sdk/file-actionsFreeComponent
Per-file actions menu — download, copy, rename, move and delete.
Install it
npx shadcn@latest add https://files-sdk.dev/r/file-actions.jsonSource
1"use client";23import type { UseFilesResult } from "files-sdk/react";4import {5 CopyIcon,6 DownloadIcon,7 Loader2Icon,8 MoreHorizontalIcon,9 PencilIcon,10 Trash2Icon,11} from "lucide-react";12import type { ReactNode } from "react";13import { useCallback, useState } from "react";1415import { Button, buttonVariants } from "@/components/ui/button";16import {17 Dialog,18 DialogContent,19 DialogDescription,20 DialogFooter,21 DialogHeader,22 DialogTitle,23} from "@/components/ui/dialog";24import {25 DropdownMenu,26 DropdownMenuContent,27 DropdownMenuItem,28 DropdownMenuSeparator,29 DropdownMenuTrigger,30} from "@/components/ui/dropdown-menu";31import { Input } from "@/components/ui/input";32import { cn } from "@/lib/utils";3334export interface FileActionsProps {35 /** A `useFiles()` instance — every action runs through it. */36 files: UseFilesResult;37 /** The key the actions operate on. */38 fileKey: string;39 /** Called after a successful copy/rename/move/delete so the parent can refresh. */40 onChanged?: () => void;41 /** Custom trigger content, rendered inside the trigger button. Defaults to a styled `⋯` icon. */42 children?: ReactNode;43 className?: string;44}4546type Action = "copy" | "rename" | "move" | "delete";4748const TITLES: Record<Action, string> = {49 copy: "Copy to",50 delete: "Delete file",51 move: "Move to",52 rename: "Rename file",53};5455const parentOf = (key: string): string => {56 const slash = key.lastIndexOf("/");57 return slash === -1 ? "" : key.slice(0, slash + 1);58};5960/**61 * A `⋯` actions menu for a single key — download, copy, rename, move and delete,62 * all routed through the `useFiles()` instance you pass in. Copy/rename/move open63 * a small prompt for the destination; delete confirms first.64 */65export const FileActions = ({66 files,67 fileKey,68 onChanged,69 children,70 className,71}: FileActionsProps) => {72 const [action, setAction] = useState<Action | null>(null);73 const [dest, setDest] = useState("");74 const [busy, setBusy] = useState(false);7576 const open = useCallback(77 (next: Action) => {78 const parent = parentOf(fileKey);79 // Rename edits just the basename; copy/move edit the whole key.80 setDest(next === "rename" ? fileKey.slice(parent.length) : fileKey);81 setAction(next);82 },83 [fileKey]84 );8586 const download = useCallback(async () => {87 const file = await files.download(fileKey);88 const blob = await file.blob();89 const url = URL.createObjectURL(blob);90// … 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 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 | |
| Share Dialogshare-dialog | files-sdk | Components | Free | 2 deps |
