KQ-682 · PAYMENT/PLAN

Payment Plan

A total, a slider, and the plan it makes: the knob glides between whole instalment counts on snap while the rail and stop ticks follow, and the headline per-payment figure rolls its digit columns on the same spring. Changing the count rebuilds the plan — new rows open from a ResizeObserver-measured height in a cascade on glide, rows that leave close on the exit ease — and the split is done in whole cents so the rows sum to the charge exactly, with the remainder handed to the earliest payments and named in the caption. It is a real role="slider": arrows step, Page keys move by three, Home and End take the ends, and a drag captures the pointer only after 4px so a plain click still lands on the stop it hit.

KQ-682 · PAYMENT/PLAN
Order BSX-3390
  1. Payment 1 of 3, today, $436.56
  2. Payment 2 of 3, in 1 month, $436.56
  3. Payment 3 of 3, in 2 months, $436.56
Plan fee 2%
$25.68
3 payments of $436.56 a month

3 × $436.56 · charged $1,309.68

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/payment-plan

Props

total
number
default
The amount to split, in major units.
value / defaultValue
number
default 3
Controlled or initial instalment count.
onValueChange
(count: number) => void
default
Fires from the drag, click or key that changed the count.
min / max
number
default 2 / 12
The fewest and most instalments the slider allows.
cadence
"weekly" | "fortnightly" | "monthly"
default "monthly"
Spacing of the instalments; names the row labels and the per-payment caption.
feeRate
number
default 0
Fraction of the total added as a plan fee; above zero it adds a fee line and raises what is charged.
format
(value: number) => string
default Intl.NumberFormat("en-US", { style: "currency", currency: "USD" })
Turns an amount into its printed string. The default pins an explicit locale so server and client agree.
label
string
default "Payment plan"
Names the slider and the plan for assistive technology.