Conditional visibility
Every element accepts if=. The element, and everything inside it, is shown only while the condition is true.
state water=true read=false walk=true
card
check "Water" bind=water
check "Read" bind=read
check "Walk" bind=walk
text "Water packed" tone=good if=water
text "All done" tone=good if={water && read && walk}if= takes a state name (if=water) or an expression (if={count > 0}). Hidden elements take no space and can't be focused or pressed.
Several lines under one condition
Put the lines under a line holding only if=. Like each, it has no look of its own:
state todos=[{text: "Water", done: true}, {text: "Map", done: true}]
card
each items=todos as=t
check "{t.text}" bind=t.done
if={count(todos, 'done') == len(todos)}
text "All done!" tone=good
button "Start over" variant=secondary on=clear:todos
empty "Nothing left to do" if={len(todos) == 0}Else
Right after an if= line (a block or an element with if=), at the same indent, else shows its lines when the condition doesn't hold. else if={…} adds another case:
state view="Week"
card
segmented bind=view options="Week,Month,Year"
if={view == 'Week'}
text "This week"
else if={view == 'Month'}
text "This month"
else
text "This year"Like if, else needs nothing to close it, so a spec still streams line by line.
Choosing a look with an expression
Props that take a fixed set of values, such as tone= and variant=, can also be expressions, which is often clearer than two elements with opposite conditions:
state remaining=-40
card
stat label="Remaining" value={money(remaining)} tone={remaining < 0 ? 'bad' : 'good'}
button "Adjust" variant={remaining < 0 ? 'primary' : 'secondary'} on=set:remaining:120Empty and loading states
An empty element with if= covers the "nothing to show" case. While data is on its way from your app, skeleton placeholders can stand in (Loading, success and failure).