'use client'; import { forwardRef, HTMLAttributes } from 'react'; import styles from './split-text.module.css'; export interface SplitTextProps extends HTMLAttributes { /** The text to split */ children: string; /** Split by: words, chars, or lines */ splitBy?: 'words' | 'chars' | 'lines'; /** Animation delay per unit in ms */ delay?: number; /** Animation duration per unit */ duration?: number; /** Preset animation class */ variant?: 'fade' | 'slide-up' | 'slide-down' | 'scale' | 'stagger'; /** Preserve whitespace for word splits */ preserveSpaces?: boolean; } export const SplitText = forwardRef( ( { children, splitBy = 'words', delay = 50, duration = 400, variant = 'fade', preserveSpaces = true, className, style, ...props }, ref ) => { let elements: JSX.Element[] = []; let units: string[]; switch (splitBy) { case 'chars': units = children.split(''); break; case 'lines': units = children.split('\n'); break; case 'words': default: units = children.split(' '); break; } elements = units.map((unit, index) => { const isLast = index === units.length - 1; const spaceAfter = splitBy === 'words' && !isLast && preserveSpaces ? ' ' : ''; const lineBreak = splitBy === 'lines' && !isLast ?
: ''; return ( {unit} {spaceAfter} {lineBreak} ); }); return ( {elements} ); }); SplitText.displayName = 'SplitText'; export default SplitText;