Badge
Badges attach a small count, label, or status indicator to another element.
Use the Badge component to annotate an element, such as an avatar or icon, with a count or status. Badge wraps its children and positions the indicator on a corner.
Without children, Badge renders as an inline label. anchorOrigin and
anchorOverlap and anchorOffset apply only when the badge wraps an element. Text stays on one
line, and the indicator grows to fit its content with padding.
Import
import { Badge } from "@puzzle-ui/ui";Basic usage
Pass the indicator through content and the element to annotate as children.
Color
Use color with a theme role (primary, secondary, accent, danger, info) or any hex value. For hex colors, the text color is chosen automatically for contrast. The default is primary.
Size
Use size to set the minimum width and height of the badge in pixels. The default is 20; values below 16 are raised to 16. The font size scales with it.
Position and overlap
Use anchorOrigin to choose the corner (vertical: top | bottom, horizontal: left | right). The default is top right. Set anchorOverlap="circular" when the child is round so the badge sits on the curve instead of the bounding-box corner.
Anchor offset
Use anchorOffset={{ vertical: 8, horizontal: 12 }} to move the indicator
in pixels from its normal anchor position. Positive values move inward from
the selected corner; negative values move outward. The default is zero on
both axes. Offsets work with rectangular and circular overlap and are ignored
for standalone labels.
API reference
Badge props
| Prop | Type | Default | Description |
|---|---|---|---|
content | ReactNode | — | Content of the badge, such as a count. Required. |
size | number | 20 | Minimum width and height in pixels. Values below 16 become 16. |
color | BadgeColor | "primary" | primary, secondary, accent, danger, info, or a hex string such as #7c3aed. |
anchorOrigin | { vertical: "top" | "bottom"; horizontal: "left" | "right" } | { vertical: "top", horizontal: "right" } | Corner where the badge is placed. |
anchorOffset | { vertical: number; horizontal: number } | { vertical: 0, horizontal: 0 } | Finite pixel offsets; positive moves inward, negative outward. |
anchorOverlap | "rectangular" | "circular" | "rectangular" | Positioning relative to a rectangular or round child. |
className | string | — | Additional CSS class names on the wrapper. |
children | ReactNode | — | Element the badge is attached to. |
TypeScript types
The component exports BadgeProps, BadgeColor, AnchorOrigin, AnchorOffset and AnchorOverlap.
Theming
Role colors use the --puzzle-color-<role> and --puzzle-color-<role>-foreground tokens, so badges follow light, dark, and scoped themes. The default palette uses distinct colors for each role; custom themes can choose their own. Hex colors bypass the theme.
Accessibility
Badge does not add any ARIA semantics. Screen readers read content as plain text next to the child, so for status dots or ambiguous counts, convey the meaning in the child's accessible name (for example aria-label="Inbox, 4 unread").