# `Dala.Ui.List`
[🔗](https://github.com/manhvu/dala/blob/main/lib/dala/ui/list.ex#L1)

Data-driven list component.

A `type: :list` node in your render tree is shorthand for a scrollable list
backed by Elixir data. Dala expands it into a `lazy_list` before rendering,
wrapping each row in a tappable container.

## Basic usage

The default renderer turns each item into a text row. No setup needed:

    %{
      type:  :list,
      props: %{id: :my_list, items: assigns.names},
      children: []
    }

Handle selections in `handle_info/2`:

    def handle_info({:select, :my_list, index}, socket) do
      item = Enum.at(socket.assigns.names, index)
      {:noreply, Dala.Socket.assign(socket, :selected, item)}
    end

## Custom renderer

Register a renderer in `mount/3` to control how each item looks:

    def mount(_params, _session, socket) do
      socket =
        socket
        |> Dala.Socket.assign(:items, load_items())
        |> Dala.Ui.List.put_renderer(:my_list, fn %{name: name, subtitle: sub} ->
          %{
            type: :column,
            props: %{padding: 12},
            children: [
              %{type: :text, props: %{text: name,  text_size: :base}, children: []},
              %{type: :text, props: %{text: sub,   text_size: :sm, text_color: :gray_500}, children: []}
            ]
          }
        end)
      {:ok, socket}
    end

## Default renderer rules

When no custom renderer is registered:
- Binary → text row with the string
- `%{label: _}` → text row with the label
- `%{text: _}`  → text row with the text
- Anything else → `inspect/1` fallback

# `default_renderer`

```elixir
@spec default_renderer(term()) :: map()
```

The default item renderer. Handles binaries, maps with `:label`/`:text`, and
falls back to `inspect/1` for anything else.

# `expand`

```elixir
@spec expand(map(), map(), pid()) :: map()
```

Walk a render tree and expand all `type: :list` nodes into `lazy_list` nodes.

Called internally by `Dala.Screen` before passing the tree to `Dala.Ui.Renderer`.
`renderers` is the `list_renderers` map from `socket.__dala__`. `pid` is the
screen process (used as the tap target for row-select events).

# `put_renderer`

```elixir
@spec put_renderer(Dala.Socket.t(), atom(), (term() -&gt; map())) :: Dala.Socket.t()
```

Register a custom item renderer for a list.

`id` must match the `:id` prop on the `type: :list` node.
`renderer` is a 1-arity function that receives one item and returns a node map.

Call this from `mount/3` or `handle_info/2` — it is stored in `socket.__dala__`
and picked up at render time.

---

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