Skip to content
Flow-UILive

Widget state

Where ephemeral UI state lives when the server owns the content.

Server data is immutable. What the user is doing right now, a stepper count, an expanded accordion, a draft in a field, is not. Flow-UI separates the two cleanly: content comes from the response, ephemeral state lives in a page scoped store.

The store#

Every page owns a WidgetStateStore, keyed by widget id plus a name the widget chooses. Because state lives outside the views, it survives lazy container recycling: scroll a stepper off screen and back, and its count is still there.

Inside a widgetswift
private var count: Binding<Int> {
    context.state.binding(
        widgetID: context.widgetID,
        key: "count",
        default: content.initial ?? 0
    )
}

binding(widgetID:key:default:) returns a SwiftUI Binding, ready to hand to any control.

Lifecycle rules#

Two rules, both intentional:

  • Refresh clears the store. A pull to refresh means new content; stale interaction state would lie about it.
  • Pagination keeps the store. Appending page two must not reset the stepper the user just touched on page one.

Reaching the backend#

State changes become server knowledge through actions. The stepper fires its change action on every step; an api action carries the news to your endpoint, and the response can mutate the page in return:

json
{
  "type": "stepper_row",
  "id": "item_42",
  "data": { "title": "USB C Cable", "min": 0, "max": 10, "initial": 1 },
  "actions": { "change": { "type": "api", "endpoint": "cart/update", "item": "42" } }
}