Badge
Atombeta@macaw-ds/ui · since 0.1.0A short, non-interactive status label such as Paid, Overdue or Draft. Not a button, not a counter.
Import
import { Badge, badgeVariants } from '@macaw-ds/ui';Props
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "neutral" | "success" | "warning" | "critical" | "info" | "accent" | neutral | Meaning. success for settled or active, warning for pending or attention, critical for failed or overdue, info for informational, accent for highlighted, neutral for draft or archived. |
| variant | "soft" | "solid" | "outline" | soft | Emphasis. soft (tinted) is the default in tables; solid for a single prominent status on a detail page; outline for the quietest option. |
| size | "sm" | "md" | md | 20 or 24 px tall. sm inside dense table rows. |
| dot | boolean | false | Leading dot in the tone colour, for live or state indicators. Accessibility: Decorative (aria-hidden). The text must still say the state. |
| children | ReactNode | Paid | The status word or two. |
Slots
Named parts you pass content into.
- children
Tokens used
Every value this component renders comes from one of these tokens.
| Token | Light | Dark |
|---|---|---|
| badge.radius component · dimension | 9999px | 9999px |
| badge.height.sm component · dimension | 20px | 20px |
| badge.height.md component · dimension | 24px | 24px |
| color.status.success-bg semantic · color | oklch(0.97 0.03 152) | oklch(0.24 0.05 152) |
| color.status.success-fg semantic · color | oklch(0.37 0.1 152) | oklch(0.88 0.1 152) |
| color.status.success-solid semantic · color | oklch(0.44 0.12 152) | oklch(0.68 0.15 152) |
| color.status.success-solid-fg semantic · color | oklch(1 0 0) | oklch(0.11 0.01 250) |
| color.status.success-line semantic · color | oklch(0.6 0.15 152) | oklch(0.5 0.14 152) |
| color.status.warning-bg semantic · color | oklch(0.98 0.03 80) | oklch(0.25 0.05 50) |
| color.status.warning-fg semantic · color | oklch(0.41 0.11 50) | oklch(0.9 0.12 80) |
| color.status.critical-bg semantic · color | oklch(0.97 0.02 27) | oklch(0.25 0.07 27) |
| color.status.critical-fg semantic · color | oklch(0.39 0.14 27) | oklch(0.88 0.08 27) |
| color.status.info-bg semantic · color | oklch(0.97 0.02 230) | oklch(0.24 0.05 230) |
| color.status.info-fg semantic · color | oklch(0.38 0.09 230) | oklch(0.88 0.07 230) |
| color.status.neutral-bg semantic · color | oklch(0.965 0.003 250) | oklch(0.21 0.012 250) |
| color.status.neutral-fg semantic · color | oklch(0.29 0.012 250) | oklch(0.925 0.005 250) |
| color.status.accent-bg semantic · color | oklch(0.97 0.02 262) | oklch(0.24 0.08 262) |
| color.status.accent-fg semantic · color | oklch(0.38 0.15 262) | oklch(0.88 0.08 262) |
| text.size.label-sm semantic · dimension | 0.75rem | 0.75rem |
| text.size.caption semantic · dimension | 0.6875rem | 0.6875rem |
Eject
Ejecting copies the source into your repo and records it in .macaw/ejected.json, so the fork stays visible. The same file is served as a shadcn-compatible registry item.
npx @macaw-ds/cli add badge --ejectnpx shadcn@latest add https://macaw-design-system.vercel.app/r/badge.jsonBundle budget: 2,500 bytes gzipped, enforced by size-limit in CI.
Manifest
registry/manifests/badge.json, the contract the playground, CLI, plugin and MCP server read.
{
"name": "Badge",
"slug": "badge",
"package": "@macaw-ds/ui",
"status": "beta",
"since": "0.1.0",
"level": "atom",
"category": "feedback",
"purpose": "A short, non-interactive status label such as Paid, Overdue or Draft. Not a button, not a counter.",
"description": "Status labels for records and rows. Six tones map to the status colour tokens; three variants trade emphasis for density. The text carries the meaning so colour is never the only signal.",
"exports": [
"Badge",
"badgeVariants"
],
"props": {
"tone": {
"type": "enum",
"values": [
"neutral",
"success",
"warning",
"critical",
"info",
"accent"
],
"default": "neutral",
"required": false,
"description": "Meaning. success for settled or active, warning for pending or attention, critical for failed or overdue, info for informational, accent for highlighted, neutral for draft or archived.",
"control": "select"
},
"variant": {
"type": "enum",
"values": [
"soft",
"solid",
"outline"
],
"default": "soft",
"required": false,
"description": "Emphasis. soft (tinted) is the default in tables; solid for a single prominent status on a detail page; outline for the quietest option."
},
"size": {
"type": "enum",
"values": [
"sm",
"md"
],
"default": "md",
"required": false,
"description": "20 or 24 px tall. sm inside dense table rows."
},
"dot": {
"type": "boolean",
"default": false,
"required": false,
"description": "Leading dot in the tone colour, for live or state indicators.",
"a11y": "Decorative (aria-hidden). The text must still say the state."
},
"children": {
"type": "node",
"default": "Paid",
"required": false,
"description": "The status word or two."
}
},
"slots": [
"children"
],
"tokens": [
"badge.radius",
"badge.height.sm",
"badge.height.md",
"color.status.success-bg",
"color.status.success-fg",
"color.status.success-solid",
"color.status.success-solid-fg",
"color.status.success-line",
"color.status.warning-bg",
"color.status.warning-fg",
"color.status.critical-bg",
"color.status.critical-fg",
"color.status.info-bg",
"color.status.info-fg",
"color.status.neutral-bg",
"color.status.neutral-fg",
"color.status.accent-bg",
"color.status.accent-fg",
"text.size.label-sm",
"text.size.caption"
],
"a11y": {
"role": "none (a span with text)",
"focusable": false,
"keyboard": [],
"name": "The text content. A badge has no role; it reads as part of the surrounding text.",
"notes": [
"Every tone pairing meets 4.5:1 for text in both themes.",
"Colour reinforces the word; it never replaces it. \"Overdue\" in critical, not a red dot alone.",
"Badges are not interactive. For a filter chip or a removable tag, a different component is needed (not in the system yet)."
]
},
"budget": {
"gzip": 2500
},
"rules": [
"The label is a word or two that states the status in plain language.",
"Tone follows meaning, not decoration: critical means failed or overdue, never \"important\".",
"One badge per status; do not stack badges to combine meanings."
],
"dos": [
"Use soft badges in tables and solid on a record's header.",
"Use dot with neutral for \"Draft\" and with success for \"Active\"."
],
"donts": [
"Do not make badges clickable; they have no role and no focus style.",
"Do not use badges as counters; a count is Text numeric."
],
"examples": [
{
"name": "Default",
"props": {
"children": "Paid",
"tone": "success"
}
},
{
"name": "Overdue",
"props": {
"children": "Overdue",
"tone": "critical"
}
},
{
"name": "Solid",
"props": {
"children": "Refunded",
"tone": "info",
"variant": "solid"
}
},
{
"name": "Outline",
"props": {
"children": "Draft",
"tone": "neutral",
"variant": "outline"
}
},
{
"name": "With dot",
"props": {
"children": "Active",
"tone": "success",
"dot": true
}
},
{
"name": "Small",
"props": {
"children": "Pending",
"tone": "warning",
"size": "sm"
}
}
],
"registryDependencies": [],
"dependencies": [
"class-variance-authority"
],
"related": [
"text"
]
}