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.
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
| Task | Status | Started |
|---|---|---|
| Send reminders for invoices past 30 daysCollections assistant | Needs review | 4m ago |
| Book a kickoff with a new customerOnboarding guide | Completed | 1h ago |
| Tag this week's billing ticketsSupport triage | Pending | Yesterday |
| Import supplier price listInventory watcher | Failed | Today |
| Draft quarterly reviewWeekly reporter | In progress | Today |
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 · [email protected] · accepted
- Adds Leo Martins · [email protected]
- Removes Priya Nair · [email protected] · declined
- Qualify an inbound lead
- Prepare a quarterly review with revenue, churn, and open risks
- Handle a refund request
Overflow
Inner truncation in tight cells, with an outline count for hidden values.
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
Rendered as links and buttons
The render prop swaps the element while keeping badge styles and focus.
Usage
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">
[email protected] · 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
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.