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