Skip to content

Commit 4fdf422

Browse files
committed
Cleaning up landing pages and animations
1 parent b952b6e commit 4fdf422

19 files changed

Lines changed: 381 additions & 304 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System.ComponentModel;
2+
using Spectre.Console;
3+
using Spectre.Console.Cli;
4+
5+
namespace Spectre.Docs.Cli.Examples.DemoApps.QuickStart;
6+
7+
/// <summary>
8+
/// Quick start example for the CLI documentation index page.
9+
/// </summary>
10+
public static class HomePageExample
11+
{
12+
/// <summary>
13+
/// A complete CLI application demonstrating commands, arguments, and options.
14+
/// </summary>
15+
public static int Run(string[] args)
16+
{
17+
var app = new CommandApp<GreetCommand>();
18+
return app.Run(args);
19+
}
20+
}
21+
22+
/// <summary>
23+
/// Settings for the greet command.
24+
/// </summary>
25+
public class GreetSettings : CommandSettings
26+
{
27+
[CommandArgument(0, "<name>")]
28+
[Description("The name to greet")]
29+
public required string Name { get; init; }
30+
31+
[CommandOption("-c|--count")]
32+
[Description("Number of times to greet")]
33+
[DefaultValue(1)]
34+
public int Count { get; init; }
35+
}
36+
37+
/// <summary>
38+
/// A command that greets a user by name.
39+
/// </summary>
40+
public class GreetCommand : Command<GreetSettings>
41+
{
42+
protected override int Execute(CommandContext context, GreetSettings settings, CancellationToken cancellation)
43+
{
44+
for (var i = 0; i < settings.Count; i++)
45+
{
46+
AnsiConsole.MarkupLine($"Hello, [green]{settings.Name}[/]!");
47+
}
48+
return 0;
49+
}
50+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Output "Spectre.Docs/Content/assets/cli-homepage.svg"
2+
3+
Set Shell "pwsh"
4+
Set FontSize 22
5+
Set Theme "one dark"
6+
Set TransparentBackground "true"
7+
Set Cols 70
8+
Set Rows 14
9+
Set EndBuffer 5s
10+
Set WorkingDirectory "Spectre.Docs.Cli.Examples/bin/Debug/net10.0"
11+
Env SPECTRE_APP "M:Spectre.Docs.Cli.Examples.DemoApps.QuickStart.HomePageExample.Run(System.String[])"
12+
13+
Type "./example --help"
14+
Sleep 400ms
15+
Enter
16+
Sleep 2500ms
17+
18+
Type "./example Alice"
19+
Sleep 400ms
20+
Enter
21+
Sleep 1s
22+
23+
Type "./example Alice --count 3"
24+
Sleep 400ms
25+
Enter
26+
Sleep 1s
27+
28+
Type "./example Alice -c 5"
29+
Sleep 400ms
30+
Enter
31+
Sleep 3s
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Spectre.Console;
2+
3+
namespace Spectre.Docs.Examples.Showcase;
4+
5+
/// <summary>
6+
/// Quick start examples for the Spectre.Console documentation index page.
7+
/// </summary>
8+
public class QuickStartSample : BaseSample
9+
{
10+
/// <summary>
11+
/// Demonstrates basic Spectre.Console features including markup, tables, and status spinners.
12+
/// </summary>
13+
public override void Run(IAnsiConsole console)
14+
{
15+
// Styled text with markup
16+
AnsiConsole.MarkupLine("[bold blue]Welcome[/] to [green]Spectre.Console[/]!");
17+
18+
// A simple table
19+
var table = new Table()
20+
.AddColumn("Feature")
21+
.AddColumn("Description")
22+
.AddRow("[green]Markup[/]", "Rich text with colors and styles")
23+
.AddRow("[blue]Tables[/]", "Structured data display")
24+
.AddRow("[yellow]Progress[/]", "Spinners and progress bars");
25+
AnsiConsole.Write(table);
26+
27+
// Status spinner for work
28+
AnsiConsole.Status()
29+
.Start("Processing...", ctx =>
30+
{
31+
Thread.Sleep(2500);
32+
});
33+
34+
AnsiConsole.MarkupLine("[green]Done![/]"); }
35+
}

Spectre.Docs.Examples/VCR/canvas.tape

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Set Cols 82
88
Set Rows 16
99
Set EndBuffer 5s
1010

11-
Exec "dotnet run --project .\Spectre.Docs.Examples\ --no-build showcase canvas"
11+
Exec "dotnet run --project ./Spectre.Docs.Examples/ --no-build showcase canvas"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Output "Spectre.Docs/Content/assets/quickstart.svg"
2+
3+
Set DisableCursor true
4+
Set FontSize 22
5+
Set Theme "one dark"
6+
Set TransparentBackground "true"
7+
Set Cols 82
8+
Set Rows 14
9+
Set EndBuffer 2s
10+
11+
Exec "dotnet run --project .\Spectre.Docs.Examples\ --no-build showcase quick-start"
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
@page "/cli"
2+
@using Spectre.Console
3+
@inject IMarkdownContentService<SpectreConsoleCliFrontMatter> CliContentServices
4+
@inject ContentEngineOptions ContentEngineOptions
5+
6+
<PageTitle>Spectre.Console.Cli Documentation - @ContentEngineOptions.SiteTitle</PageTitle>
7+
8+
<article class="prose dark:prose-invert max-w-none">
9+
<h1>Spectre.Console.Cli Documentation</h1>
10+
<p class="lead text-lg text-base-600 dark:text-base-400">
11+
Build powerful command-line applications with Spectre.Console.Cli, a modern framework with a focus on type safety and developer experience.
12+
</p>
13+
14+
<h2>Start Here</h2>
15+
<p>Get Spectre.Console.Cli running in seconds:</p>
16+
<CodeBlock Language="bash">dotnet add package Spectre.Console.Cli</CodeBlock>
17+
18+
<p>Then try this quick example that creates a simple greeting command:</p>
19+
<CodeBlock Language="csharp:xmldocid">
20+
T:Spectre.Docs.Cli.Examples.DemoApps.QuickStart.GreetSettings
21+
T:Spectre.Docs.Cli.Examples.DemoApps.QuickStart.GreetCommand
22+
</CodeBlock>
23+
24+
<p>In your Program.cs, wire it up:</p>
25+
<CodeBlock Language="csharp:xmldocid,bodyonly">M:Spectre.Docs.Cli.Examples.DemoApps.QuickStart.HomePageExample.Run(System.String[])</CodeBlock>
26+
27+
28+
<p>Run it with <code>dotnet run -- World --count 3</code> to see typed argument parsing in action.</p>
29+
30+
<p>You should see something like this:</p>
31+
32+
<Screenshot Src="/assets/cli-quickstart.svg" Alt="Screencast of Spectre.Console in action"></Screenshot>
33+
34+
<hr />
35+
36+
<h2>Explore the Documentation</h2>
37+
<p>
38+
From simple single-command tools to complex CLI applications with nested commands and dependency injection,
39+
we've got you covered. The tutorials will walk you through the fundamentals, while the how-to guides
40+
tackle specific scenarios you'll encounter in real projects.
41+
</p>
42+
43+
@foreach (var group in _groupedPages.OrderBy(g => GetSectionOrder(g.Key)))
44+
{
45+
<div class="mb-8">
46+
<h2>@group.Key</h2>
47+
<ul>
48+
@foreach (var page in group.Value.OrderBy(p => p.FrontMatter.Order).ThenBy(p => p.FrontMatter.Title))
49+
{
50+
<li>
51+
<a href="@(page.Url)">@(page.FrontMatter.Title)</a>
52+
@if (!string.IsNullOrWhiteSpace(page.FrontMatter.Description))
53+
{
54+
<span class="text-base-500 dark:text-base-400"> - @(page.FrontMatter.Description)</span>
55+
}
56+
</li>
57+
}
58+
</ul>
59+
</div>
60+
}
61+
</article>
62+
63+
@code {
64+
private Dictionary<string, List<MarkdownContentPage<SpectreConsoleCliFrontMatter>>> _groupedPages = new();
65+
66+
private static readonly Dictionary<string, string> SectionNames = new()
67+
{
68+
{ "tutorials", "Tutorials" },
69+
{ "how--to", "How-To Guides" },
70+
{ "reference", "Reference" },
71+
{ "explanation", "Explanation" }
72+
};
73+
74+
private static readonly Dictionary<string, int> SectionOrder = new()
75+
{
76+
{ "Tutorials", 1 },
77+
{ "How-To Guides", 2 },
78+
{ "Explanation", 3 },
79+
{ "Reference", 4 }
80+
};
81+
82+
private static int GetSectionOrder(string sectionName) =>
83+
SectionOrder.GetValueOrDefault(sectionName, 99);
84+
85+
protected override async Task OnInitializedAsync()
86+
{
87+
var allPages = await CliContentServices.GetAllContentPagesAsync();
88+
89+
// Group pages by their first path segment after /cli/
90+
foreach (var page in allPages)
91+
{
92+
var pathParts = page.Url.Split('/', StringSplitOptions.RemoveEmptyEntries);
93+
if (pathParts.Length >= 2)
94+
{
95+
var sectionKey = pathParts[1]; // e.g., "tutorials", "how--to"
96+
var sectionName = SectionNames.GetValueOrDefault(sectionKey, sectionKey);
97+
98+
if (!_groupedPages.ContainsKey(sectionName))
99+
{
100+
_groupedPages[sectionName] = new List<MarkdownContentPage<SpectreConsoleCliFrontMatter>>();
101+
}
102+
_groupedPages[sectionName].Add(page);
103+
}
104+
}
105+
106+
await base.OnInitializedAsync();
107+
}
108+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
@page "/console"
2+
@using Spectre.Console
3+
@inject IMarkdownContentService<SpectreConsoleFrontMatter> ConsoleContentServices
4+
@inject ContentEngineOptions ContentEngineOptions
5+
6+
<PageTitle>Spectre.Console Documentation - @ContentEngineOptions.SiteTitle</PageTitle>
7+
8+
<article class="prose dark:prose-invert max-w-none">
9+
<h1>Spectre.Console Documentation</h1>
10+
<p class="lead text-lg text-base-600 dark:text-base-400">
11+
Create beautiful, cross-platform console applications with Spectre.Console.
12+
</p>
13+
14+
<h2>Start Here</h2>
15+
<p>Get Spectre.Console running in seconds:</p>
16+
<CodeBlock Language="bash">dotnet add package Spectre.Console</CodeBlock>
17+
18+
<p>Then try this quick example that demonstrates styled text, a table, and a status spinner:</p>
19+
<CodeBlock Language="csharp:xmldocid,bodyonly">M:Spectre.Docs.Examples.Showcase.QuickStartSample.Run(Spectre.Console.IAnsiConsole)</CodeBlock>
20+
21+
<p>You're application should look something like this:</p>
22+
23+
<Screenshot Src="/assets/quickstart.svg" Alt="Screencast of Spectre.Console in action"></Screenshot>
24+
25+
<hr />
26+
27+
<h2>Explore the Documentation</h2>
28+
<p>
29+
Whether you're just getting started or looking to master advanced features, we've organized everything
30+
to help you find what you need. Start with the tutorials to build a solid foundation, then dive into
31+
specific topics as your projects grow.
32+
</p>
33+
34+
@foreach (var group in _groupedPages.OrderBy(g => GetSectionOrder(g.Key)))
35+
{
36+
<div class="mb-8">
37+
<h2>@group.Key</h2>
38+
<ul>
39+
@foreach (var page in group.Value.OrderBy(p => p.FrontMatter.Order).ThenBy(p => p.FrontMatter.Title))
40+
{
41+
<li>
42+
<a href="@(page.Url)">@(page.FrontMatter.Title)</a>
43+
@if (!string.IsNullOrWhiteSpace(page.FrontMatter.Description))
44+
{
45+
<span class="text-base-500 dark:text-base-400"> - @(page.FrontMatter.Description)</span>
46+
}
47+
</li>
48+
}
49+
</ul>
50+
</div>
51+
}
52+
</article>
53+
54+
@code {
55+
private Dictionary<string, List<MarkdownContentPage<SpectreConsoleFrontMatter>>> _groupedPages = new();
56+
57+
private static readonly Dictionary<string, string> SectionNames = new()
58+
{
59+
{ "tutorials", "Tutorials" },
60+
{ "how--to", "How-To Guides" },
61+
{ "widgets", "Widgets" },
62+
{ "live", "Live Rendering" },
63+
{ "prompts", "Prompts" },
64+
{ "reference", "Reference" },
65+
{ "explanation", "Explanation" }
66+
};
67+
68+
private static readonly Dictionary<string, int> SectionOrder = new()
69+
{
70+
{ "Tutorials", 1 },
71+
{ "How-To Guides", 2 },
72+
{ "Widgets", 3 },
73+
{ "Prompts", 4 },
74+
{ "Live Rendering", 5 },
75+
{ "Explanation", 6 },
76+
{ "Reference", 7 },
77+
};
78+
79+
private static int GetSectionOrder(string sectionName) =>
80+
SectionOrder.GetValueOrDefault(sectionName, 99);
81+
82+
protected override async Task OnInitializedAsync()
83+
{
84+
var allPages = await ConsoleContentServices.GetAllContentPagesAsync();
85+
86+
// Group pages by their first path segment after /console/
87+
foreach (var page in allPages)
88+
{
89+
var pathParts = page.Url.Split('/', StringSplitOptions.RemoveEmptyEntries);
90+
if (pathParts.Length >= 2)
91+
{
92+
var sectionKey = pathParts[1]; // e.g., "tutorials", "how--to", "widgets"
93+
var sectionName = SectionNames.GetValueOrDefault(sectionKey, sectionKey);
94+
95+
if (!_groupedPages.ContainsKey(sectionName))
96+
{
97+
_groupedPages[sectionName] = [];
98+
}
99+
_groupedPages[sectionName].Add(page);
100+
}
101+
}
102+
103+
await base.OnInitializedAsync();
104+
}
105+
}

0 commit comments

Comments
 (0)