KQ-1704 · CREDIT/REFILL
Credit Refill
A low-credit sheet that docks over the work it interrupts, showing what remains and how long it lasts at the current rate. Choosing a pack pours the balance gauge — a vial, a flask or a capsule of liquid — up to the new total on springs.glide while its surface leans against the pour and settles as a damped slosh, the bought share firming from a lighter band when the charge goes through; one frame loop runs only while the liquid moves. Packs are a radiogroup whose highlight slides on springs.snap, auto-recharge reveals a threshold slider that follows the pointer 1:1 and settles on its step with the release velocity, and arrows, Page keys, Home and End drive both.
Credits running low
312 left · about 2 h 10 min
312 credits · 2,412 after the pack
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/credit-refill
Props
- balance
- number
- default 312
- Credits left right now.
- rate
- number
- default 144
- Credits used per hour; the runway is balance ÷ rate.
- packs
- CreditRefillPack[]
- default defaultCreditRefillPacks
- The packs on offer: { id, credits, price, bonus? }.
- value / defaultValue
- string
- default — / the second pack
- The chosen pack id, controlled or initial.
- onValueChange
- (id) => void
- default —
- Fires from the press or key that chose a pack.
- autoRecharge / defaultAutoRecharge
- boolean
- default — / false
- Whether auto-recharge is on, controlled or initial.
- onAutoRechargeChange
- (on, threshold) => void
- default —
- Fires when auto-recharge is switched, with the threshold it will use.
- threshold / defaultThreshold
- number
- default — / 200
- Top up when credits fall below this, controlled or initial.
- onThresholdChange
- (threshold) => void
- default —
- Fires as the slider settles on a new 50-credit step.
- thresholdMax
- number
- default 1000
- The threshold slider's top end.
- onBuy
- (pack) => void | Promise
- default —
- Buy was pressed; a promise holds the button and a rejection keeps the pack chosen with its reason.
- open / defaultOpen
- boolean
- default — / true
- Whether the sheet is up, controlled or initial; dismissed, a pill stays to reopen it.
- onOpenChange
- (open) => void
- default —
- Fires when the sheet is dismissed or reopened.
- onDismiss
- () => void
- default —
- The sheet was dismissed: the close button, Escape, or Close after a buy.
- paymentMethod
- string
- default "Card ending 4417"
- Where the charge goes, in words.
- now
- number
- default —
- The moment the runway counts from, in ms; adds "until about 16:40".
- status
- "ready" | "loading" | "error"
- default "ready"
- Whether the packs have arrived.
- onRetry
- () => void
- default —
- Try again was pressed after the packs failed to load.
- children
- ReactNode
- default —
- The work the sheet sits over; it stays usable behind it.
- gaugeStyle
- "vial" | "orb" | "bar"
- default "vial"
- The gauge: a tall vial, a round flask, or a wide capsule.
- density
- "compact" | "cozy" | "roomy"
- default "cozy"
- Padding, gaps and type size.
- accent
- "cobalt" | "mint" | "amber" | "ink" | string
- default "cobalt"
- The liquid, the selection and Buy: a named pigment or any CSS colour.
- formatMoney
- (amount) => string
- default Intl USD
- How a price is written.
- disabled
- boolean
- default false
- Buying and auto-recharge are unavailable; the sheet can still be read and dismissed.
- className
- string
- default —
- Classes for the frame; a height class replaces its default 35rem.
| Prop | Type | Default | Description |
|---|---|---|---|
| balance | number | 312 | Credits left right now. |
| rate | number | 144 | Credits used per hour; the runway is balance ÷ rate. |
| packs | CreditRefillPack[] | defaultCreditRefillPacks | The packs on offer: { id, credits, price, bonus? }. |
| value / defaultValue | string | — / the second pack | The chosen pack id, controlled or initial. |
| onValueChange | (id) => void | — | Fires from the press or key that chose a pack. |
| autoRecharge / defaultAutoRecharge | boolean | — / false | Whether auto-recharge is on, controlled or initial. |
| onAutoRechargeChange | (on, threshold) => void | — | Fires when auto-recharge is switched, with the threshold it will use. |
| threshold / defaultThreshold | number | — / 200 | Top up when credits fall below this, controlled or initial. |
| onThresholdChange | (threshold) => void | — | Fires as the slider settles on a new 50-credit step. |
| thresholdMax | number | 1000 | The threshold slider's top end. |
| onBuy | (pack) => void | Promise | — | Buy was pressed; a promise holds the button and a rejection keeps the pack chosen with its reason. |
| open / defaultOpen | boolean | — / true | Whether the sheet is up, controlled or initial; dismissed, a pill stays to reopen it. |
| onOpenChange | (open) => void | — | Fires when the sheet is dismissed or reopened. |
| onDismiss | () => void | — | The sheet was dismissed: the close button, Escape, or Close after a buy. |
| paymentMethod | string | "Card ending 4417" | Where the charge goes, in words. |
| now | number | — | The moment the runway counts from, in ms; adds "until about 16:40". |
| status | "ready" | "loading" | "error" | "ready" | Whether the packs have arrived. |
| onRetry | () => void | — | Try again was pressed after the packs failed to load. |
| children | ReactNode | — | The work the sheet sits over; it stays usable behind it. |
| gaugeStyle | "vial" | "orb" | "bar" | "vial" | The gauge: a tall vial, a round flask, or a wide capsule. |
| density | "compact" | "cozy" | "roomy" | "cozy" | Padding, gaps and type size. |
| accent | "cobalt" | "mint" | "amber" | "ink" | string | "cobalt" | The liquid, the selection and Buy: a named pigment or any CSS colour. |
| formatMoney | (amount) => string | Intl USD | How a price is written. |
| disabled | boolean | false | Buying and auto-recharge are unavailable; the sheet can still be read and dismissed. |
| className | string | — | Classes for the frame; a height class replaces its default 35rem. |