JobProgress
v1.0.1Updated 19 Oct 2026One long-running operation that is happening on a SERVER — a move, copy, delete, archive or any kind a host names. Distinct from UploadTray, which counts the bytes it is sending and therefore always knows the percentage: here the host POLLS and gets whatever the server chose to report, so percent is OPTIONAL and a job with no size yet draws an indeterminate bar rather than a zero that reads as stalled. Queued, running, paused, done, failed and cancelled each have their own word, bar and controls, and a failed job shows the server's own message verbatim. JobProgressList stacks several under one heading.
Preview
Live · 8 stories▸Why this is recommendedjobprogressbackgroundtask+5
The default, out-of-the-box JobProgress.
- ✓Show how far a server-side move or copy has got
- ✓Report a long background job the user started and walked away from
- ✓A tray of background jobs with cancel and retry
- ✓Say why a batch operation failed
- percent is optional — a server that has not worked out a total yet gets an indeterminate bar with no aria-valuenow, never an invented zero
- processed / total is the other honest shape, and the percentage derives from it
- Queued is not running: its own word and a still bar, so a queue of forty does not read as forty stalled jobs
- A failed job shows the SERVER’s message verbatim — the only thing that says whether to retry, call someone, or change the input
- A cancelled job shows no bar at all; a frozen 61% invites the reading that it might still finish
- Cancel while the job can still be stopped, Retry only on a failure, Dismiss only once it has settled — and none of them without a handler
- Polite live region on the STATUS LINE, not the whole panel, so a re-render of the buttons does not re-announce the job
- Labelled role="group" named from the job’s title, or its kind when it has none
- An ETA in minutes above a minute and seconds below, and only while running
- An unrecognised state renders as running rather than throwing — a server that grows a state must not blank the page
- Every figure through the locale formatter (Thai numerals under a LocaleProvider)
- JobProgressList: several jobs under one replaceable heading, rendering nothing when the list is empty
- i18n: labels prop over DEFAULT_JOB_PROGRESS_LABELS — the kind words, the six state words, the percentage and count templates, the ETA templates and every control
- ✕File uploads the browser is sending (use UploadTray / UploadProgress, which own the transfer and know the bytes)
- ✕A short action inside a button (use the button’s own loading state)
- ✕A determinate bar with no job around it (use Progress)
- ✕Transient success or failure messages (use Sonner toasts)
Install
Ask your agent, or call the MCP tool directly. The resolved bundle is written into your project.
Usage
Tick variants in the left menu — each adds a tab with that variant’s real story source, the same code the preview above renders.
Props
jobJob = { id, kind?, title?, detail?, state, percent?, processed?, total?, error?, etaSeconds? }. state is "queued" | "running" | "paused" | "done" | "failed" | "cancelled"; kind picks a default title when title is absent
yesonCancelShown only while the job is queued, running or paused
—onRetryShown only on a failed job
—onDismissShown only once the job is done, failed or cancelled
—labelsOverride any built-in string. Keys: jobProgress ({title}), move/copy/delete/archive/job, queued/running/paused/done/failed/cancelled, percentComplete ({percent}), processedOfTotal ({processed}/{total}), working, etaMinutes ({minutes}), etaSeconds ({seconds}), cancel, retry, dismiss, backgroundJobs. English defaults ship verbatim as DEFAULT_JOB_PROGRESS_LABELS. The job’s own error is NOT a label — it is the server’s text and arrives in whatever language the backend speaks
—