Skip to content

Commit 5f70726

Browse files
authored
Merge pull request #10 from shellui-dev/feat/nav-suite
feat: nav-suite : sidebar layout variant + search dialog + mobile bar
2 parents 765153a + 14e517e commit 5f70726

25 files changed

Lines changed: 1009 additions & 30 deletions

examples/ShellDocs.Preview/Components/Pages/DocsPage.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ else
2020
<div class="doc-not-found">
2121
<h1>Page not found</h1>
2222
<p>The page <code>@Path</code> doesn't exist yet.</p>
23-
<p><a href="/docs/introduction">Back to introduction</a></p>
23+
<p><a href="/docs/introduction"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:0.35rem"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>Back to introduction</a></p>
2424
</div>
2525
}
2626

examples/ShellDocs.Preview/Components/Pages/Home.razor

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,10 @@ Works in Server, WASM, and static output.
196196
<h2>Built by the ShellUI team.</h2>
197197
<p>Same taste, same craftsmanship, same install-and-go DX. Free forever, MIT-licensed, community-driven.</p>
198198
<div class="hero-actions">
199-
<a class="btn primary" href="/docs/introduction">Read the docs <span>→</span></a>
199+
<a class="btn primary" href="/docs/introduction">
200+
<span>Read the docs</span>
201+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
202+
</a>
200203
<a class="btn ghost" href="https://github.com/shellui-dev/shelldocs" target="_blank" rel="noopener">Contribute on GitHub</a>
201204
</div>
202205
</div>
@@ -328,16 +331,18 @@ Works in Server, WASM, and static output.
328331
.btn {
329332
display: inline-flex;
330333
align-items: center;
331-
gap: 0.5rem;
332-
padding: 0.65rem 1.25rem;
334+
gap: 0.4rem;
335+
padding: 0.6rem 1.15rem;
333336
border-radius: 9999px;
334337
border: 1px solid transparent;
335338
text-decoration: none;
336339
font-weight: 500;
337340
font-size: 0.9rem;
338341
letter-spacing: -0.005em;
342+
white-space: nowrap;
339343
transition: background 150ms, border-color 150ms, color 150ms;
340344
}
345+
.btn svg { width: 0.9rem; height: 0.9rem; flex-shrink: 0; }
341346
.btn.primary {
342347
background: var(--primary);
343348
color: var(--primary-foreground);

examples/ShellDocs.Preview/Components/Pages/Showcase.razor

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@
4545
<div class="show-cta">
4646
<h2>Ship your docs on ShellDocs?</h2>
4747
<p>Open a PR to get listed here. Include a screenshot, a one-line description, and your live URL.</p>
48-
<a class="btn primary" href="https://github.com/shellui-dev/shelldocs" target="_blank" rel="noopener">Submit on GitHub →</a>
48+
<a class="btn primary" href="https://github.com/shellui-dev/shelldocs" target="_blank" rel="noopener">
49+
<span>Submit on GitHub</span>
50+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="14" height="14"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
51+
</a>
4952
</div>
5053
</div>
5154

examples/ShellDocs.Preview/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
o.SiteName = "ShellDocs";
1515
o.SiteTagline = "the docs framework for .NET";
1616
o.GitHubRepo = "shellui-dev/shelldocs";
17+
// Try the new floating-sidebar variant. Flip to TopNav for the classic look.
18+
o.LayoutVariant = DocsLayoutVariant.Sidebar;
1719
o.AddNavMenu("Documentation",
1820
new NavMenuItem("Getting Started", "/docs/introduction",
1921
"Install, configure, and ship your first ShellDocs site.",

src/ShellDocs.Components/Chrome/DocsHeader.razor

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
@inject ShellDocsOptions Options
22
@inject ShellDocs.Components.Chrome.MobileNavState MobileNav
3+
@inject IJSRuntime JS
34

45
<header class="docs-header">
56
<div class="docs-header-inner">
@@ -62,14 +63,17 @@
6263
</nav>
6364

6465
<div class="docs-header-actions">
65-
<button type="button" class="docs-header-search" aria-label="Search">
66-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35"/></svg>
67-
<span class="docs-header-search-label">Search</span>
68-
<span class="docs-header-kbd">
69-
<kbd>Ctrl</kbd>
70-
<kbd>K</kbd>
71-
</span>
72-
</button>
66+
@if (ShowSearch)
67+
{
68+
<button type="button" class="docs-header-search" @onclick="OpenSearch" aria-label="Search">
69+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35"/></svg>
70+
<span class="docs-header-search-label">Search</span>
71+
<span class="docs-header-kbd">
72+
<kbd>Ctrl</kbd>
73+
<kbd>K</kbd>
74+
</span>
75+
</button>
76+
}
7377

7478
<ThemeToggle />
7579

@@ -86,9 +90,15 @@
8690
@implements IDisposable
8791

8892
@code {
93+
/* Search chip toggle. Marketing pages (HomeLayout) pass false — visitors
94+
there aren't looking to grep docs. Docs pages (DocsLayout TopNav variant)
95+
leave the default true. */
96+
[Parameter] public bool ShowSearch { get; set; } = true;
97+
8998
private const string DefaultIcon =
9099
"<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\"/></svg>";
91100

92101
protected override void OnInitialized() => MobileNav.OnChange += StateHasChanged;
93102
public void Dispose() => MobileNav.OnChange -= StateHasChanged;
103+
private Task OpenSearch() => JS.InvokeVoidAsync("shelldocsSearch.open").AsTask();
94104
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@inject MobileNavState MobileNav
2+
@inject IJSRuntime JS
3+
4+
<div class="docs-mobile-bar" role="toolbar" aria-label="Mobile toolbar">
5+
<button type="button" class="docs-mobile-tool" @onclick="MobileNav.Toggle" aria-label="Toggle navigation">
6+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
7+
@if (MobileNav.IsOpen)
8+
{
9+
<line x1="18" y1="6" x2="6" y2="18"/>
10+
<line x1="6" y1="6" x2="18" y2="18"/>
11+
}
12+
else
13+
{
14+
<line x1="3" y1="6" x2="21" y2="6"/>
15+
<line x1="3" y1="12" x2="21" y2="12"/>
16+
<line x1="3" y1="18" x2="21" y2="18"/>
17+
}
18+
</svg>
19+
</button>
20+
21+
<button type="button" class="docs-mobile-tool" @onclick="OpenSearch" aria-label="Search">
22+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35"/></svg>
23+
</button>
24+
25+
<ThemeToggle />
26+
</div>
27+
28+
@code {
29+
private Task OpenSearch() => JS.InvokeVoidAsync("shelldocsSearch.open").AsTask();
30+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.docs-mobile-bar {
2+
position: sticky;
3+
top: 0;
4+
z-index: 30;
5+
display: flex;
6+
align-items: center;
7+
gap: 0.25rem;
8+
padding: 0.5rem 0.75rem;
9+
background: color-mix(in oklch, var(--background) 90%, transparent);
10+
backdrop-filter: saturate(180%) blur(12px);
11+
-webkit-backdrop-filter: saturate(180%) blur(12px);
12+
border-bottom: 1px solid var(--border);
13+
}
14+
@media (min-width: 1024px) {
15+
.docs-mobile-bar { display: none; }
16+
}
17+
18+
::deep .docs-mobile-tool {
19+
display: inline-flex;
20+
align-items: center;
21+
justify-content: center;
22+
width: 2rem;
23+
height: 2rem;
24+
padding: 0;
25+
background: transparent;
26+
border: 0;
27+
border-radius: calc(var(--radius) - 3px);
28+
color: var(--muted-foreground);
29+
cursor: pointer;
30+
transition: color 150ms, background 150ms;
31+
}
32+
::deep .docs-mobile-tool:hover { color: var(--foreground); background: var(--muted); }
33+
::deep .docs-mobile-tool svg { width: 1.15rem; height: 1.15rem; }
34+
35+
/* Push ThemeToggle to the right end */
36+
::deep .theme-toggle { margin-left: auto; }
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@inject ShellDocsOptions Options
2+
@inject IJSRuntime JS
3+
@inject SidebarCollapseState Collapse
4+
5+
<div class="docs-sidebar-header">
6+
<div class="docs-sidebar-brand-row">
7+
<a class="docs-sidebar-brand" href="/">
8+
<span class="docs-sidebar-logo-dot"></span>
9+
<span class="docs-sidebar-brand-name">@(!string.IsNullOrEmpty(Options.SiteName) ? Options.SiteName : "Docs")</span>
10+
</a>
11+
<button type="button" class="docs-sidebar-collapse" @onclick="Collapse.Toggle" aria-label="Collapse sidebar" title="Collapse sidebar">
12+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
13+
<rect x="3" y="4" width="18" height="16" rx="2"/>
14+
<line x1="9" y1="4" x2="9" y2="20"/>
15+
</svg>
16+
</button>
17+
</div>
18+
19+
<button type="button" class="docs-sidebar-search" @onclick="OpenSearch" aria-label="Search">
20+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35"/></svg>
21+
<span class="docs-sidebar-search-label">Search…</span>
22+
<span class="docs-sidebar-search-kbd">
23+
<kbd>@ShortcutKey</kbd>
24+
<kbd>K</kbd>
25+
</span>
26+
</button>
27+
</div>
28+
29+
@code {
30+
private string ShortcutKey => OperatingSystem.IsMacOS() ? "" : "Ctrl";
31+
private Task OpenSearch() => JS.InvokeVoidAsync("shelldocsSearch.open").AsTask();
32+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
.docs-sidebar-header {
2+
display: flex;
3+
flex-direction: column;
4+
gap: 0.75rem;
5+
padding: 0.85rem 0.75rem 0.5rem 1rem;
6+
flex-shrink: 0;
7+
}
8+
9+
.docs-sidebar-brand-row {
10+
display: flex;
11+
align-items: center;
12+
justify-content: space-between;
13+
gap: 0.5rem;
14+
}
15+
16+
.docs-sidebar-brand {
17+
display: inline-flex;
18+
align-items: center;
19+
gap: 0.5rem;
20+
text-decoration: none;
21+
color: var(--foreground);
22+
font-weight: 600;
23+
font-size: 0.95rem;
24+
letter-spacing: -0.01em;
25+
padding: 0.15rem 0.2rem;
26+
border-radius: calc(var(--radius) - 3px);
27+
transition: opacity 150ms;
28+
min-width: 0;
29+
flex: 1;
30+
}
31+
.docs-sidebar-brand:hover { opacity: 0.8; }
32+
33+
.docs-sidebar-collapse {
34+
display: inline-flex;
35+
align-items: center;
36+
justify-content: center;
37+
width: 1.85rem;
38+
height: 1.85rem;
39+
padding: 0;
40+
background: transparent;
41+
border: 0;
42+
border-radius: calc(var(--radius) - 3px);
43+
color: var(--muted-foreground);
44+
cursor: pointer;
45+
transition: color 150ms, background 150ms;
46+
flex-shrink: 0;
47+
}
48+
.docs-sidebar-collapse:hover { color: var(--foreground); background: var(--muted); }
49+
.docs-sidebar-collapse svg { width: 1rem; height: 1rem; }
50+
.docs-sidebar-logo-dot {
51+
width: 1.125rem;
52+
height: 1.125rem;
53+
border-radius: 4px;
54+
background: var(--foreground);
55+
flex-shrink: 0;
56+
}
57+
58+
.docs-sidebar-search {
59+
display: inline-flex;
60+
align-items: center;
61+
gap: 0.5rem;
62+
padding: 0.4rem 0.5rem 0.4rem 0.6rem;
63+
background: var(--muted);
64+
border: 1px solid transparent;
65+
color: var(--muted-foreground);
66+
border-radius: calc(var(--radius) - 2px);
67+
cursor: pointer;
68+
font-family: inherit;
69+
font-size: 0.8125rem;
70+
text-align: left;
71+
width: 100%;
72+
transition: background 150ms, color 150ms, border-color 150ms;
73+
}
74+
.docs-sidebar-search:hover {
75+
color: var(--foreground);
76+
border-color: var(--border);
77+
}
78+
.docs-sidebar-search svg { width: 0.875rem; height: 0.875rem; flex-shrink: 0; }
79+
.docs-sidebar-search-label { flex: 1; }
80+
.docs-sidebar-search-kbd { display: inline-flex; gap: 0.2rem; }
81+
.docs-sidebar-search-kbd kbd {
82+
font-family: var(--font-mono);
83+
font-size: 0.62rem;
84+
font-weight: 600;
85+
background: var(--background);
86+
border: 1px solid var(--border);
87+
padding: 0.05rem 0.3rem;
88+
border-radius: 4px;
89+
color: var(--muted-foreground);
90+
line-height: 1;
91+
min-width: 1.1rem;
92+
text-align: center;
93+
}

src/ShellDocs.Components/Chrome/PackageSelector.razor

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
</svg>
99
</span>
1010
<span class="pkg-value">@Selected.Title</span>
11-
<svg class="pkg-chevrons" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
12-
<polyline points="8 10 12 6 16 10"/>
13-
<polyline points="16 14 12 18 8 14"/>
11+
<svg class="pkg-chevron @(_open ? "open" : "")" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
12+
<polyline points="6 9 12 15 18 9"/>
1413
</svg>
1514
</button>
1615

0 commit comments

Comments
 (0)