Explainable total

A React component in Beamline's Dashboard category.

A total that answers "why this much?" in place: it unfolds into the steps that made it — a waterfall whose bars start where the last step ended, each step with its kind, its reason in real numbers, its source and a thread to the steps it came from; where the host allows, a step's lever (add-on, discount, quantity) re-solves the rest, a pinned version shows what changed, and a re-solved total waits to be applied.

Use it for

  • A number with money in it that people question: a quote, an invoice, a refund, a checkout, a commission, a first month's rent.
  • The host computes every amount and writes each step's reason; the part presents, threads and animates and never adds money up itself.

Not for

Anatomy

  • rest: the label, the total (or what's due now of it), Estimate / Not applied when true, Why?
  • sheet: the label and Close; the steps; the total row with its bar, the due-now mark and, when pinned, the difference; pin and apply
  • step: glyph and kind word, label (lock, set-by chip), a waterfall bar on one shared scale (a soft end for a range, an outline for the pinned version), the amount with its difference; the lever; the reason with its source while read; the host's next-break nudge; parts under it

States

  • rest
  • open
  • pending (the last total readable, dotted, Recalculating…)
  • error (no number, Try again)
  • unapplied (Apply $…)
  • pinned (outlines and differences)
  • ineligible step (struck, not counted, with why)
  • locked step
  • range

Keyboard

  • Enter or Space on the total opens it; Escape or Close folds it back with focus on the total
  • Tab reaches each step's label (its reason shows and its basis lights) and each lever: switch, slider (arrows), number field (arrows, typing)
  • A lever's change announces the new total and the difference

Motion

The total unfolds in place (the shared height morph). A lever's change moves the bars to their new places and rolls the changed digits (slot text); the thread draws between a step and the steps it came from. Reduced motion places at once.

Props

PropTypeDefaultDescription
label (required)string—What the total is: "Quote total", "Refund", "First month".
steps (required)TotalStep[]—Drawn in this order, each bar starting where the last ended; the host recomputes every amount when a lever moves (a lever may change any step, not only its own).
total (required)TotalAmount—The host's total; the part never adds money up itself.
duenumber—What is due now, when it isn't all of it (a deposit).
estimateboolean—An estimate says so at rest and in the sheet.
currencystring—
format((amount: number) => string)—Money in the host's own format; default: the locale's currency format for `currency`.
status"error" | "pending" | "ready"—"pending" while the host recalculates (the last total stays readable), "error" when it can't.
onRetry(() => void)—
onLeverChange((stepId: string, value: number | boolean) => void)—
appliednumber—The amount actually applied, when a re-solved total is only a suggestion until applied.
onApply(() => void | Promise<unknown>)—
pinnableboolean—Offer "Pin this version" to compare against. Default true when any step has a lever.
openboolean—Controlled open state; omit to use defaultOpen.
defaultOpenboolean—Initial open state when uncontrolled; defaults to false.
onOpenChange((open: boolean) => void)—Reports an open-state change; no callback by default.
classNamestring—Classes on the documented visual root; no override by default.
classNamesPartial<Record<"root" | "row" | "total" | "trigger" | "actions" | "bar" | "sheet", stri…—Classes for the named visual parts; no overrides by default.
styleCSSProperties—Inline styles on the documented visual root; no overrides by default.
refRef<HTMLDivElement>—Receives the documented native target or imperative handle; omitted by default.
onLeverCommit((stepId: string, value: number | boolean) => void)—A lever's settled value: a slider released, a switch flipped, a quantity entered. Recalculate on the server here; `onLeverChange` follows every step for an instant local answer.

Built from

Used in

Dependencies

lucide-react

Import

import { ExplainableTotal } from "@beamline/explainable-total";

Get it

Explainable total is part of Beamline UI. Install the parts you need in your React app as compiled packages or editable source. Get Beamline · Connect your agent

More in Dashboard

  • Explainable change: A metric whose change explains itself: at rest the value, the change against a named period and a thin ribbon of its causes under the change; opened in…
  • Budget vessels: Budgets as glasses of money: the liquid is what is left (free money on top, committed money as a lighter layer under it), the lip at the period's budget…
  • Insight cards: Findings from an agent, one per page: the sentence, the series it is about with their change, a chart to scrub that names each point, and a follow-up…
  • Tracker: A row of status blocks for uptime, job runs or daily checks, with tooltips and a legend.
  • Metric card: A KPI that fills its tile: label, a value that rolls to each new number, the change with arrow, sign and tone, what it compares with and the value it…
  • Category bar: One bar split into labelled ranges with an optional marker that names its range.
  • Bar list: Ranked horizontal bars, label and value over a meter, one line per row when there is room — top pages, sources, customers.
  • App shell: The frame for every app screen: collapsible sidebar with grouped navigation, top bar and page.

Part of Beamline UI: polished, editable React components and complete screens for custom applications. Build your own style from any look; tokens, fonts, radii, motion; not only colours.