import React, { forwardRef, ReactNode, HTMLAttributes } from 'react'; import { cn } from '../../lib/utils'; // Badge variants type BadgeVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info' | 'neutral'; // Badge sizes type BadgeSize = 'sm' | 'md' | 'lg'; // Badge props interface interface BadgeProps extends HTMLAttributes { variant?: BadgeVariant; size?: BadgeSize; icon?: ReactNode; iconPosition?: 'left' | 'right'; rounded?: boolean; children?: ReactNode; } // Helper function to get variant styles const getVariantStyles = (variant: BadgeVariant) => { switch (variant) { case 'primary': return 'bg-primary text-white'; case 'secondary': return 'bg-secondary text-white'; case 'success': return 'bg-success text-white'; case 'warning': return 'bg-warning text-gray-900'; case 'error': return 'bg-danger text-white'; case 'info': return 'bg-info text-white'; case 'neutral': return 'bg-gray-200 text-gray-800'; default: return 'bg-primary text-white'; } }; // Helper function to get size styles const getSizeStyles = (size: BadgeSize) => { switch (size) { case 'sm': return 'text-xs px-2 py-0.5'; case 'md': return 'text-sm px-3 py-1'; case 'lg': return 'text-base px-4 py-1.5'; default: return 'text-sm px-3 py-1'; } }; // Helper function to get icon spacing const getIconSpacing = (size: BadgeSize, iconPosition: 'left' | 'right') => { const spacing = { sm: iconPosition === 'left' ? 'mr-1' : 'ml-1', md: iconPosition === 'left' ? 'mr-1.5' : 'ml-1.5', lg: iconPosition === 'left' ? 'mr-2' : 'ml-2', }; return spacing[size]; }; // Helper function to get icon size const getIconSize = (size: BadgeSize) => { const sizeClasses = { sm: 'w-3 h-3', md: 'w-4 h-4', lg: 'w-5 h-5', }; return sizeClasses[size]; }; // Main Badge Component export const Badge = forwardRef( ( { variant = 'primary', size = 'md', icon, iconPosition = 'left', rounded = true, className = '', children, ...props }, ref ) => { return (
{/* Icon - Left position */} {icon && iconPosition === 'left' && ( {icon} )} {/* Badge content */} {children && {children}} {/* Icon - Right position */} {icon && iconPosition === 'right' && ( {icon} )}
); } ); Badge.displayName = 'Badge'; // Badge Group Component for multiple badges interface BadgeGroupProps extends HTMLAttributes { children?: ReactNode; gap?: 'xs' | 'sm' | 'md' | 'lg'; } export const BadgeGroup = forwardRef( ({ gap = 'sm', className = '', children, ...props }, ref) => { const gapClasses = { xs: 'gap-1', sm: 'gap-2', md: 'gap-3', lg: 'gap-4', }; return (
{children}
); } ); BadgeGroup.displayName = 'BadgeGroup'; // Export types for external use export type { BadgeProps, BadgeVariant, BadgeSize, BadgeGroupProps };