# `Expresso.Element.Tree`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/tree.ex#L1)

The walks over a tree of elements

A container, such as a text box, a column or a list, holds its children
under the key `:elements`. Each function of this module reads the children
of an element with `children/1`, so each walk reads them in the same way.
An element without the key, such as a `pause`, has no children, and `nil`
is an empty list.

Each function visits the elements in document order: an element comes
before its children, and its children come before the next element. A
function that changes the elements calls the function of the caller on an
element first, and then it walks the children of the result.

The overlay expansion, the overlay check, `Expresso.Overlay.Render.identify/1`
and `Expresso.Placement` keep their own walks, because they carry the
context of the parent or they have their own rules. The first three read
the children with `children/1` too. `Expresso.Placement` also reads the
key `:timeline` of a chart.

# `element`

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

An element struct, or a different map with the key `:elements`

# `children`

```elixir
@spec children(element()) :: [element()]
```

Return the children of an element

The function returns `[]` for an element without the key `:elements`, and
for the value `nil`.

    iex> Expresso.Element.Tree.children(%{elements: [%{text: "a"}]})
    [%{text: "a"}]
    iex> Expresso.Element.Tree.children(%{elements: nil})
    []
    iex> Expresso.Element.Tree.children(%{text: "a"})
    []

# `descendants`

```elixir
@spec descendants([element()] | nil) :: [element()]
```

Return each element of a list and each element under it, in document order

    iex> tree = [%{name: "a", elements: [%{name: "b"}]}, %{name: "c"}]
    iex> tree |> Expresso.Element.Tree.descendants() |> Enum.map(& &1.name)
    ["a", "b", "c"]

# `map`

```elixir
@spec map([element()] | nil, (element() -&gt; element())) :: [element()]
```

Change each element of a list and each element under it

The function calls `fun` on an element, and then it changes the children
of the result. An element without the key `:elements` stays without it.

# `map_deck`

```elixir
@spec map_deck(deck, (element() -&gt; element())) :: deck when deck: map()
```

Change each element of each slide of a deck, as `map/2` does

The function takes a deck or a different map with the key `:slides`.

# `map_ok`

```elixir
@spec map_ok([element()] | nil, (element() -&gt; {:ok, element()} | {:error, reason})) ::
  {:ok, [element()]} | {:error, reason}
when reason: term()
```

Change each element of a list and each element under it, and stop at the
first error

`fun` returns `{:ok, element}` or `{:error, reason}`. The function returns
`{:ok, elements}`, or the first error in document order.

# `map_reduce`

```elixir
@spec map_reduce([element()] | nil, acc, (element(), acc -&gt; {element(), acc})) ::
  {[element()], acc}
when acc: term()
```

Change each element of a list and each element under it, with a value that
goes from one element to the next

`fun` takes an element and the value, and it returns the changed element
and the next value, as for `Enum.map_reduce/3`.

# `map_reduce_deck`

```elixir
@spec map_reduce_deck(deck, acc, (element(), acc -&gt; {element(), acc})) :: {deck, acc}
when deck: map(), acc: term()
```

Change each element of each slide of a deck, with a value that goes from
one element to the next, as `map_reduce/3` does

The value goes from the last element of a slide to the first element of
the next slide.

---

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