KQ-1770 · INVOICE/DRILLDOWN
Invoice Drilldown
An invoice viewer with the list of invoices on one side and the chosen one in full on the other, where a metered line opens to show the usage records that made it. Opening a line grows its region to the measured height on springs.glide while the parts slide down from 8px a cascade apart and a guide rule grows down from the line; the sum lands last, saying it matches the line or what it differs by, and the line's own figure takes one accent wash so every total traces to its parts. The invoice list is a listbox (arrows, Home, End) whose selection slides on springs.snap, each line is a native disclosure button (Enter or Space toggles, Up and Down walk, Right opens, Left closes), and a paid invoice's tick draws on springs.flick.
Invoices
Fernworks · Studio plan
INV-0142 · due · $1,314.44
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/invoice-drilldown
Props
- invoices
- DrilldownInvoice[]
- default defaultDrilldownInvoices
- The invoices, newest first: { id, number, periodStart, periodEnd, issued, due, status, tax, paidOn?, note? }.
- lineItems
- DrilldownLineItem[]
- default defaultDrilldownLineItems
- Every line of every invoice: { id, invoiceId, label, detail?, amount, records? }.
- value / defaultValue
- string
- default — / the first invoice
- The selected invoice id, controlled or initial.
- onValueChange
- (id) => void
- default —
- Fires from the press or key that chose an invoice.
- expanded / defaultExpanded
- string[]
- default — / []
- The open line ids, controlled or initial.
- onExpandedChange
- (ids) => void
- default —
- Fires with every open line id after a line opens or closes.
- onDownload
- (invoice) => void | Promise
- default —
- Download was pressed; return a promise to show it working.
- onDispute
- (invoice, line | null) => void
- default —
- Dispute was pressed for the invoice (line null) or for one line.
- onPay
- (invoice) => void | Promise
- default —
- Pay was pressed; a returned promise holds the button and a rejection is stated.
- now
- number
- default Oct 17 2026
- The moment due dates count from, in ms.
- account
- string
- default "Fernworks · Studio plan"
- Whose invoices these are.
- status
- "ready" | "loading" | "empty" | "error"
- default "ready"
- Whether the invoices have arrived.
- onRetry
- () => void
- default —
- Try again was pressed after the invoices failed to load.
- tableStyle
- "ruled" | "striped" | "boxed"
- default "ruled"
- How the lines are set.
- rowHeight
- number
- default 40
- Height of a line in px; usage lines take four-fifths.
- accent
- "cobalt" | "plum" | "mint" | "ink" | string
- default "cobalt"
- Selection, open lines and Pay: a named pigment or any CSS colour.
- formatMoney
- (amount) => string
- default Intl USD
- How money is written.
- disabled
- boolean
- default false
- Pay, Download and Dispute are unavailable; everything stays readable.
- className
- string
- default —
- Classes for the viewer; it caps at 36rem tall and its panes scroll inside.
| Prop | Type | Default | Description |
|---|---|---|---|
| invoices | DrilldownInvoice[] | defaultDrilldownInvoices | The invoices, newest first: { id, number, periodStart, periodEnd, issued, due, status, tax, paidOn?, note? }. |
| lineItems | DrilldownLineItem[] | defaultDrilldownLineItems | Every line of every invoice: { id, invoiceId, label, detail?, amount, records? }. |
| value / defaultValue | string | — / the first invoice | The selected invoice id, controlled or initial. |
| onValueChange | (id) => void | — | Fires from the press or key that chose an invoice. |
| expanded / defaultExpanded | string[] | — / [] | The open line ids, controlled or initial. |
| onExpandedChange | (ids) => void | — | Fires with every open line id after a line opens or closes. |
| onDownload | (invoice) => void | Promise | — | Download was pressed; return a promise to show it working. |
| onDispute | (invoice, line | null) => void | — | Dispute was pressed for the invoice (line null) or for one line. |
| onPay | (invoice) => void | Promise | — | Pay was pressed; a returned promise holds the button and a rejection is stated. |
| now | number | Oct 17 2026 | The moment due dates count from, in ms. |
| account | string | "Fernworks · Studio plan" | Whose invoices these are. |
| status | "ready" | "loading" | "empty" | "error" | "ready" | Whether the invoices have arrived. |
| onRetry | () => void | — | Try again was pressed after the invoices failed to load. |
| tableStyle | "ruled" | "striped" | "boxed" | "ruled" | How the lines are set. |
| rowHeight | number | 40 | Height of a line in px; usage lines take four-fifths. |
| accent | "cobalt" | "plum" | "mint" | "ink" | string | "cobalt" | Selection, open lines and Pay: a named pigment or any CSS colour. |
| formatMoney | (amount) => string | Intl USD | How money is written. |
| disabled | boolean | false | Pay, Download and Dispute are unavailable; everything stays readable. |
| className | string | — | Classes for the viewer; it caps at 36rem tall and its panes scroll inside. |