Components
Upload queue
Keep individual file progress, errors and cancellation visible. The caller owns the transfer.
import { … } from "@fungi.computer/caps/blocks/upload-queue";Hero
import { UploadQueue, type UploadQueueItem,} from "@fungi.computer/caps/blocks/upload-queue";
const thumbnail = `data:image/svg+xml,${encodeURIComponent( '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><rect width="32" height="32" fill="#8a6d3b"/></svg>',)}`;
const items: UploadQueueItem[] = [ { id: "1", name: "spore-print-01.jpg", preview: { kind: "image", url: thumbnail }, progress: 62, progressLabel: "62%", statusLabel: "Uploading", actions: { cancel: { label: "Cancel", accessibleLabel: "Cancel spore-print-01.jpg" }, }, }, { id: "2", name: "field-notes.pdf", preview: { kind: "file" }, progress: 100, progressLabel: "Done", statusLabel: "Uploaded", actions: { remove: { label: "Remove", accessibleLabel: "Remove field-notes.pdf" }, }, }, { id: "3", name: "cluster-02.jpg", preview: { kind: "file" }, progress: null, progressLabel: "", statusLabel: "Upload failed", alert: "Network error.", actions: { retry: { label: "Retry", accessibleLabel: "Retry cluster-02.jpg" }, }, },];
export default function Hero() { return ( <UploadQueue className="w-full max-w-sm" items={items} onCancel={() => { /* This specimen has no host action. */ }} onRemove={() => { /* This specimen has no host action. */ }} onRetry={() => { /* This specimen has no host action. */ }} /> );}Interactive
import { UploadQueue, type UploadQueueItem,} from "@fungi.computer/caps/blocks/upload-queue";import { useState } from "react";
const initial: UploadQueueItem[] = [ { id: "1", name: "harvest-log.csv", preview: { kind: "file" }, progress: 40, progressLabel: "40%", statusLabel: "Uploading", actions: { cancel: { label: "Cancel", accessibleLabel: "Cancel harvest-log.csv" }, }, }, { id: "2", name: "notes.txt", preview: { kind: "file" }, progress: 100, progressLabel: "Done", statusLabel: "Uploaded", actions: { remove: { label: "Remove", accessibleLabel: "Remove notes.txt" }, }, },];
export default function Interactive() { const [items, setItems] = useState(initial); const remove = (id: string) => { setItems((rows) => rows.filter((row) => row.id !== id)); }; return ( <UploadQueue className="w-full max-w-sm" items={items} onCancel={remove} onRemove={remove} onRetry={() => { /* This specimen has no host action. */ }} /> );}