Skip to contentAsheeUIAsheeUI

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. label is 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, not 3.