Components · Charts
DeltaIndicator
An up, down or flat change with sign, arrow and a spoken sentence; colour follows which direction is better.
Better, worse and lower-is-better
import { DeltaIndicator } from '@rookcom/monarch-react/charts';
<DeltaIndicator value={0.124} comparison="vs last month" locale="en-US" />
<DeltaIndicator value={-0.052} comparison="vs last month" locale="en-US" />
<DeltaIndicator
current={182}
previous={240}
format="number"
unit="ms"
goodDirection="down"
comparison="vs last week"
locale="en-US"
/>
<DeltaIndicator
value={1250}
format="currency"
currency="USD"
goodDirection="down"
comparison="in spend"
locale="en-US"
/>Usage examples
Flat, no data and pill
import { DeltaIndicator } from '@rookcom/monarch-react/charts';
<DeltaIndicator value={0.0004} comparison="vs last week" locale="en-US" />
<DeltaIndicator current={14} previous={0} />
<DeltaIndicator value={0.08} appearance="pill" size="md" locale="en-US" />
<DeltaIndicator
value={-3}
format="number"
goodDirection="neither"
appearance="pill"
/>Purpose
Shows how a value moved between two periods, the same way everywhere: arrow, signed percentage or amount, an optional comparison, and green or red depending on whether that direction is good.
Use when
- A period-over-period change next to a KPI, in a table cell or in a list row.
- Changes where down is good, such as costs, response time, churn or a ranking position.
- Generating the same wording for a chart summary or
aria-label(formatDelta).
Avoid when
- Showing a trend over many points: use a sparkline or line chart.
- Status that is not a change (healthy, failing): use StatusBadge.
Design principles
- Meaning never depends on colour: the arrow, the sign (+ or a true minus) and the spoken direction carry it; colour only says better or worse.
goodDirectiondecides colour, not the sign: a 12% fall in cost is green.- Nothing to compare is not zero: a missing or zero baseline shows "No earlier data", not "+∞%" or "0%".
- A change that rounds to zero when written ("0%") is shown as "No change", never "+0%".
- Formatting is Intl.NumberFormat with the given locale; currency goes through Money.
API reference
import { DeltaIndicator, formatDelta } from '@rookcom/monarch-react/charts';| Export | Kind | Rendering | Root class |
|---|---|---|---|
DeltaIndicator | component | server-safe | .mn-delta-indicator |
formatDelta | utility | server-safe | – |
The ref and native <span> attributes go to the root.
formatDelta(options) returns { value, direction, tone, text, magnitude, label }, the same text and spoken sentence the component renders, for chart summaries and exports.
Exported from @rookcom/monarch-react/charts.
Generated from the TypeScript declarations of packages/react/src/components/charts/delta-indicator.
Properties
With format="percent" (the default) value is a ratio: 0.12 is 12%. Pass current and previous to have the change computed instead.
DeltaIndicator
A change between two periods: direction arrow, signed value and an optional comparison. Colour follows `goodDirection`, so a fall in costs is green; the arrow, sign and spoken "up 12% vs last month, better" carry the meaning without colour.
| Prop | Type | Description |
|---|---|---|
appearance | "pill" | "plain" | `plain` (default) is inline text; `pill` puts the change in a tinted chip. |
className | string | |
comparison | ReactNode | The comparison period after the change, e.g. "vs last month". Shown muted and spoken. |
currency | string | ISO 4217 code for `format="currency"`, e.g. `USD`. Required in that format. |
current | number | null | This period's value; with `previous`, the change is computed. |
flatThreshold | number | Changes whose size is at or below this count as flat. Default 0. |
format | DeltaFormat | Default `percent`. |
formatOptions | Intl.NumberFormatOptions | Extra `Intl.NumberFormat` options, e.g. `{ maximumFractionDigits: 0 }`. |
formatValue | ((magnitude: number) => string) | Writes the size of the change yourself (no sign); replaces `format`, `unit` and `formatOptions`. |
goodDirection | DeltaGoodDirection | Which direction is an improvement. Default `up`. |
hideIcon | boolean | Hides the direction arrow. The sign and the spoken direction remain. |
id | string | |
labels | Partial<DeltaLabels> | Words to show and speak; merged over the English defaults. |
locale | string | BCP 47 locale. Default: the runtime locale. |
previous | number | null | The previous period's value. With `format="percent"` the change is `(current − previous) / |previous|`, and a `previous` of 0 has no baseline, so it shows `labels.noData`. Otherwise the change is `current − previous`. |
size | "sm" | "md" | `sm` (default) for card footers, `md` next to body text. |
unit | string | Unit written after a `number` change, e.g. `pt` or `ms`. |
value | number | null | The change itself. With `format="percent"` it is a ratio (0.12 is 12%). `null` means there is nothing to compare with. Takes precedence over `current` and `previous`. |
Variants
| Prop | Values | Description |
|---|---|---|
format | 'percent''number''currency' | percent (default) writes a ratio as a percentage; number with an optional unit (pt, ms); currency through Money with currency. |
goodDirection | 'up''down''neither' | Which direction is an improvement. Default up. neither keeps the change neutral grey. |
appearance | 'plain''pill' | pill puts the arrow and value in a tinted chip (data-appearance). |
size | 'sm''md' | sm (default) for card footers and tables, md beside body text. |
States
| State | Exposed as | Behaviour |
|---|---|---|
| Up / down | data-direction="up|down" | Arrow, signed value, visually hidden direction word and "better" or "worse". |
| Better / worse / neutral | data-tone="positive|negative|neutral" | Derived from the direction and goodDirection. |
| Flat | data-direction="flat" | Zero, within flatThreshold, or rounding to zero: a dash and "No change", neutral. |
| No data | data-empty | value null or not finite, current or previous missing, or a previous of 0 for a percentage: "No earlier data". |
Interaction behaviour
- None. DeltaIndicator is read-only text.
Keyboard support
Not interactive, so there is no keyboard behaviour.
Accessibility
- Role
- none (inline text)
- Accessible name
- The visually hidden sentence, e.g. "up 12% vs last month, better".
- The arrow and the signed value are
aria-hidden; a visually hidden "up 12%" or "down 8%" is read instead, so screen readers never say "plus" or skip a glyph. - The comparison is real text, read after the change, followed by a hidden "better" or "worse" when a direction is better.
- Every word is replaceable through
labelsfor translation. - In forced-colours mode the pill keeps a border; the arrow and sign remain.
Responsive behaviour
- The change never wraps; the comparison may wrap onto the next line in narrow cells.
Theme support
- Better uses
--mn-color-success-strong, worse--mn-color-danger-strong, neutral--mn-color-text-muted; all meet AA text contrast in light, dark and high-contrast themes. - The pill tint is the matching
-subtletoken.
Do and don't
Do
- Set
goodDirection="down"for costs, latency, churn, bounce rate and rank positions. - Pass the comparison period ("vs last month") so the change is never ambiguous.
- Use
formatDeltafor chart summaries so the words match the indicator.
Don't
- Do not compute a percentage against a zero baseline; let DeltaIndicator show "No earlier data".
- Do not invent a change when the product has no previous value: pass
null. - Do not use a status colour on its own to show direction.
Related components
- StatCard: A KPI tile that shows a DeltaIndicator through
change. - Money: Formats currency changes.
- Sparkline: A trend over many points rather than one change.
- StatusBadge: A state rather than a change.
Dependencies
| Kind | Depends on |
|---|---|
| npm packages | react |
| Monarch components | Money, VisuallyHidden |
Testing coverage
- Signed percentage with spoken direction, comparison and quality; arrow hidden.
- goodDirection down (costs) and neither; computed percentage and absolute changes with a unit.
- Currency through Money and a custom formatter.
- Flat for zero, inside the dead band and when rounding to zero.
- No-data label for null, NaN, missing or zero baselines.
- Translated labels and locale; pill, size, hideIcon; ref forwarding; formatDelta output.
| Check | Covered |
|---|---|
| Axe in jsdom | Yes |
| Server rendering | Yes |
| Browser suites | Visual baselines: /__gallery/delta-indicator; Cross-browser axe: /components/delta-indicator |
Tests: packages/react/src/components/charts/delta-indicator