KQ-717 · RATE/LADDER
Rate Ladder
A ladder of term deposits: two stiles with a rung per term, the shortest at the bottom and the longest at the top, so higher rungs pay more. Picking a rung lifts it off the stiles on snap — two pixels up, a raised surface and a cobalt edge, one crisp overshoot — while the rung it replaces settles back, and on the same beat the headline rate rolls its digits and, given a principal, the interest at maturity rolls beside it. Beneath the ladder a timeline runs from the deposit date to the longest term: a marker and its date flag slide on glide to the chosen maturity while the elapsed track fills to it, with the flag clamped inside the axis against measured widths. The ladder is a radio group with a roving tabindex where arrows select as they move, and the readout is a status line that announces a pick once.
12 months · 4.30% · Matures Sep 8, 2027 · Earns $215.00
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/rate-ladder
Props
- rungs
- Rung[]
- default —
- Term deposits as { months, rate }, ascending by months; the rate is percent per year.
- value / defaultValue
- number
- default the middle rung's months
- Controlled or initial term in months.
- onValueChange
- (months: number) => void
- default —
- Fires from the press or key that picked a rung.
- amount
- number
- default —
- Principal; given it, the interest at maturity (amount × rate ÷ 100 × months ÷ 12) is shown and read.
- start
- string
- default —
- The deposit date as YYYY-MM-DD; the timeline starts here and maturities are computed in UTC, so no clock is read.
- format
- (value: number) => string
- default Intl.NumberFormat("en-US", { style: "currency", currency: "USD" })
- Formats every amount. The default pins an explicit locale so server and client agree.
- formatDate
- (date: Date) => string
- default Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" })
- Formats the maturity date on the flag, the axis and in every sentence.
- label
- string
- default —
- Names the ladder; printed as the heading and read as the radio group's label.
| Prop | Type | Default | Description |
|---|---|---|---|
| rungs | Rung[] | — | Term deposits as { months, rate }, ascending by months; the rate is percent per year. |
| value / defaultValue | number | the middle rung's months | Controlled or initial term in months. |
| onValueChange | (months: number) => void | — | Fires from the press or key that picked a rung. |
| amount | number | — | Principal; given it, the interest at maturity (amount × rate ÷ 100 × months ÷ 12) is shown and read. |
| start | string | — | The deposit date as YYYY-MM-DD; the timeline starts here and maturities are computed in UTC, so no clock is read. |
| format | (value: number) => string | Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }) | Formats every amount. The default pins an explicit locale so server and client agree. |
| formatDate | (date: Date) => string | Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" }) | Formats the maturity date on the flag, the axis and in every sentence. |
| label | string | — | Names the ladder; printed as the heading and read as the radio group's label. |