KQ-1262 · SETTLE/BUTTON
Settle Button
A pay button laid out like a checkout bar, the amount on an odometer with one wheel per digit: a press sweeps a fill in the paid colour in behind the text, and as its front crosses each digit that wheel rolls down to zero, closing in on the last digit exponentially and holding there while the onPay promise is pending. Resolved, the characters fold away in a cascade on the exit ease, Pay rolls to Paid on springs.snap and a check is stamped where the last digit stood on springs.recoil, its stroke drawn on springs.flick; declined, the fill retreats on springs.glide, the wheels roll back up and the face tints to danger. Enter and Space press it through the native click, and each change is spoken once in a polite live region.
Basinworks supply
Invoice 0419 · due Oct 9
due Oct 9 · coldbrook ··42
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/settle-button
Props
- amount
- number
- default —
- What is owed, in major units — dollars, not cents.
- currency
- string
- default "USD"
- ISO 4217 code: sets the sign, the separators and how many places roll.
- locale
- string
- default the currency's home locale
- The formatting locale. USD en-US, EUR de-DE, GBP en-GB, JPY ja-JP, otherwise en-US — fixed, so the server and the browser format alike.
- format
- (amount: number) => string
- default Intl.NumberFormat
- Formats the amount for the label and the spoken text; every digit in its output becomes a wheel.
- onPay
- () => Promise<unknown> | unknown
- default —
- Takes the payment. A returned promise holds the meter short of zero until it settles.
- state
- "idle" | "pending" | "success" | "error"
- default —
- Controlled state. Omit it and the press and the promise drive the button.
- onStateChange
- (state: SettleState, error?: unknown) => void
- default —
- Every change of state — the press, the promise, a hold running out — with the rejection on error.
- speed
- number
- default 1
- How fast the amount runs down, 0.5 to 2 times.
- stamp
- number
- default 0.6
- How hard the check is stamped, 0 to 1: 0 only draws it, 1 slams it down with an ink ring.
- label
- string
- default "Pay"
- The word before the amount.
- pendingLabel
- string
- default "Paying"
- The word while the payment is in flight.
- paidLabel
- string
- default "Paid"
- The word once paid.
- retryLabel
- string
- default "Retry"
- The word after a failure, when a press tries again.
- errorLabel
- string
- default "Payment declined"
- What failed, spoken and shown as the button's title. A rejection's own message replaces it.
- successHold
- number
- default 0
- How long Paid holds before the amount rolls back up, in ms; 0 keeps it paid. Counts only while the page is visible.
- errorHold
- number
- default 2400
- How long the failure tint holds, in ms; 0 keeps it until the next press.
- size
- "sm" | "md" | "lg"
- default "md"
- 36, 44 or 52px tall.
- accent
- string
- default "var(--primary)"
- The unpaid face.
- fill
- string
- default "oklch(from var(--success) 0.55 c h)"
- The paid colour that sweeps in behind the digits.
- sound
- boolean
- default false
- Play a tick as each digit reaches zero, the stamp's chime and the decline's buzz — only for a payment the visitor pressed.
- disabled
- boolean
- default false
- Takes the button out of use.
- className
- string
- default —
- Classes for the outer wrapper.
| Prop | Type | Default | Description |
|---|---|---|---|
| amount | number | — | What is owed, in major units — dollars, not cents. |
| currency | string | "USD" | ISO 4217 code: sets the sign, the separators and how many places roll. |
| locale | string | the currency's home locale | The formatting locale. USD en-US, EUR de-DE, GBP en-GB, JPY ja-JP, otherwise en-US — fixed, so the server and the browser format alike. |
| format | (amount: number) => string | Intl.NumberFormat | Formats the amount for the label and the spoken text; every digit in its output becomes a wheel. |
| onPay | () => Promise<unknown> | unknown | — | Takes the payment. A returned promise holds the meter short of zero until it settles. |
| state | "idle" | "pending" | "success" | "error" | — | Controlled state. Omit it and the press and the promise drive the button. |
| onStateChange | (state: SettleState, error?: unknown) => void | — | Every change of state — the press, the promise, a hold running out — with the rejection on error. |
| speed | number | 1 | How fast the amount runs down, 0.5 to 2 times. |
| stamp | number | 0.6 | How hard the check is stamped, 0 to 1: 0 only draws it, 1 slams it down with an ink ring. |
| label | string | "Pay" | The word before the amount. |
| pendingLabel | string | "Paying" | The word while the payment is in flight. |
| paidLabel | string | "Paid" | The word once paid. |
| retryLabel | string | "Retry" | The word after a failure, when a press tries again. |
| errorLabel | string | "Payment declined" | What failed, spoken and shown as the button's title. A rejection's own message replaces it. |
| successHold | number | 0 | How long Paid holds before the amount rolls back up, in ms; 0 keeps it paid. Counts only while the page is visible. |
| errorHold | number | 2400 | How long the failure tint holds, in ms; 0 keeps it until the next press. |
| size | "sm" | "md" | "lg" | "md" | 36, 44 or 52px tall. |
| accent | string | "var(--primary)" | The unpaid face. |
| fill | string | "oklch(from var(--success) 0.55 c h)" | The paid colour that sweeps in behind the digits. |
| sound | boolean | false | Play a tick as each digit reaches zero, the stamp's chime and the decline's buzz — only for a payment the visitor pressed. |
| disabled | boolean | false | Takes the button out of use. |
| className | string | — | Classes for the outer wrapper. |