Delta Badge
- Stable
- WCAG 2.2 evidence
- RTL
A pill that shows how a figure changed, for example "+4.2%" in a metric card. The direction is an
arrow glyph (up-right, down-right or a minus) and, for assistive technology, hidden text ("Increase, good"), so neither
the direction nor the good or bad meaning depends on colour alone for screen reader users (WCAG 1.1.1, 1.3.1, 1.4.1). The
value is always left to right (1.3.2). Presentational: renders in React Server Components. Consumer duties: sighted people who cannot tell green from red see the arrow but not whether the change is good, because
the Figma design separates "up good" from "up bad" by colour only; say what the figure is in the surrounding text ("Churn")
so the meaning is clear from context. Format the value for the locale and translate labels.
import { DeltaBadge } from "@nexera-ui/react";- 5
- examples
- 3
- props
- 1
- live controls
- 1
- platform
- 7
- WCAG criteria
- 1
- block uses it
Try every prop. Copy the code.
Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.
import { DeltaBadge } from "@nexera-ui/react";
<DeltaBadge />Examples 4
The same examples as Storybook, rendered live. Open Code to copy one.
In context
In a metric: the figure the change belongs to is named in the text, so "up bad" (costs) and "up good" (revenue) are clear from context. Screen readers also hear the direction and whether it is good ("+4.2% Increase, good").
import { DeltaBadge } from "@nexera-ui/react";
const metrics = [
{ label: "Revenue", figure: "$128,400", trend: "up-good", value: "+4.2%" },
{ label: "Payroll cost", figure: "$84,300", trend: "up-bad", value: "+6.1%" },
{ label: "Attrition", figure: "3.2%", trend: "down-good", value: "-1.8%" },
{ label: "Engagement score", figure: "71", trend: "down-bad", value: "-3.5%" },
{ label: "Headcount", figure: "212", trend: "flat", value: "0%" },
] as const satisfies readonly {
label: string;
figure: string;
trend: DeltaBadgeTrend;
value: string;
}[];
export function InContext() {
return (
<ul className="m-0 flex max-w-sm list-none flex-col gap-3 p-0">
{metrics.map((row) => (
<li key={row.label} className="flex items-center justify-between gap-3">
<span className="text-body-default text-secondary">{row.label}</span>
<span className="flex items-center gap-2">
<span className="text-body-strong text-primary">{row.figure}</span>
<DeltaBadge value={row.value} trend={row.trend} />
</span>
</li>
))}
</ul>
);
}
Translated labels
The hidden texts are translatable: pass labels with a complete phrase per trend (here German).
import { DeltaBadge } from "@nexera-ui/react";
const trends = [
{ trend: "up-good", value: "+4.2%" },
{ trend: "up-bad", value: "+4.2%" },
{ trend: "down-good", value: "-1.8%" },
{ trend: "down-bad", value: "-1.8%" },
{ trend: "flat", value: "0%" },
] as const satisfies readonly { trend: DeltaBadgeTrend; value: string }[];
export function TranslatedLabels() {
return (
<div className="flex flex-wrap items-center gap-4" lang="de">
{trends.map(({ trend, value }) => (
<DeltaBadge
key={trend}
trend={trend}
value={value}
labels={{
"up-good": "Anstieg, gut",
"up-bad": "Anstieg, schlecht",
"down-good": "Rückgang, gut",
"down-bad": "Rückgang, schlecht",
flat: "Unverändert",
}}
/>
))}
</div>
);
}
Long content
A long value wraps inside a narrow container instead of widening the page.
import { DeltaBadge } from "@nexera-ui/react";
export function LongContent() {
return (
<div className="max-w-40">
<DeltaBadge value="+4.2% against the same quarter of last year" />
</div>
);
}
Right to left
Right-to-left: the arrow moves to the start (right) and the value keeps its left-to-right order ("-1.8%", not "%1.8-").
import { DeltaBadge } from "@nexera-ui/react";
const trends = [
{ trend: "up-good", value: "+4.2%" },
{ trend: "up-bad", value: "+4.2%" },
{ trend: "down-good", value: "-1.8%" },
{ trend: "down-bad", value: "-1.8%" },
{ trend: "flat", value: "0%" },
] as const satisfies readonly { trend: DeltaBadgeTrend; value: string }[];
export function RightToLeft() {
return (
<div dir="rtl" lang="ar" className="flex flex-wrap items-center gap-4">
{trends.map(({ trend, value }) => (
<DeltaBadge
key={trend}
trend={trend}
value={value}
labels={{
"up-good": "زيادة، جيد",
"up-bad": "زيادة، سيئ",
"down-good": "انخفاض، جيد",
"down-bad": "انخفاض، سيئ",
flat: "دون تغيير",
}}
/>
))}
</div>
);
}
Props 3
Press "Try it" on a card to load that prop into the playground.
3 props shown
value*NexerastringThe change. Format it for your locale and include the sign: the number is shown left to right, as numbers are in right-to-left pages.
trendNexera"up-good" | "up-bad" | "down-good" | "down-bad" | "flat"Direction and meaning. The arrow (up, down or a minus) shows the direction; the colour (green, red or grey) shows whether it is good or bad, and hidden text says both.
labelsNexeraPartial<Record<DeltaBadgeTrend, string>>Text for assistive technology, read after the value, per trend: whether the figure rose or fell and whether that is good or bad ("+4.2% Increase, good"). Each entry is a complete phrase so it translates as one unit; entries you leave out keep their English default ("Increase, good", "Increase, bad", "Decrease, good", "Decrease, bad", "No change"). Translate all five for your locale (WCAG 1.1.1, 1.4.1).
* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.
Accessible by default.
Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.
WCAG 2.2 evidence
4 direct · 3 supporting- 1.1.1Non-text ContentLevel A · tested directly
- 1.3.1Info and RelationshipsLevel A · tested directly
- 1.3.2Meaningful SequenceLevel A · supporting test
- 1.4.1Use of ColorLevel A · tested directly
- 1.4.10ReflowLevel AA · supporting test
- 1.4.12Text SpacingLevel AA · supporting test
- 4.1.2Name, Role, ValueLevel A · tested directly
Fits any width.
Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.
Styling hooks
Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.
<DeltaBadge className="shadow-sm" />Used in blocks
Related components
- AccordionItemOne collapsible section of an FAQ or settings page.
- AreaChartA stacked area chart: layers piled up over time with the title, range switch, actions and legend of the card.
- AvailabilityRowOne person's availability across a window of the day: an avatar with initials and the name, and a timeline with the busy periods drawn as bars.
- AvatarA person or organisation shown as a photo, initials or an icon.
- AvatarGroupA row of overlapping avatars with a "+N" chip for the rest.
- AvatarLabelAn avatar with a name and an optional subtitle beside it, for a person in a list, a header or a mention.
- BadgeShort status or category label: `Tone` x `Variant` x `Size`, with an optional dot, leading icon and remove button.
- BadgeGroupA pill that pairs a small badge with a short message, for an announcement or a status line.