An A2UI surface — a canvas holding a flat list of components.
A surface is the top-level container for A2UI components. It has a unique id,
a list of components (flat adjacency list, not nested tree), an optional
root_component_id that identifies the entry point for rendering, and an
optional data map for initial data model values.
Why flat?
A2UI uses a flat adjacency list rather than nested component trees. This makes surfaces LLM-friendly (flat lists are easier to generate incrementally than nested trees) and enables efficient streaming updates (add, modify, or remove individual components without rebuilding the whole structure).
Parent-child relationships are expressed via children property on container
components (Card, Row, Column, etc.), which reference other component IDs.
Examples
%A2UI.Surface{
id: "dashboard",
root_component_id: "main-card",
components: [
%A2UI.Component{id: "title", type: :text, properties: %{...}},
%A2UI.Component{id: "main-card", type: :card, properties: %{
children: ["title"]
}}
]
}
Summary
Functions
Adds a component to the surface.
Returns the number of components in the surface.
Finds a component by ID.
Creates a new empty surface.
Sets a value in the surface's data model.
Sets the root component ID for rendering.
Types
@type t() :: %A2UI.Surface{ catalog_id: String.t() | nil, components: [A2UI.Component.t()], data: map(), id: String.t(), root_component_id: String.t() | nil }
Functions
@spec add_component(t(), A2UI.Component.t()) :: t()
Adds a component to the surface.
@spec component_count(t()) :: non_neg_integer()
Returns the number of components in the surface.
@spec get_component(t(), String.t()) :: A2UI.Component.t() | nil
Finds a component by ID.
Creates a new empty surface.
Sets a value in the surface's data model.
Sets the root component ID for rendering.