2.0 beta — new releases can include breaking changes. Stable 1.x docs
dimah-s3v2.0.0-beta.0
ComponentsDownload & Delete

Download

Download buttons, a progress bar, and toasts for useDownload or useFetchDownload.

The download family renders one download hook. Download holds the hook, DownloadTrigger downloads one object, and DownloadProgress shows the bytes of a fetch download. One hook serves every trigger in the root, and each object key has its own state.

For a stored file with its download and delete actions, use ObjectCard.

Preview

One useFetchDownload hook for a list of files. While a file downloads, its button fills with the progress, and a click cancels it.

  • quarterly-report.pdf8.0 MB
  • brand-assets.zip24.0 MB
  • launch-video.mp416.0 MB

Install

Complete UI Setup first: the stylesheet and one <Toaster />. Then add this component:

import {
  Download,
  DownloadProgress,
  DownloadToasts,
  DownloadTrigger,
} from "@dimah-s3/ui";

Usage

"use client";

import { useDownload } from "@dimah-s3/react";
import { Download, DownloadToasts, DownloadTrigger } from "@dimah-s3/ui";

type Invoice = { key: string; name: string };

export function InvoiceList({ invoices }: { invoices: Invoice[] }) {
  const download = useDownload({ route: "invoices" });

  return (
    <>
      <Download download={download}>
        <ul>
          {invoices.map((invoice) => (
            <li key={invoice.key}>
              {invoice.name}
              <DownloadTrigger
                objectKey={invoice.key}
                fileName={invoice.name}
                size="sm"
              />
            </li>
          ))}
        </ul>
      </Download>
      <DownloadToasts download={download} />
    </>
  );
}

Download renders no element of its own. DownloadTrigger takes every Button prop, and children replace its icon and label.

Examples

Progress bar

DownloadProgress shows the bytes of a fetch download, next to the trigger that started it.

Button styles

DownloadTrigger is a Button, so variant, size, and the other props are forwarded, and children replace the icon and label. An icon-only trigger needs an aria-label; while it cancels a fetch download, it shows only the cancel icon. These triggers use useDownload, which hands the file to the browser.

The trigger follows the hook you pass to the root.

  • useDownload signs a URL and hands it to the browser, which saves the file. While the URL is signed, the trigger is disabled, stays focusable, and shows a spinner.
  • useFetchDownload fetches the bytes in the page. While the call runs, the trigger fills with the progress and a click cancels the download. Its label becomes "Cancel" and its accessible name Cancel download of {name}. The second click of a double-click does not cancel.

The trigger carries data-phase with the phase of the newest call for its key. See useDownload for both hooks.

Progress

DownloadProgress is a progress bar for the running fetch download of one key. It has role="progressbar", names the file, and reads the bytes received. It is indeterminate until the total size is known. Pass fileSize to the trigger to give the bar a total before the response does.

const download = useFetchDownload({ route: "exports" });

<Download download={download}>
  <DownloadTrigger objectKey={report.key} fileSize={report.size} />
  <DownloadProgress objectKey={report.key} />
</Download>;

It renders nothing with useDownload, which has no byte progress, and while no call for the key runs.

Toasts

Mount DownloadToasts once per hook, next to one <Toaster />.

  • useDownload: "Download started" once the browser has the URL.
  • useFetchDownload: a "Downloading" toast with the bytes and a Cancel action, then "Download complete".
  • Both: "Download failed" with the error, and "Download cancelled".

A second DownloadToasts for the same hook renders nothing and warns in development. Calls that settled before it mounted are not announced.


Props

import type {
  DownloadProps,
  DownloadTriggerProps,
  DownloadProgressProps,
  DownloadToastsProps,
} from "@dimah-s3/ui";

Download

Prop

Type

DownloadTrigger

Prop

Type

DownloadProgress

Prop

Type

DownloadToasts

Prop

Type

Frequently asked questions

On this page