# `Expresso.Element.Hierarchy.Steps`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/hierarchy/steps.ex#L1)

The steps of a tree: the groups of `reveal`, the dim, the steps of each
box, and the moves of `reflow`

A box of a tree is not inside the box of its parent in the HTML, so the
overlay contract cannot hide the boxes under a node with the node. This
module gives each box the steps of its node, or of the nearest node above
it with steps. The line to a node takes the steps of the node.

`Expresso.Overlay.Expand` calls `groups/2` before the counter walk and
`dim/1` after the expansion, as it does for the `reveal` and the `dim`
options of a list. The renderer calls `effective/1` and `rules/2`.

# `center`

# `dim`

```elixir
@spec dim([Expresso.Element.Node.t()]) :: [Expresso.Element.Node.t()]
```

Dim each box from the first step of a later box

A box takes the steps of its node, or of the nearest node above it with
steps. The function adds an `on` entity with the state `dim` to each node,
as the `dim` option of a list does to each item. A box without steps does
not dim.

# `effective`

```elixir
@spec effective(Expresso.Element.Node.t()) :: %{
  required(String.t()) =&gt; [pos_integer()] | nil
}
```

Return the steps of the box of each node, by its name

A node without steps takes the steps of the nearest node above it with
steps. A box with `nil` shows at each step of the tree.

    iex> alias Expresso.Element.Node
    iex> root = %Node{name: "a", elements: [%Node{name: "b", steps: [2, 3], elements: [%Node{name: "c"}]}]}
    iex> Expresso.Element.Hierarchy.Steps.effective(root)
    %{"a" => nil, "b" => [2, 3], "c" => [2, 3]}

# `groups`

```elixir
@spec groups(Expresso.Element.Hierarchy.t(), pos_integer()) ::
  {Expresso.Element.Hierarchy.t(), pos_integer()}
```

Give each group of the `reveal` option one step from the counter

The groups come from the tree after the options of the values, so `sort`
gives the order of `:nodes`. Each node of a group shows from the step of
its group. A node with its own `at` option keeps it, and a `:next` in it
takes a step after the groups. The nodes under it take its steps. The function returns the tree and the
counter after the groups.

# `layouts`

```elixir
@spec layouts(
  Expresso.Element.Node.t(),
  [Expresso.Element.Hierarchy.Layout.size()],
  keyword(),
  Expresso.Element.Hierarchy.Layout.t()
) :: [{pos_integer(), Expresso.Element.Hierarchy.Layout.t()}]
```

Return the boxes of each step of a tree with `reflow`

The function calculates one layout for each step from the boxes that show
at that step. A node that does not show keeps its place when a node under
it shows. The result maps each step to the layout of that step, moved to
the center of the full layout: across for `:top_down`, and down for
`:left_right`.

# `offsets`

```elixir
@spec offsets(
  [{pos_integer(), Expresso.Element.Hierarchy.Layout.t()}],
  Expresso.Element.Hierarchy.Layout.t()
) :: [{pos_integer(), String.t(), number(), number()}]
```

Return the offset of each box at each step of a tree with `reflow`

An offset is the place of the box at the step, less its place in the full
layout. A box that does not show at a step takes the offset of the next
step at which it shows, so it fades in at its place and does not move.
After its last step, it keeps the offset of its last step.

---

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