Badge

Product state label: new, sale, bundle, low stock, verified. Optional live dot.

ui
$npx shadcn@latest add @storekit/badge
badge

Live and interactive. Switch the brand in the frame header to see the same source under another token file.

Installation

$npx shadcn@latest add @storekit/badge
$pnpm dlx shadcn@latest add @storekit/badge
$yarn dlx shadcn@latest add @storekit/badge
$bunx --bun shadcn@latest add @storekit/badge

Source

components/storekit/ui/badge.tsx
40 lines
import { cn } from "@/components/storekit/lib/cn"

/* Small label for product state: new, sale, bundle, low stock, verified. */

type Tone = "neutral" | "accent" | "sale" | "success" | "ink" | "outline"

const tones: Record<Tone, string> = {
  neutral: "bg-sk-surface text-sk-ink",
  accent: "bg-sk-accent text-sk-accent-ink",
  sale: "bg-sk-sale/[0.12] text-sk-sale",
  success: "bg-sk-savings/[0.12] text-sk-savings",
  ink: "bg-sk-ink text-sk-paper",
  outline: "border border-sk-line text-sk-muted",
}

export function Badge({
  tone = "neutral",
  dot,
  className,
  children,
}: {
  tone?: Tone
  dot?: boolean
  className?: string
  children: React.ReactNode
}) {
  return (
    <span
      className={cn(
        "inline-flex items-center gap-1.5 rounded-sk-chip px-2 py-0.5 text-[11px] font-semibold uppercase leading-5 tracking-[0.06em]",
        tones[tone],
        className
      )}
    >
      {dot ? <span className="relative flex h-1.5 w-1.5"><span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-current opacity-60" /><span className="relative inline-flex h-1.5 w-1.5 rounded-full bg-current" /></span> : null}
      {children}
    </span>
  )
}

Usage

Import from "@/components/storekit/ui/badge" and pass your product data. The demo above exercises the full prop surface with sample values.

Badge, StoreKit