morethanadiagnosis-hub/web/components/common/Badge.tsx
Claude 9232ebe294
feat(web): complete Phase 1 - foundation components, layouts, and hooks
Implemented complete design system and foundational infrastructure:

**Design System Components:**
- Button (all variants: primary, secondary, ghost, danger)
- Input & Textarea (with validation and error states)
- Card (elevated, outlined, flat variants)
- Modal/Dialog (with focus trap and accessibility)
- Avatar (with fallback initials)
- Badge (all color variants)
- Form helpers (FormField, Checkbox, Select)
- Link component with Next.js integration
- Navigation (Header, Footer with responsive design)

**Layouts:**
- MainLayout (with Header/Footer for public pages)
- AuthLayout (minimal layout for auth flows)
- DashboardLayout (with sidebar navigation)

**Hooks & Utilities:**
- useAuth() - authentication state management
- useApi() - API calls with loading/error states
- useLocalStorage() - persistent state management
- apiClient - Axios instance with token refresh
- authStore - Zustand store for auth state

**Configuration:**
- Tailwind config with design tokens
- Dark mode support via CSS variables
- Global styles with accessibility focus
- WCAG 2.2 AA+ compliant focus indicators

All components follow accessibility best practices with proper ARIA labels,
keyboard navigation, and screen reader support.

Job ID: MTAD-IMPL-2025-11-18-CL
2025-11-18 01:02:05 +00:00

45 lines
1.4 KiB
TypeScript

'use client'
import React from 'react'
export type BadgeVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'neutral'
export type BadgeSize = 'sm' | 'md' | 'lg'
export interface BadgeProps {
variant?: BadgeVariant
size?: BadgeSize
children: React.ReactNode
className?: string
}
const variantStyles: Record<BadgeVariant, string> = {
primary: 'bg-primary-100 text-primary-800 dark:bg-primary-900 dark:text-primary-200',
secondary: 'bg-secondary-100 text-secondary-800 dark:bg-secondary-900 dark:text-secondary-200',
success: 'bg-success-100 text-success-800 dark:bg-success-900 dark:text-success-200',
warning: 'bg-warning-100 text-warning-800 dark:bg-warning-900 dark:text-warning-200',
error: 'bg-error-100 text-error-800 dark:bg-error-900 dark:text-error-200',
neutral: 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200',
}
const sizeStyles: Record<BadgeSize, string> = {
sm: 'px-2 py-0.5 text-xs',
md: 'px-2.5 py-1 text-sm',
lg: 'px-3 py-1.5 text-base',
}
export const Badge = ({
variant = 'neutral',
size = 'md',
children,
className = '',
}: BadgeProps) => {
const baseStyles = 'inline-flex items-center font-medium rounded-full'
const combinedClassName = `${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]} ${className}`.trim()
return (
<span className={combinedClassName}>
{children}
</span>
)
}