defmodule Pdf.Component.Divider do @moduledoc """ Divider component for PDF documents. Renders a horizontal or vertical line separator with configurable color, width, style (solid/dashed), and margin. Inspired by Material UI's Divider component. ## Examples # Simple horizontal divider doc |> Pdf.Component.Divider.render({50, 400}, %{width: 200}) # Dashed divider with color doc |> Pdf.Component.Divider.render({50, 400}, %{ width: 200, color: {0.8, 0.8, 0.8}, style: :dashed, thickness: 0.5 }) # Vertical divider doc |> Pdf.Component.Divider.render({250, 700}, %{ height: 100, orientation: :vertical }) """ @default_color {0.85, 0.85, 0.85} @default_thickness 0.5 @default_dash_pattern {3, 3} @doc """ Render a divider at `{x, y}`. ## Style options - `:width` — length for horizontal dividers (default `0`, required for horizontal) - `:height` — length for vertical dividers (default `0`, required for vertical) - `:orientation` — `:horizontal` (default) or `:vertical` - `:color` — line color (default light gray) - `:thickness` — line width in points (default `0.5`) - `:style` — `:solid` (default) or `:dashed` - `:dash` — custom dash pattern `{on, off}` (default `{3, 3}`) - `:margin_top` — space above (default `0`) - `:margin_bottom` — space below (default `0`) """ def render(doc, {x, y}, style \\ %{}) do orientation = Map.get(style, :orientation, :horizontal) color = Map.get(style, :color, @default_color) thickness = Map.get(style, :thickness, @default_thickness) line_style = Map.get(style, :style, :solid) margin_top = Map.get(style, :margin_top, 0) margin_bottom = Map.get(style, :margin_bottom, 0) y = y - margin_top doc = doc |> Pdf.save_state() |> Pdf.set_stroke_color(color) |> Pdf.set_line_width(thickness) doc = apply_dash(doc, line_style, Map.get(style, :dash, @default_dash_pattern)) doc = case orientation do :vertical -> h = Map.get(style, :height, 0) Pdf.line(doc, {x, y}, {x, y - h}) _horizontal -> w = Map.get(style, :width, 0) Pdf.line(doc, {x, y}, {x + w, y}) end doc = Pdf.restore_state(doc) if margin_bottom > 0 do Pdf.spacer(doc, margin_bottom) else doc end end defp apply_dash(doc, :solid, _pattern), do: doc defp apply_dash(doc, :dashed, {on, off}) do Pdf.set_dash(doc, [on, off]) end end