codefast/ui

Command Palette

Search for a command to run...

Source
Display

Badge

Compact label for status, category, or count. Four variants cover most use cases.

Examples

Variants

Five styles for status, category, and emphasis.

DefaultSecondaryDestructiveOutlineGhost
13 lines
import { Badge } from "@codefast/ui/badge";

export function BadgeVariants() {
  return (
    <div className="flex flex-wrap gap-2">
      <Badge>Default</Badge>
      <Badge variant="secondary">Secondary</Badge>
      <Badge variant="destructive">Destructive</Badge>
      <Badge variant="outline">Outline</Badge>
      <Badge variant="ghost">Ghost</Badge>
    </div>
  );
}

Custom Colors

You can customize the colors of a badge by adding custom classes such as bg-green-50 dark:bg-green-800 to the Badge component.

BlueGreenSkyPurpleRed
13 lines
import { Badge } from "@codefast/ui/badge";

export function BadgeCustomColors() {
  return (
    <div className="flex flex-wrap gap-2">
      <Badge className="bg-blue-50 text-blue-700 dark:bg-blue-950 dark:text-blue-300">Blue</Badge>
      <Badge className="bg-green-50 text-green-700 dark:bg-green-950 dark:text-green-300">Green</Badge>
      <Badge className="bg-sky-50 text-sky-700 dark:bg-sky-950 dark:text-sky-300">Sky</Badge>
      <Badge className="bg-purple-50 text-purple-700 dark:bg-purple-950 dark:text-purple-300">Purple</Badge>
      <Badge className="bg-red-50 text-red-700 dark:bg-red-950 dark:text-red-300">Red</Badge>
    </div>
  );
}

With Icon

You can render an icon inside the badge. Use data-icon='inline-start' to render the icon on the left and data-icon='inline-end' to render the icon on the right.

VerifiedBookmark
17 lines
import { Badge } from "@codefast/ui/badge";
import { BadgeCheck, BookmarkIcon } from "lucide-react";

export function BadgeWithIconLeft() {
  return (
    <div className="flex flex-wrap gap-2">
      <Badge variant="secondary">
        <BadgeCheck data-icon="inline-start" />
        Verified
      </Badge>
      <Badge variant="outline">
        Bookmark
        <BookmarkIcon data-icon="inline-end" />
      </Badge>
    </div>
  );
}

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

شارةثانويمدمرمخططمتحققإشارة مرجعية
62 lines
import { Badge } from "@codefast/ui/badge";
import { BadgeCheck, BookmarkIcon } from "lucide-react";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      badge: "Badge",
      secondary: "Secondary",
      destructive: "Destructive",
      outline: "Outline",
      verified: "Verified",
      bookmark: "Bookmark",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      badge: "شارة",
      secondary: "ثانوي",
      destructive: "مدمر",
      outline: "مخطط",
      verified: "متحقق",
      bookmark: "إشارة مرجعية",
    },
  },
  he: {
    dir: "rtl",
    values: {
      badge: "תג",
      secondary: "משני",
      destructive: "הרסני",
      outline: "קווי מתאר",
      verified: "מאומת",
      bookmark: "סימנייה",
    },
  },
};

export function BadgeRtl() {
  const { dir, t } = useTranslation(translations, "ar");

  return (
    <div className="flex w-full flex-wrap justify-center gap-2" dir={dir}>
      <Badge>{t.badge}</Badge>
      <Badge variant="secondary">{t.secondary}</Badge>
      <Badge variant="destructive">{t.destructive}</Badge>
      <Badge variant="outline">{t.outline}</Badge>
      <Badge variant="secondary">
        <BadgeCheck data-icon="inline-start" />
        {t.verified}
      </Badge>
      <Badge variant="outline">
        {t.bookmark}
        <BookmarkIcon data-icon="inline-end" />
      </Badge>
    </div>
  );
}

With Spinner

You can render a spinner inside the badge. Remember to add the data-icon='inline-start' or data-icon='inline-end' prop to the spinner.

DeletingGenerating
17 lines
import { Badge } from "@codefast/ui/badge";
import { Spinner } from "@codefast/ui/spinner";

export function BadgeWithSpinner() {
  return (
    <div className="flex flex-wrap gap-2">
      <Badge variant="destructive">
        <Spinner data-icon="inline-start" />
        Deleting
      </Badge>
      <Badge variant="secondary">
        Generating
        <Spinner data-icon="inline-end" />
      </Badge>
    </div>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

5 lines
import { Badge } from "@codefast/ui/badge";

export function BadgeUsage() {
  return <Badge>Badge</Badge>;
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

Badge

Features

  • Six variants — default, secondary, outline, destructive, ghost, link.
  • asChild renders the child element (e.g. a link) instead of a <span>.
  • A child marked data-icon="inline-start" or "inline-end" (an icon or a Spinner) gets matching spacing automatically, same convention as Button.

API reference

Props for each part of the component. All native element props are also forwarded.

Badge

Renders a <span>, or its child element when asChild is set.

variant"default" | "secondary" | "outline" | "destructive" | "ghost" | "link"

Visual style of the badge.

Default"default"

asChildboolean

Merge props onto the single child — e.g. an <a> — instead of a <span>.

Defaultfalse

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

  • A badge is decorative text by default and needs no role.
  • When a badge conveys status (e.g. “Error”), keep the meaning in the text, not colour alone.
  • When made interactive via asChild, ensure the child element is itself focusable (a link or button).

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Keep badge text to one or two words.
  • Use destructive/secondary variants to map to a consistent status scale.

Don’t

  • Don’t put long sentences or interactive controls inside a badge.
  • Don’t use a badge as the only signal for critical state.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.