Badge with an animated pulsing glow dot. Supports status variants out of the box.
Made by LéoLiveGhostIn ProgressPendingOfflineDraft
"use client";
import { GlowingBadge } from "@/components/unlumen-ui/glowing-badge";
export const GlowingBadgeDemo = ({
variant = "success",
pulse = true,
dot = true,
}: {
variant?: "default" | "success" | "warning" | "error" | "info";
pulse?: boolean;
dot?: boolean;
}) => {
return (
<div className="flex flex-wrap items-center justify-center gap-3 p-8">
<GlowingBadge variant="success" pulse={pulse} dot={dot}>
Live
</GlowingBadge>
<GlowingBadge variant="neutral" pulse={pulse} dot={dot}>
Ghost
</GlowingBadge>
<GlowingBadge variant="info" pulse={pulse} dot={dot}>
In Progress
</GlowingBadge>
<GlowingBadge variant="warning" pulse={pulse} dot={dot}>
Pending
</GlowingBadge>
<GlowingBadge variant="error" pulse={pulse} dot={dot}>
Offline
</GlowingBadge>
<GlowingBadge variant="default" pulse={pulse} dot={dot}>
Draft
</GlowingBadge>
</div>
);
};Installation
Install the following dependencies:
Copy and paste the following code into your project:
"use client";
import { type HTMLAttributes } from "react";
import { motion } from "motion/react";
import { cn } from "@/lib/utils";
type GlowingBadgeVariant =
| "default"
| "success"
| "warning"
| "error"
| "info"
| "neutral";
interface GlowingBadgeProps extends HTMLAttributes<HTMLSpanElement> {
variant?: GlowingBadgeVariant;
pulse?: boolean;
dot?: boolean;
}
const variantStyles: Record<
GlowingBadgeVariant,
{ badge: string; glow: string; dot: string }
> = {
default: {
badge: "bg-foreground text-background",
glow: "bg-foreground/30",
dot: "bg-background",
},
neutral: {
badge: "bg-muted text-foreground border-muted",
glow: "bg-foreground/30",
dot: "bg-foreground",
},
success: {
badge: "bg-emerald-500 text-emerald-100",
glow: "bg-emerald-500",
dot: "bg-emerald-200",
},
warning: {
badge: "bg-amber-500 text-amber-100",
glow: "bg-amber-500",
dot: "bg-amber-200",
},
error: {
badge: "bg-red-500 text-red-100",
glow: "bg-red-500",
dot: "bg-red-200",
},
info: {
badge: "bg-blue-500 text-blue-100",
glow: "bg-blue-500",
dot: "bg-blue-200",
},
};
function GlowingBadge({
variant = "default",
pulse = true,
dot = true,
children,
className,
...props
}: GlowingBadgeProps) {
const styles = variantStyles[variant];
return (
<span className="relative inline-flex">
<span
className={cn(
"absolute inset-0 rounded-full blur-md opacity-60",
styles.glow,
)}
/>
<span
className={cn(
"relative inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium",
styles.badge,
className,
)}
{...props}
>
{dot && (
<span className="relative flex h-1.5 w-1.5 shrink-0">
{pulse && (
<motion.span
className={cn(
"absolute inline-flex h-full w-full rounded-full opacity-75",
styles.dot,
)}
animate={{ scale: [1, 2.5, 1], opacity: [0.75, 0, 0.75] }}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut",
}}
/>
)}
<span
className={cn(
"relative inline-flex h-1.5 w-1.5 rounded-full",
styles.dot,
)}
/>
</span>
)}
{children}
</span>
</span>
);
}
export { GlowingBadge };
export type { GlowingBadgeProps, GlowingBadgeVariant };Update the import paths to match your project setup.
Usage
import { GlowingBadge } from "@/components/unlumen-ui/glowing-badge";<GlowingBadge variant="success">Live</GlowingBadge>
<GlowingBadge variant="warning" pulse={false}>Pending</GlowingBadge>Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "default" | "success" | "warning" | "error" | "info" | "default" | Color variant for the badge. |
pulse | boolean | true | Animate the dot with a pulsing ring. |
dot | boolean | true | Show the status dot. |
children | ReactNode | — | Badge label content. |
className | string | — | Extra classes on the root element. |