File Preview
files-sdk/file-previewFreeComponent
Lazy preview of a single stored file (image, PDF or text) with metadata.
Install it
npx shadcn@latest add https://files-sdk.dev/r/file-preview.jsonSource
1"use client";23import type { StoredFile } from "files-sdk";4import type { UseFilesResult } from "files-sdk/react";5import { FileIcon, Loader2Icon } from "lucide-react";6import { useEffect, useRef, useState } from "react";7import type { ReactNode } from "react";89import { cn } from "@/lib/utils";1011export interface FilePreviewProps {12 /** A `useFiles()` instance — resolves metadata and bytes through it. */13 files: UseFilesResult;14 /** A key string, or an already-resolved `StoredFile`. */15 file: string | StoredFile;16 /** Endpoint for the gateway download-proxy fallback. Default `"/api/files"`. */17 endpoint?: string;18 /**19 * Replace the built-in preview with a custom viewer (e.g. a PDF, DOCX or20 * CSV viewer component). Called once metadata resolves, with the same `src`21 * and `text` the built-in preview would use — except that when this is set,22 * a `src` is resolved for **every** non-text type, not just images and23 * PDFs, so viewers for formats the built-in preview can't render still get24 * a URL. PDFs arrive as a `blob:` URL; other types as a signed or proxy URL.25 */26 renderPreview?: (preview: {27 file: StoredFile;28 src?: string;29 text?: string;30 }) => ReactNode;31 className?: string;32}3334const formatBytes = (bytes: number): string => {35 if (bytes === 0) {36 return "0 B";37 }38 const units = ["B", "KB", "MB", "GB", "TB"];39 const exponent = Math.min(40 Math.floor(Math.log(bytes) / Math.log(1024)),41 units.length - 142 );43 return `${(bytes / 1024 ** exponent).toFixed(exponent === 0 ? 0 : 1)} ${units[exponent]}`;44};4546const Body = ({47 error,48 isLoading,49 src,50 text,51 type,52}: {53 error?: string;54 isLoading: boolean;55 src?: string;56 text?: string;57 type?: string;58}) => {59 if (isLoading) {60 return (61 <Loader2Icon className="size-6 animate-spin text-muted-foreground" />62 );63 }64 if (error) {65 return <p className="text-destructive text-sm">{error}</p>;66 }67 if (src && type === "application/pdf") {68 return (69 <object70 aria-label="PDF preview"71 className="h-72 w-full"72 data={src}73 type="application/pdf"74 >75 <a href={src} rel="noreferrer" target="_blank">76 Open PDF preview77 </a>78 </object>79 );80 }81 if (src) {82 // Portable <img> rather than next/image so the component drops into any app.83 return (84 // eslint-disable-next-line nextjs/no-img-element85 <img86 alt="preview"87// … truncated
What it pulls in
npm packages
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 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 |
