// Copyright (c) Microsoft. All rights reserved.
using Harness.ConsoleReactiveFramework;
namespace Harness.ConsoleReactiveComponents;
///
/// Props for .
///
public record TextScrollPanelProps : ConsoleReactiveProps
{
/// Gets the items to render in the scroll panel. Each item is a pre-rendered
/// console string (may include ANSI escape sequences and newlines).
public IReadOnlyList Items { get; init; } = [];
}
///
/// State for .
///
/// The number of items already rendered.
public record TextScrollPanelState(int RenderedCount = 0) : ConsoleReactiveState;
///
/// A component that renders pre-rendered string items within a scroll area.
/// All items are considered finalized — only new items since the last render are output.
/// Use to force a full re-render.
///
public class TextScrollPanel : ConsoleReactiveComponent
{
///
/// Initializes a new instance of the class.
///
public TextScrollPanel()
{
this.State = new TextScrollPanelState();
}
///
/// Resets the panel so all items will be re-rendered on the next Render call.
///
public void Reset()
{
this.State = new TextScrollPanelState();
}
///
public override void RenderCore(TextScrollPanelProps props, TextScrollPanelState state)
{
if (props.Items.Count == 0)
{
return;
}
// Move cursor to the bottom of the scroll area
Console.Write(AnsiEscapes.MoveCursor(props.Y + props.Height - 1, props.X));
// Output only new items since last rendered
for (int i = state.RenderedCount; i < props.Items.Count; i++)
{
Console.Write(props.Items[i]);
}
// Update state to track what we've rendered
this.State = new TextScrollPanelState(props.Items.Count);
}
}