Operations on the A2UI component adjacency list.
Components are stored as a flat %{id => %Component{}} map. This module
provides functions to walk the tree via ID references without reconstructing
a nested structure.
Summary
Functions
Determines how a component references its children.
Expands a template configuration into virtual component instances.
Finds the root component (id "root") in the components map.
Validates that all child ID references in components point to existing components.
Functions
@spec child_ids(A2UI.Component.t()) :: {:ids, [String.t()]} | {:template, map()} | {:none, []}
Determines how a component references its children.
Returns:
{:ids, [id]}— for"child"(single) or"children"(list) props{:template, template_config}— for"children"map with"template"key{:none, []}— when no children are referenced
Examples
iex> comp = %A2UI.Component{id: "c", type: "Card", props: %{"child" => "inner"}}
iex> A2UI.ComponentTree.child_ids(comp)
{:ids, ["inner"]}
iex> comp = %A2UI.Component{id: "r", type: "Row", props: %{"children" => ["a", "b"]}}
iex> A2UI.ComponentTree.child_ids(comp)
{:ids, ["a", "b"]}
@spec expand_template(map(), A2UI.DataModel.t(), String.t()) :: {:ok, [{String.t(), non_neg_integer(), String.t()}]} | {:error, atom()}
Expands a template configuration into virtual component instances.
Given a template config like %{"componentId" => "item", "path" => "/items"},
looks up the array at path in the data model and produces one entry per element.
Returns {:ok, [{virtual_id, index, scope_path}]} or {:error, reason}.
Virtual IDs follow the pattern "componentId__index".
Scope paths follow "base_path/path/index".
@spec root(%{required(String.t()) => A2UI.Component.t()}) :: {:ok, A2UI.Component.t()} | {:error, :no_root}
Finds the root component (id "root") in the components map.
Examples
iex> components = %{"root" => %A2UI.Component{id: "root", type: "Column"}}
iex> A2UI.ComponentTree.root(components)
{:ok, %A2UI.Component{id: "root", type: "Column"}}
@spec validate_references(%{required(String.t()) => A2UI.Component.t()}) :: :ok | {:error, {:missing_refs, [{String.t(), String.t()}]}}
Validates that all child ID references in components point to existing components.
Returns :ok if all references are valid, or {:error, {:missing_refs, list}}
with a list of {parent_id, missing_child_id} tuples.