KQ-672 · SPEND/RING
Spend Ring
The month drawn once, as a ring: the arc grows clockwise with the share of the budget already spent through strokeDashoffset on a pathLength circle, settling on glide because a total is a quantity arriving rather than a switch flipping. A one-notch dash walks the same circle at the month's own progress, so fill behind the mark reads on pace and fill past it turns warn, while spend past the budget wraps a second danger arc back over the ring's head on snap. The centre figure counts through a motion value, and a two-stop radio group under the ring swaps it between spent and left with Arrow keys, Home and End, its knob travelling on a shared layoutId.
Day 18/30 · $820 of $1,400 · on pace
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/spend-ring
Props
- spent
- number
- default —
- Money spent this month. May exceed the budget; the overage is drawn.
- budget
- number
- default —
- The month's budget.
- day
- number
- default —
- Day of the month, 1-based; places the pace mark on the ring.
- daysInMonth
- number
- default 30
- Length of the month.
- readout / defaultReadout
- "spent" | "left"
- default spent
- Controlled or initial centre figure.
- onReadoutChange
- (readout: "spent" | "left") => void
- default —
- Fires from the click or key that changed the centre figure.
- format
- (value: number) => string
- default —
- Formats every money figure; defaults to an explicit en-US currency formatter.
- size
- number
- default 168
- Ring diameter in px, applied as a maximum — the ring shrinks with its container rather than overhanging it.
- label
- string
- default —
- Names the ring; printed above it and used for assistive technology.
| Prop | Type | Default | Description |
|---|---|---|---|
| spent | number | — | Money spent this month. May exceed the budget; the overage is drawn. |
| budget | number | — | The month's budget. |
| day | number | — | Day of the month, 1-based; places the pace mark on the ring. |
| daysInMonth | number | 30 | Length of the month. |
| readout / defaultReadout | "spent" | "left" | spent | Controlled or initial centre figure. |
| onReadoutChange | (readout: "spent" | "left") => void | — | Fires from the click or key that changed the centre figure. |
| format | (value: number) => string | — | Formats every money figure; defaults to an explicit en-US currency formatter. |
| size | number | 168 | Ring diameter in px, applied as a maximum — the ring shrinks with its container rather than overhanging it. |
| label | string | — | Names the ring; printed above it and used for assistive technology. |