Badge
A short, non-interactive label that states what something is or how it stands.
A badge answers one question about the thing beside it, paid, overdue, draft, twelve, in the
smallest space that can still be read. It is a <span>: no pointer, no focus, no pressed state,
so it belongs inside the row, heading or cell that already carries the meaning.
That is what separates it from its siblings. Chip is a token the reader can press or remove,
Avatar stands in for an entity, and a badge only describes one. Chip and Badge share a
vocabulary of treatments; only the chip is a control.
Usage
import { Badge } from "@asheeui/web";
<Badge color="success">Paid</Badge>
children is the badge's text and its accessible name at once. startContent and endContent
put a node either side of it, an icon, a glyph, and a count is content rather than a prop:
<Badge>12</Badge> is the whole of it.
Treatments and colour
Four treatments, and no underlined: a badge has no baseline for a line to sit on and no
pointer for an underline to invite. solid is a filled accent surface, faded a tint of it,
bordered its outline, and ghost the bare text. The framework's own treatment is faded,
which is what makes a badge read as a quiet annotation rather than as a button nobody can press.
Colour is a role rather than a hex value, primary, secondary, success, warning,
danger, and treatment and role are resolved together, because a badge's emphasis comes from
the pair. A faded success badge is an annotation that the thing is fine; a solid one says
it loudly. The preview above shows one role per condition, all at the framework's treatment.
An icon without text
An icon-only badge has no visible text to be named by, so label states the name assistive
technology reads while the icon and the markup beside it are treated as decoration. A badge
with visible text needs nothing: its text is already its name.
label is not a tooltip and is never drawn on screen, it stands in for the content as the
badge's name. It is therefore a statement about a badge with no text: give a badge both and the
visible content is what is shown and announced, and the label is ignored. Where the badge is the
only place a condition appears, give it text instead.
Props
size and radius are registered by the component as md and full; variant and color
are deliberately not, so they resolve from the application's defaultVariant (faded) and
defaultColor (primary), and a page that configures nothing still gets the framework's quiet
badge. Because radius is registered, full beats the application's defaultRadius: a badge
is a pill in a boxy product too, unless components.badge.radius or the instance says
otherwise.
The treatment the cascade produces is landed on one a badge can draw, so an application whose
defaultVariant is underlined gets bordered badges rather than none, the same rule Chip
follows.
children, label, startContent and endContent are instance-only, because they state the
fact being reported rather than the design it is drawn with.
Accessibility
- The element is a
<span>, so it is not in the tab order and has no role of its own: nothing about it can be pressed or focused, and it is read as text in the flow where it was written. - A badge with visible text is named by that text.
labelis for the case with none: it becomes the accessible name while the icon decoration is hidden. When both are given the visible content wins, the label is not rendered, and a development warning explains, because a name that contradicts the text beside it is worse than no name at all. - There is no live region: a badge that changes after the page has loaded is not announced because it changed. Announce the change in the surrounding text, or through the framework's toast.
- Colour is never conveyed to assistive technology, so the text has to stand on its own,
Overdue, not3.