Components

Delta

A compact trend indicator — a directional arrow plus a change value. Colour (intent) is decoupled from direction, so an inverted metric like falling attrition reads as good.

Install

npx shadcn@latest add @alix/delta

Preview

+12.4%-2.1%0.0%-2.4pt

Usage

// Formatted strings need explicit direction and intent:
<Delta value="+12.4%" direction="up" intent="positive" />

// Inverted metric — attrition fell, which is good. Arrow down, colour green:
<Delta value="-2.4pt" direction="down" intent="positive" />

Examples

01

Numeric inference

A numeric value infers direction and intent when the displayed value does not need a unit.

12.4-2.10
<Delta value={12.4} />
<Delta value={-2.1} />
<Delta value={0} />
02

Formatted strings

Set direction and intent when the value is pre-formatted as a percent, point change, or currency.

+8.2%-1.4pt$0.0M
<Delta value="+8.2%" direction="up" intent="positive" />
<Delta value="-1.4pt" direction="down" intent="negative" />
<Delta value="$0.0M" direction="flat" intent="neutral" hideArrow />
03

Inverted metric intent

Direction is the motion; intent is the meaning, so falling attrition can still read positive.

-2.4pt+1.1pt0.0pt
<Delta value="-2.4pt" direction="down" intent="positive" />
<Delta value="+1.1pt" direction="up" intent="negative" />
<Delta value="0.0pt" direction="flat" intent="neutral" />
04

Inside metrics and ledgers

Stat and DataTable both accept Delta as a composed trend slot without mirroring its API.

People movement

Quarter over quarter

Voluntary attrition6.8%
-2.4ptvs. Q2
People movement by cohort
CohortChange
Managing directors-1.2pt
Senior delivery+0.8pt
Analyst bench0.0pt
<Panel title="People movement" description="Quarter over quarter" flush>
  <div className="grid gap-5 p-5 md:grid-cols-[14rem_1fr]">
    <Stat
      label="Voluntary attrition"
      value="6.8%"
      delta={<Delta value="-2.4pt" direction="down" intent="positive" />}
      caption="vs. Q2"
    />
    <DataTable
      caption="People movement by cohort"
      dense
      rows={[
        { cohort: "Managing directors", change: "-1.2pt", direction: "down" as const, intent: "positive" as const },
        { cohort: "Senior delivery", change: "+0.8pt", direction: "up" as const, intent: "negative" as const },
        { cohort: "Analyst bench", change: "0.0pt", direction: "flat" as const, intent: "neutral" as const },
      ]}
      columns={[
        { key: "cohort", header: "Cohort", cell: (row) => row.cohort, cellClassName: "font-medium" },
        {
          key: "change",
          header: "Change",
          numeric: true,
          cell: (row) => <Delta value={row.change} direction={row.direction} intent={row.intent} size="sm" />,
        },
      ]}
    />
  </div>
</Panel>

When to use it

Use it for

  • Period-over-period change beside a Stat, inside a StatCard, or in a DataTable column.
  • Metrics where motion and meaning can differ, such as falling attrition, cost, or cycle time.
  • Compact dashboard trend labels that need tabular figures and a directional glyph.

Reach for something else

  • Historical shape or volatility over several periods — use Sparkline instead.
  • Operational status such as on track or at risk — use Badge instead.
  • A standalone KPI value — use Stat or StatCard instead.

Props

PropTypeDefaultDescription
valueReactNodeThe change to display, e.g. "12.4%", "+340", -2.1. A number infers direction from its sign.
direction"up" | "down" | "flat"Which arrow to show. Inferred from a numeric value's sign when omitted. Picks the glyph only — colour is intent, kept separate.
intent"positive" | "negative" | "neutral"Colour, by meaning not motion. Decoupled from direction so a falling cost/attrition can read positive. Inferred from direction when omitted — set it when down is good.
hideArrowbooleanfalseHide the arrow glyph and show the value alone.
size"sm" | "md""md"Text + glyph scale.

See also