Skip to content

divider element's :style is dropped by UI.Layout.Engine, making fg/bg unusable from the DSL #217

@bmanturner

Description

@bmanturner

Summary

Raxol.View.Components.divider/1 accepts a :style option:

# lib/raxol/view/components.ex:178-187
def divider(opts \\ []) do
  opts = if is_list(opts), do: Map.new(opts), else: opts

  %{
    type: :divider,
    style: Map.get(opts, :style, %{}),
    char: Map.get(opts, :char, "-")
  }
end

And UIRenderer.render_visible_element/3 is ready to honor it:

# lib/raxol/ui/ui_renderer.ex:270-281
defp render_visible_element(
       %{type: :divider, x: x, y: y, width: w, char: char} = element,
       _theme,
       _parent_style
     ) do
  style = Map.get(element, :style, %{})
  fg = Map.get(style, :fg, :white)
  bg = Map.get(style, :bg, :black)
  ch = String.at(char || \"-\", 0) || \"-\"

  for col <- 0..(w - 1), do: {x + col, y, ch, fg, bg, []}
end

But the UI Layout Engine drops :style when it builds the positioned element:

# lib/raxol/ui/layout/engine.ex:356-369
def process_element(%{type: :divider} = divider, space, acc) do
  char = Map.get(divider, :char, \"-\")

  [
    %{
      type: :divider,
      x: space.x,
      y: space.y,
      width: space.width,
      height: 1,
      char: char
      # <-- :style missing here
    }
    | acc
  ]
end

So by the time the renderer reads element.style, it's always %{}, and every divider paints white-on-black regardless of what the caller set.

Reproduction

column do
  [
    text(\"above\"),
    divider(char: \"\", style: %{fg: \"#555555\"}),
    text(\"below\")
  ]
end

Expected: dark-gray divider line.
Actual: white divider line. The :style map set in the DSL never reaches the renderer.

Suggested fix

Add style: Map.get(divider, :style, %{}) to the positioned element at engine.ex:359-368. One-line change; the renderer side is already correct.

While there: _parent_style at ui_renderer.ex:273 is explicitly ignored. Since :fg/:bg are in StyleProcessor.@inheritable_properties, callers might reasonably expect a divider to inherit from its parent when no explicit style is set. Worth a separate decision.

Related

Tested on Raxol 2.4.0. Working locally via a one-line patch to lib/raxol/ui/layout/engine.ex.

Same failure pattern as #216 — style map dropped between the View DSL and the renderer — but different element (:divider vs :box) and different drop site (the engine's divider constructor rather than the box one nesting under attrs.style). Filing separately for clean triage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions