Badge
Small pill label for status, metadata, categories, and other compact read-only qualifiers across the dashboard.
Overview
Badge is one of the most common display primitives in the brand dashboard.
It is the default pill-style label for:
- entity and workflow status
- metadata qualifiers such as roles, categories, and types
- compact icon-plus-label chips in tables, cards, and panels
- short clickable pills in secondary interactions
The primitive itself is intentionally small:
- one required
label - optional
color - optional
IconorimageSrc - optional
onRemove - optional
onClick
Most of the meaning comes from the calling feature mapping domain values to badge labels and colors.
Basic Usage
import { Badge } from '@fsai/shared-ui';
<Badge label="Active" color="green" />
<Badge label="Pending Review" color="orange" />
<Badge label="Draft" color="gray" />With Icon Or Image
Use Icon for compact semantic reinforcement:
<Badge label="Registered" color="green" Icon="CircleCheck" />
<Badge label="Operations" color="blue" Icon="Suitcase" />Use imageSrc when the badge should show a tiny image or avatar-like thumbnail. imageSrc takes precedence over Icon.
<Badge
label="Jane Applicant"
imageSrc={leadAvatar}
color="white"
/>Colors
Badge does not have semantic variants like success or warning. Instead, product code maps business meaning to one of the supported badge colors:
| Color | Common usage |
|---|---|
gray | neutral labels, inactive states, metadata with low emphasis |
blue | informational states, categories, sections, typed labels |
green | success, healthy, active, completed |
orange | warning, pending, needs attention |
red | failure, blocked, expired, destructive state |
dark-red | stronger negative emphasis when the red palette needs more contrast |
purple | specialized categorization where purple is already part of the domain language |
black | very high-contrast pills on light surfaces |
white | neutral pills on colored or busy surfaces, or image-driven badges |
Keep these mappings close to the feature or domain config instead of scattering ad hoc inline choices everywhere.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Required badge text. |
color | 'blue' | 'gray' | 'orange' | 'red' | 'green' | 'dark-red' | 'black' | 'purple' | 'white' | gray | Visual color treatment. |
Icon | IconName | ComponentType<SVGAttributes<...>> | — | Optional leading icon. Ignored when imageSrc is present. |
imageSrc | string | null | — | Optional leading image thumbnail. |
className | string | — | Additional classes for spacing, hover treatment, or local layout tweaks. |
onClick | MouseEventHandler<HTMLSpanElement> | — | Optional click handler. Adds pointer cursor, but the root remains a span. |
style | CSSProperties | — | Inline styles on the root. |
onRemove | () => void | — | Shows a trailing remove control. |
removeIcon | IconName | CrossSmall | Override for the remove icon when onRemove is provided. |
Common Usage Patterns
Status Badge
The most common pattern is a small mapping helper:
const PROJECT_STATUS_CONFIG = {
active: { label: 'Active', color: 'green' },
paused: { label: 'Paused', color: 'orange' },
archived: { label: 'Archived', color: 'gray' },
} as const;
<Badge
label={PROJECT_STATUS_CONFIG[status].label}
color={PROJECT_STATUS_CONFIG[status].color}
/>This keeps label and color decisions consistent across tables, panels, and cards.
Metadata Pill
For roles, types, categories, and other qualifiers, badges are often neutral or lightly emphasized:
<Badge label="Operations" color="blue" Icon="Suitcase" />
<Badge label="Pending Invite" color="orange" />Clickable Secondary Badge
Some screens use Badge as a small clickable affordance:
<Badge
label={lead.name}
imageSrc={lead.imageSrc}
color="white"
onClick={() => openLeadPanel(lead.id)}
className="hover:bg-gray-bg-accent transition"
/>This is acceptable for secondary interactions, but Badge is still not a native button component.
One important use case is related-entity navigation in dense surfaces such as panel headers, where the badge gives a compact way to jump to the linked entity without adding a larger row or card.
Brand Dashboard Usage Patterns
Representative usages:
| Pattern | Path | Notes |
|---|---|---|
| Table status chip | fsai/apps/brand-dashboard/src/pages/Projects/components/ProjectsTable.tsx | Canonical domain-config-driven status badge in a DataTable column. |
| State and compliance status | fsai/apps/brand-dashboard/src/pages/States/States.components.tsx | Strong example of mapping business states to badge color and icon. |
| Workflow status | fsai/apps/brand-dashboard/src/pages/Workflows/WorkflowRunPanel.tsx | Uses a badge in a panel header to show operational state. |
| Team and invite metadata | fsai/apps/brand-dashboard/src/pages/OrganizationSettings/OrganizationSettingsTeam/OrganizationSettingsTeam.tsx | Uses badges for roles and invite lifecycle labels. |
| Finder and analytics results | fsai/apps/brand-dashboard/src/pages/Marketing/Finder/FinderResultsTable.tsx | Shows status and quality badges inside dense result tables. |
| Event type badges | fsai/apps/brand-dashboard/src/pages/EmailAnalytics/EventsList.tsx | Small categorical badges in analytics/event streams. |
| Clickable lead pill | fsai/apps/brand-dashboard/src/pages/Deals/Deals.tsx | Demonstrates imageSrc, color="white", and onClick for a secondary navigation affordance. |
| Section metadata | fsai/apps/brand-dashboard/src/pages/Projects/ProjectDetail/PhaseView/PhaseView.primitives.tsx | Uses icon-plus-label badge as compact structural metadata. |
Important Conventions
Badgeis a generic display primitive. It does not know your domain statuses by itself.- Prefer a small config object or helper to map domain values to badge
label,color, and optionalIcon. imageSrcoverridesIcon.- The root element is a
span, not abutton. If the badge becomes a meaningful action, make sure the interaction remains accessible. - Long labels truncate inside the pill, so keep labels short and stable.
- Some features use specialized badge-like components such as
VendorTypeBadge,InlineEntityManager.Badge, or other local wrappers. Use the primitiveBadgewhen you need the generic platform pill rather than a domain-specific abstraction. - For cross-linking to related entities,
Badgeis best when the relationship is secondary metadata. Use a real button or richer row/card when the relationship is more important than a compact pill can comfortably express.
Guidelines
- Do use
Badgefor short status and metadata labels in lists, tables, cards, and panels - Do centralize color-and-label mappings for business enums
- Do keep labels short enough to survive narrow columns
- Do use an icon when it adds meaning, not just decoration
- Don't treat
Badgeas a primary action control - Don't invent ad hoc pill styles when the standard badge already fits