Badge

A compact label for status, counts, and categories. Single-element like Button; status variants are soft tints derived from semantic tokens, so they re-theme everywhere.

Online Betav2.4.0 main

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add badge

Usage#

usage.tsxTSX
import { Badge } from "@/components/ui/badge"export function Example() {  return <Badge>New</Badge>}

Playground#

The whole control set is derived from the component’s recipe: change a tone or add a size and this follows on its own. Note that dismissal isn’t a flag but a handler, so the trailing button exists exactly when onRemove does.

In review
Playground
Props

The tone. Soft fills for status, solid for emphasis.

Fully rounded instead of the control radius.

The house default for a status badge.

Adds a trailing dismiss button via onRemove.

badge.tsxTSX
<Badge>In review</Badge>

Variants#

DefaultPrimarySecondaryOutline

Status#

Soft status variants pair a tinted background (the status hue at /10) with a darker text counterpart and no border, so the fill carries the color while the label stays legible. Both derive from one semantic token (--success, --warning, --info), so they re-theme across all four themes.

Approved Merged In review Pending Failed Running Skipped

Categorical#

Four extra hues for labeling categories, feature flags, and tags. All follow the same soft-tint pattern and re-theme across all four themes.

Beta New Featured DesignEngineeringFrontendDeprecated v1 Legacy

With dot#

The dot prop adds a leading status dot in the variant color - ideal for presence and at-a-glance state. The background is stripped so only the dot carries the color.

OnlineAwayBusyOfflineIn a callFocusedOn breakDo not disturb

Toggling the dot#

Drive dot from state and the change animates: the dot grows in and pushes the label over, the tint gives way to the hairline, and the label settles on foreground. Turning it off plays the same thing in reverse, back to the tinted badge. A badge that never passes dot renders no dot at all.

OnlineSyncingFocused

Custom color#

When the color arrives with the data (a dispatch call code with its category hex, a team, a label a user picked), pass it as color. The variant still picks the treatment: any page-ground tone gives the soft tint, with the label pulled toward the theme's foreground so a pale yellow still reads; primary (or secondary) gives a solid fill whose ink is chosen from the color itself, near-black on a light fill and white on a dark one; outline draws the hairline in the color. With dot the dot takes it.

10-3110-5010-1610-6010-9110-99
RobberyTrafficMedicalShots firedUnits free10-16

The ink is read from hex (#rgb, #rrggbb, with or without alpha) and rgb(); any other form (a named color, hsl(), a var()) paints fine but gets white ink, so prefer hex for solid badges. The same choice is exported as readableInk(color), returning "dark" or "light", for your own surfaces.

Sizes#

OnlineOnlineOnlinev2.4.0v2.4.0v2.4.0

Pill#

Set pill for fully rounded edges - pairs well with dot and icon badges.

DefaultOnline Betav2.4.0

With icon#

Verified Beta New Featured Private feature/auth

Dismissible#

Pass onRemove to render a trailing dismiss button. Give each a descriptive removeLabel for screen readers.

DesignEngineeringMarketingResearch

As child#

Use asChild to render the badge styles on another element - e.g. a link - via Radix Slot.

API reference#

Badge

A single <span> that labels a status, count or category. Forwards all native <span> props; accepts className, merged last.

PropTypeDefaultDescription
variant"default" | "primary" | "secondary" | "outline" | "success" | "warning" | "info" | "destructive" | "purple" | "pink" | "teal" | "orange" | "overlay" | "overlayLight""default"The fill: neutral, solid, outline, a soft status tint, a categorical hue, or a dark or light glass for media.
size"sm" | "md" | "lg""md"Padding, type and icon size.
pillbooleanfalseFully rounded ends.
dotboolean-A leading dot in the current color; the fill gives way to a hairline. Passing a boolean (even false) keeps the slot mounted, so flipping it animates.
colorstring-Any CSS color. Paints the variant's treatment from it: a soft tint for the page-ground tones, a solid fill with a computed dark or white ink for primary / secondary, the hairline for outline; the dot takes it as is. Ignored by the overlay* fills. The root gets data-color and, when solid, data-ink (dark | light). The exported readableInk(color) returns that same pick.
onRemove() => void-Renders a trailing dismiss button that calls it.
removeLabelstring"Remove"The accessible label of the dismiss button. Name the item ("Remove Design").
asChildbooleanfalseRenders the badge styles onto its single child (Radix Slot), such as a link. Ignores dot and onRemove.

FAQ#

A Badge labels: it states status, a count, or a category and is not meant to be clicked. A Button performs an action. If a user is expected to interact, reach for Button (or a chip with an explicit control). The exception is asChild, which lets the badge styling wrap a link.