89 lines
2.3 KiB
TypeScript
89 lines
2.3 KiB
TypeScript
import * as React from 'react';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
variant?:
|
|
| 'default'
|
|
| 'primary'
|
|
| 'secondary'
|
|
| 'outline'
|
|
| 'success'
|
|
| 'warning'
|
|
| 'destructive'
|
|
| 'info';
|
|
size?: 'sm' | 'md';
|
|
dot?: boolean;
|
|
}
|
|
|
|
const Badge = React.forwardRef<HTMLDivElement, BadgeProps>(
|
|
(
|
|
{
|
|
className,
|
|
variant = 'default',
|
|
size = 'md',
|
|
dot = false,
|
|
children,
|
|
...props
|
|
},
|
|
ref
|
|
) => {
|
|
const variants = {
|
|
default:
|
|
'border-transparent bg-primary/10 text-primary hover:bg-primary/20',
|
|
primary:
|
|
'border-transparent bg-primary/10 text-primary hover:bg-primary/20',
|
|
secondary:
|
|
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
outline: 'border-border text-foreground bg-background',
|
|
success:
|
|
'border-transparent bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 hover:bg-emerald-500/20',
|
|
warning:
|
|
'border-transparent bg-amber-500/10 text-amber-600 dark:text-amber-400 hover:bg-amber-500/20',
|
|
destructive:
|
|
'border-transparent bg-destructive/10 text-destructive hover:bg-destructive/20',
|
|
info: 'border-transparent bg-sky-500/10 text-sky-600 dark:text-sky-400 hover:bg-sky-500/20',
|
|
};
|
|
|
|
const dotColors = {
|
|
default: 'bg-primary',
|
|
primary: 'bg-primary',
|
|
secondary: 'bg-secondary-foreground',
|
|
outline: 'bg-foreground',
|
|
success: 'bg-emerald-500',
|
|
warning: 'bg-amber-500',
|
|
destructive: 'bg-destructive',
|
|
info: 'bg-sky-500',
|
|
};
|
|
|
|
const sizes = {
|
|
sm: 'px-2 py-0.5 text-xs font-medium',
|
|
md: 'px-2.5 py-1 text-xs font-semibold',
|
|
};
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
className={cn(
|
|
'inline-flex items-center gap-1.5 rounded-full border transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 shrink-0',
|
|
variants[variant],
|
|
sizes[size],
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
{dot && (
|
|
<span
|
|
className={cn('h-1.5 w-1.5 rounded-full', dotColors[variant])}
|
|
aria-hidden="true"
|
|
/>
|
|
)}
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
|
|
Badge.displayName = 'Badge';
|
|
|
|
export { Badge };
|