Badge
shadcn-htmx/badgeFreeComponent
Small visual marker — status pill / counter / label. Six variants; renders as span (default) or anchor (with href).
Live preview
live · rendered by the registry
Rendered by shadcn-htmx on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://shadcn-htmx.productdevbook.com/r/badge.jsonSource
1/** @jsxImportSource hono/jsx */2import type { PropsWithChildren } from "hono/jsx"3import { cloneElement, isValidElement } from "hono/jsx"4import { cn, type ClassValue } from "@/registry/lib/cn"56// Badge — shadcn-htmx, htmx v4 + Tailwind v4.7//8// Source of truth (variants + base class 1:1):9// repos/shadcn-ui/apps/v4/registry/new-york-v4/ui/badge.tsx10//11// A non-interactive visual marker. Renders as <span> by default. Pass12// `as="a"` (or `asChild` with a child anchor) to make it a link — the13// upstream uses Radix Slot.Root; we use cloneElement.14//15// Accessibility:16// - The badge's content (text) IS the accessible name. If you render an17// icon-only badge, set `ariaLabel` so screen readers can name it.18// - Status-style badges ("New", "3 unread") that update in place should19// live inside an aria-live region (use Alert / Toast for that, not20// Badge). Badge itself is presentational.21// - See repos/mdn/files/en-us/web/html/reference/elements/span/index.md for22// <span> semantics (none — it's a generic inline container).2324export type BadgeVariant =25 | "default"26 | "secondary"27 | "destructive"28 | "outline"29 | "ghost"30 | "link"3132const base =33 "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] " +34 "focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 " +35 "aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 " +36 "[&>svg]:pointer-events-none [&>svg]:size-3"3738const variants: Record<BadgeVariant, string> = {39 default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",40 secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",41 destructive:42 "bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",43 outline:44 "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",45 ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",46 link: "text-primary underline-offset-4 [a&]:hover:underline",47}4849export function badgeClasses(opts?: {50 variant?: BadgeVariant51 class?: ClassValue52}): string {53 const variant = opts?.variant ?? "default"54 return cn(base, variants[variant], opts?.class)55}5657type BadgeProps = PropsWithChildren<{58// … truncated
More from shadcn-htmx
All 83 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | shadcn-htmx | Components | Free | no deps | |
| Active Searchactive-search | shadcn-htmx | Components | Free | no deps | |
| Alertalert | shadcn-htmx | Components | Free | no deps | |
| Alert Dialogalert-dialog | shadcn-htmx | Components | Free | no deps | |
| Aspect Ratioaspect-ratio | shadcn-htmx | Components | Free | no deps | |
| Auto Gridauto-grid | shadcn-htmx | Components | Free | no deps | |
| Autocompleteautocomplete | shadcn-htmx | Components | Free | no deps | |
| Autosize Textareaautosize-textarea | shadcn-htmx | Components | Free | no deps |
