veza/apps/web/src/components/ui/badge.tsx

61 lines
1.8 KiB
TypeScript

import { ReactNode } from 'react';
import { cn } from '@/lib/utils';
export interface BadgeProps {
children: ReactNode;
variant?: 'default' | 'primary' | 'success' | 'warning' | 'error' | 'secondary';
size?: 'sm' | 'md' | 'lg';
dot?: boolean;
count?: number;
className?: string;
}
/**
* Composant Badge pour afficher des labels, compteurs, ou statuts.
*/
export function Badge({
children,
variant = 'default',
size = 'md',
dot,
count,
className,
}: BadgeProps) {
return (
<span
className={cn(
'inline-flex items-center rounded-full font-medium',
size === 'sm' && 'px-2 py-0.5 text-xs',
size === 'md' && 'px-2.5 py-0.5 text-sm',
size === 'lg' && 'px-3 py-1 text-base',
variant === 'default' &&
'bg-muted text-muted-foreground border border-border',
variant === 'secondary' &&
'bg-purple-100 text-purple-800 dark:bg-purple-900/20 dark:text-purple-200',
variant === 'primary' &&
'bg-blue-100 text-blue-800 dark:bg-blue-900/20 dark:text-blue-200',
variant === 'success' &&
'bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-200',
variant === 'warning' &&
'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/20 dark:text-yellow-200',
variant === 'error' &&
'bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-200',
className,
)}
>
{dot && (
<span
className={cn(
'w-2 h-2 rounded-full bg-current mr-1',
size === 'sm' && 'w-1.5 h-1.5',
size === 'lg' && 'w-2.5 h-2.5',
)}
/>
)}
{children}
{count !== undefined && (
<span className="ml-1 font-semibold">({count})</span>
)}
</span>
);
}