Status Badge
ericts-ui/status-badgeFreeComponent
A compact animated badge for status labels with icon and text slot transitions.
Live preview
live · rendered by the registry
Rendered by ericts-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.ericts.com/r/status-badge.jsonSource
1"use client";23import {4 AlertTriangle,5 Check,6 Circle,7 Info,8 LoaderCircle,9 X,10 type LucideIcon,11} from "lucide-react";12import {13 AnimatePresence,14 motion,15 useReducedMotion,16 type HTMLMotionProps,17 type Variants,18} from "motion/react";19import type { ReactNode } from "react";2021import { cn } from "@/lib/utils";2223export type StatusBadgeStatus =24 | "neutral"25 | "info"26 | "success"27 | "warning"28 | "danger"29 | "loading";3031export type StatusBadgeSize = "sm" | "md";3233export interface StatusBadgeProps34 extends Omit<HTMLMotionProps<"span">, "children"> {35 status?: StatusBadgeStatus;36 size?: StatusBadgeSize;37 children?: ReactNode;38 icon?: ReactNode;39 showIcon?: boolean;40 pulse?: boolean;41 contentKey?: string | number;42 /**43 * Make the badge itself a polite live region, so transitions like44 * loading → success are announced (the icon is `aria-hidden` and a swapped45 * label alone is not announced). Defaults to true.46 *47 * The role goes on the badge rather than on an extra sr-only copy of the48 * label, so the text exists once and is never read twice. Set to false when49 * the badge is decorative or the surrounding UI already announces the change.50 */51 announce?: boolean;52}5354const EASE = [0.4, 0, 0.2, 1] as const;55const SPRING_LAYOUT = {56 type: "spring",57 stiffness: 420,58 damping: 38,59 mass: 0.7,60} as const;61const CONTENT_TRANSITION = {62 type: "spring",63 duration: 0.3,64 bounce: 0,65} as const;6667const statusClassNames: Record<StatusBadgeStatus, string> = {68 neutral: "border-border bg-muted text-muted-foreground",69 info: "border-primary/25 bg-primary/10 text-primary",70 success:71 "border-ericts-success/25 bg-ericts-success/10 text-ericts-success-foreground",72 warning:73 "border-ericts-warning/25 bg-ericts-warning/10 text-ericts-warning-foreground",74 danger: "border-destructive/25 bg-destructive/10 text-destructive",75 loading: "border-primary/25 bg-primary/10 text-primary",76};7778const sizeClassNames: Record<StatusBadgeSize, string> = {79 sm: "h-6 gap-1.5 px-2 text-[11px]",80 md: "h-8 gap-2 px-3 text-xs",81};8283const iconClassNames: Record<StatusBadgeSize, string> = {84 sm: "size-3",85 md: "size-3.5",86};8788const statusIcons: Record<StatusBadgeStatus, LucideIcon> = {89 neutral: Circle,90 info: Info,91 success: Check,92 warning: AlertTriangle,93 danger: X,94 loading: LoaderCircle,95};9697const iconVariants: Variants = {98 initial: {99 opacity: 0,100 y: 12,101 scale: 0.96,102 rotateX: -35,103 },104 animate: {105// … truncated
What it pulls in
npm packages
Files it writes
More from ericts-ui
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Adaptive Draweradaptive-drawer | ericts-ui | Components | Free | 2 deps | |
| Adaptive Switchadaptive-switch | ericts-ui | Components | Free | 2 deps | |
| Check Markcheck-mark | ericts-ui | Components | Free | no deps · 2 files | |
| Context Cursorcontext-cursor | ericts-ui | Components | Free | 1 dep | |
| Copy Buttoncopy-button | ericts-ui | Components | Free | 2 deps | |
| Expandable Dialogexpandable-dialog | ericts-ui | Components | Free | 1 dep | |
| Expandable Panelexpandable-panel | ericts-ui | Components | Free | 2 deps | |
| Expandable Segmented Tabsexpandable-segmented-tabs | ericts-ui | Components | Free | 1 dep |
