Entry point for rendering A2UI surfaces as Phoenix function components.
Dispatches each component type to its module via a compile-time type registry built from default components and application config.
Compile-time configuration
The type registry is assembled at compile time from two config keys:
:component_modules— a%{String.t() => module()}map of custom or override component modules. Default:%{}.:use_default_components— whentrue(the default), the 18 built-in components are included and your custom modules are merged on top. Set tofalseto supply your own complete set.
Override a built-in component
# config/config.exs
config :a2ui, component_modules: %{
"Button" => MyApp.A2UI.Button
}Add a new component type
config :a2ui, component_modules: %{
"StatusBadge" => MyApp.A2UI.StatusBadge
}Replace all defaults
config :a2ui,
use_default_components: false,
component_modules: %{
"Text" => MyApp.A2UI.Text,
"Button" => MyApp.A2UI.Button
# ... only your modules are used
}Use default_components/0 to inspect the built-in type → module map at
runtime (e.g. to merge programmatically in a test).
Theme CSS variables
When a createSurface message includes a theme map, the renderer applies
matching values as CSS custom properties on the .a2ui-surface wrapper div.
This lets agent-provided theme colors cascade to all child components via
standard CSS inheritance.
Currently supported mappings:
| Theme key | CSS custom property |
|---|---|
primary_color | --a2ui-primary |
The built-in CSS references --a2ui-primary for buttons, focus rings, and
other accent elements with a fallback default in :root. A per-surface
theme override takes precedence without affecting other surfaces on the page.
Properties with nil values are omitted from the inline style.
Writing custom components
See A2UI.ComponentRenderer for the behaviour, assigns contract, available
helpers, and a full example.
Summary
Functions
Builds a map of ARIA/accessibility attributes from the component's accessibility field.
Extracts the data model path from a binding map.
Renders a single component by dispatching to its type module.
Returns the default component type→module map.
Expands a template config into a list of {component, scope_path} tuples.
Builds phx-change attributes for an input component bound to a data model path.
Like input_attrs/2 but includes phx-value-input-type for components
that need to disambiguate (e.g. ChoicePicker radio vs checkbox).
Returns a list of CSS layout utility class strings for justify and align props.
Renders children of a component using ComponentTree.child_ids/1.
Resolves a single named child component from props.
Resolves a prop value through data binding.
Renders an entire A2UI surface. Finds the root component and renders the tree.
Returns a CSS custom property string for flex weight, or nil if no weight.
Functions
Builds a map of ARIA/accessibility attributes from the component's accessibility field.
Returns an empty map if accessibility is nil.
Extracts the data model path from a binding map.
Used by input components to set phx-value-path.
Renders a single component by dispatching to its type module.
Assigns
component—%A2UI.Component{}ctx—%RenderContext{}
Attributes
component(:any) (required)ctx(:any) (required)
Returns the default component type→module map.
@spec expand_template_entries(map(), A2UI.Components.RenderContext.t()) :: [ {A2UI.Component.t(), String.t()} ]
Expands a template config into a list of {component, scope_path} tuples.
Used by List and Renderer to materialise template children from data model arrays.
Returns [] on error or when the template component is not found.
Builds phx-change attributes for an input component bound to a data model path.
Returns an empty map when path is nil (no binding).
Like input_attrs/2 but includes phx-value-input-type for components
that need to disambiguate (e.g. ChoicePicker radio vs checkbox).
Returns a list of CSS layout utility class strings for justify and align props.
Renders children of a component using ComponentTree.child_ids/1.
Handles static children (IDs list), template children, and no children.
Assigns
component—%A2UI.Component{}ctx—%RenderContext{}
Attributes
component(:any) (required)ctx(:any) (required)
@spec resolve_child(map(), String.t(), A2UI.Components.RenderContext.t()) :: A2UI.Component.t() | nil
Resolves a single named child component from props.
Looks up key in props to get a component ID, then fetches that component
from ctx.components. Returns nil if the key is absent or the ID is not found.
@spec resolve_prop(map(), String.t(), A2UI.Components.RenderContext.t(), any()) :: any()
Resolves a prop value through data binding.
Returns the resolved value or the fallback if resolution fails.
Renders an entire A2UI surface. Finds the root component and renders the tree.
Assigns
surface—%A2UI.Surface{}
Attributes
surface(:any) (required)
Returns a CSS custom property string for flex weight, or nil if no weight.