Skip to Content
BlocksAccountBalanceBlock

AccountBalanceBlock

View available, pending and total balances with their currency and the time they were last known to be correct.

Plan idea 81, category Finance & billing. Status experimental, verification level unmeasured — see verification before adopting it.

Import

import { AccountBalanceBlock } from "@raydenui/ui/blocks"; import type { AccountBalanceEntry, AccountBalanceAction } from "@raydenui/ui/blocks";

Usage

Every amount is a minor-unit integer in the block’s single currency: GBP 248350 displays as £2,483.50, JPY 248350 as ¥248,350.

<AccountBalanceBlock title="Account balance" account={{ name: "Everyday current account", reference: "•••• 4417", icon: "bank" }} currency="GBP" locale="en-GB" available={248350} pending={12000} total={260350} primary="available" asOf="2026-09-24T08:15:00Z" timeZone="Europe/London" asOfNote="Balances refresh every 15 minutes." onRefresh={() => refetchBalances()} />

total is supplied, never derived. available + pending is wrong whenever a hold, an overdraft or a reserve is involved, and the block does not know which applies.

Three kinds of absence

ValueMeaningRenders
a numbera real balance, 0 includedthe formatted amount
nullgenuinely unknownunknownLabel
undefinednot applicable herethe figure is omitted entirely

0 is a real balance and never stands in for unknown.

<AccountBalanceBlock currency="GBP" available={0} pending={null} unknownLabel="Not available" />

Extra balance lines

const extraBalances: AccountBalanceEntry[] = [ { id: "reserved", label: "Reserved", amount: 4500, hint: "Held until 26 September", icon: "lock" }, { id: "overdraft", label: "Overdraft available", amount: 50000 }, ]; <AccountBalanceBlock currency="GBP" available={248350} extraBalances={extraBalances} />;

Masking balances

balancesHidden is controlled. The block never decides to mask a balance and never stores the preference — your application owns both.

const [hidden, setHidden] = useState(false); <AccountBalanceBlock currency="GBP" available={248350} balancesHidden={hidden} onToggleBalanceVisibility={() => setHidden((value) => !value)} hiddenValueLabel="Hidden" />;

The toggle is omitted entirely without onToggleBalanceVisibility, and so is the refresh control without onRefresh.

Actions

AccountBalanceAction is FinanceAction: a destination, an action, or an entry the viewer may not use. There is no fourth arm, so a control with nothing to do cannot be expressed.

<AccountBalanceBlock currency="GBP" available={248350} actions={[ { id: "send", label: "Send money", onClick: () => startTransfer(), tone: "primary" }, { id: "statements", label: "Statements", href: "/statements" }, { id: "close", label: "Close account", unavailableReason: "Only the account owner can close it." }, ]} />

Loading, error and empty

<AccountBalanceBlock currency="GBP" state="loading" loadingMessage="Loading balances" />
<AccountBalanceBlock currency="GBP" state="error" errorTitle="Balances could not be loaded" errorDescription="The banking service did not respond." onRetry={() => refetchBalances()} />
<AccountBalanceBlock currency="GBP" state="empty" emptyTitle="No account selected" emptyDescription="Choose an account to see its balances." emptyAction={{ id: "choose", label: "Choose account", onClick: () => openPicker() }} />

Props

PropTypeDefaultDescription
titleReactNode"Account balance"Block title.
headingLevel"h1"–"h6""h2"Element for title.
descriptionReactNode—Supporting sentence.
eyebrowReactNode—Small label above the title. Not a heading.
account{ name, reference?, icon? }—Display only. reference must already be masked.
statusFinanceStatus—{ label, tone?, description? }.
currencystring"GBP"ISO 4217 code shared by every figure.
localestring"en-GB"Keeps server and client formatting identical.
unknownLabelstring"Not available"Words shown wherever an amount is null.
availableFinanceMoneyValue—Spendable balance.
pendingFinanceMoneyValue—Cleared soon, not yet spendable.
totalFinanceMoneyValue—Total held. Supplied, never derived.
extraBalancesAccountBalanceEntry[]—Further lines, e.g. reserved, overdraft, incoming.
primary"available" | "pending" | "total""available"Which figure is the headline.
availableLabelstring—Label override.
pendingLabelstring—Label override.
totalLabelstring—Label override.
asOfFinanceDateValue—When the figures were last known correct. null is unknown.
asOfLabelstring"Updated"Label for the timestamp.
timeZonestring—IANA zone for asOf.
formatAsOf(value: Date) => string—Takes precedence over locale and zone formatting.
asOfNoteReactNode—One line under the timestamp.
onRefresh() => void—The refresh control is omitted entirely without it.
refreshLabelstring"Refresh balances"Refresh control label.
balancesHiddenboolean—Controlled. Masks every figure.
onToggleBalanceVisibility() => void—The toggle is omitted entirely without it.
showBalancesLabelstring"Show balances"Toggle label when hidden.
hideBalancesLabelstring"Hide balances"Toggle label when shown.
hiddenValueLabelstring"Hidden"Shown in place of a masked figure.
actionsAccountBalanceAction[]—Account actions.
actionsLabelstring"Account actions"Accessible name for the action group.
state"default" | "loading" | "empty" | "error""default"Lifecycle owned by your application.
loadingMessagestring"Loading balances"Announced while loading.
errorTitlestring"Balances could not be loaded"Shown while state="error".
errorDescriptionReactNode—Shown while state="error".
onRetry() => void—The retry control is omitted entirely without it.
emptyTitlestring"No account selected"Shown while state="empty".
emptyDescriptionReactNode—Shown while state="empty".
emptyActionFinanceAction—Recovery step on the empty panel.
classNamestring—Lands on the container root, outside the card padding.

AccountBalanceEntry

MemberTypeDescription
idstringRequired, stable.
labelstringRequired.
amountFinanceMoneyValueMinor-unit integer, or null for genuinely unknown.
hintReactNodeOne short line under the figure.
iconIconNameOptional.

FinanceMoneyValue is number | null | undefined. FinanceDateValue is Date | string | number | null | undefined.

States

  • default — the balance figures.
  • loading / error — with an optional retry control.
  • empty — no account selected, with an optional recovery action.
  • balances hidden — every figure masked, under your application’s control.
  • unknown figure — per figure, from a null amount.
  • no figures supplied — none of available, pending or total given.

Verification

No verification run exists for this block yet. The batch that built it had its run interrupted and is repeating it, and its batch report (docs/blocks-batch-d.md) did not exist when this page was written. This page was reconciled against the block’s public TypeScript types and its 14 story exports, and the block resolves from a built package with its types — nothing more.

Not verified: layout at any width, contrast in either mode, keyboard flows, theme overrides, a screen-reader pass, any non-Chromium engine, operating-system text-size settings, or physical devices.

Known limitations

  • total is supplied, never derived.
  • The block reads no account data and refreshes nothing itself; onRefresh hands that to your application.
  • Every amount in one block shares a single currency and locale.
  • account.reference must already be masked by the caller. Never pass a full account number.
Last updated on