Chat · A2UI

Component Catalog

The built-in A2UI catalog provides 18 Angular components implementing the A2UI v0.9 basic catalog — display, layout, interactive controls, media, and advanced inputs. Pass a2uiBasicCatalog() to the ChatComponent views input to enable A2UI rendering, or instantiate it directly for custom setups.

Import:

import { a2uiBasicCatalog } from '@threadplane/chat';

Signature

function a2uiBasicCatalog(): ViewRegistry

Returns a ViewRegistry mapping 18 A2UI type names to their Angular component implementations. Pass the result to A2uiSurfaceComponent or use it as a starting point for a custom registry.

const catalog = a2uiBasicCatalog();

On the wire, components are flat objects: id, a component string naming the catalog type, and props at the same level. Dynamic props are bare literals or { "path": "/pointer" } data-model bindings.

Display Components

Text

Renders a span of text.

A2UI typeAngular componentSelector
TextA2uiTextComponenta2ui-text
PropTypeDescription
textstringThe text content to display
variant'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'caption' | 'body'Base text style hint. Defaults to body
{"id": "greeting", "component": "Text", "text": "Hello, world!", "variant": "h2"}

Image

Renders an <img> element.

A2UI typeAngular componentSelector
ImageA2uiImageComponenta2ui-image
PropTypeDescription
urlstringImage source URL
descriptionstringAccessibility text for the image
fit'contain' | 'cover' | 'fill' | 'none' | 'scaleDown'How the image resizes to its container (CSS object-fit). Defaults to fill
variant'icon' | 'avatar' | 'smallFeature' | 'mediumFeature' | 'largeFeature' | 'header'Size/style hint. Defaults to mediumFeature

Icon

Renders a Material Symbols glyph by name — A2UI's canonical icon set. The v0.9 catalog names are camelCase (accountCircle, shoppingCart); the component maps them to the matching ligature. An inline { "svgPath": "..." } object renders a raw SVG path instead.

A2UI typeAngular componentSelector
IconA2uiIconComponenta2ui-icon
PropTypeDescription
namestring | { svgPath: string }Material Symbols name (e.g. "check", "locationOn") or an inline SVG path

Host apps must load the Material Symbols Outlined stylesheet for glyphs to render — see the @threadplane/chat README.

Divider

Renders a horizontal or vertical rule.

A2UI typeAngular componentSelector
DividerA2uiDividerComponenta2ui-divider
PropTypeDescription
axis'horizontal' | 'vertical'Orientation. Defaults to horizontal

Layout Components

Layout components receive childKeys — an array of component IDs — and render each child via json-render's RenderElementComponent. They also receive the full spec so that child elements can be looked up by key. On the wire, the children prop is a plain array of ids (or a { path, componentId } template).

Six layout components total

Row, Column, Card, and List are below. Two more layout components — Tabs and Modal — live further down (after the Interactive section) because they also expose interactive state. All six share the same childKeys + spec rendering model.

Row

Arranges children horizontally with a flex row layout.

A2UI typeAngular componentSelector
RowA2uiRowComponenta2ui-row
PropTypeDescription
childKeysstring[]Ordered list of child component IDs (from the wire children array)
justify'start' | 'center' | 'end' | 'spaceAround' | 'spaceBetween' | 'spaceEvenly' | 'stretch'Main-axis arrangement. Defaults to start
align'start' | 'center' | 'end' | 'stretch'Cross-axis alignment. Defaults to stretch
specSpecInjected automatically by the render engine

Column

Arranges children vertically with a flex column layout.

A2UI typeAngular componentSelector
ColumnA2uiColumnComponenta2ui-column
PropTypeDescription
childKeysstring[]Ordered list of child component IDs
justify'start' | 'center' | 'end' | 'spaceAround' | 'spaceBetween' | 'spaceEvenly' | 'stretch'Main-axis arrangement. Defaults to start
align'start' | 'center' | 'end' | 'stretch'Cross-axis alignment. Defaults to stretch
specSpecInjected automatically by the render engine

Card

Renders content inside a rounded bordered card container. On the wire, Card takes a single child id; wrap multiple elements in a Column or Row first.

A2UI typeAngular componentSelector
CardA2uiCardComponenta2ui-card
PropTypeDescription
childKeysstring[]Child component IDs (the wire child id, normalized to an array)
specSpecInjected automatically by the render engine

List

Renders children in a scrollable list.

A2UI typeAngular componentSelector
ListA2uiListComponenta2ui-list
PropTypeDescription
childKeysstring[]Ordered list of child component IDs
direction'vertical' | 'horizontal'Layout direction. Defaults to vertical
align'start' | 'center' | 'end' | 'stretch'Cross-axis alignment. Defaults to stretch
specSpecInjected automatically by the render engine
Template children

For data-driven lists, use the template form instead of a static id array. Set children to {"path": "/items", "componentId": "item-template"} and the surface component will expand the template once per array item, resolving relative paths per item. See the Surface Component page for details.

Interactive Components

Interactive components support two-way data binding and button actions. They receive two special injected props:

  • _bindings — a Record<string, string> auto-populated by the surface-to-spec conversion from { "path": ... } references in the component definition. Maps prop names to JSON Pointer paths. When the user changes a bound value, the component writes it back through the render state store. Agents do not write _bindings directly — they use path references (e.g., {"path": "/name"}) and the render pipeline extracts bindings automatically.
  • emit — injected by the render engine; components call it to dispatch events back to the chat.

Button

Renders a button that dispatches an action when clicked. On the wire, a Button has no text prop — its label is a child Text component referenced by id.

A2UI typeAngular componentSelector
ButtonA2uiButtonComponenta2ui-button
PropTypeDescription
childKeysstring[]Child component IDs whose rendered output is the button's content (the wire child id, normalized to an array)
variant'default' | 'primary' | 'borderless'Visual style hint. Defaults to default
disabledbooleanDisables the button when true
specSpecInjected automatically by the render engine
emitinjectedEvent emitter provided by the render engine

Action wiring: the wire action prop is protocol structure, not a component input. The surface pipeline converts an event action into a render click binding on the element:

{
  "id": "submit",
  "component": "Button",
  "child": "submit_label",
  "variant": "primary",
  "action": {
    "event": {
      "name": "submit",
      "context": {
        "email": { "path": "/email" },
        "formId": "contact"
      }
    }
  }
}

Context values can be path references (resolved at click time) or bare literals. The resulting A2uiActionMessage is emitted on <a2ui-surface>'s (action) output.

TextField

A text input with optional label, supporting single-line, multi-line, numeric, and obscured variants.

A2UI typeAngular componentSelector
TextFieldA2uiTextFieldComponenta2ui-text-field
PropTypeDescription
labelstringInput label
valuestringCurrent value (resolved from a path reference)
variant'shortText' | 'longText' | 'number' | 'obscured'Input type — longText renders a textarea, number a numeric input, obscured a password input. Defaults to shortText
placeholderstringPlaceholder text
validationRegexpstringClient-side validation pattern
_bindingsRecord<string, string>Auto-populated from path references
emitinjectedEvent emitter provided by the render engine
{
  "id": "name-field",
  "component": "TextField",
  "label": "Your name",
  "value": {"path": "/name"}
}

The path reference {"path": "/name"} becomes a live state binding, and _bindings is populated automatically.

CheckBox

A labeled checkbox with two-way binding for its checked state.

A2UI typeAngular componentSelector
CheckBoxA2uiCheckBoxComponenta2ui-check-box
PropTypeDescription
labelstringCheckbox label
valuebooleanCurrent checked state (resolved from a path reference)
_bindingsRecord<string, string>Auto-populated from path references
emitinjectedEvent emitter provided by the render engine

ChoicePicker

Selects one or more options from a list. Replaces the pre-v0.9 MultipleChoice component.

A2UI typeAngular componentSelector
ChoicePickerA2uiChoicePickerComponenta2ui-choice-picker
PropTypeDescription
labelstringField label
options{ label: string; value: string }[]Resolved option labels and values
valuestring | string[]Current selection — bind to a string array in the data model
variant'mutuallyExclusive' | 'multipleSelection'Single-select (radio) vs multi-select. Defaults to mutuallyExclusive
displayStyle'checkbox' | 'chips'Visual style. Defaults to checkbox
filterablebooleanShows a client-side option filter input when true
_bindingsRecord<string, string>Auto-populated from path references
emitinjectedEvent emitter provided by the render engine
{
  "id": "origin",
  "component": "ChoicePicker",
  "label": "Origin",
  "options": [
    {"label": "Los Angeles", "value": "LAX"},
    {"label": "New York", "value": "JFK"}
  ],
  "value": {"path": "/origin"},
  "variant": "mutuallyExclusive"
}

DateTimeInput

A date, time, or datetime input with two-way binding.

A2UI typeAngular componentSelector
DateTimeInputA2uiDateTimeInputComponenta2ui-date-time-input
PropTypeDescription
labelstringInput label
valuestringCurrent ISO 8601 value (resolved from a path reference)
enableDatebooleanInclude the date portion. Defaults to true
enableTimebooleanInclude the time portion. Defaults to false
minstringISO 8601 lower bound (native min)
maxstringISO 8601 upper bound (native max)
_bindingsRecord<string, string>Auto-populated from path references
emitinjectedEvent emitter provided by the render engine

The HTML input type (date, time, or datetime-local) is derived internally from enableDate and enableTime.

{
  "id": "date-field",
  "component": "DateTimeInput",
  "label": "Appointment date",
  "value": {"path": "/appointmentDate"},
  "enableDate": true,
  "enableTime": false
}

Slider

A range slider input with two-way binding.

A2UI typeAngular componentSelector
SliderA2uiSliderComponenta2ui-slider
PropTypeDescription
labelstringSlider label
valuenumberCurrent value (bind via a path reference)
minnumberMinimum value. Defaults to 0
maxnumberMaximum value
_bindingsRecord<string, string>Auto-populated from path references
emitinjectedEvent emitter provided by the render engine
{
  "id": "volume",
  "component": "Slider",
  "label": "Volume",
  "value": {"path": "/volume"},
  "min": 0,
  "max": 100
}

Layout Components (continued)

Tabs

A tabbed container that shows one child panel at a time. On the wire, tabs is an array of { title, child } pairs; the surface pipeline resolves the titles into a tabTitles string array and the child ids into childKeys.

A2UI typeAngular componentSelector
TabsA2uiTabsComponenta2ui-tabs
PropTypeDescription
tabTitlesstring[]Resolved tab titles, in order
childKeysstring[]One child component ID per tab
specSpecInjected automatically by the render engine
emitinjectedEvent emitter provided by the render engine
{
  "id": "info-tabs",
  "component": "Tabs",
  "tabs": [
    {"title": "Overview", "child": "overview-content"},
    {"title": "Details", "child": "detail-list"}
  ]
}

A dialog overlay. On the wire, Modal names a trigger component (rendered inline; clicking it opens the modal) and a content component (rendered inside the overlay). Clicking the backdrop dismisses it.

A2UI typeAngular componentSelector
ModalA2uiModalComponenta2ui-modal
PropTypeDescription
childKeysstring[]The wire trigger and content ids, in that order
specSpecInjected automatically by the render engine
emitinjectedEvent emitter provided by the render engine
{
  "id": "confirm-dialog",
  "component": "Modal",
  "trigger": "open-button",
  "content": "confirm-content"
}

Media Components

Video

Renders an HTML5 <video> element with native controls.

A2UI typeAngular componentSelector
VideoA2uiVideoComponenta2ui-video
PropTypeDescription
urlstringRequired. Video source URL
{
  "id": "intro-video",
  "component": "Video",
  "url": "https://example.com/intro.mp4"
}

AudioPlayer

Renders an HTML5 <audio> element with native controls.

A2UI typeAngular componentSelector
AudioPlayerA2uiAudioPlayerComponenta2ui-audio-player
PropTypeDescription
urlstringRequired. Audio source URL
descriptionstringA description of the audio, such as a title or summary
{
  "id": "podcast",
  "component": "AudioPlayer",
  "url": "https://example.com/episode.mp3",
  "description": "Episode 12"
}

Client-Side Functions

The v0.9 basic catalog defines typed client-side functions that can appear in { "call": ... } dynamic values and checks rules: validation (required, regex, length, numeric, email), formatting (formatString, formatNumber, formatCurrency, formatDate, pluralize), logic (and, or, not), and openUrl. The formatting and logic functions (formatString with ${...} interpolation, formatNumber, formatCurrency, formatDate, pluralize, and, or, not) execute client-side via createA2uiFunctionRegistry(), which surfaceToSpec applies to every dynamic value. openUrl runs as a local action through the surface component's built-in a2ui:localAction fallback (new tab, noopener). The validation functions (required, regex, length, numeric, email) power checks rules ({ condition, message }) on input components: the surface evaluates every rule against the live data model (user edits included) when an event action fires — failing checks block the action, render message under the offending input, and emit a VALIDATION_FAILED error message through the surface component's validationError output. A TextField.validationRegexp with a bound value contributes an implicit regex rule.

Component Summary

A2UI TypeAngular ComponentCategory
TextA2uiTextComponentDisplay
ImageA2uiImageComponentDisplay
IconA2uiIconComponentDisplay
DividerA2uiDividerComponentDisplay
RowA2uiRowComponentLayout
ColumnA2uiColumnComponentLayout
CardA2uiCardComponentLayout
ListA2uiListComponentLayout
ButtonA2uiButtonComponentInteractive
TextFieldA2uiTextFieldComponentInteractive
CheckBoxA2uiCheckBoxComponentInteractive
ChoicePickerA2uiChoicePickerComponentInteractive
TabsA2uiTabsComponentLayout
ModalA2uiModalComponentLayout
VideoA2uiVideoComponentMedia
AudioPlayerA2uiAudioPlayerComponentMedia
DateTimeInputA2uiDateTimeInputComponentInteractive
SliderA2uiSliderComponentInteractive

What's Next