Repeatable field groups
Use a repeatable field group when an object array should be completed with ordinary fields instead of editing an entire JSON document. Workflow routes, recipients, request headers, tool parameters, and approval steps are common examples.
Object repeatable field group repeater-group
{
"routes": [
{
"id": "vip",
"match": "customer.level = vip",
"destination": "sales"
},
{
"id": "fallback",
"match": "execution.status = failed",
"destination": "review"
}
]
}Primitive repeatable items repeater
Arrays of primitive values such as strings and numbers use a compact repeater. Each row edits one value directly and retains add, reorder, and remove actions.
{
"labels": [
"priority",
"external"
]
}Binding a row template
The Schema defines the array and object structure. A repeater node binds the array, and its child fields bind below items.
The compiler produces a path template such as routes.*.match, which the Renderer resolves to a concrete path such as routes.1.match. Each nested repeater level adds another index. Host errors and asynchronous field validation use concrete paths.
UI node properties
The array Schema's minItems and maxItems control item counts. Child width uses the 12-column layout and automatically stacks in a narrow container.
Choosing a row identity protocol
The default is a runtime identity. It preserves field state across local insertion, editing, movement, and removal without changing the controlled value.
When an external state store replaces complete row objects, the host can provide hostAdapter.identifyRepeaterItem to derive a key from existing business data. The callback cannot mutate the object; duplicate, missing, or invalid identifiers fall back to a runtime key.
UiNode.itemKey is optional. The compiler accepts it only when the item Schema declares the corresponding property as a required string. New rows receive that value because the document has explicitly included identity in the business-value protocol. Do not add a rowId to workflow configuration solely for an engine's internal needs.
Runtime behavior
- Add, remove, move up, and move down return the complete controlled value.
- The corresponding action becomes disabled at a
minItemsormaxItemsboundary. - Read-only state covers row fields, ordering, addition, removal, and form actions.
- The validation summary focuses the exact nested input.
- Row grids automatically stack when the embedding container narrows.
- Primitive arrays continue to use the compact repeater control.
Binding rules and data sources to the current row
A computed, validate, visible, or enabled rule that runs per item must set scope: "row". Paths in the document retain their template form:
Row expressions can read global paths, the current row, or an enclosing row in a nested structure. Errors and traces use concrete paths, while calculation failures and incremental caches remain isolated to the current concrete row.
Data-source dependencies use the same template. For routes.*.provider, a request for the third row includes both the template and routes.2.provider in request.scope.dependencies. The host reads the controlled value by concrete path and does not need to store row metadata.
The routing form is a reference embedded example. Its routes value remains a plain { when, route }[] while supporting row validation and host-managed per-row options.
Current boundaries
Use Data grids when direct fields need compact comparison. Data grids support dialog drafts, bulk operations, and virtual scrolling for large arrays. Matrix questions that share one option set use the separate matrix-single or matrix-multiple field.
