# A2uiSurfaceComponent

Package: `@threadplane/chat` · 0.3.4

Reference: /docs/api/chat/A2uiSurfaceComponent

```typescript
import { A2uiSurfaceComponent } from '@threadplane/chat';
```

## A2uiSurfaceComponent

Renders an A2UI surface. Supports two input shapes:
- `state` (preferred): chat-side `A2uiSurfaceState`, converted to a
 json-render spec whose `$bindState` props defer each component until
 its data has arrived.
- `surface` (legacy): wire-format `A2uiSurface` fed into `<render-spec>`;
 kept for backwards compatibility.

When both inputs are set, `state` takes priority for rendering AND for
action-message construction; `surface` is only consulted when `state`
is unset.

```typescript
export declare class A2uiSurfaceComponent  {
  constructor();
  readonly action: import("@angular/core").OutputEmitterRef<A2uiActionMessage>;
  readonly catalog: import("@angular/core").InputSignal<Readonly<Record<string, import("@threadplane/render").RenderViewEntry | Type<unknown>>> | Readonly<Record<string, import("@threadplane/render").RenderViewEntry | Type<unknown>>>>;
  readonly events: import("@angular/core").OutputEmitterRef<RenderEvent>;
  readonly handlers: import("@angular/core").InputSignal<Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>>>;
  readonly internalHandlers: import("@angular/core").Signal<{
        'a2ui:event': (params: Record<string, unknown>) => A2uiActionMessage | undefined;
        'a2ui:localAction': (params: Record<string, unknown>) => unknown;
    }>;
  readonly liveStore: import("@threadplane/render").SignalStateStore;
  onRenderEvent(event: RenderEvent): void;
  readonly primaryColor: import("@angular/core").Signal<string | null>;
  readonly registry: import("@angular/core").Signal<import("@threadplane/render").AngularRegistry>;
  readonly rootIds: import("@angular/core").Signal<string[]>;
  readonly spec: import("@angular/core").Signal<import("@json-render/core").Spec | null>;
  readonly state: import("@angular/core").InputSignal<A2uiSurfaceState | undefined>;
  readonly surface: import("@angular/core").InputSignal<A2uiSurface | undefined>;
  readonly surfaceFallback: import("@angular/core").InputSignal<Type<unknown> | undefined>;
  readonly validationError: import("@angular/core").OutputEmitterRef<A2uiErrorMessage>;
}
```

**Angular selector:** `a2ui-surface`

- Input `catalog` (required): `Readonly<Record<string, RenderViewEntry | Type<unknown>>> | Readonly<Record<string, RenderViewEntry | Type<unknown>>>`

- Input `handlers`: `Record<string, (params: Record<string, unknown>) => unknown>`

- Input `state`: `A2uiSurfaceState | undefined`

- Input `surface`: `A2uiSurface | undefined`

- Input `surfaceFallback`: `Type<unknown> | undefined`

- Output `action`: `A2uiActionMessage`

- Output `events`: `RenderEvent`

- Output `validationError`: `A2uiErrorMessage`

### Constructor · overload 1

Constructs a new instance of the `A2uiSurfaceComponent` class

```typescript
constructor();
```

### action

```typescript
readonly action: import("@angular/core").OutputEmitterRef<A2uiActionMessage>;
```

### catalog

```typescript
readonly catalog: import("@angular/core").InputSignal<Readonly<Record<string, import("@threadplane/render").RenderViewEntry | Type<unknown>>> | Readonly<Record<string, import("@threadplane/render").RenderViewEntry | Type<unknown>>>>;
```

### events

```typescript
readonly events: import("@angular/core").OutputEmitterRef<RenderEvent>;
```

### handlers

```typescript
readonly handlers: import("@angular/core").InputSignal<Record<string, (params: Record<string, unknown>) => unknown | Promise<unknown>>>;
```

### internalHandlers

Merge built-in A2UI handlers with consumer-provided handlers.

```typescript
readonly internalHandlers: import("@angular/core").Signal<{
        'a2ui:event': (params: Record<string, unknown>) => A2uiActionMessage | undefined;
        'a2ui:localAction': (params: Record<string, unknown>) => unknown;
    }>;
```

### liveStore

Surface-owned live state store: `$bindState` props read it and input
components write user edits into it, so event-time logic (checks,
action context) sees CURRENT values instead of the agent-seeded
snapshot. Seeded from spec.state with user edits preserved. Public so
hosts (and tests) can read the live values of a rendered surface.

```typescript
readonly liveStore: import("@threadplane/render").SignalStateStore;
```

### onRenderEvent · overload 1

```typescript
onRenderEvent(event: RenderEvent): void;
```

### primaryColor

Agent-set primary color from `createSurface.theme.primaryColor`.
Returns null when unset so the host binding doesn't override the
consumer's `:root`-level `--a2ui-primary` default.

```typescript
readonly primaryColor: import("@angular/core").Signal<string | null>;
```

### registry

Convert ViewRegistry to AngularRegistry for RenderSpecComponent.

```typescript
readonly registry: import("@angular/core").Signal<import("@threadplane/render").AngularRegistry>;
```

### rootIds

Roots from the surface state. The v0.9 wire contract reserves the
component id `root` as the single tree root; we keep the renderer
permissive in case future surfaces emit multiple top-level
components.

Conservative: returns only the first key from componentViews
insertion order.

```typescript
readonly rootIds: import("@angular/core").Signal<string[]>;
```

### spec

Convert the A2UI surface to a json-render Spec for rendering.
 Prefers `state().surface` (the progressively-built wire surface)
 over the legacy `surface` input. surfaceToSpec handles
 children-id-list → spec.children translation + reserved-key
 filtering + path-ref → $bindState rewriting; the rendered tree
 then uses render-element's standard input-mapping
 (`childKeys: el.children`) so catalog components receive the
 inputs they actually declare.

An earlier slot-based progressive renderer mounted root components
 but never populated their childKeys input, leaving Columns/Rows/etc.
 with no children; the spec conversion replaced it.

```typescript
readonly spec: import("@angular/core").Signal<import("@json-render/core").Spec | null>;
```

### state

Chat-side surface state with per-component readiness. When set,
this takes priority and the progressive renderer is used.

```typescript
readonly state: import("@angular/core").InputSignal<A2uiSurfaceState | undefined>;
```

### surface

Wire-format surface (legacy path — kept for backwards compat).

```typescript
readonly surface: import("@angular/core").InputSignal<A2uiSurface | undefined>;
```

### surfaceFallback

Optional top-level placeholder when the surface has no components
yet. Defaults to A2uiDefaultFallbackComponent.

```typescript
readonly surfaceFallback: import("@angular/core").InputSignal<Type<unknown> | undefined>;
```

### validationError

Emitted when a submit is blocked by failing validation checks —
the spec client → agent error message (code VALIDATION_FAILED).

```typescript
readonly validationError: import("@angular/core").OutputEmitterRef<A2uiErrorMessage>;
```