# `A2UICore.State.Components`
[🔗](https://github.com/a2ui-elixir/a2ui/blob/v0.1.1/umbrella/apps/a2ui_core/lib/a2ui_core/state/components.ex#L1)

The set of components on a surface, keyed by id.

An immutable collection: every function returns a new value. Adding an
id that already exists is a `:state` error (replacing is `put/2`);
removing an absent id is a no-op, as in the reference.

Iteration (`to_list/1`, `ids/1`) is in sorted id order, which keeps
graph validation deterministic.

    iex> alias A2UICore.State.{Component, Components}
    iex> {:ok, set} = Components.new() |> Components.add(Component.new("root", "Column"))
    iex> Components.has?(set, "root")
    true
    iex> {:error, error} = Components.add(set, Component.new("root", "Text"))
    iex> error.message
    "Component with id 'root' already exists."

# `t`
*since 0.1.0* 

```elixir
@type t() :: %A2UICore.State.Components{
  items: %{optional(String.t()) =&gt; A2UICore.State.Component.t()}
}
```

# `add`
*since 0.1.0* 

```elixir
@spec add(t(), A2UICore.State.Component.t()) ::
  {:ok, t()} | {:error, A2UICore.Error.t()}
```

Adds a component; an existing id is a `:state` error.

# `from_list`
*since 0.1.0* 

```elixir
@spec from_list([A2UICore.State.Component.t()]) :: t()
```

Builds a set from components, the last one winning on a repeated id.

# `get`
*since 0.1.0* 

```elixir
@spec get(t(), String.t()) :: A2UICore.State.Component.t() | nil
```

The component with `id`, or `nil`.

# `has?`
*since 0.1.0* 

```elixir
@spec has?(t(), String.t()) :: boolean()
```

Whether a component with `id` exists.

# `ids`
*since 0.1.0* 

```elixir
@spec ids(t()) :: [String.t()]
```

The component ids, sorted.

# `new`
*since 0.1.0* 

```elixir
@spec new() :: t()
```

An empty set.

# `put`
*since 0.1.0* 

```elixir
@spec put(t(), A2UICore.State.Component.t()) :: t()
```

Adds or replaces a component.

# `remove`
*since 0.1.0* 

```elixir
@spec remove(t(), String.t()) :: t()
```

Removes a component (an absent id is ignored).

# `size`
*since 0.1.0* 

```elixir
@spec size(t()) :: non_neg_integer()
```

The number of components.

# `to_list`
*since 0.1.0* 

```elixir
@spec to_list(t()) :: [A2UICore.State.Component.t()]
```

The components, sorted by id.

# `trees`
*since 0.1.0* 

```elixir
@spec trees(t()) :: [map()]
```

The component wire objects, sorted by id.

---

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