KQ-1295 · USAGE/LEDGER
Usage Ledger
An AI usage panel built from daily records: each day is a column stacked by model, by kind or as one total that grows up from the baseline on glide, the whole period sweeping in inside 360ms, while the month's spend sweeps round a budget gauge on drift toward its projected month end. The daily alert is a line you drag: it follows the finger 1:1 with a magnetic pull onto round numbers, rubber-bands past the plot, re-colours every day above it to warn as it passes, and springs onto its value on snap with the release velocity. The plot is a slider over the days (arrows step, Home and End jump, Enter selects), the line's grip a slider over the threshold (arrows one step, Page keys four), and the period a radio group.
alert at 1.5m/day · 5 of 30 days over · sep 28 is today
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/usage-ledger
Props
- threshold / defaultThreshold
- number
- default 1500000
- The daily alert in tokens: the line you drag. Days above it turn warn. Controlled or uncontrolled.
- onThresholdChange
- (threshold: number) => void
- default —
- Fires from the drag or key that moved the line, once for each round value it lands on.
- stack
- "model" | "kind" | "total"
- default "model"
- What each day's column is split by: each model, input / output / cached, or one total. The legend follows.
- range / defaultRange
- "7d" | "30d" | "90d"
- default "30d"
- The period shown: the last 7, 30 or 90 days up to now. Controlled or uncontrolled.
- onRangeChange
- (range: "7d" | "30d" | "90d") => void
- default —
- Fires from the period control with the new period.
- thresholdStep
- number
- default —
- The round number the line snaps to. Defaults to a nice twelfth of the axis (250k on a 3M axis).
- models
- UsageModel[]
- default defaultUsageModels
- The models billed: id, name, an optional colour, and a price per million input, output and cached tokens.
- days
- UsageDay[]
- default defaultUsageDays
- One record per day (date as YYYY-MM-DD), with tokens per model id. The default is ninety seeded days.
- now
- number | Date
- default —
- Today: where the period ends and the month's spend is counted to. Defaults to the last day in days.
- budget
- number
- default 330
- The monthly budget. The gauge shows the month's spend against it and where the month is heading.
- onDaySelect
- (date: string) => void
- default —
- Enter on the focused day, or a click on a column.
- format
- (amount: number) => string
- default —
- Money in the gauge and its caption. Defaults to US dollars in locale.
- formatTokens
- (tokens: number) => string
- default —
- Token counts on the axis, the grip, the readouts and the legend. Defaults to compact: 820k, 1.5M.
- formatDate
- (date: string) => string
- default —
- Day labels from a YYYY-MM-DD date. Defaults to "Sep 14".
- locale
- string
- default "en-US"
- The locale of the default money format. Fixed, so the server and the browser print the same.
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the usage 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 "Usage"
- 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 detent for each round value the line lands on, pitched by height; a tick for each day the keyboard steps and for a period change.
- disabled
- boolean
- default false
- Read only: the line, the days and the period cannot be moved.
- className
- string
- default —
- Classes for the root. It is 560px tall and scrolls inside itself; pass a height class to change it.
| Prop | Type | Default | Description |
|---|---|---|---|
| threshold / defaultThreshold | number | 1500000 | The daily alert in tokens: the line you drag. Days above it turn warn. Controlled or uncontrolled. |
| onThresholdChange | (threshold: number) => void | — | Fires from the drag or key that moved the line, once for each round value it lands on. |
| stack | "model" | "kind" | "total" | "model" | What each day's column is split by: each model, input / output / cached, or one total. The legend follows. |
| range / defaultRange | "7d" | "30d" | "90d" | "30d" | The period shown: the last 7, 30 or 90 days up to now. Controlled or uncontrolled. |
| onRangeChange | (range: "7d" | "30d" | "90d") => void | — | Fires from the period control with the new period. |
| thresholdStep | number | — | The round number the line snaps to. Defaults to a nice twelfth of the axis (250k on a 3M axis). |
| models | UsageModel[] | defaultUsageModels | The models billed: id, name, an optional colour, and a price per million input, output and cached tokens. |
| days | UsageDay[] | defaultUsageDays | One record per day (date as YYYY-MM-DD), with tokens per model id. The default is ninety seeded days. |
| now | number | Date | — | Today: where the period ends and the month's spend is counted to. Defaults to the last day in days. |
| budget | number | 330 | The monthly budget. The gauge shows the month's spend against it and where the month is heading. |
| onDaySelect | (date: string) => void | — | Enter on the focused day, or a click on a column. |
| format | (amount: number) => string | — | Money in the gauge and its caption. Defaults to US dollars in locale. |
| formatTokens | (tokens: number) => string | — | Token counts on the axis, the grip, the readouts and the legend. Defaults to compact: 820k, 1.5M. |
| formatDate | (date: string) => string | — | Day labels from a YYYY-MM-DD date. Defaults to "Sep 14". |
| locale | string | "en-US" | The locale of the default money format. Fixed, so the server and the browser print the same. |
| status | "ready" | "loading" | "error" | "ready" | Whether the usage has arrived: a skeleton while loading, a message with Try again on error. |
| onRetry | () => void | — | Try again was pressed while status is "error". |
| title | string | "Usage" | The panel's heading; also its accessible name unless label is given. |
| label | string | — | The panel's accessible name. Defaults to the title. |
| sound | boolean | false | A detent for each round value the line lands on, pitched by height; a tick for each day the keyboard steps and for a period change. |
| disabled | boolean | false | Read only: the line, the days and the period cannot be moved. |
| className | string | — | Classes for the root. It is 560px tall and scrolls inside itself; pass a height class to change it. |