Bound Helpers

The UI builder layer re-exports:

  • ActionBoundValue
  • LiteralValue
  • bound
  • Condition

These helpers exist because this project supports more than one binding style, depending on where the UI is authored.

In Python render code, the most explicit form is the factory API under sdk.ui.bound. That is the low-level shape used to declare a store-bound value, a data-model bound value, an action-bound value, or an explicit literal.

ActionBoundValue(...) is the shorthand for a client value loaded through an action instead of read from store state. LiteralValue(...) does the same for plain literals when you want to be explicit instead of relying on implicit string handling.

In YAML, the same ideas are exposed through compact strings such as @state/page/..., @state/global/..., @state/..., @data/..., @action/..., @literal/..., and @t/..., or through the equivalent explicit object form with type, path, scope, args, and default.

Use a store-bound form when the client should read reactive state. Use a data-bound form when the component should read from the current surface data model. Use an action-bound form when the value should be computed or loaded lazily by invoking an action. Use a literal form when the content must remain plain text even if it resembles binding syntax.

sdk.ui.bound.store("/draft_title", scope="page", default="")
sdk.ui.bound("/draft_title", scope="page", default="")
sdk.ui.bound.data("/filters/search", default="")
sdk.ui.bound.action("demo.users.count", args={"status": "active"}, default=0)
sdk.ui.ActionBoundValue("demo.users.count", args={"status": "active"}, default=0)
sdk.ui.bound.literal("Dashboard")
sdk.ui.LiteralValue("Dashboard")

For YAML, the compact form and the explicit object form are equivalent. The important distinction is:

  • type: store or @state/... means client store binding
  • bare path or @data/... means surface data-model binding

Examples:

sdk.ui.bound.literal("Dashboard")
sdk.ui.bound.store("/draft_title", scope="page", default="")
sdk.ui.bound("/draft_title", scope="page", default="")
sdk.ui.bound.data("/filters/search", default="")
sdk.ui.bound.action("demo.users.count", args={"status": "active"}, default=0)
sdk.ui.ActionBoundValue("demo.users.count", args={"status": "active"}, default=0)
sdk.ui.Condition.AND(
    sdk.ui.Condition(
        sdk.ui.bound.store("/current_path", scope="global", default="/"),
        "==",
        "/demo/users",
    )
)