# `Dala.Screen.Screen`
[🔗](https://github.com/manhvu/dala/blob/main/lib/dala/screen/screen.ex#L1)

Screen behaviour and Spark DSL entry point.

## Usage

    defmodule MyApp.CounterScreen do
      use Dala.Screen

      attribute :count, :integer, default: 0

      screen name: :counter do
        column gap: :space_sm do
          text "Count: @count"
          button "Increment", on_tap: :increment
        end
      end

      def handle_event(:increment, _params, socket) do
        {:noreply, Dala.Socket.assign(socket, :count, socket.assigns.count + 1)}
      end
    end

## Starting a screen

    Dala.Screen.start_root(MyApp.CounterScreen, %{})

## Dispatching events

  Dala.Screen.dispatch(pid, "increment", %{})

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `dispatch`

```elixir
@spec dispatch(identifier :: pid() | atom() | integer(), message :: term()) ::
  :ok | {:error, :not_found}
```

Send a message to a screen identified by `identifier` (id, name, or pid).

Returns `:ok` if sent, `{:error, :not_found}` if identifier doesn't match any screen.

## Examples

    MyApp.MyScreen.dispatch(:my_screen, {:update, data})
    MyApp.MyScreen.dispatch(123, {:update, data})
    MyApp.MyScreen.dispatch(pid, {:update, data})

# `dispatch`

```elixir
@spec dispatch(pid(), String.t(), map()) :: :ok
```

Dispatch a UI event to the screen process. Returns `:ok` synchronously once
the event has been processed and the state updated.

# `ensure_safe_area`

```elixir
@spec ensure_safe_area(Dala.Socket.t()) :: Dala.Socket.t()
```

Ensure the socket has a `:safe_area` assign populated.

On iOS, reads the safe area insets from the platform NIF.
On Android and in test mode, sets all insets to 0.0.

If the socket already has a `:safe_area` assign, returns it unchanged.

# `get_current_module`

```elixir
@spec get_current_module(pid()) :: module()
```

Return the module of the currently active screen in the navigation stack.
Intended for testing and debugging.

# `get_nav_history`

```elixir
@spec get_nav_history(pid()) :: [{module(), Dala.Socket.t()}]
```

Return the navigation history (list of `{module, socket}` pairs, head = most recent).
Intended for testing and debugging.

# `get_socket`

```elixir
@spec get_socket(pid()) :: Dala.Socket.t()
```

Return the current socket state of a running screen.
Intended for testing and debugging — not for production app logic.

# `handle_call`

Apply a navigation action directly. Used by `Dala.Test` to drive navigation
programmatically without needing a UI event. Synchronous — the caller blocks
until the navigation (and re-render, in production mode) completes.

Valid actions mirror the `Dala.Socket` navigation functions:
- `{:push, dest, params}` — push a new screen
- `{:pop}` — pop to the previous screen
- `{:pop_to, dest}` — pop to a specific screen in history
- `{:pop_to_root}` — pop to the root of the current stack
- `{:reset, dest, params}` — replace the entire nav stack

# `list`

```elixir
@spec list() :: [%{id: integer(), name: atom() | nil, pid: pid(), module: module()}]
```

List all registered screens.

Returns a list of maps with `:id`, `:name`, `:pid`, `:module`.

# `safe_area_for_platform`

```elixir
@spec safe_area_for_platform(atom()) :: map()
```

Return safe area insets for the given platform.

iOS: reads from the platform NIF.
Other: returns zeroed insets.

Useful for testing and for code that needs safe area values without a socket.

# `start_link`

```elixir
@spec start_link(module(), map(), keyword()) :: GenServer.on_start()
```

Start a screen process linked to the calling process.

`params` is passed as the first argument to `mount/3`.

# `start_root`

```elixir
@spec start_root(module(), map(), keyword()) :: GenServer.on_start()
```

Start a screen as the root UI screen. Calls mount, renders the component tree
via `Dala.Ui.Renderer`, and sends the binary tree to the native side.

This is the main entry point for production use. `start_link/3` is for tests
(no NIF calls).

---

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