# `Drafter.ActionHandler`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/action/action_handler.ex#L1)

Behaviour for handling application action return values.

Implement this behaviour to intercept action tuples returned from `handle_event/3`
and translate them into state changes. Handlers live in the registering process's
dictionary and are checked most-recently-registered first, stopping at the first
that returns `{:ok, new_state}`. See `Drafter.ActionRegistry` for registration and
dispatch. An action no handler claims leaves the accumulated state unchanged.

## Example

    defmodule MyApp.DrawerHandler do
      @behaviour Drafter.ActionHandler

      @impl true
      def handle_action({:open_drawer, id}, acc_state) do
        {:ok, %{acc_state | open_drawer: id}}
      end

      def handle_action(_action, _acc_state), do: :unhandled
    end

Register before calling `Drafter.run/2`:

    Drafter.ActionRegistry.register(MyApp.DrawerHandler)
    Drafter.run(MyApp)

Return `{:add_event, message, :info}` from any `handle_event/3` clause and the
registered handler will receive it automatically.

# `action`

```elixir
@type action() :: term()
```

The action tuple an application or widget returned.

# `app_state`

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

The state accumulated so far while folding this event's actions.

# `result`

```elixir
@type result() :: {:ok, app_state()} | :unhandled
```

What a handler returns.

`{:ok, new_state}` claims the action and stops dispatch; `:unhandled` passes it to
the next handler. Any other return raises `CaseClauseError` in
`Drafter.ActionRegistry.dispatch/2`.

# `handle_action`

```elixir
@callback handle_action(action(), app_state()) :: result()
```

Handle one action, returning `{:ok, new_state}` to claim it or `:unhandled` to pass.

---

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