Components
Badge
A versatile badge component for displaying status, labels, and metadata with multiple variants and shapes.
import { Badge } from '@/components/ui/badge';
export function BadgeDemo() {
return (
<div className='flex items-center gap-3'>
<Badge variant='positive'>Active</Badge>
<Badge variant='info'>Beta</Badge>
<Badge variant='negative'>Error</Badge>
</div>
);
}Installation
CLI
npx shadcn@latest add "https://maksud.dev/r/badge"Manual
Install the following dependencies:
npm install @radix-ui/react-slot class-variance-authorityCopy and paste the following code into your project.
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import type * as React from 'react';
import { cn } from '@/lib/utils';
const badgeVariants = cva(
'inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden whitespace-nowrap border px-1.5 font-semibold text-xs leading-4 transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3',
{
variants: {
variant: {
positive: 'border-success/30 bg-success/10 text-success',
info: 'border-primary/30 bg-primary/10 text-primary',
negative: 'border-destructive/30 bg-destructive/10 text-destructive',
warning: 'border-attention/30 bg-attention/10 text-attention',
urgent: 'border-destructive bg-destructive text-destructive-foreground',
},
shape: {
default: 'rounded-md',
pill: 'rounded-full',
square: 'rounded-none',
},
},
defaultVariants: {
variant: 'positive',
shape: 'default',
},
}
);
interface BadgeProps extends React.ComponentProps<'span'>, VariantProps<typeof badgeVariants> {
asChild?: boolean;
icon?: React.ReactNode;
}
function Badge({
className,
variant,
shape,
asChild = false,
icon,
children,
...props
}: BadgeProps) {
const Comp = asChild ? Slot : 'span';
return (
<Comp data-slot='badge' className={cn(badgeVariants({ variant, shape }), className)} {...props}>
{icon && <span className='flex h-3 w-3 items-center justify-center'>{icon}</span>}
{children}
</Comp>
);
}
export { Badge, badgeVariants };Layout
Import the component and use it in your application.
import { Badge } from "@/components/ui/badge";
export default function Example() {
return (
<Badge variant="positive">Active</Badge>
);
}Examples
Variants
import { Badge } from '@/components/ui/badge';
export function BadgeVariantsDemo() {
return (
<div className='flex flex-wrap items-center gap-3'>
<Badge variant='positive'>Positive</Badge>
<Badge variant='info'>Info</Badge>
<Badge variant='negative'>Negative</Badge>
<Badge variant='warning'>Warning</Badge>
<Badge variant='urgent'>Urgent</Badge>
</div>
);
}The Badge component supports five different variants: positive, info, negative, warning, and urgent.
Shapes
import { Badge } from '@/components/ui/badge';
export function BadgeShapesDemo() {
return (
<div className='flex flex-wrap items-center gap-3'>
<Badge variant='info' shape='default'>
Default
</Badge>
<Badge variant='info' shape='pill'>
Pill
</Badge>
<Badge variant='info' shape='square'>
Square
</Badge>
</div>
);
}Choose from three different shapes: default (rounded-md), pill (rounded-full), and square (rounded-none).
With Icons
import { Badge } from '@/components/ui/badge';
import { AlertTriangle, Check, Info, X } from 'lucide-react';
export function BadgeWithIconsDemo() {
return (
<div className='flex flex-wrap items-center gap-3'>
<Badge variant='positive' icon={<Check />}>
Success
</Badge>
<Badge variant='info' icon={<Info />}>
Information
</Badge>
<Badge variant='warning' icon={<AlertTriangle />}>
Warning
</Badge>
<Badge variant='negative' icon={<X />}>
Error
</Badge>
</div>
);
}Badges can include icons to provide additional visual context using the icon prop. Using this prop is optional, you can also pass the icon as a child.
API Reference
| Prop | Description |
|---|---|
variant | The visual style variant of the badge. |
shape | The shape of the badge corners. |
icon | Optional icon to display before the badge content. |
asChild | When true, renders as a child component (e.g., Link) instead of a span element. |
Accessibility
- The badge uses semantic
<span>element by default - Supports all standard span HTML attributes
- When used as a status indicator, consider adding
aria-labelfor screen readers - Icons should be decorative; important information should be in the text content