/** * VoiceStatusIndicator Component * * Reusable visual indicator for voice mode states with icons, animations, * and optional status text labels. * * @example * ```tsx * // Basic usage - icon only * * * // With label * * * // Different size * * ``` */ import React from 'react'; import type { BrowserVoiceStatus } from '@/hooks/useBrowserVoice'; import { useI18n } from '@/lib/i18n'; import { Icon } from "@/components/icon/Icon"; import type { IconName } from "@/components/icon/icons"; export interface VoiceStatusIndicatorProps { /** Current voice status */ status: BrowserVoiceStatus; /** Show text label next to icon */ showLabel?: boolean; /** Size of the indicator */ size?: 'sm' | 'md' | 'lg'; /** Optional className for styling */ className?: string; /** Whether conversation mode is active (shows indicator dot when idle) */ conversationMode?: boolean; } const sizeClasses = { sm: { icon: 'w-4 h-4', container: 'gap-1.5', }, md: { icon: 'w-5 h-5', container: 'gap-2', }, lg: { icon: 'w-6 h-6', container: 'gap-2.5', }, }; const statusConfig: Record< BrowserVoiceStatus, { icon: IconName; color: string; labelKey: | 'voice.status.idle' | 'voice.status.listening' | 'voice.status.processing' | 'voice.status.speaking' | 'voice.status.error'; animation?: string; } > = { idle: { icon: "mic-off", color: 'text-muted-foreground', labelKey: 'voice.status.idle', }, listening: { icon: "mic", color: 'text-primary', labelKey: 'voice.status.listening', animation: 'animate-pulse', }, processing: { icon: "loader-4", color: 'text-primary', labelKey: 'voice.status.processing', animation: 'animate-spin', }, speaking: { icon: "volume-up", color: 'text-green-500', labelKey: 'voice.status.speaking', }, error: { icon: "alert", color: 'text-destructive', labelKey: 'voice.status.error', }, }; /** * VoiceStatusIndicator - Visual indicator for voice mode states */ export function VoiceStatusIndicator({ status, showLabel = false, size = 'md', className = '', conversationMode = false, }: VoiceStatusIndicatorProps) { const { t } = useI18n(); const config = statusConfig[status]; const statusIconName = config.icon; const sizeClass = sizeClasses[size]; const containerClass = showLabel ? sizeClass.container : ''; return (
{showLabel && ( {t(config.labelKey)} )}
); } export default VoiceStatusIndicator;