Skip to content
hightouchUI

Design system

b082b00

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

Default
Pending
Icon
Progress
Rectangle
Circle
Subtle
Label
Label
Label
Label
Label
Info
Label
Label
Label
Label
Label
Success
Label
Label
Label
Label
Label
Warning
Label
Label
Label
Label
Label
Error
Label
Label
Label
Label
Label
Upsell
Label
Label
Label
Label
Label
Ghost
Label
Label
Label
Label
Label
Accent
Label
Label
Label
Label
Label
Dark
Label
Label
Label
Label
Label

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's showDuration instead.
  • 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.

NameDefaultDescription
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.
isPendingfalsebooleanWhen 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.

NameDefaultDescription
truncatetruebooleanDisplay as much badges as possible on a single row and show the rest in a popover.
removePortalfalsebooleanDetermines 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.