Pre-alphaThe registry and the CLI are not published yet.Roadmap

Badge

Status or counter pill.

Deployments

3

A

web · main2 min ago

Ready

api · fix/authBuilding for 48s

Building

docs · nextQueued

Queued

app · releaseFailed after 3m

Error

worker · v1Last week
Archived
edge · betaPreview

Preview

Installation

npx axiom add badge
pnpm dlx axiom add badge
yarn dlx axiom add badge
bun x axiom add badge

Colors come from badge.<variant>.default.{background,foreground,border} in the component tokens. Counters and dots use badge.count, whose border is the color of the ring.

Usage

import { Badge } from '@/components/ui/badge';

<Badge variant="success" dot>Ready</Badge>
<Badge count={3} />

Props

PropTypeDefaultDescription
childrenReactNode—The label. One or two words.
variant'neutral' | 'highlight' | 'info' | 'success' | 'warning' | 'error' | 'outline' | 'inverse''neutral'Color from the theme’s feedback colors: subtle background with a saturated label. highlight is the brand highlight fill; outline and inverse are neutral alternatives.
dotbooleanfalseSmall dot before the label in the label color, to reinforce a status.
iconIconName—Icon of your registry before the label. Replaces dot.
countnumber—Renders a round counter instead of a label, in feedback.error. 0 hides the badge.
maxnumber99Above this, the counter shows 99+.
size'sm' | 'md''md'Minimum height: 18 or 22pt.
ringboolean—For a counter or lone dot: a 2pt ring in badge.count.border around it, to detach it from what it sits on. Badge.Anchor turns it on for its badge; set it yourself to stack a counter on something without an anchor.
accessibilityLabelstring—For counters, what is counted: "3 unread notifications".
styleStyleProp<ViewStyle>—Extra styles for the pill.

Badge.Anchor

Positions a count or dot badge on the corner of another element.

The ring that detaches the badge from the element belongs to the badge, not to the anchor: the anchor turns on the badge’s ring through context. So the ring is only there when the badge is: <Badge count={0} /> renders nothing, ring included, and an animated badge carries its ring with it.

PropTypeDefaultDescription
childrenReactNode—The element to decorate: an IconButton, an Avatar.
badgeReactNode—The badge to place. Use count or dot. null shows none.
placement'top-right' | 'bottom-right''top-right'Corner.

The anchor doesn’t animate. It stays mounted when badge is null, so to animate the badge in and out, wrap it in an Animated.View with entering and exiting. The ring scales and fades with the badge:

import Animated, { ZoomIn, ZoomOut } from "react-native-reanimated";

<Badge.Anchor
	badge={
		online ? (
			<Animated.View entering={ZoomIn} exiting={ZoomOut}>
				<Badge dot />
			</Animated.View>
		) : null
	}
	placement="bottom-right"
>
	<Avatar name="Jane Cooper" />
</Badge.Anchor>;

Badges don’t handle presses. If the user can tap it to filter or remove it, use a Chip.

Use cases

Unread counter on an icon

Badge.Anchor with count on a navigation icon. The accessibility label says what the number means.

Home

12

<Badge.Anchor
	badge={
		<Badge count={unread} accessibilityLabel={`${unread} unread messages`} />
	}
>
	<IconButton icon="inbox" accessibilityLabel="Inbox" onPress={openInbox} />
</Badge.Anchor>

Order status

The variant carries meaning: success for delivered, warning for delayed. Keep the text, color alone isn’t enough.

Orders

#104823 items · $88.90

Delayed

#104311 item · $32.00

Delivered

#103882 items · $19.50

Refunded

const statusBadge = {
	delayed: (
		<Badge variant="warning" icon="clock">
			Delayed
		</Badge>
	),
	delivered: (
		<Badge variant="success" icon="check">
			Delivered
		</Badge>
	),
	refunded: <Badge variant="error">Refunded</Badge>,
};

Label on a card

A neutral or inverse badge on top of media to tag the content: “New”, “Live”, “Pro”.

LIVE

Launch keynote

Pro

12.4k watching
<Badge variant="error" dot>LIVE</Badge>
<Badge variant="inverse">Pro</Badge>