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

Normalization for LivePanels cross-space drag/drop declarations and payloads.

Drag/drop is explicit opt-in. Items declare the actions they allow and the
placement spaces they may target. Browser drop requests use a single
payload shape:

    %{
      action: :move | :copy | :add,
      target_space: :world | :viewport,
      x: integer,
      y: integer,
      w: pos_integer,
      h: pos_integer,
      anchor: LivePanels.Canvas.Placement.anchor(),
      source_item_id: String.t(), # required for :move and :copy
      source_type: atom() | String.t(), # required for :add
      opts: map()
    }

# `action`

```elixir
@type action() :: :move | :copy | :add
```

# `capability`

```elixir
@type capability() :: %{actions: [action()], targets: [target()]}
```

# `drop`

```elixir
@type drop() :: %{
  :action =&gt; action(),
  :target_space =&gt; target(),
  :placement =&gt; LivePanels.Canvas.Placement.frame(),
  optional(:source_item_id) =&gt; String.t(),
  optional(:source_type) =&gt; atom() | String.t(),
  opts: map()
}
```

# `target`

```elixir
@type target() :: LivePanels.Canvas.Placement.space()
```

# `actions`

```elixir
@spec actions() :: [action()]
```

Returns the supported drag/drop actions.

# `actions_attr`

```elixir
@spec actions_attr(capability() | nil | term()) :: String.t()
```

Serializes allowed drag/drop actions for HTML data attributes.

# `allowed?`

```elixir
@spec allowed?(capability() | nil | term(), action(), target()) :: boolean()
```

Returns true when a drag/drop capability allows an action into a target space.

# `empty`

```elixir
@spec empty() :: capability()
```

Returns an empty drag/drop capability declaration.

# `normalize_capability`

```elixir
@spec normalize_capability(term()) :: {:ok, capability() | nil} | {:error, atom()}
```

Normalizes an item drag/drop capability declaration.

# `targets`

```elixir
@spec targets() :: [target()]
```

Returns the placement spaces that can receive drops.

# `targets_attr`

```elixir
@spec targets_attr(capability() | nil | term()) :: String.t()
```

Serializes allowed drag/drop target spaces for HTML data attributes.

---

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