'use client'; import { forwardRef, useState, FormEvent, KeyboardEvent, HTMLAttributes } from 'react'; import styles from './echo-chat.module.css'; export type TransformType = 'none' | 'reverse' | 'glitch' | 'repeat' | 'scramble'; export interface EchoChatProps extends HTMLAttributes { /** Accent color */ accentColor?: string; /** Echo color for responses */ echoColor?: string; /** Maximum messages to display */ maxMessages?: number; /** Color variant */ variant?: 'default' | 'cyber' | 'terminal' | 'fire' | 'nuclear'; /** Size variant */ size?: 'default' | 'compact' | 'large'; /** Default transform type */ defaultTransform?: TransformType; /** Show transform selector */ showTransformSelector?: boolean; /** Placeholder text */ placeholder?: string; /** Send button text */ sendButtonText?: string; /** On message send callback */ onSend?: (message: string, transform: TransformType) => void; /** Custom echo function */ echoFunction?: (message: string, transform: TransformType) => string; } const DEFAULT_ECHO: Record string> = { none: (text) => text, reverse: (text) => text.split('').reverse().join(''), glitch: (text) => { const chars = '!<>-_\\/[]{}'; return text .split('') .map((char) => (Math.random() > 0.7 ? chars[Math.floor(Math.random() * chars.length)] : char)) .join(''); }, repeat: (text) => `${text}... ${text}... ${text}...`, scramble: (text) => { const words = text.split(' '); return words.map((word) => word.split('').sort(() => Math.random() - 0.5).join('')).join(' '); }, }; export const EchoChat = forwardRef( ( { accentColor = '#00ff00', echoColor = '#ff00ff', maxMessages = 50, variant = 'default', size = 'default', defaultTransform = 'none', showTransformSelector = true, placeholder = 'Type a message...', sendButtonText = 'Send', onSend, echoFunction, className, ...props }, ref ) => { const [messages, setMessages] = useState>([]); const [input, setInput] = useState(''); const [transform, setTransform] = useState(defaultTransform); const [messageId, setMessageId] = useState(0); const processEcho = (text: string, transformType: TransformType): string => { if (echoFunction) { return echoFunction(text, transformType); } return DEFAULT_ECHO[transformType](text); }; const handleSend = (e?: FormEvent) => { e?.preventDefault(); if (!input.trim()) return; const newUserMessage = { id: messageId, text: input, isUser: true, transform }; setMessages((prev) => [...prev, newUserMessage]); const echoText = processEcho(input, transform); const newEchoMessage = { id: messageId + 1, text: echoText, isUser: false, transform }; setMessages((prev) => { const updated = [...prev, newEchoMessage]; return updated.slice(-maxMessages); }); setMessageId((prev) => prev + 2); setInput(''); onSend?.(input, transform); }; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); } }; return (
{showTransformSelector && (
Echo Mode:
)}
{messages.map((msg) => (
{msg.isUser ? 'YOU' : 'ECHO'}
{msg.text}
))} {messages.length === 0 && (
No messages yet. Start the conversation...
)}
setInput(e.target.value)} onKeyDown={handleKeyDown} placeholder={placeholder} />
System Ready
); } ); EchoChat.displayName = 'EchoChat'; export default EchoChat;