KQ-1324 · BILLING/PANEL

Billing Panel

A billing settings panel built from data: the cards on file are a deck that sits in a pile and fans out like a hand, unfolds into wallet strips, or lies flat, every pose a glide from one function of the deck's measured width; Make default lifts the chosen card, slides it to the front on glide and the Default tag slides across to it on snap. The next bill rolls digit by digit on snap as you drag the projected-usage slider 1:1 — it rubber-bands against what has already been used and lands on its step with the throw's velocity — and invoices download through a promise with a turning ring and a check drawn on flick. The deck is a tablist (arrows open the pile and move, Escape folds it), the projection a slider (arrows, Page keys, Home and End).

KQ-1324 · BILLING/PANEL

Billing

Team plan · $49.00 a month · renews Oct 1

Payment methods

Coldbrook Bank · •••• 4417

Business debit · Expires 08/28 · Fieldline Labs

Next bill

Due Oct 1 · in 12 days

Estimated $139.32

+$19.44 vs September

Team plan
$49.00
200k events over 100k
$80.00
Tax · 8%
$10.32
Projected events this cycle300k
182k used · day 18 of 30

Invoices

6 invoices
  • FL-2609Sep 1, 2026$119.88Paid
  • FL-2608Aug 1, 2026$132.84Paid
  • FL-2607Jul 1, 2026$98.28Paid
  • FL-2606Jun 1, 2026$107.35Failed
  • FL-2605May 1, 2026$87.48Paid
  • FL-2604Apr 1, 2026$21.60Refunded

default coldbrook bank ···· 4417 · next bill $139.32 · due oct 1

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/billing-panel

Props

methods
BillingMethod[]
default defaultBillingMethods
The cards on file: id, issuer, kind, last four, expiry, holder, an invented network mark and a tint (any CSS colour, kept at a fixed lightness).
primaryMethod / defaultPrimaryMethod
string
default —
The id of the default card — the one charged. Controlled or uncontrolled; defaults to the first method.
onPrimaryMethodChange
(id: string) => void
default —
Fires from Make default with the new default's id. A controlled host that refuses it leaves the deck as it was.
expanded / defaultExpanded
boolean
default false
Whether the deck is fanned open. Controlled or uncontrolled; ignored when stack is "none".
onExpandedChange
(expanded: boolean) => void
default —
Fires from the press, arrow key or Escape that opened or folded the deck.
onAddMethod
() => void
default —
Add was pressed. Without it there is no Add button.
onRemoveMethod
(id: string) => void
default —
Remove was pressed on a card that is not the default. Without it there is no Remove button; remove the card from methods to see it leave.
plan
BillingPlan
default defaultBillingPlan
The plan: name, price per cycle, the next bill's date (YYYY-MM-DD) and the cycle's length in days.
meter
BillingMeter
default defaultBillingMeter
The metered part of the bill: name and unit, used so far, included, the slider's max and step, and tier prices per 1,000 units above the allowance.
taxRate
number
default 0.08
Tax on plan and usage, 0 to 1.
usage / defaultUsage
number
default —
The projected usage for this cycle: the slider's value. Controlled or uncontrolled; defaults to the pace so far carried to the cycle's end.
onUsageChange
(usage: number) => void
default —
Fires from the drag or key that moved the projection, once per step it lands on.
invoices
BillingInvoice[]
default defaultBillingInvoices
Past invoices, newest first: number, date, amount, status (paid, open, failed, refunded) and an optional description line.
onDownload
(invoice: BillingInvoice) => void | Promise<unknown>
default —
Download was pressed. Return a promise and the row waits with a turning ring, then shows a check (or the error, and retries on the next press).
onChangePlan
() => void
default —
Change plan was pressed. Without it there is no button.
now
number | Date
default defaultBillingNow
Today: how far into the cycle the bill is, which sets the pace and the days left.
format
(amount: number) => string
default —
Money everywhere in the panel. Defaults to currency in locale.
formatUsage
(units: number) => string
default —
Usage counts. Defaults to compact: 182k, 1.2M.
formatDate
(date: string) => string
default —
Invoice dates from YYYY-MM-DD. Defaults to "Sep 1, 2026".
locale
string
default "en-US"
The default money format's locale. Fixed, so the server and the browser print the same.
currency
string
default "USD"
The default money format's currency.
stack
"fan" | "wallet" | "none"
default "fan"
How the cards sit: a pile that fans out like a hand, a pile that unfolds into strips, or a flat grid.
estimate
"total" | "itemized"
default "itemized"
How the next bill reads: one rolling total with a caption, or the total plus plan, usage and tax lines (each rolling) over a bar that re-proportions on glide.
density
"compact" | "regular" | "comfortable"
default "regular"
Padding, invoice row height and how much each row says: one line, two, or two plus its description.
status
"ready" | "loading" | "error"
default "ready"
Whether the billing data has arrived: a skeleton while loading, a message with Try again on error.
onRetry
() => void
default —
Try again was pressed while status is "error".
title
string
default "Billing"
The panel's heading; also its accessible name unless label is given.
label
string
default —
The panel's accessible name. Defaults to the title.
sound
boolean
default false
A click for each press (deck, card, Make default, Remove, Add, Download, Back to pace) and a tick, pitched by usage, for each step the projection crosses.
disabled
boolean
default false
Read only: nothing opens, moves or downloads.
className
string
default —
Classes for the root. It is 560px tall and scrolls inside itself; pass a height class to change it.