ComponentsData display

Badge

A small label for status, counts, and metadata. Nine tones, a wrapping chip size, and a render prop for links and buttons.

Variants and sizes

Nine variants in the default pill and the wrapping chip size.

default
PinnedConnectedNeeds reviewRecommendedDraftWill be deletedComing soonNo statusView workflow
chip
Pinned · Brand guidelines 2026.pdfLeo Martins · leo@example.comNeeds your input · Approve a refund over $500team-planning@group.calendar.example.comQualify an inbound leadPriya Nair · priya.nair@example.com · declinedMaya Chen · maya@example.com · acceptedNo statusbilling-runbook.md

Status in lists

Trailing status badges, with loading, empty, and error states supplied by the app.

  • ChatReplies in two channelsConnected
  • MailReads new mailInstalled
  • TrackerSearches one boardNeeds attention
  • DriveWaiting for an administratorNot granted
  • DocsNot supported in this regionUnavailable
  • FormsPlanned integrationComing soon
Agent tasks
TaskStatusStarted
Send reminders for invoices past 30 daysCollections assistantNeeds review4m ago
Book a kickoff with a new customerOnboarding guideCompleted1h ago
Tag this week's billing ticketsSupport triagePendingYesterday
Import supplier price listInventory watcherFailedToday
Draft quarterly reviewWeekly reporterIn progressToday

Icons and counts

Leading icons, counts inside controls, and an inline-end icon slot.

  • 3 added
  • 2 updated
  • Will be deleted
  • Adds video call
  • Notify guests
  • Don’t notify
  • Repeats
  • Private
  • Open

Chips

Chips wrap long values and hold avatars or removable content.

  • Maya Chen · maya@example.com · accepted
  • Adds Leo Martins · leo@example.com
  • Removes Priya Nair · priya.nair@example.com · declined
  • Qualify an inbound lead
  • Prepare a quarterly review with revenue, churn, and open risks
  • Handle a refund request
c_9f3a1e0b7d2c4a58b6e1f0d9a7c3b2e1@group.calendar.example.com

Overflow

Inner truncation in tight cells, with an outline count for hidden values.

UrgentBilling and invoicing enquiries from enterprise accountsWaiting on customer+2
Billing and invoicing enquiries12
No status12

In headings and status regions

Badges next to titles, in labels, and inside live status regions.

Brand guidelines 2026.pdfPinned

Contact detailsOptionalShared with guests

Send a reminder after three daysRecommended

Not yet applied

Rendered as links and buttons

The render prop swaps the element while keeping badge styles and focus.

Usage

Badge usageTSX
import { Badge } from "@tulipfarm/sprout/badge";
import { Check } from "reicon-react/icons/Check";

<Badge variant="success">
  <Check aria-hidden="true" />
  Connected
</Badge>
<Badge variant="secondary">Draft</Badge>
<Badge variant="outline" size="chip">
  maya@example.com · accepted
</Badge>

variant is "default", "success", "warning", "info", "secondary", "destructive", "outline", "ghost", or "link". The default tone follows --sprout-primary, so it turns green with the TulipFarm preset.

size="default" is a single-line pill. size="chip" grows in height and wraps long values such as email addresses or IDs. Direct child icons are sized to 12px. Mark an icon with data-icon="inline-start" or "inline-end" to tighten the padding on that side.

Render as another element

Badge renderTSX
import { Badge, badgeVariants } from "@tulipfarm/sprout/badge";

<Badge variant="link" render={<Link to="/workflows" />}>
  View workflow
  <ArrowUpRight data-icon="inline-end" aria-hidden="true" />
</Badge>

<a href="/docs" className={badgeVariants({ variant: "outline" })}>
  Docs
</a>

Badge renders a span. The Base UI render prop swaps the element for a link, a button, or your router's link. Links and buttons get hover tones, a focus ring, and pointer cursors. Plain spans stay static. badgeVariants() returns the same classes for elements you render yourself.

The element gets data-slot="badge", data-variant, and data-size for styling hooks. className, title, role, ARIA attributes, and ref pass through.

Content and overflow

A badge never grows wider than its container. In tight cells, wrap the text in a span with min-w-0 truncate and give the badge a min-w-0 flex parent. Show the full value in a title on the cell, and summarize hidden values with an outline count such as +2.

Accessibility

A badge is plain text. Its words must carry the meaning; color only adds emphasis. Mark decorative icons aria-hidden. For changes that color or strikethrough implies, add visually hidden text such as "Adds" or "Removes".

To announce status changes, put the badge in your own role="status" region. For a compact chip that needs a fuller name, use role="img" with an aria-label. Set aria-invalid to show an invalid value. Transitions last 120–180ms and stop when reduced motion is requested.

Loading spinners, empty messages, retry actions, and status mapping belong to your application. Sprõut supplies only the label.

Theme tokens

Badges use --sprout-primary-subtle, --sprout-secondary, --sprout-success, --sprout-warning, --sprout-info, --sprout-danger, and their -subtle pairs. Override them in light and dark modes like any other Sprõut token.