GitHub

File Thumbnail

Render compact file thumbnails from files, URLs, blobs, text sources, images, or custom preview content.

File Thumbnail gives document lists, upload queues, file browsers, and attachment trays one thumbnail component for every file source. Pass a browser File, a URL/blob/text source, an external image preview, or custom rendered content; the component handles the frame, loading shimmer, first-unit document rendering, fade-in, and fallback state.

Image
dashboard.png
PDF
DOCX
PPTX
XLSX
CSV
Markdown
HTML
JSON
Code
Text
TIFF

Installation

pnpm dlx shadcn@latest add @retab/file-thumbnail

Usage

import { FileThumbnail } from "@/components/ui/file-thumbnail";
 
export function PdfThumbnail({ file }: { file: File }) {
  return (
    <FileThumbnail file={file} thumbnailShape="square" thumbnailSize="md" />
  );
}
 
export function UrlThumbnail() {
  return (
    <FileThumbnail
      source={{
        kind: "url",
        url: "/contract.pdf",
        fileName: "contract.pdf",
        mimeType: "application/pdf",
      }}
      thumbnailShape="square"
      thumbnailSize="md"
    />
  );
}

States

FileThumbnail renders supported documents to their first unit: page 1 for PDF and DOCX, the first sheet for XLSX, the first slide for PPTX, the first TIFF frame, the HTML body for MSG emails, or the head of CSV, text, markdown, and HTML files. Images render directly. Unsupported files fall back to the compact extension surface.

LoadedpreviewImageUrl
invoice.pdf
Loadingstate="loading"
Fallbackno preview
xlsx
CustompreviewContent
640 × 480

When you already have a generated preview, pass it directly:

<FileThumbnail
  file={{ name: "invoice.pdf", type: "application/pdf" }}
  previewImageUrl="/previews/invoice-page-1.png"
/>
 
<FileThumbnail
  file={{ name: "custom.bin", type: "application/octet-stream" }}
  previewContent={<div className="grid size-full place-items-center">Ready</div>}
/>

Use state="loading" or state="error" when an external thumbnail pipeline is in charge of the preview lifecycle.

File Tooltip Example

Keep TooltipContent padding-free when the tooltip is only a larger file preview. The tooltip body can be just FileThumbnail, with the trigger owning the file name and accessible label.

Useful Behaviors

  • Accepts browser File objects, URL sources, Blob sources, text sources, external preview image URLs, or custom React preview content.
  • Renders only the first unit of supported documents, never the whole document.
  • Shows a shimmer while document renderers load or an image preview decodes.
  • Falls back to a muted extension surface for unsupported files and errors.
  • Keeps the visual frame consistent across generated and externally supplied previews.

API Reference

FileThumbnail

PropTypeDefaultRequired
fileThumbnailFile | File-No
sourceViewerSource | File-No
asFileCategoryauto-detectNo
classNamestring-No
previewAspectRationumber3 / 4No
thumbnailShape"document" | "square"documentNo
thumbnailSize"xs" | "sm" | "md" | "lg" | "xl"-No
previewClassNamestring-No
previewContentReact.ReactNode-No
previewImageUrlstring | null-No
anchor"top-left" | "top-right" | "bottom-left""top-left"No
retryKeyReact.Key-No
state"loading" | "loaded" | "error"-No
onError(error, info) => void-No
onPreviewError() => void-No

file is enough for browser uploads. Use source for URL, Blob, or inline text sources. Use as only when the file name or MIME type is missing, wrong, or intentionally viewed as another supported category.

previewContent and previewImageUrl take priority over generated document rendering. That keeps the component useful when another system already produced the thumbnail.

FileThumbnail also forwards standard div props such as aria-label, data-*, event handlers, and style. Its internal data-slot="file-thumbnail" is kept stable for styling and tests.

ThumbnailFile

PropTypeDefaultRequired
namestring-Yes
typestring-Yes

Source

file-thumbnail.tsx