'use client'; import { forwardRef, HTMLAttributes, useEffect, useState } from 'react'; import styles from './ascii-art.module.css'; export interface AsciiArtProps extends HTMLAttributes { /** ASCII art content (multi-line string) */ children: string; /** Size variant */ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'; /** Color variant */ variant?: 'default' | 'blood' | 'cyber' | 'matrix' | 'amber' | 'ghost' | 'gradient'; /** Animation effect */ animation?: 'none' | 'typing' | 'reveal' | 'glitch' | 'flicker' | 'pulse'; /** Show scanlines overlay */ scanlines?: boolean; /** Show border */ bordered?: boolean; /** Border title */ title?: string; /** Delay between lines for reveal animation (ms) */ revealDelay?: number; /** Custom color */ color?: string; } export const AsciiArt = forwardRef( ( { children, size = 'md', variant = 'default', animation = 'none', scanlines = false, bordered = false, title, revealDelay = 100, color, className, style, ...props }, ref ) => { const [revealedLines, setRevealedLines] = useState(0); const lines = children.split('\n'); useEffect(() => { if (animation === 'reveal') { setRevealedLines(0); let lineIndex = 0; const interval = setInterval(() => { if (lineIndex < lines.length) { setRevealedLines(lineIndex + 1); lineIndex++; } else { clearInterval(interval); } }, revealDelay); return () => clearInterval(interval); } }, [animation, lines.length, revealDelay, children]); const containerClasses = [ styles.container, styles[size], variant !== 'default' && styles[variant], animation !== 'none' && styles[animation], scanlines && styles.scanlines, bordered && styles.bordered, className ].filter(Boolean).join(' '); const renderContent = () => { if (animation === 'reveal') { return lines.map((line, i) => ( {line} {'\n'} )); } return children; }; return (
        {renderContent()}
      
); } ); AsciiArt.displayName = 'AsciiArt'; export default AsciiArt;