Badge
Labels a value with a clinical status, using colour and a label together — never colour alone.
Installation
npx shadcn@latest add https://qure-ui.qure.ai/r/badge.jsonUsage
import { Badge, BadgeDot } from '@/components/ui/badge'<Badge tone="urgent"><BadgeDot /> Critical</Badge>A badge describes the thing next to it. It is not a control: it has no focus ring, no pressed state and no hit target worth the name, so a badge that filters a worklist when clicked is a button wearing the wrong clothes. If it does something, make it a Button; if it merely says something, this is the component.
Tone
tone is the clinical axis and the only one that carries meaning. Everything else is
presentation.
| Tone | Means |
|---|---|
neutral | No judgement — a category, a filter, a label |
brand | In progress, assigned, ours |
success | Done, cleared, within range |
attention | Needs someone, but not now |
urgent | Needs someone now |
Pick the tone from what the reader should do about it, not from how the word feels. "Rejected"
sounds bad and is often neutral: the study has left the queue and needs nobody.
Variant
Fill weight, holding the tone's colour. Soft is the default, matching Figma — a column of solid urgent tags turns a worklist red and stops any single one of them being urgent. Keep solid for the one row in fifty that has to break out of the page, and use outline where badges sit on an already-tinted surface and a soft fill would disappear into it.
Size
24px and 20px. md is the default; drop to sm inside dense table rows, where a 24px chip
forces the row height up for the sake of one word.
With an icon
BadgeDot is composed rather than injected, so a badge can carry an icon instead. An icon is
worth the space when it distinguishes two statuses of the same tone — a clock for "past SLA"
against a triangle for "critical" — and is noise when it just restates the word.
In a worklist
| Accession | Study | Status |
|---|---|---|
| ACC-482913 | CT Chest | Critical |
| ACC-482910 | Chest X-ray | Past SLA |
| ACC-482904 | CT Head | In review |
| ACC-482891 | Chest X-ray | Signed |
The place badges actually live. One badge per row, in its own column, at sm, all of them the
same variant so the tone is the only thing varying — that is what makes the red row findable
when there are forty of them.
Never colour alone
Roughly 1 in 12 men has a red-green deficiency, and a reporting monitor is calibrated for images rather than for UI. Every badge should survive its colour being removed, which is what the label and the dot are for.
A dot with no text is not a badge, it is a decoration. If the status can only be read from the colour of a circle, nobody in greyscale and nobody using a screen reader can read it at all.
API Reference
No primitive behind it — a span with everything a span accepts, plus:
Prop
Type
BadgeDot takes no props of its own. It is aria-hidden, 6px, and coloured by currentColor,
so it follows whichever tone the badge is wearing.