import * as React from "react"; import {Letter as LetterData, PlayerAndScore} from "word_grid"; import {ChangeEvent, JSX} from "react"; import { cellTypeToDetails, CellType, LocationType, PlayableLetterData, CoordinateData, TileDispatchActionType, TileDispatch, HighlightableLetterData, } from "./utils"; export function TileSlot(props: { tile?: React.JSX.Element | undefined, location: CoordinateData, dispatch: TileDispatch }): React.JSX.Element { let isDraggable = props.tile !== undefined; function onDragStart(e: React.DragEvent) { e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("wordGrid/coords", JSON.stringify(props.location)); } function onDrop(e: React.DragEvent) { const startLocation: CoordinateData = JSON.parse(e.dataTransfer.getData("wordGrid/coords")); const thisLocation = props.location; props.dispatch({action: TileDispatchActionType.MOVE, start: startLocation, end: thisLocation}); } let className = "tileSpot"; if (props.location.location === LocationType.GRID) { className += " ephemeral"; } return
{e.preventDefault()}} > {props.tile}
} export function Letter(props: { data: HighlightableLetterData, letterUpdater?: (value: string) => void }): React.JSX.Element { function modifyThisLetter(value:string){ props.letterUpdater(value); } function onBlankInput(e: ChangeEvent){ let value = e.target.value.toUpperCase(); if(value.length > 1){ value = value[value.length - 1]; } else if(value.length == 0){ modifyThisLetter(value); return; } // Now check that it's a letter let is_letter = value.match("[A-Z]") != null; if(is_letter){ modifyThisLetter(value); } else { // Cancel and do nothing e.preventDefault(); } } if(props.data.is_blank && props.data.ephemeral) { return
{props.data.points}
} else { let className = "text"; if (props.data.is_blank) { // not ephemeral className += " prev-blank"; } let letterClassName = "letter"; if (props.data.highlight) { letterClassName += " highlight"; } return
{props.data.text}
{props.data.points}
} } export function TileTray(props: { letters: Array, trayLength: number, dispatch: TileDispatch }): React.JSX.Element { let elements: JSX.Element[] = []; for (let i=0; i ); } props.letters .filter((x) => {return x !== undefined;}) .forEach((letter, i) => { if (letter.location === LocationType.TRAY) { elements[letter.index] = { props.dispatch({action: TileDispatchActionType.SET_BLANK, blankIndex: i, newBlankValue: value}) }} />} key={"letter" + letter.index} location={{location: LocationType.TRAY, index: letter.index}} dispatch={props.dispatch} /> } }); return (
{elements}
) } export function Grid(props: { cellTypes: CellType[], playerLetters: Array, boardLetters: HighlightableLetterData[], dispatch: TileDispatch}) { const elements = props.cellTypes.map((ct, i) => { const {className, text} = cellTypeToDetails(ct); let tileElement: JSX.Element; if (props.boardLetters[i] !== undefined) { tileElement = ; } else { tileElement = <> {text} ; } return
{tileElement}
; }); props.playerLetters .filter((letter) => {return letter !== undefined}) .forEach((letter, i) => { if (letter.location === LocationType.GRID) { const ct = props.cellTypes[letter.index]; const {className} = cellTypeToDetails(ct); elements[letter.index] =
{ props.dispatch({action: TileDispatchActionType.SET_BLANK, blankIndex: i, newBlankValue: value}); }} />} location={{location: LocationType.GRID, index: letter.index}} dispatch={props.dispatch} />
; } }); return
{elements}
} export function Scores(props: {playerScores: Array}){ let elements = props.playerScores.map((ps) => { return

{ps.name}

{ps.score}
; }); return
{elements}
}