Skip to content

Conditional visibility ​

Every element accepts if=. The element, and everything inside it, is shown only while the condition is true.

sayshape
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}
Rendered by the SayShape engineOpen in playground

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:

sayshape
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}
Rendered by the SayShape engineOpen in playground

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:

sayshape
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"
Rendered by the SayShape engineOpen in playground

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:

sayshape
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:120
Rendered by the SayShape engineOpen in playground

Empty 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).

SayShape v0.1 is an early prototype under the MIT License. Status · GitHub