File Card

A card for a single file: a realistic file-type illustration or image thumbnail, the name, a meta line, trailing actions and an optional progress bar. Composes into attachment rows and upload trays.

Annual report 2025.pdf
2.4 MB · PDF document
hero-banner.png
880 KB · Uploaded
q3-forecast.xlsx

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add file-card

Usage#

File Card is composed from named parts, like Card. The FileCard root owns the surface, variant, state, and density; the parts (FileCardIcon, FileCardName, FileCardProgress) read it from context.

attachment.tsxTSX
import {  FileCard,  FileCardIcon,  FileCardContent,  FileCardName,  FileCardMeta,  FileCardActions,  fileTypeFromName,} from "@/components/ui/file-card"import { Button } from "@/components/ui/button"import { DownloadSimple, Trash } from "@phosphor-icons/react"export function Attachment({ file }) {  return (    <FileCard>      <FileCardIcon type={fileTypeFromName(file.name)} />      <FileCardContent>        <FileCardName>{file.name}</FileCardName>        <FileCardMeta>{file.size}</FileCardMeta>      </FileCardContent>      <FileCardActions>        <Button variant="ghost" size="sm" iconOnly aria-label="Download"><DownloadSimple /></Button>        <Button variant="ghost" size="sm" iconOnly aria-label="Remove"><Trash /></Button>      </FileCardActions>    </FileCard>  )}

Anatomy#

A row reads left-to-right: a FileCardIcon (or FileCardThumbnail) leads, a FileCardContent column fills with the FileCardName over a muted FileCardMeta line, and FileCardActions ride the right edge. The name truncates so a long filename never pushes the actions off the card.

Annual report 2025.pdf
2.4 MB · PDF document

File types#

Pass type to FileCardIcon and it renders a realistic file illustration: a sheet with a dog-eared corner and a colored band stamped with the extension. The tone re-themes across all four palettes: PDFs read red, images purple, sheets green, and so on. The band shows a short stand-in (PDF, XLS, IMG…) by default; pass label to stamp the real extension (the demo below shows DOCX, XLSX, TSX). Don’t know the type up front? Derive it from the filename with fileTypeFromName(file.name). The illustration is FileIcon, also usable on its own: every extension, its soft and solid variants and SVG downloads live on File Icons.

document.pdf
pdf
photo.png
image
clip.mp4
video
track.mp3
audio
letter.docx
doc
budget.xlsx
sheet
deck.pptx
slides
assets.zip
archive
index.tsx
code
notes.txt
text

Thumbnail#

For images, swap the glyph tile for a FileCardThumbnail. It fills the same footprint, clips the preview to the concentric radius, and carries a subtle inset outline so the image edge reads cleanly on any surface. Always pass a meaningful alt.

Mountain landscape
mountain-vista.jpg
1.8 MB · 2400 × 1600
Circuit board
circuit-closeup.jpg
2.1 MB · 3000 × 2000

Tile layout#

Same card, second arrangement. Pass layout="tile" and the row becomes the square cell of an image grid: the FileCardThumbnail fills it edge to edge and FileCardActions become a blurred scrim that fades in on hover or keyboard focus. The tile itself never moves - no lift, no press scale - so the photo and the wash carry the whole interaction. Pair it with File Upload’s FileUploadGrid.

A-frame cabin among autumn trees
Lakeside cabin at dusk
Sunlit forest canopy

Upload progress#

Drop a FileCardProgress into the content column to show an in-flight upload. It renders the DS Progress bar, so a live value animates smoothly, the percentage uses tabular-nums, and the bar re-tones to destructive when the card’s state is error. Swap it for a FileCardMeta once the upload lands.

The readout is droppable. Leave it in and the label and percentage sit above the bar; pass hideValue and move the number out to a FileCardValue beside the content column, and the bar runs the full width with the percentage holding the row’s right edge.

product-demo.mp4
Uploading…
product-demo.mp4
0%

States#

The root state drives the surface and the trailing FileCardStatus glyph: uploading spins, success lights a green check, and error pulls a soft destructive border with a warning so a failed file reads at a glance.

contract-draft.docx
Uploading…
contract-final.docx
312 KB · Uploaded
contract-broken.docx
File exceeds the 10 MB limit

Variants#

default sits on a hairline border with a soft shadow; outline drops the shadow for flat, gridded lists; elevated trades the border for a lifted shadow when a card needs to float; ghost strips all chrome and padding so the row sits flush in feeds, comment threads, and dense lists. The file illustration still carries the file’s identity.

brand-guidelines.pdf
default
brand-guidelines.pdf
outline
brand-guidelines.pdf
elevated
brand-guidelines.pdf
ghost

Density#

Density is Koala’s cross-cutting spacing axis (see Density). For File Card it tunes padding, gap, and the media tile. compact is the dense app default for upload trays and file lists; comfortable is roomier. Set it per-card or for a whole list with DensityProvider.

design-assets.zip
compact
design-assets.zip
comfortable

Interactive#

A file row is inert by default. When the whole card should open the file, pass asChild to render it as a link and interactive to add the pointer, hover lift, and focus ring. For per-file actions instead, keep the card inert and drop Buttons into FileCardActions.

API reference#

FileCard forwards all div props and adds layout (row | tile), variant (default | outline | elevated | ghost), state (idle | uploading | success | error), density (compact | comfortable), interactive, and asChild. The parts ( FileCardContent, FileCardName, FileCardMeta, FileCardValue, FileCardActions) forward div props. FileCardIcon adds type and an optional label band override (or pass your own glyph as children); FileCardThumbnail forwards img props and requires alt; FileCardProgress takes value, label, and hideValue; FileCardStatus takes an optional status (else it reads the card’s state). The helper fileTypeFromName(name) maps a filename to a type. Every part accepts className, merged last.

FAQ#

Pass `type` to FileCardIcon to render a realistic file illustration (a sheet with a dog-eared corner and a colored extension band) with a re-themable tint, for example "pdf" reads red and "image" reads purple. If you only have a filename, call `fileTypeFromName(file.name)` and pass its result as the type; it falls back to "default" for unknown or extensionless names. By default the band shows a short per-type stand-in (PDF, XLS, IMG…); pass `label` to stamp the exact extension, e.g. label="CSV".