Files
skills/docs/ui/react/react-ui/src/components/badge/badge.md
2026-05-29 08:20:56 +01:00

5.2 KiB

Badge

(no submodules)

- badge.variants — `badgeVariants` is the cva config……
  • badge.variants — badgeVariants is the cva config that powers the <Badge> chassis component. It exposes a variant axis with four ru…

  • badge.variants — badgeVariants is the cva config……

  • badge.variants — badgeVariants is the cva config that powers the <Badge> chassis component. It exposes a variant axis with four ru…

  • badge.variants — badgeVariants is the cva config……

  • badge.variants — badgeVariants is the cva config that powers the <Badge> chassis component. It exposes a variant axis with four ru…

  • badge.variants — badgeVariants is the cva config…

  • badge.variants — badgeVariants is the cva config that powers the <Badge> chassis component. It exposes a variant axis with four ru…

  • badge.variants — badgeVariants is the cva config that powers the <Badge> chassis component. It exposes a variant axis 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 variant axis (default / secondary / destructive / outline).
  • transition-colors + motion-reduce:transition-none so 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) — a ThemePlugin may 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 size axis — 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-center is set so badges can contain an icon + label child pair without consumer flex setup. A gap-1 className 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-full rule produces the pill shape; combined with the small px-2.5 py-0.5 and text-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 for tabIndex={0} use cases).