Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Invoice Download Batch Billing Block for Radix UI

Fourteen paid invoices in a table with a checkbox on every row, a head checkbox that shows a dash for a partial pick, Shift-click range selection, quarter buttons, a running total and a real CSV download of the ticked rows.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let customers pick the invoices their accountant needs and take them in one file, with this invoice download for React with Radix UI. A hairline frame with a plus mark on each corner holds a native table of fourteen paid invoices, each row with a Checkbox, the invoice number and what it bills for, the issue date and the amount in tabular figures. The checkbox in the head is ticked, empty or a dash when only some rows are picked. Shift-click a second box and every row between the two takes the state of the box you clicked, and four quarter Buttons tick a quarter's invoices at once (press the same one again to clear). A toolbar band above the table holds them and a Clear button; the foot says "3 selected, $87.00" in a polite status line and holds the only Shine Button, "Download 3 invoices", which saves a real CSV built in the browser. The bands are ruled by Guides, the foot is pinned on a phone, and a phone folds the date under the invoice number. It's built from Checkbox, Button, Shine Button and Guides, with a CSS entrance only. For billing pages, accountant exports and any subscription app.

FAQ

How do I fill it with my invoices?

Edit INVOICES: each has an id (its number), an ISO date, a description and cents, the amount in whole cents so a total never meets a rounding error. The quarters are worked out from the dates, so a new invoice joins its quarter by itself. Add a status column and a PDF link per row if you offer them; this block only needs the amount and the date.

How does the range selection work?

Click one box, then Shift-click another: every row between them takes the state of the box you clicked, ticked or cleared, whichever order you picked them in. From the keyboard, hold Shift and press Space on a focused box. The block reads the Shift key from the click in the capture phase and stops the browser from extending a text selection, which would swallow the click. A polite note says how many rows a range changed.

Is the download real?

Yes. The button builds a CSV of the ticked invoices (number, date, description, amount and status) in the browser and saves it as folioby-invoices-2026-10-12.csv. Fields are quoted when they need it and a value that starts with =, +, - or @ is prefixed so a spreadsheet never reads it as a formula. Nothing is uploaded. PDFs have to come from your server: add a second route that zips them for the same ids.

What if nothing is ticked?

The button stays in the page and keeps its place, but is marked unavailable; pressing it answers in the status line ("Tick at least one invoice first.") instead of saving an empty file. Clear does the same when there is nothing to clear.

Is it accessible?

It is a native table with a caption, column headers and the invoice number as each row's header. Every checkbox is named for its invoice ("Select invoice FB-0198") and the head box is "Select all invoices". Ticked rows are set apart by a bar at their start as well as a tint, and the quarter buttons are toggle buttons that report whether they are pressed. The head checkbox's mixed state is drawn as a dash in the same solid foreground tone.

How does it look on a phone?

The date column goes and the date folds under the invoice number, so each row is a checkbox, the invoice and its amount. The foot with the download button is pinned to the bottom of the screen, so the button is always in reach however long the list is.