Init
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<div class="flex min-h-screen">
|
||||
|
||||
@* Desktop sidebar — collapsible *@
|
||||
<aside class="@($"hidden shrink-0 border-r border-sidebar-border bg-sidebar transition-all duration-300 ease-in-out md:block {(sidebarCollapsed ? "w-16" : "w-64")}")">
|
||||
<NavMenu Collapsed="sidebarCollapsed" OnToggleSidebar="ToggleSidebar" />
|
||||
</aside>
|
||||
|
||||
@* Mobile overlay *@
|
||||
@if (mobileOpen)
|
||||
{
|
||||
<div class="fixed inset-0 z-40 flex md:hidden">
|
||||
@* Backdrop *@
|
||||
<div class="fixed inset-0 bg-black/60 backdrop-blur-sm" @onclick="CloseMobile"></div>
|
||||
|
||||
@* Drawer *@
|
||||
<aside class="relative z-50 flex w-72 flex-col bg-sidebar shadow-xl">
|
||||
@* Close button *@
|
||||
<button class="absolute right-3 top-3 rounded-md p-1 text-muted-foreground transition-colors hover:bg-sidebar-accent hover:text-sidebar-foreground"
|
||||
@onclick="CloseMobile">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M18 6 6 18" /><path d="m6 6 12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
<NavMenu OnNavigated="CloseMobile" />
|
||||
</aside>
|
||||
</div>
|
||||
}
|
||||
|
||||
@* Main content *@
|
||||
<div class="flex flex-1 flex-col overflow-hidden">
|
||||
@* Top bar *@
|
||||
<header class="sticky top-0 z-10 flex h-14 items-center gap-4 border-b border-border bg-background/80 px-4 backdrop-blur-sm md:px-6">
|
||||
@* Mobile menu button *@
|
||||
<button class="rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground md:hidden"
|
||||
@onclick="OpenMobile">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="4" x2="20" y1="12" y2="12" /><line x1="4" x2="20" y1="6" y2="6" /><line x1="4" x2="20" y1="18" y2="18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
@* Desktop collapse toggle *@
|
||||
<button class="hidden rounded-md p-1.5 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground md:inline-flex"
|
||||
@onclick="ToggleSidebar"
|
||||
title="@(sidebarCollapsed ? "Expand sidebar" : "Collapse sidebar")">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect width="18" height="18" x="3" y="3" rx="2" />
|
||||
<path d="M9 3v18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="flex-1 text-sm font-medium text-muted-foreground">
|
||||
Enciphered UI Components
|
||||
</div>
|
||||
<a href="https://learn.microsoft.com/aspnet/core/"
|
||||
target="_blank"
|
||||
class="text-sm text-muted-foreground transition-colors hover:text-foreground">
|
||||
About
|
||||
</a>
|
||||
</header>
|
||||
|
||||
@* Page content *@
|
||||
<main class="flex-1 overflow-auto p-4 md:p-6">
|
||||
@Body
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool sidebarCollapsed;
|
||||
private bool mobileOpen;
|
||||
|
||||
private void ToggleSidebar() => sidebarCollapsed = !sidebarCollapsed;
|
||||
private void OpenMobile() => mobileOpen = true;
|
||||
private void CloseMobile() => mobileOpen = false;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
@* Sidebar header *@
|
||||
<div class="flex h-14 items-center border-b border-sidebar-border px-4">
|
||||
<button type="button"
|
||||
class="flex items-center gap-2 font-semibold text-sidebar-foreground rounded-md transition-colors hover:bg-sidebar-accent px-1 py-1"
|
||||
title="Toggle sidebar"
|
||||
@onclick="HandleToggle">
|
||||
<img src="enci_white.svg" alt="Logo" class="h-6 w-6 shrink-0 transition-transform duration-300" />
|
||||
@if (!Collapsed)
|
||||
{
|
||||
<span class="text-sm tracking-tight">Enciphered</span>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@* Navigation *@
|
||||
<div class="flex flex-col gap-1 p-3">
|
||||
@if (!Collapsed)
|
||||
{
|
||||
<p class="mb-1 px-2 text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
||||
Navigation
|
||||
</p>
|
||||
}
|
||||
|
||||
<NavLink class="@NavLinkClass" href="" Match="NavLinkMatch.All"
|
||||
ActiveClass="bg-sidebar-accent text-accent-foreground"
|
||||
@onclick="HandleNav"
|
||||
title="Home">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8" />
|
||||
<path d="M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||
</svg>
|
||||
@if (!Collapsed)
|
||||
{
|
||||
<span>Home</span>
|
||||
}
|
||||
</NavLink>
|
||||
|
||||
<NavLink class="@NavLinkClass" href="weather"
|
||||
ActiveClass="bg-sidebar-accent text-accent-foreground"
|
||||
@onclick="HandleNav"
|
||||
title="Weather">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z" />
|
||||
</svg>
|
||||
@if (!Collapsed)
|
||||
{
|
||||
<span>Weather</span>
|
||||
}
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter] public bool Collapsed { get; set; }
|
||||
[Parameter] public EventCallback OnToggleSidebar { get; set; }
|
||||
[Parameter] public EventCallback OnNavigated { get; set; }
|
||||
|
||||
private string NavLinkClass => Collapsed
|
||||
? "nav-link group flex items-center justify-center rounded-md p-2 text-sm font-medium text-sidebar-foreground transition-colors hover:bg-sidebar-accent"
|
||||
: "nav-link group flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium text-sidebar-foreground transition-colors hover:bg-sidebar-accent";
|
||||
|
||||
private async Task HandleToggle()
|
||||
{
|
||||
if (OnToggleSidebar.HasDelegate)
|
||||
await OnToggleSidebar.InvokeAsync();
|
||||
}
|
||||
|
||||
private async Task HandleNav()
|
||||
{
|
||||
if (OnNavigated.HasDelegate)
|
||||
await OnNavigated.InvokeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user