Conditionals & Loops
If, For, and ReactiveFor build children reactively. They are exported directly from PeanutUI.
PeanutUI.If
PeanutUI.For
PeanutUI.ReactiveFor
PeanutUI.LazyIf
If picks a branch based on a condition, which can be a plain boolean or a ref:
PeanutUI.If(condition, function()
return PeanutUI.TextLabel { text = "Yes" }
end).End()Chain ElseIf and Else, then call End():
PeanutUI.If(PeanutUI.isEqual(count, 1), function()
return PeanutUI.TextLabel { text = "One" }
end)
.ElseIf(PeanutUI.isEqual(count, 2), function()
return PeanutUI.TextLabel { text = "Two" }
end)
.Else(function()
return PeanutUI.TextLabel { text = "Many" }
end)
.End()When the condition changes, the branch is swapped automatically — the old widget is destroyed and the new one created.
TIP
For static values better use if value then PeanutUI.TextLabel() else nil.
WARNING
Do not use If for frequently changed values because it re-creates the whole widget and Roblox Instance because it may cause performance issues. Alternatively use visible property of widgets with computed or isEqual
For
For loops over a static table and creates a widget per item:
PeanutUI.For({ "a", "b", "c" }, function(value, index)
return PeanutUI.TextLabel {
text = value
}
end)ReactiveFor
ReactiveFor loops over a reactive table and updates as it changes:
const items = PeanutUI.Reactive({ "a", "b" }, true)
PeanutUI.ReactiveFor(items, function(value)
return PeanutUI.TextLabel {
text = value
}
end, function(value, index)
return value -- key
end)The third argument is a key function — it maps each item to a stable key so widgets are reused rather than recreated when the list changes.
WARNING
ReactiveFor requires a reactive table. Passing a plain table errors — use For for static tables, or wrap the table in reactive.
TIP
Use a shallow reactive table for ReactiveFor so nested tables don't cause unnecessary recalculations.
Lazy
Lazy defers widget creation until the Roblox tree is being built — when widgets become visible to the user. The createFn is not called when the Box is built; it runs later, and the resulting widget is added and created then.
PeanutUI.Lazy(function()
return PeanutUI.TextLabel { text = "Created later" }
end)Use it to keep expensive widget construction off the initial build path, or to create children only once the surrounding tree is being built. It returns a Box widget, so it slots into a children list like the other control-flow helpers.
The most common case is an invisible widget tree: when a subtree starts hidden, you don't want to build it before it's actually shown. Wrap the subtree in Lazy so its widgets aren't created until the tree is being built, rather than eagerly on the initial build.
Using them in children
These return a Box widget, so they slot straight into a children list:
PeanutUI.Frame(
{ size = PeanutUI.Size(200, 200) },
{
PeanutUI.TextLabel { text = "Header" },
PeanutUI.If(PeanutUI.isEqual(count, 0), function()
return PeanutUI.TextLabel { text = "Empty" }
end).End(),
PeanutUI.For(items, function(value)
return PeanutUI.TextLabel { text = value }
end),
}
)