Raxol.UI.Components.Harness.BlockBody (Raxol v2.6.1)

View Source

T5's fold-aware entry point: renders a %Raxol.UI.Components.Harness.Block{} as its real, merged per-kind component when expanded, and as Block's own proven one-line-summary-plus-outcome-row when folded.

Per harness-ui-roadmap.md's T5 accept criteria ("each block kind renders its component; folded forms show one-line summary + outcome row") and the D-PA note carried in Block's own moduledoc ("fold semantics post-seal are policy... T5 just renders whatever fold state the block carries"): this module never re-derives or re-emits fold state, it only reads block.fold and picks a rendering strategy.

  • :folded -- delegates to Block.render/2 unchanged. That render is already exactly "header line (fold glyph + kind glyph + summary)
    • outcome row" -- reusing it means the folded form is never a second, possibly-drifting implementation of the same summary.
  • :expanded -- mounts the real component via Raxol.UI.Components.Harness.BodyProvider.mount/3. On any mount failure (schema violation, unknown kind, wrong-kind refusal) or an uncaught raise from inside the mounted component's init/1/render/2 (a bad-shaped-but-present prop -- BodyProvider.validate/2 only checks key presence, never a value's inner shape, see its moduledoc) this falls back to Block.render/2 -- the same total-safety contract Block itself keeps for its own render/construction failures -- and emits the matching telemetry/log, so a fallback is never silent. The rescue lives HERE, at this module's own boundary, not inside BodyProvider.mount/3: this is the module whose moduledoc makes the total-safety promise, and BodyProvider stays a pure, independently test-facing schema seam with no defensive try/rescue of its own.

The completion row survives the expanded mount

A successfully mounted component's view REPLACES Block.render/2's own body entirely -- which would otherwise silently drop Block.completion_rows/2's honesty row (see Block's moduledoc, "The completion row") for every kind except the opaque/plain-text fallback. When the mount succeeds AND block.content carries a :completion key, render/2 wraps the mounted view and the completion row(s) in one Components.column/1 (unfaded -- %{dim: true} only, no prominence threading through this seam, kept simple per T5's own scope). A block with no :completion key mounts and renders exactly as before, no wrapping at all -- byte-identical to today's render.

This unit renders into a plain view map, same as every component in this package (Raxol.View.Components-shaped, buffer-testable without a real terminal) -- no I/O of its own.

Summary

Functions

Renders block's body. context is threaded to Block.render/2 (folded case) and to BodyProvider.mount/3 (expanded case) unchanged; the expanded case also passes block.outcome through for :tool_call's status derivation (see BodyProvider.mount/3's :outcome option).

Functions

render(block, context \\ %{})

@spec render(Raxol.UI.Components.Harness.Block.t(), map()) :: map()

Renders block's body. context is threaded to Block.render/2 (folded case) and to BodyProvider.mount/3 (expanded case) unchanged; the expanded case also passes block.outcome through for :tool_call's status derivation (see BodyProvider.mount/3's :outcome option).