Controls
Five controls take a value from a player: <Slider>, <NumberField>, <TextField>, <Select> and <Toggle>. Each draws the control alone, on the menu tokens, so a game that sets its menu’s colours sets its controls with them.
Their props are in Slider, NumberField, TextField, Select and Toggle.
Every control works the same way:
labelis its accessible name. The control draws no label of its own, as Unity’sSliderand Godot’sHSliderdraw none: the layout around it does, with a Text.valueandonChangeare the caller’s. The control holds no state, so the value it shows is the one the game holds. A NumberField is the one exception: it shows what the player is typing until Enter or the field loses focus.disableddims it, and it takes no change.classNamegoes on the control, for its width in a row.- Any other attribute of the element passes through, as
name,autoComplete,maxLengthoraria-describedbydo, and arefon a TextField reaches its input. The control keeps the ones it sets:value,onChangeand the label.
import { useState } from "react";import { Hud, NumberField, Panel, Select, Slider, Slot, Text, TextField, Toggle,} from "@spawnite/engine";
export function CharacterSetup() { const [name, setName] = useState(""); const [weapon, setWeapon] = useState("Sword"); const [hue, setHue] = useState(200); const [gold, setGold] = useState(100); const [helmet, setHelmet] = useState(true);
return ( <Hud> <Panel slot={Slot.Center} freeCursor> <Text as="label" className="flex items-center gap-3"> Name <TextField label="Name" value={name} placeholder="Character" onChange={setName} /> </Text> <Text as="label" className="flex items-center gap-3"> Weapon <Select label="Weapon" options={["Sword", "Bow", "Staff"]} value={weapon} onChange={setWeapon} /> </Text> <Text as="label" className="flex items-center gap-3"> Hair <Slider label="Hair" value={hue} min={0} max={360} onChange={setHue} className="w-48" /> </Text> <Text as="label" className="flex items-center gap-3"> Gold <NumberField label="Gold" value={gold} min={0} onChange={setGold} /> </Text> <Text as="label" className="flex items-center gap-3"> Helmet <Toggle label="Helmet" value={helmet} onChange={setHelmet} /> </Text> </Panel> </Hud> );}A Panel that holds a control sets freeCursor, so a player under a camera that captures the cursor can reach it.
Slider
Section titled “Slider”<Slider label value min max onChange> picks a number along a track, filled in the accent up to the value. step is 1 unless set. onChange runs at each value the slider moves to; onCommit runs once where a drag or a key press ends, for a change worth making once, such as a save. valueText words the value for a screen reader, such as “50 percent”. style takes what comes from data: --slider-track paints the track, as a colour ramp does.
NumberField
Section titled “NumberField”<NumberField label value onChange> takes a typed number. It calls onChange when the player presses Enter or leaves the field, never at each key, because “0.” on the way to “0.5” is no number. Text that is not a number keeps the value. min and max hold what it reports between them, and display words the value the field shows, such as two decimals.
TextField
Section titled “TextField”<TextField label value onChange> takes a line of text and calls onChange at each key. onCommit runs on Enter and when the field loses focus. placeholder is what the empty field shows.
A key typed in a NumberField or a TextField stops at the field, so a game’s own key listener never takes a letter as a move or a digit as a card pick. Escape and Tab pass through, for a dialog that closes on Escape or traps the focus.
Select
Section titled “Select”<Select label options value onChange> picks one choice from a list that opens. It is the browser’s own, so a phone opens its wheel for it. An option is a string, or { value, label } where the words it shows differ from the value it reports. placeholder is what it shows while value is empty, and a player cannot pick it.
Toggle
Section titled “Toggle”<Toggle label value onChange> is an on-and-off switch, filled in the accent while on. A press calls onChange with the other state. For a choice among a few buttons, use a Button with pressed.
What they are not
Section titled “What they are not”A setting the engine’s Settings panel should hold is a row on the settings page, which lays out its own label, description and cost. These controls are for a game’s own windows.