Badge
Badges display a short status, category, or count next to the resource they describe.
Example
Usage
Variants
Pick the variant by what the badge communicates:
subtle(default): neutral information.info: draws attention without a positive or negative tone.success: a positive or successful state.warning: a state that needs attention soon.error: negative or immediately concerning information.upsell: billing plans and features a customer can unlock.ghost: an uninitialized state.accent: review and approval states, like a pending approval.dark: a badge on top of media, like an image or a video.
Dark
Use the dark variant for a label on top of media, like a status or a media type on a creative. The dark background keeps the label legible on any content. Do not use it on the page canvas. For a video's length, use HtVideo's showDuration instead of placing a badge yourself.
Sizes
Use md, the default, for most badges. Use sm inside dense rows, buttons, and media tiles. Use lg next to large headings.
Shape
Badges are pill-shaped by default. Use shape="rectangle" to match square-cornered neighbors, like a table cell or a tag list.
Use shape="circle" for an icon-only badge. It needs svgIcon, iconSrc, or progress, and does not render children. Pass aria-label when the icon carries meaning.
Icons
Add an icon only when it makes the label clearer. Do not use icons for decoration.
Use iconColor only when a different icon color carries meaning.
Use iconSrc for integration logos.
Pending
Use isPending for a tentative or not-yet-final state. It adds a dashed border to any variant.
Progress
Use progress while work is running. It replaces svgIcon and iconSrc and takes the variant's text color. Pass "indeterminate" when there is no value to report, or a number from 0 to 100.
Numbers
Use textVariant="numeric" for numbers that change in place, like durations and counts. Tabular digits keep the badge width steady as the value changes.
A small numeric badge also works as a count inside a button.
Truncation
Long labels truncate with an ellipsis when the badge runs out of room.
Actions
Use rightActionProps to add an action, like remove, after the label.
As a button
Use BadgeButton when the whole badge is clickable. It renders a button, so it is keyboard focusable and announced as a button.
Groups
Use BadgeGroup to show several badges on one line. Badges that do not fit are hidden, so they also leave the tab order and the accessibility tree. The "+N" button lists them in a popover.
Pass the children's variant and size to BadgeGroup too, so the "more" button matches them.
The overflow popover renders in a portal by default. Pass removePortal to render it in place.
Pass truncate={false} when the container has room for every badge and nothing needs to collapse.
Combinations
Guidelines
When to use
- When displaying a short category, status, or count next to the resource it describes.
- When labeling media, such as a creative's status or type, with the dark variant. Keep dark badges off the page canvas.
When not to use
- If conveying live operational state rather than a category, use a status indicator instead.
- If showing a video's length, use
HtVideo'sshowDurationinstead. - If the user enters or removes values in a field, use a badge input instead.
Placement
Put a badge immediately after the resource it describes.
Content
Keep labels to one or two words.
Props
Badge
Inherits margin props.
| Name | Default | Description |
|---|---|---|
variant | "subtle" | "subtle"
| "info"
| "success"
| "warning"
| "error"
| "upsell"
| "ghost"
| "accent"
| "dark"Badge variant determines the purpose it is used for, and it's appearance. |
size | "md" | "sm" | "md" | "lg"Determines the size of the badge. |
isPending | false | booleanWhen true, renders the badge with a dashed border to indicate a
tentative or not-yet-finalized state. Combines with any variant. |
progress | — | number | "indeterminate"Renders a progress indicator in the left icon slot. Pass a number
0–100 for determinate progress, or "indeterminate" to render a
spinner. Replaces svgIcon/iconSrc while active. Combines with
isPending and any variant. |
svgIcon | — | ComponentType<SVGAttributes<SVGElement>>Badge icon that's displayed on the left.
Can be either a component or an object with props to override defaults. |
iconSrc | — | stringURL for an image icon. |
iconColor | — | ColorOverride the default icon color. |
textVariant | — | undefined | "numeric" | "monospace"Text style for the label. Use "numeric" for values that change in place,
like durations and counts, so digits keep a fixed width. |
rightActionProps | — | IconButtonProps & Record<`data-${string}`, string>Right action configuration. |
aria-label | — | stringAccessible name for the badge, for icon-only or progress badges whose
meaning isn't carried by visible text. The badge renders as role="img"
so the label is valid (a plain span can't carry aria-label).
Mutually exclusive with rightActionProps: the img role would hide
the action from assistive tech. |
shape | — | "rectangle" | "circle"Determines the shape of the badge. Use "circle" to render an
icon-only circular badge (requires svgIcon, iconSrc, or
progress). |
children | — | ReactNodeBadge text. |
BadgeGroup
Wraps a set of Badge components and collapses the ones that do not fit.
Inherits margin props.
| Name | Default | Description |
|---|---|---|
truncate | true | booleanDisplay as much badges as possible on a single row and show the rest in a popover. |
removePortal | false | booleanDetermines if the popover content is rendered in a portal. |
variant | "subtle" | "subtle" | "info" | "success" | "warning" | "error" | "upsell" | "ghost" | "accent" | "dark"Determines the appearance of the "more" button, if applicable. Use the same variant as the group's children badges. |
size | "md" | "sm" | "md" | "lg"Determines the size of "more" button, if applicable. Use the same size as the group's children badges. |
children | — | ReactNodeBadges. |