# `A2UIPhoenix.Context`
[🔗](https://github.com/a2ui-elixir/a2ui/blob/v0.1.1/umbrella/apps/a2ui_phoenix/lib/a2ui_phoenix/context.ex#L1)

What a component needs to render inside a surface.

  * `:surface_id`, `:surface` and `:resolver` — the surface and its
    resolved tree (`A2UICore.Resolution.NodeResolver`);
  * `:components` — the component map, `%{type => function_component}`;
  * `:target` — the `phx-target` of the surface's events (the
    `A2UIPhoenix.Surface` LiveComponent);
  * `:ui` — the surface's local UI state by node `ref` (the open tab, an
    open modal, a choice filter); never sent to the agent;
  * `:markdown` — an optional `(String.t() -> Phoenix.HTML.safe())`
    used for body text (`nil` renders text as is);
  * `:mcp_sandbox` — the URL of the MCP App sandbox proxy page (`nil`
    uses `A2UIPhoenix.Components.MCP.default_sandbox/0`).

Custom components receive it as `@ctx` and use the helpers below to
name their inputs and DOM ids the way the surface expects.

# `t`
*since 0.1.0* 

```elixir
@type t() :: %A2UIPhoenix.Context{
  components: %{
    optional(String.t()) =&gt; (map() -&gt; Phoenix.LiveView.Rendered.t())
  },
  markdown: (String.t() -&gt; Phoenix.HTML.safe()) | nil,
  mcp_sandbox: String.t() | nil,
  resolver: A2UICore.Resolution.NodeResolver.t() | nil,
  surface: A2UICore.State.Surface.t() | nil,
  surface_id: String.t() | nil,
  target: term(),
  ui: %{optional(pos_integer()) =&gt; map()}
}
```

# `dom_id`
*since 0.1.0* 

```elixir
@spec dom_id(t(), A2UICore.Resolution.Node.t() | pos_integer(), String.t() | nil) ::
  String.t()
```

A DOM id for `node`, unique on the page while the node is mounted;
`suffix` names an element inside the component.

    iex> ctx = %A2UIPhoenix.Context{surface_id: "main form"}
    iex> A2UIPhoenix.Context.dom_id(ctx, 7, "input")
    "a2ui-main_form-7-input"

# `input_name`
*since 0.1.0* 

```elixir
@spec input_name(A2UICore.Resolution.Node.t() | pos_integer(), String.t()) ::
  String.t()
```

The form name of an input of `node`: `field` is the component property
the input writes (`"value"` by default).

    iex> A2UIPhoenix.Context.input_name(7)
    "a2ui[7][value]"

# `node`
*since 0.1.0* 

```elixir
@spec node(t(), pos_integer()) :: A2UICore.Resolution.Node.t() | nil
```

The mounted node with `ref`, or `nil`.

# `ui`
*since 0.1.0* 

```elixir
@spec ui(t(), A2UICore.Resolution.Node.t(), atom(), term()) :: term()
```

A value of the local UI state of `node`, or `default`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
