# `Expresso.Overlay.Render`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/overlay/render.ex#L1)

The part of the renderer that writes the CSS contract of the overlays

`identify/1` gives each element with an `on` entity a value for the
`data-el` attribute. `attributes/1` makes the `data-on` and `data-el`
attributes of one element. `style/1` makes the generated style block of a
deck. `Expresso.Renderer` calls each of them.

`docs/overlays.md` gives the contract.

# `attributes`

```elixir
@spec attributes(struct()) :: [{String.t(), String.t()}]
```

Make the overlay attributes of one element

An element with step numbers gets `data-on`, with a space between each
number, and `data-effect` for an effect that is not `:fade`, such as
`data-effect="fly-up"`. An element with an identity gets `data-el`. An
element with either also gets `data-speed` and `data-easing` for a value
that is not `nil`, such as `data-speed="slow"`, `data-speed="450"` and
`data-easing="ease-out"`. An element with the `morph` option gets
`data-morph-key`, and an element with a signature from
`Expresso.Morph.sign/1` gets `data-morph-signature`. The function returns
an empty list for an element without each of these values, and the render
function of the element puts the list into its root tag.

# `identify`

```elixir
@spec identify(Expresso.Deck.t()) :: Expresso.Deck.t()
```

Write the identity of each element with an `on` entity

The value goes into the `el` field of the element. It holds the number of
the slide and the position of the element in the tree, such as `s2-e1`. The
position counts each element of the slide in document order, and a parent
comes before its children. Therefore the value is stable between two renders
of the same deck. An element without an `on` entity keeps `nil`.

The function also writes the effect of each element into its `effect`
field. The effect is the nearest value of these: the `effect` field of the
element, the field of the nearest parent with a value, the `:effect` key of
the metadata of the slide, and the key of the metadata of the deck. The
default is `:fade`. A list with `reveal true` and an effect therefore gives
the effect to each item.

The `speed` and `easing` fields follow the same rule. They have no default,
and `nil` gives the time and the easing of the theme.

# `max_step`

```elixir
@spec max_step(Expresso.Slide.t()) :: pos_integer()
```

Give the maximum step number of a slide

The transformer writes the number into `metadata.max_step`. A slide from the
imperative API has no such key, and its maximum is 1.

# `style`

```elixir
@spec style(Expresso.Deck.t()) :: String.t()
```

Make the generated style block of a deck

The block has these parts:

- One `@property` rule for each state of the deck. It registers the custom
  property as a number with the initial value 0.
- One rule for each step number to the maximum step number of the deck. It
  shows each element with that number in its `data-on` attribute, and it
  sets `--shown: 1`. The theme reads that property for an effect. It also
  plays the `--enter-animation` of the effect, and the theme plays the
  `--exit-animation` of a hidden element.
- One rule for each `on` entity, in document order. It sets the custom
  properties of the entity on the element, at each step of the entity. A
  `dim` value also sets `--dimmed`, which the theme reads for the dimmed
  colors.
- The rules of the frames and of the `highlight` option of each chart, from
  `Expresso.Element.Chart.rules/1`. Each rule of a frame sets the custom
  properties of the frame at its steps, and each rule of a group dims the
  other series at the step of the group.
- The rules of the moves of each tree with `reflow` and of the groups of
  its `highlight` option, from `Expresso.Element.Hierarchy.rules/1`.
- One rule for each speed in milliseconds of the deck, such as
  `[data-speed="450"] { --speed: 450ms; }`. The theme gives the presets.

Call `identify/1` first, because the third and the fourth parts read the
fields that it writes.

---

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