Appearance
2. State and templates
State is a signal made with state(). Reading and writing it in <script> uses .value; in the template a top-level signal is used bare.
xml
<contract>
{
"name": "Tally",
"role": "group",
"parts": ["root", "add"],
"events": { "change": "fired with the new count" }
}
</contract>
<script>
const count = state(0)
const label = derived(() => `${count.value} so far`)
function add() {
count.value++
emit('change', count.value)
}
</script>
<template>
<div class="root">
<button class="add" @click="add">Add one</button>
<p>{label}</p>
<p if="count > 2">That is a few.</p>
<p else>Keep going.</p>
</div>
</template>state(0)creates a signal.derived()computes from other signals and updates when they change.{label}renders text.@clickattaches a handler.ifandelsechoose between sibling elements.emit('change', value)calls the parent's@changehandler. The compiler checks the name against the contract'sevents: emitchnageand it is an error.
Nothing re-renders as a whole. Each { } is bound to the signals it reads, so clicking updates one text node.
Check
Add <Tally /> to a page, run the dev server and click the button. Then remove "events" from the contract and run tessera check: emitting change is now an error (T4010).