Responding to events
An event prop takes a function, a handler, that runs when the player does that thing.
Adding a handler
Section titled “Adding a handler”Write the handler inline, on the element that is the target:
<layer x={0} y={ROW_H} w="fill" h={ROW_H} onClick={() => { setShiftDrop(1 - shiftDrop); }}> <CheckboxRow label="Shift-click to drop" on={shiftDrop} /></layer>To handle a click on a component you wrote, such as <CheckboxRow>, put a
<layer> around the call and give the layer the handler.
A handler that is one call can call a function you named:
<text x="center" y={180} w={120} h={16} text="Restore defaults" font={Fonts.SMALL} align="center" valign="middle" shadow color={Colors.DIM} onClick={() => { restoreDefaults(); }} />The events
Section titled “The events”| Prop | Fires when |
|---|---|
onClick | the player clicks |
onClickRepeat | repeatedly, while the button is held down |
onHold | while the pointer is held on the component |
onRelease | the button is released |
onMouseEnter | the pointer enters |
onMouseLeave | the pointer leaves |
onMouseRepeat | repeatedly, while the pointer is inside |
onScrollWheel | the wheel turns over the component |
onOptionSelect | a right-click menu option is chosen — Hover and menus |
onDrag, onDragComplete | the component is dragged, and dropped — Drag and drop |
onTargetEnter, onTargetLeave | a spell or item on this component is selected as something to use, and unselected |
onKey | a key is pressed while the interface is open — Keyboard, input and drag |
onResize | the game window resized the component |
onTimer | about fifty times a second, until stopped. See Timers |
onLoad | once, when the interface opens |
onLoad can fill in a label as the interface opens:
<text ref={poisonLabel} x="right" y="center" w={120} h={16} text="Poison: -" font={Fonts.PLAIN} align="right" valign="middle" shadow color={Colors.WHITE} onLoad={(event) => { writePoison(event.self); }} />Reading what happened
Section titled “Reading what happened”An event that carries information passes it as the handler’s parameter. For
the wheel, event.mouseY is how far it turned and in which direction:
content.onScrollWheel = (event) => { content.scrollY = content.scrollY + event.mouseY * WHEEL; trackScroll(gutter, thumb, capTop, capBottom, content);};| Field | |
|---|---|
self | a handle to the component the event fired on — a ref you did not have to declare |
component, subId | the same component as an address: which component, and which child of it |
mouseX, mouseY | the pointer, relative to the component |
option | which menu option was chosen, numbered from 1 |
optionSubject | the subject the menu showed beside the verb |
keyCode, keyChar | the key pressed: the client’s code for the key, and the character it typed |
dragTarget, dragTargetSubId | what a drag was dropped on, or -1 for nothing |
Declare the parameter only if you read it; the name event is a convention.
Event has the full list.
Changing the component that was clicked
Section titled “Changing the component that was clicked”event.self changes the component the handler is on without a declared ref. It
reads geometry, and can be passed to any function that takes a component:
<layer ref={plate} x="left" y="center" w={PLATE} h={PLATE} options={['Nudge right']} onClick={(event) => { report(event.self, readout); }}const report = (target: ComponentId, into: ComponentId): void => { into.text = `x ${target.x!} · ${target.width!} wide`;};To change another component, declare a ref for it.
In a .map() list, the callback’s index says which row was clicked:
setTab(i).
What a handler can do
Section titled “What a handler can do”A handler body calls functions, reads props, locals, game state and cells, calls setters, and writes through refs. It returns nothing:
const restoreDefaults = (): void => { const [, setRoofs] = useState(roofRemoval); const [, setShiftDrop] = useState(shiftClickDrop); // … setRoofs(1); setShiftDrop(0); // …};A read in a handler is the value at that moment.
Taking a handler off
Section titled “Taking a handler off”Leaving a prop off writes nothing. To take a bound handler off, write null on
one arm of a conditional, or through a ref as ref.onOptionSelect = null:
<layer x={4} y="center" w={36} h={32} optionSubject="Rune scimitar" optionPriority={1} options={locked === 1 ? LOCKED_OPTIONS : OPEN_OPTIONS} onOptionSelect={locked === 1 ? null : (event) => { setChosen(nameOf(event.option)); }}>To react to a server value changing, read it in the markup or use useWatch;
see Watching and reacting.