From 45da04bb188b7e3e845c8ce0893287ecebeb1335 Mon Sep 17 00:00:00 2001 From: Khwezi Mngoma Date: Sat, 16 May 2026 11:57:01 +0200 Subject: [PATCH] Implemented navigation shelf with nav draweer button --- ShopAdmin/Components/Layout/MainLayout.razor | 21 ++- ShopAdmin/Components/Pages/NavShelf.razor | 80 +++++++++ ShopAdmin/Components/Pages/NavShelf.razor.css | 159 ++++++++++++++++++ ShopAdmin/Components/_Imports.razor | 1 + ShopAdmin/wwwroot/app.css | 22 ++- 5 files changed, 276 insertions(+), 7 deletions(-) create mode 100644 ShopAdmin/Components/Pages/NavShelf.razor create mode 100644 ShopAdmin/Components/Pages/NavShelf.razor.css diff --git a/ShopAdmin/Components/Layout/MainLayout.razor b/ShopAdmin/Components/Layout/MainLayout.razor index 8759351..2058661 100644 --- a/ShopAdmin/Components/Layout/MainLayout.razor +++ b/ShopAdmin/Components/Layout/MainLayout.razor @@ -9,7 +9,7 @@ - +
LiteCharms Shop Admin Console @@ -17,10 +17,25 @@ -
+ + +
@Body
- \ No newline at end of file + + +@code { + private bool isShelfExpanded { get; set; } = false; + + private void OnShelfStateChanged(bool newState) + { + isShelfExpanded = newState; + + // This forces Blazor to re-evaluate the DOM, instantly applying + // the "shelf-open" and "shifted-canvas" CSS utility classes. + StateHasChanged(); + } +} \ No newline at end of file diff --git a/ShopAdmin/Components/Pages/NavShelf.razor b/ShopAdmin/Components/Pages/NavShelf.razor new file mode 100644 index 0000000..2ad4566 --- /dev/null +++ b/ShopAdmin/Components/Pages/NavShelf.razor @@ -0,0 +1,80 @@ +@inject NavigationManager NavManager + + + +
+ + + +@code { + [Parameter] public bool IsOpen { get; set; } = false; + [Parameter] public EventCallback IsOpenChanged { get; set; } + + private async Task ToggleShelf() + { + IsOpen = !IsOpen; + await IsOpenChanged.InvokeAsync(IsOpen); + } + + private async Task CloseShelf() + { + if (IsOpen) + { + IsOpen = false; + await IsOpenChanged.InvokeAsync(IsOpen); + } + } +} \ No newline at end of file diff --git a/ShopAdmin/Components/Pages/NavShelf.razor.css b/ShopAdmin/Components/Pages/NavShelf.razor.css new file mode 100644 index 0000000..d1f6e8b --- /dev/null +++ b/ShopAdmin/Components/Pages/NavShelf.razor.css @@ -0,0 +1,159 @@ +/* --- 1. The Flyout Side Panel --- */ +.nav-shelf-panel { + position: fixed; + top: var(--header-height); /* Drops clean below your top-bar */ + right: -300px; /* Hidden by default */ + width: 300px; + height: calc(100vh - var(--header-height)); + background-color: var(--shelf-bg); + border-left: 1px solid rgba(144, 224, 239, 0.15); + z-index: 2000; + display: flex; + flex-direction: column; + padding: 2rem 1.5rem; + box-sizing: border-box; + transition: right 0.35s cubic-bezier(0.16, 1, 0.3, 1); + box-shadow: -15px 0 40px rgba(0, 0, 0, 0.6); +} + + .nav-shelf-panel.shelf-open { + right: 0; /* Animate into viewport */ + } + +/* --- 2. The Floating Mechanical Grip Handle --- */ +.shelf-grip { + position: fixed; + top: calc(var(--header-height) + 24px); + right: 0; + width: 44px; + height: 44px; + background-color: var(--shelf-bg); + border: 1px solid var(--border-mid-opacity); + border-right: none; + border-radius: 8px 0 0 8px; + color: var(--payoff-color); + cursor: pointer; + z-index: 2001; + display: flex; + align-items: center; + justify-content: center; + transition: right 0.35s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.2s ease; +} + + /* Moves out dynamically alongside the shelf edge when open */ + .shelf-grip.grip-open { + right: 300px; + background-color: var(--shelf-bg); + border-color: var(--border-low-opacity); + } + + .shelf-grip:hover { + background-color: #112930; + color: var(--text-white); + } + +.grip-icon { + width: 20px; + height: 20px; + display: flex; + align-items: center; + justify-content: center; +} + +/* --- 3. Panel Internal Layout & Links --- */ +.shelf-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 2rem; + padding-bottom: 1rem; + border-bottom: 1px solid rgba(144, 224, 239, 0.1); +} + + .shelf-header h3 { + font-size: 1.1rem; + font-weight: 700; + color: var(--text-white); + margin: 0; + } + +.environment-badge { + font-size: 0.65rem; + font-family: monospace; + font-weight: bold; + padding: 2px 6px; + background: rgba(0, 150, 199, 0.15); + border: 1px solid rgba(0, 150, 199, 0.4); + color: var(--payoff-color); + border-radius: 4px; +} + +.shelf-navigation { + display: flex; + flex-direction: column; + gap: 8px; +} + +/* Deep selection matching Blazor's active class matching system */ +::deep .shelf-link { + display: flex; + align-items: center; + gap: 14px; + color: rgba(255, 255, 255, 0.65); + text-decoration: none; + padding: 12px 16px; + font-size: 0.95rem; + font-weight: 500; + border-radius: 6px; + transition: all 0.2s ease; +} + + ::deep .shelf-link:hover { + background-color: rgba(0, 150, 199, 0.08); + color: var(--text-white); + } + + ::deep .shelf-link.active { + background-color: var(--brand-blue); + color: var(--text-white); + font-weight: 600; + } + +.link-icon { + width: 18px; + height: 18px; + opacity: 0.8; +} + +.icon-warn { + color: var(--payoff-color); +} + +.shelf-divider { + height: 1px; + background: rgba(144, 224, 239, 0.1); + margin: 1rem 0; +} + +/* --- 4. Content Blur/Backdrop Overlay --- */ +.shelf-backdrop { + position: fixed; + top: var(--header-height); + left: 0; + width: 100vw; + height: calc(100vh - var(--header-height)); + background-color: rgba(0, 0, 0, 0.25); + backdrop-filter: blur(0px); + z-index: 1999; + opacity: 0; + visibility: hidden; + pointer-events: none; + transition: opacity 0.3s ease, backdrop-filter 0.3s ease; +} + + .shelf-backdrop.backdrop-active { + opacity: 1; + visibility: visible; + pointer-events: auto; + backdrop-filter: blur(3px); + } diff --git a/ShopAdmin/Components/_Imports.razor b/ShopAdmin/Components/_Imports.razor index 5fd3442..6e2128b 100644 --- a/ShopAdmin/Components/_Imports.razor +++ b/ShopAdmin/Components/_Imports.razor @@ -9,3 +9,4 @@ @using ShopAdmin @using ShopAdmin.Components @using ShopAdmin.Components.Layout +@using ShopAdmin.Components.Pages diff --git a/ShopAdmin/wwwroot/app.css b/ShopAdmin/wwwroot/app.css index c5fdd03..5944cd6 100644 --- a/ShopAdmin/wwwroot/app.css +++ b/ShopAdmin/wwwroot/app.css @@ -1,10 +1,21 @@ /* --- 1. Variables & Global Reset --- */ :root { - --bar-bg: #001219; - --text-white: #ffffff; + /* --- BRAND CORES --- */ --brand-blue: #0096c7; - --hover-blue: #00b4d8; + --hover-blue: #4dabff; + /* --- NEW CANVAS BALANCE --- */ + /* Lighter, slate-tinted midnight for the main workspace body */ + --body-bg: #0b1519; + /* Deep obsidian for the fixed navigation anchors */ + --bar-bg: #03090b; + /* The NavShelf background: sits right between the bar and body */ + --shelf-bg: #070e10; + /* --- TYPOGRAPHY & LINES --- */ + --text-white: #f8f9fa; + /* Soft cyan-gray tone for secondary text and structural borders */ --payoff-color: #90e0ef; + --border-low-opacity: rgba(144, 224, 239, 0.08); + --border-mid-opacity: rgba(144, 224, 239, 0.18); --header-height: 92px; } @@ -31,7 +42,7 @@ html, body { display: flex; align-items: center; justify-content: space-between; - padding: 0 4rem; + padding: 0 4rem 0 1rem; z-index: 1000; border-bottom: 1px solid rgba(144, 224, 239, 0.15); } @@ -93,6 +104,8 @@ html, body { padding-top: var(--header-height); box-sizing: border-box; background-color: var(--bar-bg); + position: relative; + transition: padding-right 0.35s cubic-bezier(0.16, 1, 0.3, 1); } main { @@ -100,6 +113,7 @@ main { display: flex; flex-direction: column; width: 100%; + background-color: var(--body-bg) !important; } /* --- Responsive Logic --- */