5.2 KiB
Badge
(no submodules)
- badge.variants — `badgeVariants` is the cva config……-
badge.variants —
badgeVariantsis the cva config that powers the<Badge>chassis component. It exposes avariantaxis with four ru… -
badge.variants —
badgeVariantsis the cva config…… -
badge.variants —
badgeVariantsis the cva config that powers the<Badge>chassis component. It exposes avariantaxis with four ru… -
badge.variants —
badgeVariantsis the cva config…… -
badge.variants —
badgeVariantsis the cva config that powers the<Badge>chassis component. It exposes avariantaxis with four ru… -
badge.variants —
badgeVariantsis the cva config… -
badge.variants —
badgeVariantsis the cva config that powers the<Badge>chassis component. It exposes avariantaxis with four ru… -
badge.variants —
badgeVariantsis the cva config that powers the<Badge>chassis component. It exposes avariantaxis with four ru…
Purpose
<Badge> is the chassis typographic marker for @suaveplan/react-ui. It renders a small inline-flex <div> with rounded ends, semibold tracking, and one of four colour variants (default / secondary / destructive / outline). Per the shadcn skill rule, Badge should be used in place of custom styled spans for status markers, category labels, count indicators, and any other inline emphasis — hand-rolling <span className="rounded-full bg-green-100 ..."> produces a styled element with no theme awareness, no focus management, and no consistency with the rest of the surface.
The chassis surface is deliberately minimal: no size axis (badges inherit text size from the surrounding context), no internal text (children are consumer-provided), and no icon prop (icons are passed as children alongside a label). For status indicators that pair a semantic colour with iconography, use <StatusBadge> instead.
Features
- Four colour variants via the
variantaxis (default/secondary/destructive/outline). transition-colors+motion-reduce:transition-noneso reduced-motion users see instant colour changes.- Focus ring scoped to the badge element so it works when wrapped in an anchor or button.
- Hover state on filled variants — outline variant remains decorative.
- Forwards refs to the underlying
<div>. - Theme variant overrides via
useThemedVariants("Badge", badgeVariants)— aThemePluginmay add brand-new variants (e.g.variant: "premium").
Usage: Basic Example
import { Badge } from "@suaveplan/react-ui";
export function NewLabel() {
return <Badge variant="secondary">New</Badge>;
}
Usage: Advanced Example
import { Badge } from "@suaveplan/react-ui";
import { SparklesIcon } from "lucide-react";
export function FeatureFlag() {
return (
<Badge variant="outline" className="gap-1">
<SparklesIcon className="size-3" />
Beta
</Badge>
);
}
API Reference
<Badge>
forwardRef<HTMLDivElement, BadgeProps> — renders a <div> with the variant classes + consumer-supplied className merged via cn().
BadgeProps
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
"default" | "secondary" | "destructive" | "outline" |
"default" |
Colour treatment — primary fill, secondary fill, destructive fill, or transparent outline. |
all HTMLAttributes<HTMLDivElement> |
native | native | Forwarded as-is — aria-label, id, style, data-*, etc. |
badgeVariants
The bare cva resolver — exported so external consumers (themes, ejected source) can re-use the variants directly.
Errors
The Badge component does NOT call useTranslation() so it does not interact with the i18n provider. It is safe to render outside a <TranslationProvider> / <ReactUiProvider>.
Implementation Notes
- Badges are typographic markers and inherit text size from their parent. The chassis intentionally does NOT expose a
sizeaxis — consumers wanting larger markers should compose a<Badge>inside a sized container or reach for<StatusBadge>(which has its own iconography and semantic colour scale). inline-flex items-centeris set so badges can contain an icon + label child pair without consumer flex setup. Agap-1className is the conventional spacing when an icon is present.- The outline variant intentionally has no
hover:treatment because it is decorative — applying a hover background would imply interactivity the badge does not have. - The
rounded-fullrule produces the pill shape; combined with the smallpx-2.5 py-0.5andtext-xs font-semibold, the badge reads as a marker rather than a button. - Because the rendered element is a
<div>, badges nested inside paragraphs may produce invalid HTML in strict-mode renderers — wrap text-flow badges in a<span>(e.g.<p>Hello <span><Badge>New</Badge></span></p>). The chassis leaves this composition decision to the consumer rather than hardcoding a<span>(which loses the focus ring fortabIndex={0}use cases).