GameTileInput

Open in new tab

Methods

.effectCallback({ scene, round })
.attributeChanged(name)
.mark(position, letter, state)
.clearMarks()
.focus()
.clear()
.setTile(index, letter, state)
.showResult(letters, states)
.define(tag, registry)
.subscribe(context, callback)

CSS Custom Properties

PropertyDefaultDescription
--game-tile-gap6pxGap between tiles
--game-tile-fontmonospaceFont family for tile text
--game-tile-size40pxWidth and height of each tile
--game-tile-radius6pxBorder radius of each tile
--game-tile-borderrgba(255, 255, 255, 0.3)Border color of empty tiles
--game-tile-bgrgba(255, 255, 255, 0.05)Background color of empty tiles
--game-tile-textvar(--game-text, #eee)Text color of tiles
--game-tile-filled-borderrgba(255, 255, 255, 0.5)Border color of filled tiles
--game-tile-filled-bgrgba(255, 255, 255, 0.1)Background color of filled tiles
--game-tile-cursor#0b7285Color of the cursor tile
--game-tile-used#4c6ef5Color for tiles marked as "used"
--game-tile-bad#e03131Color for tiles marked as "bad"
--game-tile-good#2b8a3eColor for tiles marked as "good" (correct position)
--game-tile-close#e67700Color for tiles marked as "close" (wrong position)
--game-tile-wrong#c92a2aColor for tiles marked as "wrong" When used as a standalone element directly inside ``, the component automatically enables/disables itself based on the scene and clears and focuses on each new round. Set the `manual` attribute to suppress this behaviour when managing multiple rows yourself (e.g. a Wordle-style board where you control which row is active).

A Wordle-style tile input component. Renders a row of letter tiles with a blinking cursor, mirrors a hidden <input> element into the tiles, and dispatches events on input and submission. Supports marking tiles with visual states for guess feedback (good, close, wrong) and letter tracking (used, bad).

Attributes

length
long -- Number of tiles (word length). Defaults to 5.
disabled
boolean -- When present, the input is disabled and tiles are dimmed. Automatically set based on game state: disabled when not in the playing state.
value
string -- Get or set the current input value. Setting the attribute updates the tile display.
manual
boolean -- When present, suppresses the automatic enable/disable/clear behavior driven by game state. By default the component auto-enables when the scene is "playing", auto-disables otherwise, and auto-clears on each new round. Use manual for multi-row Wordle-style boards where you manage multiple <game-tile-input> rows yourself and want full control over state.
<game-tile-input length="5" manual></game-tile-input>

Properties

.value
string -- The current text value. Only alphabetic characters are accepted; all others are stripped on input.
.length
long -- The tile count. Reflects the length attribute. Setting this property updates the attribute and re-renders the tiles.

Methods

.focus()
Focus the hidden input so the player can type.
.clear()
Clear the current value and reset all tiles to empty.
.mark(position, letter, state)
Mark a specific letter at a specific position with a visual state. When the player types that letter at that position, the tile displays the marked class. Useful for tracking previously used letters.

Parameters:

  • position -- number -- Tile index (0-based).
  • letter -- string -- Single character.
  • state -- string -- CSS class to apply: "used", "bad", "good", "close", or "wrong".
const input = document.querySelector("game-tile-input");
input.mark(2, "a", "bad");
input.mark(0, "t", "used");
.clearMarks()
Remove all letter marks.
.setTile(index, letter, state?)
Directly set a tile's display. Overrides the input value for that position. Useful for showing guess results.

Parameters:

  • index -- number -- Tile index.
  • letter -- string -- Character to display.
  • state -- string (optional) -- CSS class: "good", "close", or "wrong".
input.setTile(0, "h", "good");
input.setTile(1, "e", "close");
input.setTile(2, "l", "wrong");
.showResult(letters, states)
Show a full word result across all tiles at once.

Parameters:

  • letters -- string[] -- Array of characters.
  • states -- string[] -- Array of CSS class names.
input.showResult(
  ["h", "e", "l", "l", "o"],
  ["good", "close", "wrong", "wrong", "good"],
);

Events Dispatched

game-tile-input
Dispatched on every character change (type or delete). Carries .value (current string) and .position (index of the last changed character). Bubbles up through the DOM, so <game-audio> can use trigger="input" to play a click sound on each keystroke.
game-tile-submit
Dispatched when the player presses Enter with a complete word (value length equals tile length). Carries .value (the submitted word).

Tile States

Tiles can have the following CSS classes, set either automatically from input + marks or manually via .setTile() / .showResult():

Class Visual Purpose
filled Highlighted border Tile has a letter
cursor Blinking teal Current input position
used Blue border/text Letter was used before at this position
bad Red border/text Letter was in a zero-scoring guess at this position
good Green background Letter is correct (right position)
close Orange background Letter exists but in wrong position
wrong Red background Letter is not in the word

Signal Access

Signal Usage
Shell signals Reads scene signal from the shell to auto-disable when not playing, auto-clears and focuses on new rounds

Usage

Basic word input:

<div when-some-scene="playing between paused">
  <game-tile-input length="6"></game-tile-input>
</div>

With click sounds on each keystroke:

<game-audio>
  <game-sample trigger="input" type="noise" gain="0.15" duration="0.025">
  </game-sample>
</game-audio>

<div when-some-scene="playing between paused">
  <game-tile-input length="5"></game-tile-input>
</div>

Handling submissions:

const input = document.querySelector("game-tile-input");

input.addEventListener("game-tile-submit", (e) => {
  const guess = e.value.toLowerCase();
  const result = checkGuess(guess, targetWord);

  input.showResult(
    guess.split(""),
    result.map((r) => r.state),
  );

  for (let i = 0; i < guess.length; i++) {
    if (result[i].state === "wrong") {
      input.mark(i, guess[i], "bad");
    } else {
      input.mark(i, guess[i], "used");
    }
  }
});