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/deltaPreview
+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
| Cohort | Change |
|---|---|
| Managing directors | -1.2pt |
| Senior delivery | +0.8pt |
| Analyst bench | 0.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
| Prop | Type | Default | Description |
|---|---|---|---|
| value | ReactNode | — | The 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. |
| hideArrow | boolean | false | Hide the arrow glyph and show the value alone. |
| size | "sm" | "md" | "md" | Text + glyph scale. |