defmodule Pdf.Component.Row do
@moduledoc """
Row component for PDF documents.
Distributes content horizontally in columns by weight.
Operates at Document level.
## Example
doc
|> Pdf.Component.Row.render({50, 700}, {400, 80}, [
{1, fn doc, area -> Pdf.text_at(doc, {area.x, area.y - 14}, "Col 1") end},
{2, fn doc, area -> Pdf.text_at(doc, {area.x, area.y - 14}, "Col 2") end}
], gap: 10)
"""
@doc """
Render a horizontal row at `{x, y}` with size `{w, h}`.
`columns` is a list of `{weight, callback}` tuples where each callback
receives `(doc, %{x, y, width, height})`.
## Options
- `:gap` — space between columns (default `0`)
"""
def render(doc, {x, y}, {w, h}, columns, opts \\ []) when is_list(columns) do
gap = Keyword.get(opts, :gap, 0)
total_weight = columns |> Enum.map(&elem(&1, 0)) |> Enum.sum()
gap_total = gap * max(length(columns) - 1, 0)
available_w = w - gap_total
{doc, _x} =
Enum.reduce(columns, {doc, x}, fn {weight, callback}, {doc, col_x} ->
col_w = available_w * (weight / total_weight)
doc = callback.(doc, %{x: col_x, y: y, width: col_w, height: h})
{doc, col_x + col_w + gap}
end)
doc
end
end