Writing markup
Markup is written directly inside your functions, with seven built-in elements.
The elements
Section titled “The elements”| Element | Draws |
|---|---|
<layer> | nothing. A container, and the only element that can hold others |
<rect> | a filled or outlined rectangle |
<text> | a line or block of text |
<sprite> | an image, or an item icon |
<model> | a 3D model, an item, or an NPC’s head |
<line> | a straight line |
<input> | an editable text field |
A button, a checkbox or a scrollbar is built from these. <ui> declares the
interface itself; see <ui>.
Markup is an expression
Section titled “Markup is an expression”A tag is a value of type Component. You can return it, assign it, and pass
it to a component:
const icon = <sprite w={18} h={18} sprite={Icons.COINS} />;null is the markup that draws nothing. A component may return it:
const ware = WARES.at(i);if (ware === null) { return null;}Return one element
Section titled “Return one element”Two siblings cannot be returned side by side. Wrap them in a <layer> or a
fragment, <>…</>:
return ( <> <text y={0} text="Name" w={80} h={16} font={Fonts.PLAIN} /> <text y={16} text="Price" w={40} h={16} font={Fonts.PLAIN} /> </>);A <layer> has a position and a size, clips its children, and hides or moves
as a unit. A fragment’s children are placed straight into its parent, so a
component that returns one cannot be placed with x or y; see
Passing props.
Close every tag
Section titled “Close every tag”<rect />, <sprite />, <text />. An element with children uses the long form:
<layer w="fill" h="fill"> <sprite w="fill" h="fill" sprite={Chrome.BACKDROP} tiling /></layer>Braces let expressions in
Section titled “Braces let expressions in”Anything in {…} is an expression. A template literal interpolates, and ? :
picks between two values:
<text x="right" y={0} w={66} h={16} text={`${ware.price} gp`} font={Fonts.PLAIN} align="right" valign="middle" shadow color={ware.price <= coins ? Colors.AMBER : Colors.RED} />Quoted attributes are strings, and a bare attribute is true: fill means
fill={true}. stringOf(n) turns a number into text when there is nothing to
put around it:
<text x="right" y="center" w={40} h={16} text={stringOf(value)} font={Fonts.PLAIN} align="right" valign="middle" shadow color={color} />Only a layer has children
Section titled “Only a layer has children”A <sprite> or <text> cannot contain anything. Put the pieces side by side
in a layer:
<layer x={6} y={y} w={{ fill: 12 }} h={rowHeight(ware)}> <sprite x={0} y={0} w={36} h={32} item={ware.item} itemCount={-1} />
<text x={44} y={0} w={116} h={14} text={ware.name} font={Fonts.PLAIN} valign="middle" shadow color={Colors.WHITE} /> <text x={44} y={13} w={116} h={12} text={categoryLabel(CategoryNames, ware)} font={Fonts.SMALL} valign="middle" shadow color={Colors.DIM} /></layer>Later siblings draw on top of earlier ones, a static layer aside.
Comments, classes and text content
Section titled “Comments, classes and text content”Comments inside markup go in braces:
<layer w="fill" h="fill"> {/* The backdrop has to come first — children draw in order */} <sprite w="fill" h="fill" sprite={Chrome.BACKDROP} tiling /></layer>Appearance is set with props (color, font, sprite, transparency), and
text with the text prop:
<text text="Confirm" w="fill" h={16} font={Fonts.BOLD} /> // yes<text w="fill" h={16} font={Fonts.BOLD}>Confirm</text> // no