Components · Files
UploadQueue
The list of uploads in flight: progress, status, cancel, retry, remove and a total summary.
Mixed statuses
Uploads
1 of 5 uploaded · 2 failed
quarterly-report.pdf2.4 MB
Uploaded
site-photo-01.jpg4.1 MB
Uploading… 62%
site-photo-02.jpg3.8 MB
Waiting
floor-plan.dwg18 MB
Upload interrupted. Check your connection and try again.
archive.zip120 MB
Larger than the 100 MB limit.
import { useState } from 'react';
import { UploadQueue, type UploadQueueItem } from '@rookcom/monarch-react/collaboration';
const MB = 1024 * 1024;
const SAMPLE: UploadQueueItem[] = [
{ id: '1', name: 'quarterly-report.pdf', size: 2.4 * MB, status: 'done' },
{ id: '2', name: 'site-photo-01.jpg', size: 4.1 * MB, status: 'uploading', progress: 62 },
{ id: '3', name: 'site-photo-02.jpg', size: 3.8 * MB, status: 'queued' },
{
id: '4',
name: 'floor-plan.dwg',
size: 18 * MB,
status: 'failed',
error: 'Upload interrupted. Check your connection and try again.',
},
{
id: '5',
name: 'archive.zip',
size: 120 * MB,
status: 'failed',
error: 'Larger than the 100 MB limit.',
retryable: false,
},
];
function QueueDemo() {
const [items, setItems] = useState(SAMPLE);
const set = (id: string, patch: Partial<UploadQueueItem>) =>
setItems((l) => l.map((i) => (i.id === id ? { ...i, ...patch } : i)));
return (
<UploadQueue
style={{ width: '100%', maxWidth: 520 }}
items={items}
onCancel={(id) => set(id, { status: 'cancelled' })}
onRetry={(id) =>
setItems((l) =>
l.map((i) => {
if (i.id !== id) return i;
const { error: _error, ...rest } = i;
return { ...rest, status: 'queued' };
}),
)
}
onRemove={(id) => setItems((l) => l.filter((i) => i.id !== id))}
onClearFinished={() =>
setItems((l) => l.filter((i) => i.status === 'uploading' || i.status === 'queued'))
}
/>
);
}
<QueueDemo />Usage examples
Without the header, with a custom step
import { UploadQueue } from '@rookcom/monarch-react/collaboration';
const MB = 1024 * 1024;
<UploadQueue
style={{ width: '100%', maxWidth: 520 }}
showSummary={false}
aria-label="Banner uploads"
items={[
{
id: 'a',
name: 'banner-wide.png',
size: 1.2 * MB,
status: 'done',
detail: 'Checking for viruses',
},
{ id: 'b', name: 'banner-square.png', size: 0.8 * MB, status: 'uploading' },
]}
/>Purpose
Shows each file the product is uploading with its progress and status, lets people cancel, retry or remove uploads, and sums up the batch. Completion and failures are announced.
Use when
- Several files upload at once, or uploads take long enough that people need to see progress.
- Uploads can fail for reasons people can act on (connection, size, quota) and should be retried.
- Pair with FileUpload, which hands over the files this list shows.
Avoid when
- A single small file uploads in a moment: a loading button or Progress is enough.
- The list shows stored files rather than uploads in progress: use a file list or table.
Design principles
- The product owns the transfer and the state; the queue only displays
itemsand reports actions by id. - Status is text and icon, never colour alone: "Uploading… 62%", "Uploaded", the error message.
- Actions appear only when they make sense and when the product handles them: cancel while active, retry for failed or cancelled uploads that can succeed, remove once finished.
- A refusal that cannot succeed unchanged (too large, wrong type) sets
retryable: false, so Retry is not offered. - Progress reuses Progress, so bars look and announce the same everywhere.
API reference
import { UploadQueue, countUploads, totalUploadProgress } from '@rookcom/monarch-react/collaboration';| Export | Kind | Rendering | Root class |
|---|---|---|---|
UploadQueue | component | client | .mn-upload-queue |
countUploads | utility | client | – |
totalUploadProgress | utility | client | – |
Items are { id, name, status, size?, progress?, error?, retryable?, thumbnail?, icon?, detail? }; status is queued, uploading, done, failed or cancelled, and progress is 0–100 (omit for an indeterminate bar).
onCancel, onRetry and onRemove receive the item id; each button appears only when its handler is given. onClearFinished adds a header button.
countUploads(items) and totalUploadProgress(items) are exported: the total leaves out failed and cancelled uploads and is weighted by size when every upload has one.
The ref is the root <section>; other attributes pass through.
Generated from the TypeScript declarations of packages/react/src/components/files/upload-queue.
Properties
UploadQueue
The list of files being uploaded: per-file progress and status, cancel, retry and remove, and a total summary. Completion and failures are announced. The product does the transfer and reports progress back.
| Prop | Type | Description |
|---|---|---|
items required | readonly UploadQueueItem[] | The uploads, in display order. The product updates status and progress. |
className | string | |
headingLevel | 3 | 4 | 6 | 2 | 5 | Heading level of the title. Default 3. |
id | string | |
messages | Partial<UploadQueueMessages> | Override labels and announcements. |
onCancel | ((id: string) => void) | Cancel a queued or uploading file. The button shows only when this is set. |
onClearFinished | (() => void) | Remove every finished, failed and cancelled file. Shows a header button. |
onRemove | ((id: string) => void) | Remove a finished, failed or cancelled file from the list. |
onRetry | ((id: string) => void) | Retry a failed or cancelled file. |
showSummary | boolean | Show the header with the title, summary and total progress. Default true. |
Variants
| Prop | Values | Description |
|---|---|---|
showSummary | 'true''false' | Show the header with title, summary ("1 of 4 uploaded · 1 failed") and total progress (default). Without it the section is named by messages.title. |
States
| State | Exposed as | Behaviour |
|---|---|---|
| Queued | data-status="queued" | "Waiting", with Cancel. |
| Uploading | data-status="uploading" | A Progress bar (determinate or indeterminate) and "Uploading… n%", with Cancel. |
| Done | data-status="done" | Success icon and "Uploaded", with Remove. |
| Failed | data-status="failed" | Error icon and the product’s message, with Retry (unless retryable is false) and Remove. |
| Cancelled | data-status="cancelled" | Muted name and "Cancelled", with Retry and Remove. |
| Active batch | data-active | Some uploads are queued or uploading; the header shows the total progress bar. |
Interaction behaviour
- Buttons call the product’s handlers; the queue changes only when new
itemsarrive. - When a row is removed while focus is in it, focus moves to the next row (or the previous one, or the heading when the list is empty).
- Moving to done or failed is announced; when the last active upload finishes in a batch of several, a summary is announced too.
detailreplaces the status text, for extra steps such as "Checking for viruses".
Keyboard support
| Keys | Action |
|---|---|
| Tab | Moves between the Retry, Cancel and Remove buttons of each row, and Clear finished. |
| Enter / Space | Activates the focused button. |
Accessibility
- Role
- region (section) labelled by its heading; a list of uploads
- Accessible name
- The heading, "Uploads" by default (
messages.title).
- Each progress bar is named "Upload progress of {file}"; the total bar is "Total upload progress".
- Buttons are named with the file: "Cancel upload of photo.jpg", "Retry upload of photo.jpg", "Remove photo.jpg from the list". Retry keeps its visible word in its name.
- A polite live region announces completed and failed uploads and the end of the batch.
- Thumbnails are decorative (
alt=""); the file name is the text. - Verified with axe in jsdom and in Chromium, Firefox and WebKit on /components/upload-queue.
Responsive behaviour
- Rows wrap: long names break anywhere, the size wraps under the name, and the actions stay at the end.
- The header wraps the Clear finished button and keeps the total bar full width. Works at 320px.
Theme support
- Colours are Monarch semantic tokens only, so light, dark and more-contrast themes apply automatically.
- Done uses
--mn-color-success-strong, failed--mn-color-danger-strong; both also have an icon and text. - Progress bars follow Progress theming, including reduced motion for the indeterminate bar.
Do and don't
Do
- Report real progress (bytes sent) when you have it; omit
progressrather than invent it. - Write failure messages people can act on, and set
retryable: falsewhen retrying cannot help. - Revoke object URLs you pass as
thumbnailwhen the row is removed.
Don't
- Do not remove failed uploads automatically; let people retry or dismiss them.
- Do not show refusals the FileUpload already explained as failed uploads.
Related components
- FileUpload: Picks and checks the files before they reach the queue.
- Progress: One progress bar for a single task.
- Toast: A short confirmation once a background upload finishes, when no list is shown.
Dependencies
| Kind | Depends on |
|---|---|
| npm packages | react |
| Monarch components | Button, Progress, FileUpload |
Uses formatBytes from FileUpload for sizes.
Testing coverage
- Counting by status and the size-weighted total progress.
- Rows show status text, per-file and total progress, sizes and the summary; axe passes.
- Cancel, Retry and Remove appear by status and handler, are named with the file and report the id; non-retryable failures get no Retry.
- Announces done and failed uploads and the end of the batch; the total bar goes when nothing is active.
- Focus moves to the next row, then the heading, when rows are removed.
- Clear finished, indeterminate progress, decorative thumbnails, custom detail; no header with a named region; translated messages; server rendering.
| Check | Covered |
|---|---|
| Axe in jsdom | Yes |
| Server rendering | Yes |
| Browser suites | Visual baselines: /__gallery/upload-queue; Cross-browser axe: /components/upload-queue |
Tests: packages/react/src/components/files/upload-queue