import { type Cell as CellModel, type ShowCoordinates } from '@scrabble-solver/types'; import classNames from 'classnames'; import { type CSSProperties, type ChangeEventHandler, type ClipboardEventHandler, type FocusEventHandler, Fragment, type KeyboardEventHandler, type RefObject, forwardRef, memo, } from 'react'; import { Ban, FlagFill } from '@/icons'; import { getCoordinate } from '@/lib'; import { BORDER_WIDTH } from '@/parameters'; import { type CellFilter } from '@/types'; import styles from './Board.module.scss'; import { Cell } from './components'; interface Props { className?: string; cellFilters: CellFilter[]; cellSize: number; coordinatesFontSize: number; coordinatesSize: number; direction: 'ltr' | 'rtl'; inputRefs: RefObject[][]; rows: CellModel[][]; showCoordinates: ShowCoordinates; style?: CSSProperties; onBlur: FocusEventHandler; onChange: ChangeEventHandler; onFocus: (x: number, y: number) => void; onKeyDown: KeyboardEventHandler; onPaste: ClipboardEventHandler; } const BoardPureBase = forwardRef( ( { className, cellSize, coordinatesFontSize, coordinatesSize, direction, cellFilters, inputRefs, rows, showCoordinates, style, onBlur, onChange, onFocus, onKeyDown, onPaste, }, ref, ) => (
{showCoordinates !== 'hidden' && ( <>
{rows[0].map((_column, index) => (
{getCoordinate(index, showCoordinates === 'original' ? 'letter' : 'number')}
))} )} {/* The dynamic changes to the board presentation need to be outside of useBackgroundImage to prevent flickering on blob URL change (i.e. when flagging a field, but not when changing game type since user's attention is not on the board when that happens)*/} {cellFilters.map(({ x, y, type }) => { const Icon = type === 'exclude' ? Ban : FlagFill; return (
); })} {rows.map((cells, y) => ( {showCoordinates !== 'hidden' && (
{getCoordinate(y, showCoordinates === 'original' ? 'number' : 'letter')}
)} {cells.map((cell, x) => ( 0 ? rows[y][x - 1] : undefined} cellRight={x < rows[y].length - 1 ? rows[y][x + 1] : undefined} cellTop={y > 0 ? rows[y - 1][x] : undefined} inputRef={inputRefs[y][x]} key={x} size={cellSize} onChange={onChange} onFocus={onFocus} /> ))}
))}
), ); export const BoardPure = memo(BoardPureBase);