jengacore.shadcn registry · Tailwind v4 · Radix and Base UI
Components
shadcn, restyled · @jengacore/badge

Badge

Tones success, warning, danger, info, neutral, outline and brand. Accepts the shadcn `variant` names too.

SettledPendingRejectedIn reviewDraftGoods not receivedIn progress

Install

terminal
npx shadcn@latest add @jengacore/badge

Without the namespace configured: npx shadcn@latest add https://ui.jengacore.com/r/<new-york-v4|base-nova>/badge.json

Registry dependencies

npm packages

class-variance-authority

Source

components/ui/badge.tsx
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"

/**
 * jengacore Badge. Status is always icon + word (use StatusBadge for domain statuses);
 * colour is never the only signal. `variant` keeps the shadcn API, `tone` is the jengacore one.
 */
const badgeVariants = cva(
  "inline-flex h-[22px] w-fit shrink-0 items-center gap-[5px] overflow-hidden rounded-sm px-[7px] text-xs font-medium whitespace-nowrap [&>svg]:pointer-events-none [&>svg]:size-3 [&>svg]:stroke-2",
  {
    variants: {
      tone: {
        neutral: "bg-muted text-foreground/85",
        success: "bg-success-subtle text-success",
        warning: "bg-warning-subtle text-warning",
        danger: "bg-destructive-subtle text-destructive",
        info: "bg-info-subtle text-info",
        /** Brand label that is not a status (a role, a module, "Recommended"). */
        primary: "bg-secondary text-secondary-foreground",
        outline: "border border-border text-muted-foreground contrast:border-input",
        ghost: "text-muted-foreground",
        link: "text-primary underline-offset-4 hover:underline",
        /** Deck and marketing tag ("IN PROGRESS"). Not for system status. */
        brand: "bg-forest-900 px-2 text-[11px] font-semibold tracking-[0.06em] text-white uppercase",
      },
    },
    defaultVariants: { tone: "neutral" },
  }
)

type Tone = NonNullable<VariantProps<typeof badgeVariants>["tone"]>

/** The tone names, for status dictionaries that map a word to a tone. */
export type BadgeTone = Tone

/** shadcn variant names, mapped onto jengacore tones. */
const VARIANT_TONE: Record<string, Tone> = {
  default: "neutral",
  secondary: "neutral",
  destructive: "danger",
  outline: "outline",
  ghost: "ghost",
  link: "link",
}

function Badge({
  className,
  tone,
  variant,
  ...props
}: React.ComponentProps<"span"> &
  VariantProps<typeof badgeVariants> & {
    variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | null
  }) {
  const resolved = tone ?? (variant ? VARIANT_TONE[variant] : undefined)
  return (
    <span
      data-slot="badge"
      data-tone={resolved ?? "neutral"}
      className={cn(badgeVariants({ tone: resolved }), className)}
      {...props}
    />
  )
}

export { Badge, badgeVariants }