Xzero UI
Pro library

Credit top-upPro

A card for buying AI credits. It shows the balance with a 14 day usage chart and how many days are left, three preset packs with bonus badges, a custom amount slider with a live price, auto top-up with a threshold and the saved Visa or Mastercard. When you buy, the new balance rolls in like an odometer.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/credit-topup
Live · keyboard ready

Drop it into a billing page, an out of credits dialog or a top-up drawer. Pass balance controlled, plus usage (daily credits, oldest first) and paymentMethods. Wire onPurchase(order, signal) to charge a saved card: resolve when the credits are added, or throw an Error with a short message to show the error state with Try again. pricing ({ unitPrice, currency, bonusTiers }) drives every price and bonus. Price orders on the server with the exported quoteCredits and the same pricing object. onAutoTopupChange and onPaymentMethodChange report settings changes. With no props it runs a simulated purchase for a workspace at 840 credits.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/credit-topup

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { CreditTopup } from "@/components/xzero/blocks/credit-topup/credit-topup";

export function BillingCredits({ workspace }) {
  return (
    <CreditTopup
      balance={workspace.credits}
      usage={workspace.dailyUsage}
      paymentMethods={workspace.cards}
      onPurchase={async (order, signal) => {
        const res = await fetch("/api/credits/purchase", { method: "POST", body: JSON.stringify(order), signal });
        if (!res.ok) throw new Error((await res.json()).message ?? "Payment failed. Try again or change card.");
      }}
      onAutoTopupChange={settings => fetch("/api/credits/auto-topup", { method: "PUT", body: JSON.stringify(settings) })}
    />
  );
}

API reference

CreditTopup

A card for buying AI credits: the balance with a 14 day usage chart and days left, preset packs with bonus badges, a custom amount slider with a live price, auto top-up with a threshold, the saved card, and a checkout that rolls the new balance in. With no props it plays a simulated purchase for a workspace at 840 credits.

PropTypeDefaultDescription
balancenumber–The current balance in credits, controlled. Any change rolls the numerals. Leave it out and the card keeps its own balance and adds each purchase to it.
defaultBalancenumber840The starting balance when balance is left out.
usageCreditUsageDay[]Oct 14 to Oct 27, 2026 sampleDaily usage, oldest first: { date: ISO date, credits }. The last day is today. Drives the bar chart, its hover readout, and the days left estimate (average of the full days).
packsnumber[][1000, 5000, 20000]Preset pack sizes in credits, shown as a radio group. Keep it to three for the layout.
pricingCreditPricing$0.01 a credit, +10% from 5,000, +15% from 20,000{ unitPrice, currency, bonusTiers: { min, percent }[] }. Prices, bonus badges, the total and the per 1,000 rate all derive from it.
range{ min: number; max: number; step: number }{ min: 500, max: 30000, step: 500 }The custom amount slider's range in credits. A slider value equal to a pack selects that pack.
defaultCreditsnumberthe second packThe amount selected on mount.
paymentMethodsCreditPaymentMethod[]Visa 4242, Mastercard 5454Saved cards: { id, brand: "visa" | "mastercard", last4, expires: "MM/YYYY" }. Change cycles through them.
thresholdsnumber[][500, 1000, 2500]Choices for the auto top-up threshold. The balance reads as running low below the selected one.
defaultAutoTopup{ enabled: boolean; threshold: number }{ enabled: false, threshold: 1000 }Auto top-up settings on mount.
onAutoTopupChange(settings: { enabled, threshold, credits }) => void–Called when auto top-up is switched or its threshold changes. credits is the selected amount including bonus.
onPaymentMethodChange(id: string) => void–Called when another saved card is chosen.
onPurchase(order: CreditOrder, signal: AbortSignal) => Promise<void>–Charges the order { credits, bonus, total, price, currency, paymentMethodId }. Resolve once the credits are added; reject with an Error and its message shows with a Try again button. Aborted on unmount. Leave it out to simulate a 1.2s charge.
onPurchased(order: CreditOrder, balance: number) => void–Called after a successful purchase with the new balance.
classNamestring–Extra class on the card.

quoteCredits

The pricing helper the card uses: quoteCredits(credits, pricing) returns { credits, bonus, total, price, currency }. Use it on the server to price the same order.

No props.

Keyboard interactions

KeysAction
TabMoves through the packs, slider, auto top-up switch, threshold, Change and Buy credits.
ArrowLeft / ArrowRightMoves between packs or thresholds and selects as it goes. Home and End jump to the first and last.
ArrowLeft / ArrowRight on the sliderSteps the custom amount by 500 credits. PageUp and PageDown take larger steps.
SpaceSwitches auto top-up.
Enter / SpaceBuys the selected credits or changes the card.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components