Skip to content
Component installs need the registry setup
VegaStack Design

File Card

One file as a card row (thumbnail or icon, name, details, actions) that opens the viewer or links to a download or page; UploadCard is its twin for uploads.

Status
stable
Since
0.25.22
Accessibility pattern
one named open button or link, named actions menu

Last updated

landscape.svg820 KBAsha Rao · 2 days ago
spec-sheet.pdf64 KBAsha Rao · today
beam-30deg-with-a-long-photometry-file-name.ies4 KBRavi Nair · last week

Install

Configure registry credentials first using the Quickstart. Before copying this item or any transitive registry dependency, verify the signed manifest and save the exact bytes for File Card before installation. Retain the digest printed by this command.

pnpm exec vegastack-design verify file-card

Install with the pinned shadcn CLI. Bare shadcn does not verify VegaStack signature or integrity.

pnpm dlx shadcn@4.21.0 add @vegastack/file-card

Run the exact offline --post-write command printed by the preflight, using its saved item path and independently retained --expected-integrity digest. Use the saved preflight for every transitive registry dependency too; stop on any mismatch before using the components.

The same command installs the registry items it composes: @vegastack/attachment, @vegastack/data-table-parts, @vegastack/dropdown-menu, @vegastack/file-kind, @vegastack/file-viewer, @vegastack/image.

Usage

import { AttachmentGroup } from "@/components/ui/attachment";
import { FileCard, UploadCard } from "@/components/ui/file-card";

<AttachmentGroup layout="cards" role="list" aria-label="Files">
  <FileCard
    name="spec-sheet.pdf"
    contentType="application/pdf"
    descriptions={["64 KB", "Asha Rao · today"]}
    file={file}
    actions={[{ label: "Remove", destructive: true, onSelect: remove }]}
  />
  <UploadCard
    name="install-guide.pdf"
    type="application/pdf"
    progress={64}
    error={null}
    onCancel={cancel}
    onRetry={retry}
  />
</AttachmentGroup>;

FileCard is the one tile every file list shares — a task's attachments, a product's files, images and accessories. It composes Attachment and adds no layout of its own: put cards in an AttachmentGroup with role="list" (each card is a listitem), choosing layout="cards" for a responsive grid, or layout="list" for full-width rows.

landscape.svg820 KBAsha Rao · 2 days ago
spec-sheet.pdf64 KBAsha Rao · today
beam-30deg-with-a-long-photometry-file-name.ies4 KBRavi Nair · last week

Anatomy

FileCard
UploadCard

Examples

Open in the viewer

Give a card its file (a FileViewerItem) and the whole card becomes one Open {name} button. It opens the viewer, paging through the group's cards; onOpen replaces the built-in viewer with your own handler.

href makes the whole card one link, for a file that opens elsewhere: a file the viewer cannot show downloads, an accessory navigates to its page. download downloads in place and names the link Download {name}; target="_blank" opens a new tab (with rel="noopener") and names it Open {name} in a new tab. The ⋯ menu stays above the link, clickable on its own. When file is set href is ignored.

install-guide.zip12 MB · downloads
Mounting bracketAccessory · opens in a new tab

Thumbnail, icon, preview

thumb shows the stored image in the media box, with its blur underneath until it loads; without one the box shows the file's type icon. preview is the picked image's local object URL: it shows while there is no thumbnail yet and sits under the thumbnail until it loads, so the card never flashes blank. icon replaces both — a lock, a page's emoji.

Muted

muted dims the media of a file the record no longer uses. Say why in descriptions, so the state is never carried by opacity alone.

old-datasheet.pdfReplaced by spec-sheet.pdf

Actions

actions is a RowAction[] — the same shape a table row's menu takes — drawn as a ⋯ menu named Actions for {name}. extra puts your own controls before it (a "Go to comment" link, a remove button).

Wording

The built-in names and text — Actions for {name}, Download {name}, Retry {name}, "Finishing upload" — are overridable through the labels prop of FileCard and of UploadCard, for another language or house style.

Uploading

UploadCard lays out like a FileCard, so a list swaps one for the other as a file finishes. It shows a determinate bar (progress), "preparing" while progress is null, "Finishing upload" once the bytes are up (finishing), and on error the reason with Retry. Cancel is always there; cancellable={false} disables it.

spec-sheet.pdf64 KB
install-guide.pdf
x
site-photo.jpg
x
warranty-scan.tiffUpload failed. Check your connection and retry.

API Reference

FileCard

PropTypeDefaultDescription
name*string—The file name: the card's title.
actionsRowAction[][]The ⋯ menu, named "Actions for {name}". Empty (and no extra) draws no actions.
contentTypestring | null—MIME type, which picks the type icon when there is no thumbnail.
descriptionsReact.ReactNode[]—The lines under the name (size, who, when). The first reads in tabular figures; a null entry is skipped.
downloadbooleanfalseWith href: the link downloads the file instead of navigating, and is named "Download {name}".
extraReact.ReactNode—Controls before the ⋯ menu (a "Go to comment" link, a remove button).
fileFileViewerItem—The file this card stands for. With it the whole card is one "Open {name}" button that opens the file viewer — the enclosing group's preview, or onOpen — and href is ignored.
hrefstring—Make the whole card a link, for a file that opens elsewhere: a download for a file the viewer cannot show, or a page to navigate to. Ignored when file is set.
iconReact.ReactNode—In place of the thumbnail or type icon — a lock, a page's emoji.
labelsFileCardLabels—Override the built-in link and menu names (for another language or wording). Each is given the file name.
mutedbooleanfalseDim the media (the file is no longer in use); say why in descriptions.
onOpen((file: FileViewerItem) => void)—Called instead of the built-in viewer when the card is opened. Needs file.
previewstring | null—The picked image's local preview (an object URL): shown while there is no thumbnail yet, and under the thumbnail until it loads, so the card never flashes blank.
size"default" | "lg" | "sm" | "xs" | null"default"The card's size.
targetReact.HTMLAttributeAnchorTarget—With href: the link's target. _blank also sets rel="noopener" and names the link "Open {name} in a new tab".
thumbFileCardThumb | null—The stored thumbnail. With it (or preview) the media shows the image instead of a type icon.

UploadCard

PropTypeDefaultDescription
error*string | null—The failure reason; shows the error state with Retry. null for none.
name*string—The file name: the card's title.
onCancel*() => void—Cancel the upload.
onRetry*() => void—Retry after an error.
progress*number | null—Upload progress, 0–100; null while preparing (fingerprint, ticket).
type*string—MIME type, which picks the type icon.
cancellablebooleantrueWhether Cancel is enabled.
finishingbooleanfalseThe bytes are up and the upload is being completed: the bar becomes "Finishing upload" and Cancel is disabled.
labelsUploadCardLabels—Override the built-in text and names (for another language or wording).
previewstring | null—The picked image as an object URL: shown at once, while it uploads.
size"default" | "lg" | "sm" | "xs" | null"default"The card's size.

Accessibility

  • Each card is a listitem: give the AttachmentGroup role="list" and an aria-label.
  • The open button and the link are named for the file and for what activating them does — Open {name}, Download {name}, Open {name} in a new tab — and the whole card is the target.
  • The ⋯ menu button is named Actions for {name}; it and any extra control sit above the open button or link, so each stays separately focusable and clickable.
  • UploadCard's bar is a named progress bar (Uploading {name}, Preparing {name}) that announces its percentage; a failure's reason is text, never colour alone.
  • Focus is the global outline from base.css, on the open button or link, following the card's corner.
ContractStates tested
Behaviourdefault, muted, uploading, processing, error, open, link, disabled
Accessibilitylabeled, semantic-html, status-announcement, focus-visible
Visualdefault, muted, error

Do / Don't

Do
Give a card either a file (opens the viewer) or an href (a download or page) and put cards in an AttachmentGroup with role=list.
Don't
Build a second file tile beside it for one more list — pass thumb, icon, descriptions and actions instead.

On this page