Files
wehub-resource-sync db620d33df
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:39:25 +08:00

84 lines
2.5 KiB
C#

// Copyright (c) Microsoft. All rights reserved.
using Harness.ConsoleReactiveFramework;
namespace Harness.ConsoleReactiveComponents;
/// <summary>
/// Props for <see cref="TopBottomRule"/>.
/// </summary>
public record TopBottomRuleProps : ConsoleReactiveProps
{
/// <summary>Gets the foreground color of the horizontal rules. If <c>null</c>, the default terminal color is used.</summary>
public ConsoleColor? Color { get; init; }
}
/// <summary>
/// A component that renders a top and bottom horizontal rule (─) with children
/// stacked vertically between them.
/// </summary>
public class TopBottomRule : ConsoleReactiveComponent<TopBottomRuleProps, ConsoleReactiveState>
{
/// <summary>
/// Calculates the total height including the top rule, children, and bottom rule.
/// </summary>
/// <param name="props">The component props containing children.</param>
/// <returns>2 (for the rules) plus the sum of all children heights.</returns>
public static int CalculateHeight(TopBottomRuleProps props)
{
int childrenHeight = 0;
foreach (var child in props.Children)
{
childrenHeight += child.BaseProps?.Height ?? 0;
}
// Top rule + children + bottom rule
return 2 + childrenHeight;
}
/// <inheritdoc />
public override void RenderCore(TopBottomRuleProps props, ConsoleReactiveState state)
{
int ruleWidth = props.Width;
string rule = new('─', ruleWidth);
if (props.Color.HasValue)
{
Console.Write(AnsiEscapes.SetForegroundColor(props.Color.Value));
}
// Top rule
Console.Write(AnsiEscapes.MoveCursor(props.Y, props.X));
Console.Write(rule);
// Render children stacked below the top rule
int currentY = props.Y + 1;
if (props.Color.HasValue)
{
Console.Write(AnsiEscapes.ResetAttributes);
}
foreach (var child in props.Children)
{
child.BaseProps = child.BaseProps! with { X = props.X, Y = currentY };
child.Render();
currentY += child.BaseProps.Height;
}
if (props.Color.HasValue)
{
Console.Write(AnsiEscapes.SetForegroundColor(props.Color.Value));
}
// Bottom rule
Console.Write(AnsiEscapes.MoveCursor(currentY, props.X));
Console.Write(rule);
if (props.Color.HasValue)
{
Console.Write(AnsiEscapes.ResetAttributes);
}
}
}