Hover and menus
Two props cover the most common interactions: hover for an appearance under
the pointer, and options for the right-click menu.
hover overrides props while the pointer is inside the component, and undoes
them when it leaves:
<sprite x={4} y="center" w={16} h={16} sprite={on === 1 ? Icons.CHECKBOX_ON : Icons.CHECKBOX_OFF} hover={{ sprite: Icons.CHECKBOX_HOVER }} />releaseAfterMs holds the override that long after the pointer leaves:
<rect w="fill" h="fill" color={0x2a2218} fill hover={{ color: 0x5a4a2a, releaseAfterMs: 400 }} />Hover on a group
Section titled “Hover on a group”For a button made of several pieces, put onMouseEnter and onMouseLeave on
the container, write a cell, and let the pieces read it:
const [hovered, setHovered] = useState(0);
return ( <layer x={x} y={0} w={w} h={22} onMouseEnter={() => { setHovered(1); }} onMouseLeave={() => { setHovered(0); }}> {/* … */} color={hovered === 1 ? Colors.WHITE : Colors.AMBER} />Right-click options
Section titled “Right-click options”options gives a component menu entries, in menu order. An empty string leaves
a slot open, so here Drop is fifth and Examine last:
<sprite x="center" y="center" w={36} h={32} item={item} itemCount={count} options={['Use', '', '', '', 'Drop', '', '', '', '', 'Examine']} />The list can be decided at run time. Name the lists, and choose between them where the component is drawn:
const OPEN_OPTIONS = ['Wield', '', '', '', 'Drop', '', '', '', '', 'Examine'];const LOCKED_OPTIONS = ['', '', '', '', '', '', '', '', '', 'Examine'];<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)); }}> <sprite x="center" y="center" w={36} h={32} item={Items.RUNE_SCIMITAR} itemCountMode="never" /></layer>onOptionSelect fires when any option is chosen; event.option says which,
numbered from 1. optionSubject is the noun after the verb (“Wield Rune scimitar”), and
optionPriority decides whose options come first when two components overlap.
Options the server handles
Section titled “Options the server handles”An option with no onOptionSelect goes to the server when chosen, which is how
buying an item or accepting a trade works. It still needs options.
continueOp offers a dialogue’s “Click here to continue” entry the same way.
Keys on options
Section titled “Keys on options”An option may carry a hotkey, written as an object with the client’s key code (Escape is 13). The key fires the option as a click would:
<text x={0} y={84} w="fill" h={16} font={Fonts.PLAIN} text={dismissed === 1 ? 'Dismissed' : 'Click here to continue'} align="center" valign="middle" shadow color={0x0000ff} continueOp options={[{ label: '', hotkey: KEY_ESCAPE }]} onOptionSelect={() => { setDismissed(1); }} />An empty label makes the option keyboard-only and keeps it out of the menu.
modifiers asks for a held modifier: 1 for ctrl, 2 for alt, 4 for shift.