import React, { useRef, useCallback, useMemo } from 'react'; import LetterInput from './LetterInput'; import ActorPopover from './ActorPopover'; function isLetter(ch) { return /[a-zA-Z]/.test(ch); } export default function GameRow({ actorName, pos, colStart, totalWidth, hintType, hintText, rowIndex, attemptedLetters = null, revealed = false }) { const inputRefs = useRef([]); const letters = actorName.split(''); const letterIndices = useMemo( () => letters.reduce((acc, ch, i) => { if (isLetter(ch)) acc.push(i); return acc; }, []), [actorName] ); const setInputRef = useCallback((index) => (el) => { inputRefs.current[index] = el; }, []); const focusNextInput = useCallback((charIndex, direction) => { const currentPos = letterIndices.indexOf(charIndex); const nextPos = currentPos + direction; if (nextPos >= 0 && nextPos < letterIndices.length) { inputRefs.current[letterIndices[nextPos]]?.focus(); } }, [letterIndices]); return ( {Array.from({ length: totalWidth + 1 }, (_, colIndex) => { const charIndex = colIndex - colStart; const isInRange = charIndex >= 0 && charIndex < letters.length; if (!isInRange) { return ; } const ch = letters[charIndex]; if (!isLetter(ch)) { return ( {ch} ); } const attemptedLetter = typeof attemptedLetters?.[charIndex] === 'string' ? attemptedLetters[charIndex].toUpperCase() : ''; const correctLetter = ch.toUpperCase(); const revealState = !revealed ? null : attemptedLetter === '' ? null : attemptedLetter === correctLetter ? 'correct' : 'wrong'; return ( focusNextInput(charIndex, 1)} onPrev={() => focusNextInput(charIndex, -1)} value={revealed ? (revealState === 'correct' ? attemptedLetter : correctLetter) : undefined} revealState={revealState} disabled={revealed} /> ); })} ); }