skrewww

Industries · Banking

Banking Balance Summary

Banking Balance Summary is a spending/income overview card with a time-range-filtered Bar Chart and a loading state.

No top-level variants of its own — time ranges are consumer-supplied Tabs, not a fixed variant set

betaReact AvailableFigma UnavailableDocs Partial
React last updated
2026-07-25
Documentation last updated
2026-07-25
Accessibility target
WCAG 2.2 AA (target)
Version
0.1.0-beta

Known open questions

  • No Figma reference exists for this component or for Industry Systems generally — confirmed absent via full file search on 2026-07-25, not an oversight.
  • Each time range renders its own Bar Chart instance inside its own Tabs panel — real per-range data is expected from the consumer, not one dataset re-scaled across ranges.

Spending overview

Each time-range tab owns its own Bar Chart data — switching tabs swaps the visualization, not just the axis scale.

7D / 30D / 90D

Spending overview

Total spent$1,284.32

Spending overview — 7D
LabelValue
Mon42
Tue88
Wed61
Thu120
Fri96
Sat210
Sun54

Loading state

Composes the existing Skeleton/SkeletonLoading primitives — no new loading-state pattern.

Toggle loading

Spending overview

Total spent$1,284.32

Spending overview — 7D
LabelValue
Mon42
Tue88
Wed61
Thu120
Fri96
Sat210
Sun54

Purpose

Banking Balance Summary is a spending/income overview card with a time-range-filtered Bar Chart and a loading state. The third Layer 4 Industry Systems pilot component; React-first, no Figma reference exists yet.

Anatomy

Composes: Card (layout wrapper, title slot) + Tabs (time-range filter, one TabsPanel per range) + Bar Chart (one instance per range, inside its panel) + Skeleton / SkeletonLoading (loading state, replaces the total figure and Tabs entirely while loading).

When to use

Summarizing spending or income over a small set of selectable time ranges (e.g. 7D/30D/90D) inside a dashboard.

When not to use

A single, non-comparative chart with no time-range filtering — compose Card + Bar Chart directly without Tabs.

Accessibility

Each time range renders its own Bar Chart instance inside its own Tabs panel, so only the selected range's chart (and its accessible name/hidden data table) is in the accessibility tree at a time — matching Tabs' own hidden-inactive-panel behavior, not a manually toggled visibility hack.

Common mistakes

Re-scaling one shared dataset for different time ranges instead of giving each range its own real data — spending data genuinely differs by range, it isn't the same series zoomed in or out. Introducing a new loading-state pattern instead of composing the existing Skeleton / SkeletonLoading primitives.

Properties

title, totalLabel, total, ranges ({ value, label, data: BarChartDatum[] }[]), defaultRange?, loading?, loadingLabel?.

Tokens used

semantic/text/primarysemantic/text/secondary

Component API

PropTypeDefaultDescription
titlestringCard title, e.g. "Spending overview".
totalLabelstringLabel shown next to the total figure, e.g. "Total spent".
totalstringPre-formatted total figure (e.g. "$1,284.32") — currency formatting is the consumer's responsibility.
ranges{ value, label, data: BarChartDatum[] }[]One entry per selectable time range, each with its own real data.
defaultRangestringDefaults to the first range's value when omitted.
loadingbooleanfalseShows Skeleton placeholders instead of the total figure and Tabs.
loadingLabelstring"Loading spending summary"Accessible label announced while loading.

React example

Copy React example
import { BankingBalanceSummary } from "@/components/ui/BankingBalanceSummary";

export function Example() {
  return (
    <BankingBalanceSummary
      title="Spending overview"
      totalLabel="Total spent"
      total="$1,284.32"
      ranges={[
        {
          value: "7d",
          label: "7D",
          data: [
            { label: "Mon", value: 42 },
            { label: "Tue", value: 88 },
          ],
        },
        {
          value: "30d",
          label: "30D",
          data: [
            { label: "Week 1", value: 320 },
            { label: "Week 2", value: 410 },
          ],
        },
      ]}
    />
  );
}