Stack
Stack several components one under the other as one piece, with one child able to follow another's result.
≈ 839 tokens per use (tool 347 · guidance 250 · typical payload 242)How token costs are estimated
Example: Stack
How did Q3 go?
Q3 in numbers
- Revenue
- $4.6MIncrease of 11%
- Best region
- EuropeIncrease of 21%
- New customers
- 312
- Net retention
- 108%
Revenue by region
| Region | Q2 | Q3 |
|---|---|---|
| North America | $1,840,000 | $1,925,000 |
| Europe | $1,210,000 | $1,462,000 |
| Asia Pacific | $865,000 | $918,000 |
| Latin America | $312,000 | $298,000 |
Europe grew most, up 21%. Latin America dipped.
When to use
- One answer needs 2–6 components that belong together and should arrive as one piece: a summary over a table, a picker over a confirmation, a chart over its KPIs.
- A component below should follow what the user does in a component above. That's a bind.
When not to use
- The parts are independent answers. Call each tool on its own; the host stacks them anyway.
- The parts are parallel views the user switches between. Use Tabs.
- The parts are a procedure with an order. Use Steps.
How it works
items lists 2–6 components by catalog name. Each may carry a short label above it, and an id that siblings can bind to:
{
"items": [
{ "id": "slot", "component": "pick_slot", "props": { "title": "Table for 4 at Casa Lume", "days": ["…"] } },
{ "component": "show_summary", "props": {
"title": "Your reservation",
"facts": [{ "label": "When", "value": { "$bind": "slot.label", "default": "Pick a time above" } }]
} }
]
}In the second scenario above, picking a time fills the reservation card at once ({ action: "select", start: "19:30" } flows into the When fact), with no call to the model. Binds only copy values; use them for pick → confirm, not to duplicate a control a component already has.
- Renders through the Renderer. Children come from the same catalog.
- One more layout inside is fine. A stack may hold columns, a grid or a split, and no deeper.
- Results. Each interactive child's result comes back as
{ child, result }, and the Renderer keeps the latest per child for binds.
How the agent should use it
- Put the main answer first.
- Give an
idonly to children others bind to. - Use
gap: "tight"for parts of one thing (a KPI and its chart), the default for separate parts.
Installation
npx shadcn@latest add https://your-site.com/r/layout-stack.json
Usage
import { LayoutStack } from "@/components/genui/layout-stack"
export const catalog = {
show_stack: LayoutStack,
show_kpis: KpiCard,
show_chart: Chart,
} satisfies GenUICatalogSchema
| Prop | Type | Notes |
|---|---|---|
items | { component, props, id?, label? }[] | 2–6 components |
gap | "tight" | "normal" | Default "normal" |
Host props: status and className. renderChild is injected by the Renderer.