# `LivePanels.Canvas.Layout`
[🔗](https://github.com/livepanels/livepanels/blob/v0.1.0/lib/livepanels/canvas/layout.ex#L1)

Headless canvas layout planning contracts.

`LivePanels.Canvas.Arrange` submits layout commands. This module exposes the
planning side: registered strategy lookup, external-engine adapter payloads,
and conversion from external coordinates back into ordinary `place_item`
command tuples.

# `adapter`

```elixir
@type adapter() :: map()
```

# `placement`

```elixir
@type placement() :: LivePanels.Canvas.Layout.Strategy.placement()
```

# `strategy`

```elixir
@type strategy() :: atom() | String.t() | module()
```

# `adapter`

```elixir
@spec adapter(
  LivePanels.Canvas.State.t(),
  LivePanels.Canvas.Layout.Context.scope(),
  keyword() | map()
) ::
  adapter()
```

Returns a context adapter payload for external layout engines.

# `adapter_commands`

```elixir
@spec adapter_commands(
  LivePanels.Canvas.State.t(),
  map() | [map()],
  keyword() | map()
) :: [
  {:place_item, String.t(), placement()}
]
```

Converts external layout coordinates into `place_item` commands.

Result entries accept atom or string keys: `id`, `x`, `y`, and optional
`w`, `h`, `space`, and `anchor`.

# `adapter_placements`

```elixir
@spec adapter_placements(
  LivePanels.Canvas.State.t(),
  map() | [map()],
  keyword() | map()
) :: [
  {String.t(), placement()}
]
```

Converts external layout coordinates into `{item_id, placement}` tuples.

# `plan`

```elixir
@spec plan(LivePanels.Canvas.State.t(), map() | nil, strategy(), keyword() | map()) ::
  {:ok, [placement()]} | {:error, term()}
```

Returns placement data for a registered layout strategy.

# `registered_strategies`

```elixir
@spec registered_strategies(Phoenix.LiveView.Socket.t() | LivePanels.Canvas.State.t()) ::
  %{
    optional(String.t()) =&gt; module()
  }
```

Returns the layout strategies available to a socket or state.

---

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