Trend delta
FreeA change as a chip: the arrow turns to the direction, the number counts to its value, and colour and words say whether it is good.
pnpm dlx shadcn@latest add https://caliperui.site/r/trend-delta.jsonRevenueUp 4.2%, good vs last week
Failed jobsDown 12.0%, good vs last week
When to use #
Use it for
- KPI cards and tables of metrics.
- Any figure shown against a previous period.
Skip it when
- Absolute values; show the number itself.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/trend-delta.json
Adds its 4 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { useState } from "react" import { Button } from "@/components/ui/button" import { TrendDelta } from "@/components/ui/trend-delta" export function TrendDeltaDemo() { const [revenue, setRevenue] = useState(4.2); const [errors, setErrors] = useState(-12); return ( <div className="grid justify-items-center gap-5"> <div className="grid gap-3 text-sm"> <p className="flex items-center gap-3"><span className="w-28 text-muted-foreground">Revenue</span><TrendDelta value={revenue} label="vs last week" /></p> <p className="flex items-center gap-3"><span className="w-28 text-muted-foreground">Failed jobs</span><TrendDelta value={errors} good="down" label="vs last week" /></p> </div> <Button size="sm" variant="secondary" onClick={() => { setRevenue((v) => Number((-v * 0.6).toFixed(1))); setErrors((v) => (v === 0 ? 8 : v > 0 ? 0 : 5)); }}>Next week</Button> </div> ); }
API reference #
TrendDelta
component
Also accepts the native props of its root element and a ref.
Accessibility #
It is built on native elements and keeps aria-hidden in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
Transitions use the shared duration and easing tokens. Under prefers-reduced-motion those tokens collapse to instant and travel distances go to zero, so state changes still happen without movement.