KQ-1263 · DOWNLOAD/TRAY

Download Tray

A download button with a tray hidden behind its bottom edge: a press dips the arrow and drops it under gravity through the label row and out of the button, while the tray slides out on the chosen spring (glide, snap or recoil) to catch it, the arrow landing with a squash on springs.recoil and the progress drawn along the tray's lip. At 100% the tray slides shut, the file size is stamped into the caption on springs.recoil, and the arrow rises back on springs.glide and flips into a check on springs.snap; pressing during the download cancels and pulls the arrow back up on springs.snap. Enter and Space press it, Escape cancels, the open tray is a progressbar, and each change is spoken once in a polite live region.

KQ-1263 · DOWNLOAD/TRAY

September statement

Coldbrook Bank · checking ··42

PDF · 8.4 MB

ready · statement-09.pdf

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/download-tray

Props

bytes
number
default —
The file's size in bytes: the readout's total and the size stamped when the tray shuts.
fileName
string
default —
The file's name, shown in the caption under the button at rest and spoken when the download starts.
kind
string
default —
A short type tag before the size in the caption, such as "PDF".
formatBytes
(bytes: number) => string
default decimal units, one place
Formats a byte count, as in "8.4 MB".
onDownload
() => Promise<unknown> | unknown
default —
Starts the download. A returned promise holds the tray open near the end until it settles; a rejection shows the error.
onCancel
() => void
default —
A press or Escape during the download cancelled it.
state
"idle" | "pending" | "success" | "error"
default —
Controlled state. Omit it and the press, the progress and the promise drive the tray.
onStateChange
(state: DownloadTrayState, error?: unknown) => void
default —
Every change of state — the press, the finish, a cancel, the promise, a hold — with the rejection on error.
value
number
default —
Controlled progress from your own transfer, 0 to 1; reaching 1 finishes. Omit it to simulate from duration.
duration
number
default 2400
How long the simulated download takes, in ms.
tray
"glide" | "snap" | "recoil"
default "glide"
The spring the tray slides out and shuts on: glide slides, snap clicks out with one overshoot, recoil bounces.
progress
"line" | "ticks" | "bytes"
default "line"
How progress is drawn along the tray's lip: a line, a row of ticks, or a line with the bytes received.
size
"sm" | "md" | "lg"
default "md"
Button 36, 40 or 48px tall over a 24, 28 or 32px well.
label
string
default "Download"
The idle label.
cancelLabel
string
default "Cancel"
The label during the download, when a press cancels.
successLabel
string
default "Downloaded"
The label once the file is in.
retryLabel
string
default "Retry"
The label after a failure, when a press tries again.
savedLabel
string
default "Saved"
The word stamped beside the size when the tray shuts.
errorLabel
string
default "Download failed"
What failed, shown under the button. A rejection's own message replaces it.
successHold
number
default 0
How long Downloaded holds before the button resets, in ms; 0 keeps it. Counts only while the page is visible.
errorHold
number
default 0
How long a failure holds before the button resets, in ms; 0 keeps it until retried.
accent
string
default "var(--accent-bright)"
The arrow, the check and the progress on the lip.
sound
boolean
default false
Play the arrow landing in the tray and the tray shutting — only for a download the visitor pressed.
disabled
boolean
default false
Takes the button out of use.
className
string
default —
Classes for the outer wrapper.