Skip to content
MIZU.

SIG—13 Signature system

TransferQueue

Uploads you can watch and steer: a concurrency-limited queue around your own transfer function, with live speed, time left, pause, retry and cancel.

View .md

Live — this one is real

Network

Simulated network: files you drop never leave your browser. Pause restarts a transfer unless your function resumes from an offset.

Handle

0%

0 of 0 done

Throughput: 0, 0

Idle0 B of 0 B

All file types · up to 200 MB each

Usage

tsx
"use client";

import { TransferQueue } from "mizu-ui";

export function Example() {
  return (
    <TransferQueue
      label="Local reads"
      transfer={async (file, { signal, onProgress }) => {
        const reader = file.stream().getReader();
        let loaded = 0;
        for (;;) {
          const { done, value } = await reader.read();
          if (done) return;
          if (signal.aborted) {
            await reader.cancel();
            throw new DOMException("Stopped", "AbortError");
          }
          loaded += value.byteLength;
          onProgress(loaded);
        }
      }}
    />
  );
}

It starts with "use client" because it keeps state or passes functions to components, so it pastes into a Next.js page as it is. Other React setups ignore the directive.

This code, running — no configuration beyond the data

0%

0 of 0 done

Throughput: 0, 0

Idle0 B of 0 B

All file types · up to 10 MB each

Source & setup

Add this component to your project with the shadcn CLI. The command copies its source into your configured UI directory, with base.css, Mizu’s tokens, and the stylesheets that hold its rules. Each rule lives in one stylesheet, so components you add together never repeat CSS. In a project without a components.json, run npx shadcn@latest init 0xuser64bit/mizu/preset first: plain init installs shadcn’s theme into your global CSS. Then load the fonts.

sh
npx shadcn@latest add 0xuser64bit/mizu/transfer-queue

Every component imports from its own path, its name in kebab case. To paste the example, replace its mizu-ui import with:

tsx
import { TransferQueue } from "@/components/ui/mizu/transfer-queue";

For npm imports, import mizu-ui/styles.css once. Fonts are optional via mizu-ui/fonts.css. Override --mizu-* tokens or use className for local styling. Requires React and Motion. A Client Component: its source starts with “use client”.

Inspect signature/TransferQueue.tsx

Source is included in the npm package under src/signature/TransferQueue.tsx.

Open full source ↗

Props

PropTypeDefaultDescription
labelstring—Region name; also names the drop zone.
transfer(file, { signal, onProgress }) => Promise—Your upload or per-file task. Honour the signal for pause and cancel; report loaded bytes. For upload progress use XMLHttpRequest's upload.onprogress — fetch cannot report it.
concurrencynumber2Transfers running at once.
accept / maxSizestring / number—Validation applied by the drop zone before anything is queued.
onComplete / onItemsChangefunction—One finished file; the whole queue after any change.
refTransferQueueHandle—add(files) — queue files from paste handlers or other sources.

Accessibility

Files arrive through the existing FileDropzone (a real button and file input, with validation errors as alerts). Each transfer is a progressbar whose value text reads its percentage, speed and time left; failures are alerts; every action names its file. Queueing, finishing, failing and cancelling are announced.

Motion

Rows slide in as files are queued and close when cleared. Progress moves continuously, batched to one update per frame; the colour changes with state and a check diamond pops on completion. The overall bar and throughput trace keep pace. Reduced motion removes the travel.

Works alongside