Skip to content

Your first component

A component is a function that returns markup. This one is a single slot of the player’s backpack:

src/inventory.ts2
const Slot = ({ item, count, slot }: { item: Item; count: Int; slot: Int }): Component => (
<layer x={(slot % COLUMNS) * SLOT_W} y={(slot / COLUMNS) * SLOT_H} w={SLOT_W} h={SLOT_H}>
{item !== -1 && (
<sprite x="center" y="center" w={36} h={32} item={item} itemCount={count}
options={['Use', '', '', '', 'Drop', '', '', '', '', 'Examine']} />
)}
</layer>
);
  • Its name starts with a capital letter.
  • It returns Component, or null to draw nothing.
  • It returns one element. Wrap several in a <layer> or <>…</>; see Writing markup.

export makes a component usable from another file.

<Slot … /> puts a Slot here. Twenty-eight slots are one map:

src/inventory.ts2
export const Backpack = (): Component => {
const inventory = useInventory(Inventories.INVENTORY);
return (
<layer w="fill" h="fill">
{inventory.map((item, slot) => (
<Slot item={item} count={inventory.count(slot)} slot={slot} />
))}
</layer>
);
};

Each Slot places itself from its slot prop; see Layout and geometry.

A component used in one place can be declared inside its caller:

export const Purse = (): Component => {
const Marker = ({ x }: { x: Int }): Component =>
<rect x={x} y={0} w={12} h={12} color={Colors.AMBER} fill />;
return (
<layer w="fill" h={16}>
<Marker x={0} />
<Marker x={20} />
</layer>
);
};

An inner component cannot see its caller’s values. Pass them as props, or move the component to the top level of the file.

A component in another file is imported by name:

src/inventory.ts2
import { createRef, useInventory } from 'ts2';
import { SunkenBox, Window } from './chrome';
import { Colors, Fonts, Icons, Inventories, Items } from './refs';

Imports name other .ts2 files in your project. Hooks come from 'ts2'; the language’s own types and helpers are already in scope.

The game opens a <ui>, returned from a function of its own:

src/inventory.ts2
const inventoryRef = createRef('docs-inventory');
export const inventoryUi = (): UI => (
<ui ref={inventoryRef} w={196} h={330}>
<Window title="Backpack">
<layer x={10} y={42} w={{ fill: 20 }} h={{ fill: 52 }}>
…
<Purse />
</layer>
</Window>
</ui>
);

The ref, declared once with createRef, is the name the game opens the interface by.