TermUI.Component.RenderNode (TermUI v0.2.0)

View Source

Represents a node in the render tree.

RenderNodes are the output of component rendering. They form a tree structure that the renderer converts to terminal buffer cells. Each node has content, styling, and optional children.

Node Types

  • Text nodes: Simple text content with optional styling
  • Box nodes: Rectangular regions that can contain children
  • Stack nodes: Vertical or horizontal arrangements of children

Examples

# Simple text node
RenderNode.text("Hello, World!")

# Styled text
style = Style.new() |> Style.fg(:red) |> Style.bold()
RenderNode.text("Error!", style)

# Box with children
RenderNode.box([
  RenderNode.text("Header"),
  RenderNode.text("Content")
])

# Horizontal stack
RenderNode.stack(:horizontal, [
  RenderNode.text("Left"),
  RenderNode.text("Right")
])

Summary

Types

A cell with position information for the :cells node type

t()

Functions

Creates a box node that can contain children.

Creates a cells node with pre-rendered cells.

Returns the number of direct children of a node.

Creates an empty render node.

Checks if a node is empty.

Sets the height of a node.

Creates a stack node that arranges children in a direction.

Creates a styled wrapper around a node.

Creates a text node with optional styling.

Sets the width of a node.

Types

direction()

@type direction() :: :vertical | :horizontal

node_type()

@type node_type() :: :text | :box | :stack | :empty | :cells

positioned_cell()

@type positioned_cell() :: %{
  x: non_neg_integer(),
  y: non_neg_integer(),
  cell: TermUI.Renderer.Cell.t()
}

A cell with position information for the :cells node type

t()

@type t() :: %TermUI.Component.RenderNode{
  cells: [positioned_cell()] | nil,
  children: [t()],
  content: String.t() | nil,
  direction: direction() | nil,
  height: non_neg_integer() | :auto | nil,
  style: TermUI.Renderer.Style.t() | nil,
  type: node_type(),
  width: non_neg_integer() | :auto | nil
}

Functions

box(children, opts \\ [])

@spec box(
  [t()],
  keyword()
) :: t()

Creates a box node that can contain children.

Options

  • :style - Style to apply to the box background
  • :width - Fixed width or :auto
  • :height - Fixed height or :auto

Examples

iex> RenderNode.box([RenderNode.text("Content")])
%RenderNode{type: :box, children: [%RenderNode{type: :text, content: "Content"}]}

iex> RenderNode.box([RenderNode.text("Styled")], style: Style.new() |> Style.bg(:blue))
%RenderNode{type: :box, style: %Style{bg: :blue}}

cells(cells, opts \\ [])

@spec cells(
  [positioned_cell()],
  keyword()
) :: t()

Creates a cells node with pre-rendered cells.

This is used by widgets that need fine-grained control over cell positioning. The cells list should contain Cell structs with absolute positions.

Examples

iex> cells = [%{x: 0, y: 0, cell: Cell.new("H")}, %{x: 1, y: 0, cell: Cell.new("i")}]
iex> RenderNode.cells(cells)
%RenderNode{type: :cells, cells: [...]}

child_count(render_node)

@spec child_count(t()) :: non_neg_integer()

Returns the number of direct children of a node.

Examples

iex> RenderNode.child_count(RenderNode.text("Hello"))
0

iex> RenderNode.child_count(RenderNode.box([RenderNode.text("A"), RenderNode.text("B")]))
2

empty()

@spec empty() :: t()

Creates an empty render node.

Examples

iex> RenderNode.empty()
%RenderNode{type: :empty}

empty?(render_node)

@spec empty?(t()) :: boolean()

Checks if a node is empty.

Examples

iex> RenderNode.empty?(RenderNode.empty())
true

iex> RenderNode.empty?(RenderNode.text("Hello"))
false

height(node, h)

@spec height(t(), non_neg_integer() | :auto) :: t()

Sets the height of a node.

Examples

iex> RenderNode.box([]) |> RenderNode.height(10)
%RenderNode{type: :box, height: 10}

stack(direction, children, opts \\ [])

@spec stack(direction(), [t()], keyword()) :: t()

Creates a stack node that arranges children in a direction.

Examples

iex> RenderNode.stack(:vertical, [RenderNode.text("Top"), RenderNode.text("Bottom")])
%RenderNode{type: :stack, direction: :vertical, children: [...]}

iex> RenderNode.stack(:horizontal, [RenderNode.text("Left"), RenderNode.text("Right")])
%RenderNode{type: :stack, direction: :horizontal, children: [...]}

styled(node, style)

@spec styled(t(), TermUI.Renderer.Style.t()) :: t()

Creates a styled wrapper around a node.

Applies additional styling to an existing node without changing its structure.

Examples

iex> node = RenderNode.text("Hello")
iex> styled = RenderNode.styled(node, Style.new() |> Style.fg(:red))
iex> styled.children
[%RenderNode{type: :text, content: "Hello"}]

text(content, style \\ nil)

@spec text(String.t(), TermUI.Renderer.Style.t() | nil) :: t()

Creates a text node with optional styling.

Examples

iex> RenderNode.text("Hello")
%RenderNode{type: :text, content: "Hello"}

iex> style = Style.new() |> Style.fg(:red)
iex> node = RenderNode.text("Error", style)
iex> node.style.fg
:red

width(node, w)

@spec width(t(), non_neg_integer() | :auto) :: t()

Sets the width of a node.

Examples

iex> RenderNode.box([]) |> RenderNode.width(20)
%RenderNode{type: :box, width: 20}