'use client'; /** * ProcessingIndicator Component * * Shows loading state during AI operations with multiple variants: * - spinner: Rotating loader icon with text (default) * - skeleton: Pulsing placeholder blocks * - pulse: Animated dots * * Epic: E3 (UI Components) * Story: E3.S4 (Processing indicator) */ import { Loader2 } from 'lucide-react'; import { cn } from '@/lib/utils'; interface ProcessingIndicatorProps { /** Loading message to display (default: "Even nadenken...") */ message?: string; /** Visual style variant */ type?: 'spinner' | 'skeleton' | 'pulse'; /** Size of the indicator */ size?: 'sm' | 'md' | 'lg'; /** Additional CSS classes */ className?: string; } /** * Size configurations for each variant */ const SIZE_CONFIG = { sm: { icon: 'w-3 h-3', text: 'text-xs', dot: 'w-1.5 h-1.5', skeleton: 'h-3', }, md: { icon: 'w-4 h-4', text: 'text-sm', dot: 'w-2 h-2', skeleton: 'h-4', }, lg: { icon: 'w-5 h-5', text: 'text-base', dot: 'w-2.5 h-2.5', skeleton: 'h-5', }, }; export function ProcessingIndicator({ message = 'Even nadenken...', type = 'spinner', size = 'md', className, }: ProcessingIndicatorProps) { const sizeConfig = SIZE_CONFIG[size]; // Spinner variant - rotating icon with text if (type === 'spinner') { return (
{message}
); } // Skeleton variant - pulsing placeholder blocks if (type === 'skeleton') { return (
); } // Pulse variant - animated dots return (
{message && ( {message} )}
); } /** * Inline spinner for use in buttons or compact spaces */ export function InlineSpinner({ size = 'sm', className, }: { size?: 'sm' | 'md' | 'lg'; className?: string; }) { const sizeConfig = SIZE_CONFIG[size]; return ( ); }