Summary#
A plain Slot places the caller's content once. Slot(item) renders it once per item, with a different value
each time — so one component can serve a list of anything.
Signature#
// in the component — pass the item
Slot(<value>);
// at the call site — receive it
SomeComponent(items: xs) { x => … }Description#
Some components are about a collection: a picker, a list, a table. The component knows how to lay the collection
out; only the app knows what one row should say. Slot(item) is what connects those.
The component passes the item:
[Composable] component Picker<T>(T[] options) {
render {
Stack {
foreach (var o in options) { Slot(o); }
}
}
}The caller supplies a template, naming the value it receives:
Picker(options: customers) { c =>
Row { Text(c.Name); Hint(c.Region); }
}That block is a template, not content: it runs once per Slot(o), and c is a different customer each time.
The template still sees everything around it. Only the named value comes from the component; the rest of the expression resolves where you wrote it, so a page's own state and the item can appear together:
string search = "";
Picker(options: customers) { c =>
Text(c.Name, bold: c.Name == search); // `c` from Picker, `search` from the page
}A plain Slot is unchanged. A component that just wraps its caller's content — a card, a panel, a dialog —
writes Slot; exactly as before. You only need the argument when the same content has to render more than once with
different values.
A component may use both. Slot(current) for the closed state of a dropdown and Slot(o) inside its list both
render the same template, with different values — which is usually what you want, since the selected row should look
like the rows it was chosen from.
If a caller passes plain content to a component that expects a template, nothing renders at that slot — the same as any unfilled slot. Slots are optional by design.
Examples#
A picker that owns the list and lets its caller own the row:
entity Customer { [MaxLength(100)] string Name; }
[Composable] component Picker<T>(T[] options) {
render {
Stack {
foreach (var o in options) { Slot(o); }
}
}
}
component Home() {
live var rows = Customer.ToList();
render {
Picker(options: rows) { c =>
Text(c.Name);
}
}
}See also#
- component — declaring a component and its parameters
- [Composable] — presentational components in public pages — marking a presentational component so any page can render it