File card
A reusable file row with progress, failure recovery, and contextual actions.
Usage
import { FileCard } from '@commenda/pathfinder/file-card';
<FileCard
file={{
id: 'return',
filename: 'Q3 2026 sales tax return.pdf',
sizeBytes: 1_200_000,
upload: { status: 'uploading', progress: 64 },
}}
actionConfig={{ onCancel: cancelUpload }}
/>;Use this card independently in a form or let File upload compose it. File icons come from the filename extension; unknown extensions use the generic file icon. File sizes use decimal units, so 1,000,000 bytes is 1 MB. Omit sizeBytes when it is unknown.
State and actions
| State | Data | Available actions |
|---|---|---|
| Uploading | { status: 'uploading', progress?: number } | Cancel |
| Complete | { status: 'complete' } | Preview, Download, Remove |
| Failed | { status: 'failed', message: string } | Retry, Remove |
A finite progress value is clamped to 0–100; omitted or non-finite progress is indeterminate. Only status: 'complete' shows Uploaded. Every action is optional and receives the stable file ID. The card never starts a request, opens a URL, or mutates the file. Actions have accessible names that include the original filename.
Long filenames and errors
Names truncate with their full text preserved in the title tooltip. Errors wrap and increase card height, keeping Retry and Remove available. Standalone cards leave list-level focus recovery and announcements to their owner; FileUpload supplies those behaviors.
API reference
| Prop | Type | Behavior |
|---|---|---|
fileRequired | UploadFileItemView fields | Stable id, original filename, optional sizeBytes, and upload state |
actionConfig | FileActionConfigView fields | onCancel, onRetry, onRemove, onPreview, onDownload; each receives an ID |
disabled | boolean | Disable all provided actions |
className | string | Host layout customization |
fileObject fields
| Field | Type | Requirement |
|---|---|---|
id | string | Required |
filename | string | Required |
sizeBytes | number | Optional |
upload | Object | Required |
file.uploadObject fields
Choose one of these 3 shapes. Do not combine fields excluded by the selected shape.
Option 1
| Field | Type | Requirement |
|---|---|---|
status | "uploading" | Required |
progress | number | Optional |
Option 2
| Field | Type | Requirement |
|---|---|---|
status | "complete" | Required |
Option 3
| Field | Type | Requirement |
|---|---|---|
status | "failed" | Required |
message | string | Required |
actionConfigObject fields
| Field | Type | Requirement |
|---|---|---|
onCancel | ((id: string) => void) | Optional |
onRetry | ((id: string) => void) | Optional |
onRemove | ((id: string) => void) | Optional |
onPreview | ((id: string) => void) | Optional |
onDownload | ((id: string) => void) | Optional |
UploadFileItem, UploadState, and FileActionConfig are exported from both file-upload and file-card subpaths. The upload state is a discriminated union: failed requires an error message, uploading optionally carries progress, and complete carries neither.
Design rules
- FILE-CARD-01: A 24px type icon, 12px leading inset/gap, 8px trailing inset, 8px radius, and subtle border. Complete/failed rows have a 56px minimum; uploading has a 63px minimum. Error content may grow.
- FILE-CARD-02: Actions reflect lifecycle state. Do not interpret progress reaching 100% as server-confirmed success. Hide actions without callbacks.
- FILE-CARD-03: Never rename a file for display or remove a failed upload silently. Preserve the original name, show a specific failure message, and retain retry/removal controls.