diff --git a/examples/Borders/Borders.csproj b/examples/Borders/Borders.csproj
new file mode 100644
index 0000000..88c1cbb
--- /dev/null
+++ b/examples/Borders/Borders.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ netcoreapp3.1
+ false
+ Demonstrates the different kind of borders.
+
+
+
+
+
+
+
diff --git a/examples/Borders/Program.cs b/examples/Borders/Program.cs
new file mode 100644
index 0000000..faf0eab
--- /dev/null
+++ b/examples/Borders/Program.cs
@@ -0,0 +1,48 @@
+using System;
+using Spectre.Console;
+using Spectre.Console.Rendering;
+
+namespace Borders
+{
+ public static class Program
+ {
+ public static void Main()
+ {
+ var items = new[]
+ {
+ Create("Ascii", Border.Ascii),
+ Create("Ascii2", Border.Ascii2),
+ Create("AsciiDoubleHead", Border.AsciiDoubleHead),
+ Create("Horizontal", Border.Horizontal),
+ Create("Simple", Border.Simple),
+ Create("SimpleHeavy", Border.SimpleHeavy),
+ Create("Minimal", Border.Minimal),
+ Create("MinimalHeavyHead", Border.MinimalHeavyHead),
+ Create("MinimalDoubleHead", Border.MinimalDoubleHead),
+ Create("Square", Border.Square),
+ Create("Rounded", Border.Rounded),
+ Create("Heavy", Border.Heavy),
+ Create("HeavyEdge", Border.HeavyEdge),
+ Create("HeavyHead", Border.HeavyHead),
+ Create("Double", Border.Double),
+ Create("DoubleEdge", Border.DoubleEdge),
+ };
+
+ AnsiConsole.WriteLine();
+ AnsiConsole.Render(new Columns(items).Collapse());
+ }
+
+ private static IRenderable Create(string name, Border border)
+ {
+ var table = new Table().SetBorder(border);
+ table.AddColumns("[yellow]Header 1[/]", "[yellow]Header 2[/]");
+ table.AddRow("Cell", "Cell");
+ table.AddRow("Cell", "Cell");
+
+ return new Panel(table)
+ .SetHeader($" {name} ", Style.Parse("blue"), Justify.Center)
+ .SetBorderStyle(Style.Parse("grey"))
+ .NoBorder();
+ }
+ }
+}
diff --git a/src/Spectre.Console.Tests/Unit/BorderTests.cs b/src/Spectre.Console.Tests/Unit/BorderTests.cs
index e179f10..fdcd369 100644
--- a/src/Spectre.Console.Tests/Unit/BorderTests.cs
+++ b/src/Spectre.Console.Tests/Unit/BorderTests.cs
@@ -1,6 +1,6 @@
using Shouldly;
-using Xunit;
using Spectre.Console.Rendering;
+using Xunit;
namespace Spectre.Console.Tests.Unit
{
@@ -30,6 +30,23 @@ namespace Spectre.Console.Tests.Unit
border.ShouldBeSameAs(Border.None);
}
}
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().NoBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(3);
+ console.Lines[0].ShouldBe("Header 1 Header 2");
+ console.Lines[1].ShouldBe("Cell Cell ");
+ console.Lines[2].ShouldBe("Cell Cell ");
+ }
}
public sealed class AsciiBorder
@@ -56,6 +73,118 @@ namespace Spectre.Console.Tests.Unit
border.ShouldBeSameAs(Border.Ascii);
}
}
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().AsciiBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("+---------------------+");
+ console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
+ console.Lines[2].ShouldBe("|----------+----------|");
+ console.Lines[3].ShouldBe("| Cell | Cell |");
+ console.Lines[4].ShouldBe("| Cell | Cell |");
+ console.Lines[5].ShouldBe("+---------------------+");
+ }
+ }
+
+ public sealed class Ascii2Border
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.Ascii2.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.Ascii2.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Ascii2);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().Ascii2Border();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("+----------+----------+");
+ console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
+ console.Lines[2].ShouldBe("|----------+----------|");
+ console.Lines[3].ShouldBe("| Cell | Cell |");
+ console.Lines[4].ShouldBe("| Cell | Cell |");
+ console.Lines[5].ShouldBe("+----------+----------+");
+ }
+ }
+
+ public sealed class AsciiDoubleHeadBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.AsciiDoubleHead.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.AsciiDoubleHead.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.AsciiDoubleHead);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().AsciiDoubleHeadBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("+----------+----------+");
+ console.Lines[1].ShouldBe("| Header 1 | Header 2 |");
+ console.Lines[2].ShouldBe("|==========+==========|");
+ console.Lines[3].ShouldBe("| Cell | Cell |");
+ console.Lines[4].ShouldBe("| Cell | Cell |");
+ console.Lines[5].ShouldBe("+----------+----------+");
+ }
}
public sealed class SquareBorder
@@ -82,6 +211,26 @@ namespace Spectre.Console.Tests.Unit
border.ShouldBeSameAs(Border.Square);
}
}
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().SquareBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("┌──────────┬──────────┐");
+ console.Lines[1].ShouldBe("│ Header 1 │ Header 2 │");
+ console.Lines[2].ShouldBe("├──────────┼──────────┤");
+ console.Lines[3].ShouldBe("│ Cell │ Cell │");
+ console.Lines[4].ShouldBe("│ Cell │ Cell │");
+ console.Lines[5].ShouldBe("└──────────┴──────────┘");
+ }
}
public sealed class RoundedBorder
@@ -108,6 +257,544 @@ namespace Spectre.Console.Tests.Unit
border.ShouldBeSameAs(Border.Square);
}
}
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().RoundedBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("╭──────────┬──────────╮");
+ console.Lines[1].ShouldBe("│ Header 1 │ Header 2 │");
+ console.Lines[2].ShouldBe("├──────────┼──────────┤");
+ console.Lines[3].ShouldBe("│ Cell │ Cell │");
+ console.Lines[4].ShouldBe("│ Cell │ Cell │");
+ console.Lines[5].ShouldBe("╰──────────┴──────────╯");
+ }
+ }
+
+ public sealed class MinimalBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.Minimal.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.Minimal.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Minimal);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().MinimalBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe(" Header 1 │ Header 2 ");
+ console.Lines[2].ShouldBe(" ──────────┼────────── ");
+ console.Lines[3].ShouldBe(" Cell │ Cell ");
+ console.Lines[4].ShouldBe(" Cell │ Cell ");
+ console.Lines[5].ShouldBe(" ");
+ }
+ }
+
+ public sealed class MinimalHeavyHeadBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.MinimalHeavyHead.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.MinimalHeavyHead.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Minimal);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().MinimalHeavyHeadBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe(" Header 1 │ Header 2 ");
+ console.Lines[2].ShouldBe(" ━━━━━━━━━━┿━━━━━━━━━━ ");
+ console.Lines[3].ShouldBe(" Cell │ Cell ");
+ console.Lines[4].ShouldBe(" Cell │ Cell ");
+ console.Lines[5].ShouldBe(" ");
+ }
+ }
+
+ public sealed class MinimalDoubleHeadBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.MinimalDoubleHead.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.MinimalDoubleHead.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.MinimalDoubleHead);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().MinimalDoubleHeadBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe(" Header 1 │ Header 2 ");
+ console.Lines[2].ShouldBe(" ══════════╪══════════ ");
+ console.Lines[3].ShouldBe(" Cell │ Cell ");
+ console.Lines[4].ShouldBe(" Cell │ Cell ");
+ console.Lines[5].ShouldBe(" ");
+ }
+ }
+
+ public sealed class SimpleBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.Simple.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.Simple.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Simple);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().SimpleBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe(" Header 1 Header 2 ");
+ console.Lines[2].ShouldBe("───────────────────────");
+ console.Lines[3].ShouldBe(" Cell Cell ");
+ console.Lines[4].ShouldBe(" Cell Cell ");
+ console.Lines[5].ShouldBe(" ");
+ }
+ }
+
+ public sealed class HorizontalBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.Horizontal.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.Horizontal.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Horizontal);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().HorizontalBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("───────────────────────");
+ console.Lines[1].ShouldBe(" Header 1 Header 2 ");
+ console.Lines[2].ShouldBe("───────────────────────");
+ console.Lines[3].ShouldBe(" Cell Cell ");
+ console.Lines[4].ShouldBe(" Cell Cell ");
+ console.Lines[5].ShouldBe("───────────────────────");
+ }
+ }
+
+ public sealed class SimpleHeavyBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.SimpleHeavy.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.SimpleHeavy.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Simple);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().SimpleHeavyBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe(" ");
+ console.Lines[1].ShouldBe(" Header 1 Header 2 ");
+ console.Lines[2].ShouldBe("━━━━━━━━━━━━━━━━━━━━━━━");
+ console.Lines[3].ShouldBe(" Cell Cell ");
+ console.Lines[4].ShouldBe(" Cell Cell ");
+ console.Lines[5].ShouldBe(" ");
+ }
+ }
+
+ public sealed class HeavyBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.Heavy.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.Heavy.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Square);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().HeavyBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("┏━━━━━━━━━━┳━━━━━━━━━━┓");
+ console.Lines[1].ShouldBe("┃ Header 1 ┃ Header 2 ┃");
+ console.Lines[2].ShouldBe("┣━━━━━━━━━━╋━━━━━━━━━━┫");
+ console.Lines[3].ShouldBe("┃ Cell ┃ Cell ┃");
+ console.Lines[4].ShouldBe("┃ Cell ┃ Cell ┃");
+ console.Lines[5].ShouldBe("┗━━━━━━━━━━┻━━━━━━━━━━┛");
+ }
+ }
+
+ public sealed class HeavyEdgeBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.HeavyEdge.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.HeavyEdge.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Square);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().HeavyEdgeBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("┏━━━━━━━━━━┯━━━━━━━━━━┓");
+ console.Lines[1].ShouldBe("┃ Header 1 │ Header 2 ┃");
+ console.Lines[2].ShouldBe("┠──────────┼──────────┨");
+ console.Lines[3].ShouldBe("┃ Cell │ Cell ┃");
+ console.Lines[4].ShouldBe("┃ Cell │ Cell ┃");
+ console.Lines[5].ShouldBe("┗━━━━━━━━━━┷━━━━━━━━━━┛");
+ }
+ }
+
+ public sealed class HeavyHeadBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.HeavyHead.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.HeavyHead.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Square);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().HeavyHeadBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("┏━━━━━━━━━━┳━━━━━━━━━━┓");
+ console.Lines[1].ShouldBe("┃ Header 1 ┃ Header 2 ┃");
+ console.Lines[2].ShouldBe("┡━━━━━━━━━━╇━━━━━━━━━━┩");
+ console.Lines[3].ShouldBe("│ Cell │ Cell │");
+ console.Lines[4].ShouldBe("│ Cell │ Cell │");
+ console.Lines[5].ShouldBe("└──────────┴──────────┘");
+ }
+ }
+
+ public sealed class DoubleBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.Double.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.Double.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.Double);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().DoubleBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("╔══════════╦══════════╗");
+ console.Lines[1].ShouldBe("║ Header 1 ║ Header 2 ║");
+ console.Lines[2].ShouldBe("╠══════════╬══════════╣");
+ console.Lines[3].ShouldBe("║ Cell ║ Cell ║");
+ console.Lines[4].ShouldBe("║ Cell ║ Cell ║");
+ console.Lines[5].ShouldBe("╚══════════╩══════════╝");
+ }
+ }
+
+ public sealed class DoubleEdgeBorder
+ {
+ [Fact]
+ public void Should_Return_Correct_Visibility()
+ {
+ // Given, When
+ var visibility = Border.DoubleEdge.Visible;
+
+ // Then
+ visibility.ShouldBeTrue();
+ }
+
+ public sealed class TheSafeGetBorderMethod
+ {
+ [Fact]
+ public void Should_Return_Safe_Border()
+ {
+ // Given, When
+ var border = Border.DoubleEdge.GetSafeBorder(safe: true);
+
+ // Then
+ border.ShouldBeSameAs(Border.DoubleEdge);
+ }
+ }
+
+ [Fact]
+ public void Should_Render_As_Expected()
+ {
+ // Given
+ var console = new PlainConsole();
+ var table = Fixture.GetTable().DoubleEdgeBorder();
+
+ // When
+ console.Render(table);
+
+ // Then
+ console.Lines.Count.ShouldBe(6);
+ console.Lines[0].ShouldBe("╔══════════╤══════════╗");
+ console.Lines[1].ShouldBe("║ Header 1 │ Header 2 ║");
+ console.Lines[2].ShouldBe("╟──────────┼──────────╢");
+ console.Lines[3].ShouldBe("║ Cell │ Cell ║");
+ console.Lines[4].ShouldBe("║ Cell │ Cell ║");
+ console.Lines[5].ShouldBe("╚══════════╧══════════╝");
+ }
+ }
+
+ private static class Fixture
+ {
+ public static Table GetTable()
+ {
+ var table = new Table();
+ table.AddColumns("Header 1", "Header 2");
+ table.AddRow("Cell", "Cell");
+ table.AddRow("Cell", "Cell");
+ return table;
+ }
}
}
}
diff --git a/src/Spectre.Console.sln b/src/Spectre.Console.sln
index 0a41ddf..1341d73 100644
--- a/src/Spectre.Console.sln
+++ b/src/Spectre.Console.sln
@@ -29,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Columns", "..\examples\Colu
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Info", "..\examples\Info\Info.csproj", "{225CE0D4-06AB-411A-8D29-707504FE53B3}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Borders", "..\examples\Borders\Borders.csproj", "{094245E6-4C94-485D-B5AC-3153E878B112}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -135,6 +137,18 @@ Global
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|x64.Build.0 = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|x86.ActiveCfg = Release|Any CPU
{225CE0D4-06AB-411A-8D29-707504FE53B3}.Release|x86.Build.0 = Release|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x64.Build.0 = Debug|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Debug|x86.Build.0 = Debug|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Release|Any CPU.Build.0 = Release|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Release|x64.ActiveCfg = Release|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Release|x64.Build.0 = Release|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.ActiveCfg = Release|Any CPU
+ {094245E6-4C94-485D-B5AC-3153E878B112}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -146,6 +160,7 @@ Global
{1F51C55C-BA4C-4856-9001-0F7924FFB179} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{33357599-C79D-4299-888F-634E2C3EACEF} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
{225CE0D4-06AB-411A-8D29-707504FE53B3} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
+ {094245E6-4C94-485D-B5AC-3153E878B112} = {F0575243-121F-4DEE-9F6B-246E26DC0844}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5729B071-67A0-48FB-8B1B-275E6822086C}
diff --git a/src/Spectre.Console/Rendering/Border.Known.cs b/src/Spectre.Console/Rendering/Border.Known.cs
index ff598f3..4bbf125 100644
--- a/src/Spectre.Console/Rendering/Border.Known.cs
+++ b/src/Spectre.Console/Rendering/Border.Known.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using Spectre.Console.Rendering;
namespace Spectre.Console
@@ -17,6 +18,16 @@ namespace Spectre.Console
///
public static Border Ascii { get; } = new AsciiBorder();
+ ///
+ /// Gets another ASCII border.
+ ///
+ public static Border Ascii2 { get; } = new Ascii2Border();
+
+ ///
+ /// Gets an ASCII border with a double header border.
+ ///
+ public static Border AsciiDoubleHead { get; } = new AsciiDoubleHeadBorder();
+
///
/// Gets a square border.
///
@@ -26,5 +37,61 @@ namespace Spectre.Console
/// Gets a rounded border.
///
public static Border Rounded { get; } = new RoundedBorder();
+
+ ///
+ /// Gets a minimal border.
+ ///
+ public static Border Minimal { get; } = new MinimalBorder();
+
+ ///
+ /// Gets a minimal border with a heavy head.
+ ///
+ public static Border MinimalHeavyHead { get; } = new MinimalHeavyHeadBorder();
+
+ ///
+ /// Gets a minimal border with a double header border.
+ ///
+ public static Border MinimalDoubleHead { get; } = new MinimalDoubleHeadBorder();
+
+ ///
+ /// Gets a simple border.
+ ///
+ public static Border Simple { get; } = new SimpleBorder();
+
+ ///
+ /// Gets a simple border with heavy lines.
+ ///
+ public static Border SimpleHeavy { get; } = new SimpleHeavyBorder();
+
+ ///
+ /// Gets a horizontal border.
+ ///
+ public static Border Horizontal { get; } = new HorizontalBorder();
+
+ ///
+ /// Gets a heavy border.
+ ///
+ public static Border Heavy { get; } = new HeavyBorder();
+
+ ///
+ /// Gets a border with a heavy edge.
+ ///
+ public static Border HeavyEdge { get; } = new HeavyEdgeBorder();
+
+ ///
+ /// Gets a border with a heavy header.
+ ///
+ public static Border HeavyHead { get; } = new HeavyHeadBorder();
+
+ ///
+ /// Gets a double border.
+ ///
+ [SuppressMessage("Naming", "CA1720:Identifier contains type name")]
+ public static Border Double { get; } = new DoubleBorder();
+
+ ///
+ /// Gets a border with a double edge.
+ ///
+ public static Border DoubleEdge { get; } = new DoubleEdgeBorder();
}
}
diff --git a/src/Spectre.Console/Rendering/Borders/Ascii2Border.cs b/src/Spectre.Console/Rendering/Borders/Ascii2Border.cs
new file mode 100644
index 0000000..84e45a2
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/Ascii2Border.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents another old school ASCII border.
+ ///
+ public sealed class Ascii2Border : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "+",
+ BorderPart.HeaderTop => "-",
+ BorderPart.HeaderTopSeparator => "+",
+ BorderPart.HeaderTopRight => "+",
+ BorderPart.HeaderLeft => "|",
+ BorderPart.HeaderSeparator => "|",
+ BorderPart.HeaderRight => "|",
+ BorderPart.HeaderBottomLeft => "|",
+ BorderPart.HeaderBottom => "-",
+ BorderPart.HeaderBottomSeparator => "+",
+ BorderPart.HeaderBottomRight => "|",
+ BorderPart.CellLeft => "|",
+ BorderPart.CellSeparator => "|",
+ BorderPart.CellRight => "|",
+ BorderPart.FooterBottomLeft => "+",
+ BorderPart.FooterBottom => "-",
+ BorderPart.FooterBottomSeparator => "+",
+ BorderPart.FooterBottomRight => "+",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/AsciiDoubleHeadBorder.cs b/src/Spectre.Console/Rendering/Borders/AsciiDoubleHeadBorder.cs
new file mode 100644
index 0000000..78116a5
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/AsciiDoubleHeadBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents an old school ASCII border with a double header border.
+ ///
+ public sealed class AsciiDoubleHeadBorder : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "+",
+ BorderPart.HeaderTop => "-",
+ BorderPart.HeaderTopSeparator => "+",
+ BorderPart.HeaderTopRight => "+",
+ BorderPart.HeaderLeft => "|",
+ BorderPart.HeaderSeparator => "|",
+ BorderPart.HeaderRight => "|",
+ BorderPart.HeaderBottomLeft => "|",
+ BorderPart.HeaderBottom => "=",
+ BorderPart.HeaderBottomSeparator => "+",
+ BorderPart.HeaderBottomRight => "|",
+ BorderPart.CellLeft => "|",
+ BorderPart.CellSeparator => "|",
+ BorderPart.CellRight => "|",
+ BorderPart.FooterBottomLeft => "+",
+ BorderPart.FooterBottom => "-",
+ BorderPart.FooterBottomSeparator => "+",
+ BorderPart.FooterBottomRight => "+",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/DoubleBorder.cs b/src/Spectre.Console/Rendering/Borders/DoubleBorder.cs
new file mode 100644
index 0000000..b0084c9
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/DoubleBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a double border.
+ ///
+ public sealed class DoubleBorder : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "╔",
+ BorderPart.HeaderTop => "═",
+ BorderPart.HeaderTopSeparator => "╦",
+ BorderPart.HeaderTopRight => "╗",
+ BorderPart.HeaderLeft => "║",
+ BorderPart.HeaderSeparator => "║",
+ BorderPart.HeaderRight => "║",
+ BorderPart.HeaderBottomLeft => "╠",
+ BorderPart.HeaderBottom => "═",
+ BorderPart.HeaderBottomSeparator => "╬",
+ BorderPart.HeaderBottomRight => "╣",
+ BorderPart.CellLeft => "║",
+ BorderPart.CellSeparator => "║",
+ BorderPart.CellRight => "║",
+ BorderPart.FooterBottomLeft => "╚",
+ BorderPart.FooterBottom => "═",
+ BorderPart.FooterBottomSeparator => "╩",
+ BorderPart.FooterBottomRight => "╝",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/DoubleEdgeBorder.cs b/src/Spectre.Console/Rendering/Borders/DoubleEdgeBorder.cs
new file mode 100644
index 0000000..b450681
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/DoubleEdgeBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a border with a double edge.
+ ///
+ public sealed class DoubleEdgeBorder : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "╔",
+ BorderPart.HeaderTop => "═",
+ BorderPart.HeaderTopSeparator => "╤",
+ BorderPart.HeaderTopRight => "╗",
+ BorderPart.HeaderLeft => "║",
+ BorderPart.HeaderSeparator => "│",
+ BorderPart.HeaderRight => "║",
+ BorderPart.HeaderBottomLeft => "╟",
+ BorderPart.HeaderBottom => "─",
+ BorderPart.HeaderBottomSeparator => "┼",
+ BorderPart.HeaderBottomRight => "╢",
+ BorderPart.CellLeft => "║",
+ BorderPart.CellSeparator => "│",
+ BorderPart.CellRight => "║",
+ BorderPart.FooterBottomLeft => "╚",
+ BorderPart.FooterBottom => "═",
+ BorderPart.FooterBottomSeparator => "╧",
+ BorderPart.FooterBottomRight => "╝",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/HeavyBorder.cs b/src/Spectre.Console/Rendering/Borders/HeavyBorder.cs
new file mode 100644
index 0000000..5a2f537
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/HeavyBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a heavy border.
+ ///
+ public sealed class HeavyBorder : Border
+ {
+ ///
+ public override Border? SafeBorder => Border.Square;
+
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "┏",
+ BorderPart.HeaderTop => "━",
+ BorderPart.HeaderTopSeparator => "┳",
+ BorderPart.HeaderTopRight => "┓",
+ BorderPart.HeaderLeft => "┃",
+ BorderPart.HeaderSeparator => "┃",
+ BorderPart.HeaderRight => "┃",
+ BorderPart.HeaderBottomLeft => "┣",
+ BorderPart.HeaderBottom => "━",
+ BorderPart.HeaderBottomSeparator => "╋",
+ BorderPart.HeaderBottomRight => "┫",
+ BorderPart.CellLeft => "┃",
+ BorderPart.CellSeparator => "┃",
+ BorderPart.CellRight => "┃",
+ BorderPart.FooterBottomLeft => "┗",
+ BorderPart.FooterBottom => "━",
+ BorderPart.FooterBottomSeparator => "┻",
+ BorderPart.FooterBottomRight => "┛",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/HeavyEdgeBorder.cs b/src/Spectre.Console/Rendering/Borders/HeavyEdgeBorder.cs
new file mode 100644
index 0000000..c01b503
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/HeavyEdgeBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a border with a heavy edge.
+ ///
+ public sealed class HeavyEdgeBorder : Border
+ {
+ ///
+ public override Border? SafeBorder => Border.Square;
+
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "┏",
+ BorderPart.HeaderTop => "━",
+ BorderPart.HeaderTopSeparator => "┯",
+ BorderPart.HeaderTopRight => "┓",
+ BorderPart.HeaderLeft => "┃",
+ BorderPart.HeaderSeparator => "│",
+ BorderPart.HeaderRight => "┃",
+ BorderPart.HeaderBottomLeft => "┠",
+ BorderPart.HeaderBottom => "─",
+ BorderPart.HeaderBottomSeparator => "┼",
+ BorderPart.HeaderBottomRight => "┨",
+ BorderPart.CellLeft => "┃",
+ BorderPart.CellSeparator => "│",
+ BorderPart.CellRight => "┃",
+ BorderPart.FooterBottomLeft => "┗",
+ BorderPart.FooterBottom => "━",
+ BorderPart.FooterBottomSeparator => "┷",
+ BorderPart.FooterBottomRight => "┛",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/HeavyHeadBorder.cs b/src/Spectre.Console/Rendering/Borders/HeavyHeadBorder.cs
new file mode 100644
index 0000000..7ba6538
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/HeavyHeadBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a border with a heavy header.
+ ///
+ public sealed class HeavyHeadBorder : Border
+ {
+ ///
+ public override Border? SafeBorder => Border.Square;
+
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "┏",
+ BorderPart.HeaderTop => "━",
+ BorderPart.HeaderTopSeparator => "┳",
+ BorderPart.HeaderTopRight => "┓",
+ BorderPart.HeaderLeft => "┃",
+ BorderPart.HeaderSeparator => "┃",
+ BorderPart.HeaderRight => "┃",
+ BorderPart.HeaderBottomLeft => "┡",
+ BorderPart.HeaderBottom => "━",
+ BorderPart.HeaderBottomSeparator => "╇",
+ BorderPart.HeaderBottomRight => "┩",
+ BorderPart.CellLeft => "│",
+ BorderPart.CellSeparator => "│",
+ BorderPart.CellRight => "│",
+ BorderPart.FooterBottomLeft => "└",
+ BorderPart.FooterBottom => "─",
+ BorderPart.FooterBottomSeparator => "┴",
+ BorderPart.FooterBottomRight => "┘",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/HorizontalBorder.cs b/src/Spectre.Console/Rendering/Borders/HorizontalBorder.cs
new file mode 100644
index 0000000..4ba3209
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/HorizontalBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a horizontal border.
+ ///
+ public sealed class HorizontalBorder : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => "─",
+ BorderPart.HeaderTop => "─",
+ BorderPart.HeaderTopSeparator => "─",
+ BorderPart.HeaderTopRight => "─",
+ BorderPart.HeaderLeft => " ",
+ BorderPart.HeaderSeparator => " ",
+ BorderPart.HeaderRight => " ",
+ BorderPart.HeaderBottomLeft => "─",
+ BorderPart.HeaderBottom => "─",
+ BorderPart.HeaderBottomSeparator => "─",
+ BorderPart.HeaderBottomRight => "─",
+ BorderPart.CellLeft => " ",
+ BorderPart.CellSeparator => " ",
+ BorderPart.CellRight => " ",
+ BorderPart.FooterBottomLeft => "─",
+ BorderPart.FooterBottom => "─",
+ BorderPart.FooterBottomSeparator => "─",
+ BorderPart.FooterBottomRight => "─",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/MinimalBorder.cs b/src/Spectre.Console/Rendering/Borders/MinimalBorder.cs
new file mode 100644
index 0000000..056d28d
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/MinimalBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a minimal border.
+ ///
+ public sealed class MinimalBorder : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => " ",
+ BorderPart.HeaderTop => " ",
+ BorderPart.HeaderTopSeparator => " ",
+ BorderPart.HeaderTopRight => " ",
+ BorderPart.HeaderLeft => " ",
+ BorderPart.HeaderSeparator => "│",
+ BorderPart.HeaderRight => " ",
+ BorderPart.HeaderBottomLeft => " ",
+ BorderPart.HeaderBottom => "─",
+ BorderPart.HeaderBottomSeparator => "┼",
+ BorderPart.HeaderBottomRight => " ",
+ BorderPart.CellLeft => " ",
+ BorderPart.CellSeparator => "│",
+ BorderPart.CellRight => " ",
+ BorderPart.FooterBottomLeft => " ",
+ BorderPart.FooterBottom => " ",
+ BorderPart.FooterBottomSeparator => " ",
+ BorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/MinimalDoubleHeadBorder.cs b/src/Spectre.Console/Rendering/Borders/MinimalDoubleHeadBorder.cs
new file mode 100644
index 0000000..06c9353
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/MinimalDoubleHeadBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a minimal border with a double header border.
+ ///
+ public sealed class MinimalDoubleHeadBorder : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => " ",
+ BorderPart.HeaderTop => " ",
+ BorderPart.HeaderTopSeparator => " ",
+ BorderPart.HeaderTopRight => " ",
+ BorderPart.HeaderLeft => " ",
+ BorderPart.HeaderSeparator => "│",
+ BorderPart.HeaderRight => " ",
+ BorderPart.HeaderBottomLeft => " ",
+ BorderPart.HeaderBottom => "═",
+ BorderPart.HeaderBottomSeparator => "╪",
+ BorderPart.HeaderBottomRight => " ",
+ BorderPart.CellLeft => " ",
+ BorderPart.CellSeparator => "│",
+ BorderPart.CellRight => " ",
+ BorderPart.FooterBottomLeft => " ",
+ BorderPart.FooterBottom => " ",
+ BorderPart.FooterBottomSeparator => " ",
+ BorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/MinimalHeavyHeadBorder.cs b/src/Spectre.Console/Rendering/Borders/MinimalHeavyHeadBorder.cs
new file mode 100644
index 0000000..6233449
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/MinimalHeavyHeadBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a minimal border with a heavy header.
+ ///
+ public sealed class MinimalHeavyHeadBorder : Border
+ {
+ ///
+ public override Border? SafeBorder => Border.Minimal;
+
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => " ",
+ BorderPart.HeaderTop => " ",
+ BorderPart.HeaderTopSeparator => " ",
+ BorderPart.HeaderTopRight => " ",
+ BorderPart.HeaderLeft => " ",
+ BorderPart.HeaderSeparator => "│",
+ BorderPart.HeaderRight => " ",
+ BorderPart.HeaderBottomLeft => " ",
+ BorderPart.HeaderBottom => "━",
+ BorderPart.HeaderBottomSeparator => "┿",
+ BorderPart.HeaderBottomRight => " ",
+ BorderPart.CellLeft => " ",
+ BorderPart.CellSeparator => "│",
+ BorderPart.CellRight => " ",
+ BorderPart.FooterBottomLeft => " ",
+ BorderPart.FooterBottom => " ",
+ BorderPart.FooterBottomSeparator => " ",
+ BorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/SimpleBorder.cs b/src/Spectre.Console/Rendering/Borders/SimpleBorder.cs
new file mode 100644
index 0000000..481c6c4
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/SimpleBorder.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a simple border.
+ ///
+ public sealed class SimpleBorder : Border
+ {
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => " ",
+ BorderPart.HeaderTop => " ",
+ BorderPart.HeaderTopSeparator => " ",
+ BorderPart.HeaderTopRight => " ",
+ BorderPart.HeaderLeft => " ",
+ BorderPart.HeaderSeparator => " ",
+ BorderPart.HeaderRight => " ",
+ BorderPart.HeaderBottomLeft => "─",
+ BorderPart.HeaderBottom => "─",
+ BorderPart.HeaderBottomSeparator => "─",
+ BorderPart.HeaderBottomRight => "─",
+ BorderPart.CellLeft => " ",
+ BorderPart.CellSeparator => " ",
+ BorderPart.CellRight => " ",
+ BorderPart.FooterBottomLeft => " ",
+ BorderPart.FooterBottom => " ",
+ BorderPart.FooterBottomSeparator => " ",
+ BorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Borders/SimpleHeavyBorder.cs b/src/Spectre.Console/Rendering/Borders/SimpleHeavyBorder.cs
new file mode 100644
index 0000000..20d47d4
--- /dev/null
+++ b/src/Spectre.Console/Rendering/Borders/SimpleHeavyBorder.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Spectre.Console.Rendering
+{
+ ///
+ /// Represents a simple border with heavy lines.
+ ///
+ public sealed class SimpleHeavyBorder : Border
+ {
+ ///
+ public override Border? SafeBorder => Border.Simple;
+
+ ///
+ protected override string GetBoxPart(BorderPart part)
+ {
+ return part switch
+ {
+ BorderPart.HeaderTopLeft => " ",
+ BorderPart.HeaderTop => " ",
+ BorderPart.HeaderTopSeparator => " ",
+ BorderPart.HeaderTopRight => " ",
+ BorderPart.HeaderLeft => " ",
+ BorderPart.HeaderSeparator => " ",
+ BorderPart.HeaderRight => " ",
+ BorderPart.HeaderBottomLeft => "━",
+ BorderPart.HeaderBottom => "━",
+ BorderPart.HeaderBottomSeparator => "━",
+ BorderPart.HeaderBottomRight => "━",
+ BorderPart.CellLeft => " ",
+ BorderPart.CellSeparator => " ",
+ BorderPart.CellRight => " ",
+ BorderPart.FooterBottomLeft => " ",
+ BorderPart.FooterBottom => " ",
+ BorderPart.FooterBottomSeparator => " ",
+ BorderPart.FooterBottomRight => " ",
+ _ => throw new InvalidOperationException("Unknown box part."),
+ };
+ }
+ }
+}
diff --git a/src/Spectre.Console/Rendering/Table.cs b/src/Spectre.Console/Rendering/Table.cs
index 6d65173..a47b3f7 100644
--- a/src/Spectre.Console/Rendering/Table.cs
+++ b/src/Spectre.Console/Rendering/Table.cs
@@ -230,7 +230,8 @@ namespace Spectre.Console
if (firstCell && showBorder)
{
// Show left column edge
- result.Add(new Segment(border.GetPart(BorderPart.CellLeft), borderStyle));
+ var part = firstRow && ShowHeaders ? BorderPart.HeaderLeft : BorderPart.CellLeft;
+ result.Add(new Segment(border.GetPart(part), borderStyle));
}
// Pad column on left side.
@@ -266,12 +267,14 @@ namespace Spectre.Console
if (lastCell && showBorder)
{
// Add right column edge
- result.Add(new Segment(border.GetPart(BorderPart.CellRight), borderStyle));
+ var part = firstRow && ShowHeaders ? BorderPart.HeaderRight : BorderPart.CellRight;
+ result.Add(new Segment(border.GetPart(part), borderStyle));
}
else if (showBorder)
{
// Add column separator
- result.Add(new Segment(border.GetPart(BorderPart.CellSeparator), borderStyle));
+ var part = firstRow && ShowHeaders ? BorderPart.HeaderSeparator : BorderPart.CellSeparator;
+ result.Add(new Segment(border.GetPart(part), borderStyle));
}
}
diff --git a/src/Spectre.Console/Rendering/Traits/Extensions/BorderExtensions.cs b/src/Spectre.Console/Rendering/Traits/Extensions/BorderExtensions.cs
index 314541b..47bd9c1 100644
--- a/src/Spectre.Console/Rendering/Traits/Extensions/BorderExtensions.cs
+++ b/src/Spectre.Console/Rendering/Traits/Extensions/BorderExtensions.cs
@@ -43,6 +43,30 @@ namespace Spectre.Console
return SetBorder(obj, Border.Ascii);
}
+ ///
+ /// Display another ASCII border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T Ascii2Border(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.Ascii2);
+ }
+
+ ///
+ /// Display an ASCII border with a double header border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T AsciiDoubleHeadBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.AsciiDoubleHead);
+ }
+
///
/// Display a rounded border.
///
@@ -55,6 +79,138 @@ namespace Spectre.Console
return SetBorder(obj, Border.Rounded);
}
+ ///
+ /// Display a minimal border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T MinimalBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.Minimal);
+ }
+
+ ///
+ /// Display a minimal border with a heavy head.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T MinimalHeavyHeadBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.MinimalHeavyHead);
+ }
+
+ ///
+ /// Display a minimal border with a double header border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T MinimalDoubleHeadBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.MinimalDoubleHead);
+ }
+
+ ///
+ /// Display a simple border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T SimpleBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.Simple);
+ }
+
+ ///
+ /// Display a simple border with heavy lines.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T SimpleHeavyBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.SimpleHeavy);
+ }
+
+ ///
+ /// Display a simple border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HorizontalBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.Horizontal);
+ }
+
+ ///
+ /// Display a heavy border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HeavyBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.Heavy);
+ }
+
+ ///
+ /// Display a border with a heavy edge.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HeavyEdgeBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.HeavyEdge);
+ }
+
+ ///
+ /// Display a border with a heavy header.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T HeavyHeadBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.HeavyHead);
+ }
+
+ ///
+ /// Display a double border.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T DoubleBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.Double);
+ }
+
+ ///
+ /// Display a border with a double edge.
+ ///
+ /// An object type with a border.
+ /// The object to set the border for.
+ /// The same instance so that multiple calls can be chained.
+ public static T DoubleEdgeBorder(this T obj)
+ where T : class, IHasBorder
+ {
+ return SetBorder(obj, Border.DoubleEdge);
+ }
+
///
/// Sets the border.
///