Statefully Documentation

Interactions

Make your prototypes interactive by connecting elements to state transitions.

Click Handlers

Use @click=event_name to trigger transitions when an element is clicked:

button @click=submit: "Submit Form"
a @click=cancel: "Cancel"
div.card @click=select: "Click to select"

Note

The event name (like submit) must match a transition defined in your spec for that state.

Event Name Mapping

Event names in your prototype map to transitions in your spec. Underscores in the prototype become spaces in the transition:

Prototype
Spec Transition
@click=submit
submit -> ...
@click=forgot_password
forgot password -> ...
@click=add_to_cart
add to cart -> ...

Interactive Example

Click the button to toggle between states:

Click Handler Example

State Diagram

Idle*
Active

Preview

The @children Directive

For nested states, use @childrento indicate where child content should be inserted:

[Dashboard]
  div.layout:
    aside.sidebar:
      @children
    main:
      h1: "Main Content"

[Dashboard/Sidebar/expanded]
  nav style="padding: 16px; background: #f5f5f5;":
    button @click=collapse: "<<"
    ul:
      li: "Home"
      li: "Settings"

[Dashboard/Sidebar/collapsed]
  nav style="padding: 16px; width: 60px; background: #f5f5f5;":
    button @click=expand: ">>"

Tip

The @children placeholder is replaced with the content from the currently active child state.

Multiple Click Handlers

A single prototype can have multiple interactive elements:

[Confirmation Dialog]
  div.dialog style="padding: 24px; border: 1px solid #ccc; max-width: 300px;":
    h2: "Are you sure?"
    p: "This action cannot be undone."
    div style="display: flex; gap: 8px; margin-top: 16px;":
      button @click=cancel style="flex: 1;": "Cancel"
      button @click=confirm style="flex: 1; background: #ef4444; color: white;": "Delete"