Staaarter

Billing Invoice Download Batch

A batch invoice download block for tax season and bulk exports. Each row has a checkbox, there's a select-all control in the header, and the footer button shows how many invoices are selected before downloading them as one ZIP. Built for billing history pages where someone needs several past invoices at once instead of clicking download five separate times.

By Staaarter Team
Billing
Updated April 2, 2026
Docs
Live preview

Docs

Installation

A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its button dependencies and any missing npm packages, and installs them straight into your project.

npx shadcn add https://staaarter.com/r/billing-invoice-download-batch.json

Prefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing67.tsx instead.

Usage

The file also exports billing67Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.

import { Billing67, billing67Demo } from "@/components/blocks/billing/billing67";

export default function Page() {
  return <Billing67 {...billing67Demo} />;
}

Props

PropTypeDefaultDescription
headingstring"Download invoices"Heading shown above the table.
descriptionstringnoneOptional one-line note under the heading.
invoicesDownloadableInvoice[]noneRows rendered in the order given, each selectable via its own checkbox.
zipFileNamestring"invoices.zip"File name shown on the download button once the batch is ready.
classNamestringnoneExtra classes for the outer container.

Types

interface DownloadableInvoice {
  id: string;
  date: string;
  amount: string;
  sizeLabel?: string;
}

Behavior notes

  • Selection is local component state, a Set of invoice ids. Checking a row or the select-all control never mutates the invoices prop.
  • The select-all checkbox reflects whether every row is currently checked, and toggling it either selects all rows or clears the selection entirely.
  • The download button is disabled until at least one row is checked, and again while the ZIP is 'preparing'.
  • Clicking download runs a two-step local simulation: a 900ms 'Preparing ZIP' loading state, then a 'ready' state naming the ZIP file for 2.5 seconds before resetting. There's no real ZIP generation or network call, wire that up server-side.
  • Row checkboxes and the select-all control are real buttons with role=checkbox and aria-checked, not native inputs, so they're keyboard and screen-reader accessible without the repo's Checkbox primitive (which doesn't exist here).

Frequently asked questions