Badge
StableA small pill that labels a status, a count or a category. Reach for it when one or two words tell the merchant the state of something at a glance: Paid, Unfulfilled, 3 new.
Tones
The tone is the meaning. neutral is the default. The four status tones carry the same meaning everywhere in Orbit, so a merchant learns them once.
What each tone means
| Tone | Means | For example |
|---|---|---|
neutral | No judgement: not started, closed, or just a fact. | Draft, Cancelled, Archived |
accent | Orbit teal: what Orbit wants you to notice. New, live, a count asking for attention. Not a status. | New, Live, 3 |
positive | Done and good. Nothing to do. | Paid, Fulfilled, In stock |
negative | Something failed, or money went back out. | Payment failed, Refunded, Disputed |
warning | Needs the merchant soon, or money is still owed. | Unfulfilled, Low stock, Awaiting payment |
info | Worth knowing, nothing to do. | Click and collect, Scheduled, Pre-order |
Variants
Three materials. subtle is the default and is right for status. solid is for counts and the few states that must shout. outline is for categories and quiet flags that sit beside a status without competing with it.
When to use each
| Variant | Use it for |
|---|---|
subtle | Status in lists, rows and headers: a tinted pill with toned text. The default. |
solid | Counts, and strong states such as Overdue. A single digit becomes a circle. |
outline | Categories and quiet flags: Trade, Pre-order, VAT 20%, Sample data. |
In both themes
Every tone in every variant, light and dark side by side. In dark the washes deepen and the status hues lift, so toned text still reads as ink with a colour.
Sizes
md is 22px tall with 12px text, the default. sm is 18px with 11px text, for dense table rows and beside 13px text.
Dot and pulse
dot puts a small tone dot before the label. It helps the eye scan a column of mixed states by colour before reading, so use it for every badge in that column or none. pulse makes the dot send out a ring on a loop, like a transmission: only for states that are live right now.
With an icon
icon leads the label at 12px (11px at sm). Use one when the picture says something the word alone does not, such as how an order is being collected. The icon is decorative; the label still has to carry the meaning.
Counts
A badge whose only content is a number, or a string of digits such as "99+", is a count. A number is formatted the UK way ({1204} shows as 1,204); a string is shown as written. A solid count is compact, and a single digit becomes a circle. When the value changes the badge bumps once, never on first render. Press the buttons to see it.
Order statuses
The mapping for orders in Orbit Commerce's store dashboard. Pick the tone by what the merchant has to do next, not by how the word feels: warning when it needs them or money is still owed, negative when something failed or money went back out.
| Status and tone | Use it when |
|---|---|
Paidpositive | The money is in. Nothing to do. |
Awaiting paymentwarning | The customer still owes it: a bank transfer, an invoice or a payment link. |
Partially paidwarning | A deposit is in and the balance is still owed. |
Payment failednegative | The charge did not go through. Do not ship yet. |
Disputednegative | The customer's bank has opened a chargeback, and it needs a reply. |
Refundednegative | Money went back to the customer. A part refund says so: Partially refunded. |
Unfulfilledwarning | Paid and waiting to ship: the next job. |
Partially fulfilledwarning | Some items have shipped and the rest are waiting. |
Fulfilledpositive | Everything has shipped. Delivered works the same way. |
Click and collectinfo | How the order is reaching the customer. Useful to know, nothing to do. |
Draftneutral | A draft order that has not been sent or paid. |
Cancelledneutral | Closed. Nothing more will happen. |
Guidelines
- Sentence case, one or two words: "Unfulfilled", "Awaiting payment". Never all caps.
- Keep the same word for the same state across the dashboard, so a filter, a badge and a message agree.
- One status per column. A row can carry a payment badge and a fulfilment badge, each in its own column.
- Pulse only for live states (a store taking orders, a sync running). A pulse that never stops means nothing.
- A badge is a label, not a control. To filter by status, use a button or a segmented control.
Accessibility
- Renders a plain
span. Screen readers read its words in place, so the label must make sense on its own: the state, not a colour. - Dots and icons are hidden from assistive tech. Colour is never the only signal, because the label names the state.
- A count reads as just the number. Keep the words that give it meaning beside it ("Unfulfilled orders 7"), or add them in a visually hidden span with the
o-sr-onlyclass next to the badge. Text inside the badge would stop it being treated as a count. - A badge that needs explaining can sit inside a Tooltip. Give it
tabIndex={0}so keyboard users can reach it. - Under reduced motion the pulse breathes in place and counts change without the bump.
Props
Also accepts every native span attribute.
| Prop | Type | Default | Description |
|---|---|---|---|
tone | 'neutral' | 'accent' | 'positive' | 'negative' | 'warning' | 'info' | 'neutral' | What the badge means. Status tones are for status only. |
variant | 'subtle' | 'solid' | 'outline' | 'subtle' | Material: a tinted pill with toned text, a filled pill, or a hairline ring. |
size | 'sm' | 'md' | 'md' | 18px with 11px text, or 22px with 12px text. |
dot | boolean | false | A tone dot before the label: 6px, or 5px at sm. |
pulse | boolean | false | The dot sends out a ring on a loop. Live states only. Implies dot. |
icon | ReactNode | None | Leading icon, 12px (11px at sm). Decorative. |
children | ReactNode | None | The label. A number, or a string of digits such as "99+", is treated as a count. |